@capxul/sdk 1.0.0-alpha.19 → 1.0.0-alpha.21

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/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as toSessionToken, C as toEpochSeconds, D as toPublishableKey, E as toOrgId, F as Errors, I as isCapxulError, M as decodeConvexError, N as CapxulError, O as toPublishableKeyId, P as EXPECTED_OPERATION_OUTCOMES, S as toEpochMs, T as toKycTier, _ as toChainId, b as toDurationMs, c as BYTES32_RE, d as toAccountId, f as toAddress, g as toAuthUserId, h as toAppId, j as toSubAccountId, k as toRoleKey, l as EVM_ADDRESS_RE$1, m as toAnonymousDistinctId, n as BrowserAuthCacheAdapter, o as AuthCachePortTag, p as toAllowedOrigin, s as APP_ID_RE, t as InMemoryAuthCacheAdapter, u as SUPPORTED_CURRENCY_CODES, v as toCountryCode, w as toJwtToken, x as toEmail, y as toCurrencyCode } from "./InMemoryAuthCacheAdapter-BuVZpnSx.mjs";
1
+ import { A as toSessionToken, C as toEpochSeconds, D as toPublishableKey, E as toOrgId, F as Errors, I as isCapxulError, M as decodeConvexError, N as CapxulError, O as toPublishableKeyId, P as EXPECTED_OPERATION_OUTCOMES, S as toEpochMs, T as toKycTier, _ as toChainId, b as toDurationMs, c as BYTES32_RE, d as toAccountId, f as toAddress, g as toAuthUserId, h as toAppId, j as toSubAccountId, k as toRoleKey, l as EVM_ADDRESS_RE$1, m as toAnonymousDistinctId, n as BrowserAuthCacheAdapter, o as AuthCachePortTag, p as toAllowedOrigin, s as APP_ID_RE, t as InMemoryAuthCacheAdapter, u as SUPPORTED_CURRENCY_CODES, v as toCountryCode, w as toJwtToken, x as toEmail, y as toCurrencyCode } from "./InMemoryAuthCacheAdapter-CHYpYyk5.mjs";
2
2
  import { concat, formatUnits, keccak256, padHex, parseUnits, recoverAddress, stringToHex, toBytes, toEventSelector, toFunctionSelector } from "viem";
3
3
  import { Context, Data, Deferred, Duration, Effect, Either, Exit, Layer, Ref, Request, Scope } from "effect";
4
4
  import { getFunctionName, makeFunctionReference } from "convex/server";
@@ -249,13 +249,31 @@ function parseV8StackFrames(error) {
249
249
  }
250
250
  return frames;
251
251
  }
252
+ /** Fixed, leak-safe frame used when the error carries no parseable stack. */
253
+ const SDK_BOUNDARY_FILENAME = "capxul-sdk-observation://boundary";
252
254
  /**
253
- * Build PostHog's `$exception_list` format from a list of frames.
254
- * Returns `[{ frames: [...] }]` or `undefined` if the frames list is empty.
255
+ * Build PostHog's `$exception_list` (always a single entry). Error Tracking
256
+ * groups on `type`, so it is ALWAYS present (the CapxulError code) the
257
+ * previous `[{ frames }]` shape omitted it and PostHog dropped the event as
258
+ * "missing field `type`". When the error has no parseable stack, a synthetic
259
+ * boundary frame stands in so the event still ingests as a real Issue (#1031).
255
260
  */
256
- function buildExceptionList(frames) {
257
- if (frames.length === 0) return void 0;
258
- return [{ frames }];
261
+ function buildExceptionList(input) {
262
+ const frames = input.frames.length > 0 ? input.frames : [{
263
+ filename: SDK_BOUNDARY_FILENAME,
264
+ function: input.operation ?? "unknown",
265
+ lineno: 1,
266
+ colno: 1
267
+ }];
268
+ return [{
269
+ type: input.type,
270
+ value: input.value,
271
+ mechanism: {
272
+ handled: true,
273
+ type: "capxul_sdk_boundary"
274
+ },
275
+ stacktrace: { frames }
276
+ }];
259
277
  }
260
278
  //#endregion
261
279
  //#region src/telemetry/get-failure-mode.ts
@@ -306,6 +324,8 @@ function resolveFailureMode(error, contextFailureMode) {
306
324
  }
307
325
  //#endregion
308
326
  //#region src/telemetry/capture-exception.ts
327
+ /** Fixed, leak-safe message — the raw error message may carry PII and never ships. */
328
+ const EXCEPTION_MESSAGE = "Capxul SDK operation failed";
309
329
  /**
310
330
  * Capture an error as a `$exception` event through the telemetry port,
311
331
  * formatted for PostHog Error Tracking.
@@ -319,16 +339,24 @@ function resolveFailureMode(error, contextFailureMode) {
319
339
  */
320
340
  function captureException(telemetry, error, context) {
321
341
  return Effect.catchAllDefect(Effect.sync(() => {
322
- const exceptionList = buildExceptionList(error instanceof Error ? parseV8StackFrames(error) : []);
342
+ const frames = error instanceof Error ? parseV8StackFrames(error) : [];
323
343
  const capxulError = isCapxulError(error) ? error : null;
344
+ const errorCode = capxulError?.code ?? context?.capxul_error_code ?? "UNKNOWN";
324
345
  const props = {
325
- capxul_error_code: capxulError?.code ?? context?.capxul_error_code ?? "UNKNOWN",
346
+ capxul_error_code: errorCode,
347
+ $exception_type: errorCode,
348
+ $exception_message: EXCEPTION_MESSAGE,
349
+ $exception_list: buildExceptionList({
350
+ type: errorCode,
351
+ value: EXCEPTION_MESSAGE,
352
+ ...context?.operation === void 0 ? {} : { operation: context.operation },
353
+ frames
354
+ }),
326
355
  layer: capxulError?.layer ?? context?.layer,
327
356
  operation: context?.operation,
328
357
  provider: context?.provider,
329
358
  failure_mode: resolveFailureMode(error, context?.failure_mode)
330
359
  };
331
- if (exceptionList !== void 0) props.$exception_list = exceptionList;
332
360
  if (capxulError?.details !== void 0) props.details = JSON.stringify(capxulError.details);
333
361
  for (const key of Object.keys(props)) if (props[key] === void 0) delete props[key];
334
362
  return telemetry.emit({
@@ -348,6 +376,45 @@ function captureExceptionSync(telemetry, error, context) {
348
376
  } catch {}
349
377
  }
350
378
  //#endregion
379
+ //#region src/internal/invocation-observation.ts
380
+ const INVOCATION_OBSERVATION = Symbol("capxul.invocation-observation");
381
+ const FAILURE_INVOCATION_SNAPSHOT = Symbol("capxul.failure-invocation-snapshot");
382
+ /** @internal Attach one immutable, non-wire invocation snapshot to an SDK-owned object. */
383
+ function attachInvocationObservation(target, context) {
384
+ const snapshot = Object.freeze(context === void 0 ? {} : { context: Object.freeze({ ...context }) });
385
+ Object.defineProperty(target, INVOCATION_OBSERVATION, {
386
+ configurable: false,
387
+ enumerable: false,
388
+ value: snapshot,
389
+ writable: false
390
+ });
391
+ return target;
392
+ }
393
+ /** @internal Read the snapshot without exposing its symbol or adding a wire field. */
394
+ function readInvocationObservation(source) {
395
+ if (typeof source !== "object" || source === null) return void 0;
396
+ return source[INVOCATION_OBSERVATION];
397
+ }
398
+ /** @internal Carry a snapshot across an SDK adapter projection without resolving again. */
399
+ function copyInvocationObservation(source, target) {
400
+ const snapshot = readInvocationObservation(source);
401
+ return snapshot === void 0 ? target : attachInvocationObservation(target, snapshot.context);
402
+ }
403
+ /** @internal Mark a failure envelope as already resolved at the public invocation boundary. */
404
+ function markFailureInvocationSnapshot(failure) {
405
+ Object.defineProperty(failure, FAILURE_INVOCATION_SNAPSHOT, {
406
+ configurable: false,
407
+ enumerable: false,
408
+ value: true,
409
+ writable: false
410
+ });
411
+ return failure;
412
+ }
413
+ /** @internal Distinguish public-boundary failures from direct adapter calls. */
414
+ function hasFailureInvocationSnapshot(failure) {
415
+ return typeof failure === "object" && failure !== null && failure[FAILURE_INVOCATION_SNAPSHOT] === true;
416
+ }
417
+ //#endregion
351
418
  //#region src/client/_shared/effect-actor-bridge.ts
352
419
  /**
353
420
  * Bridge an Effect whose typed failure carries `{ publicError: CapxulError }`
@@ -1193,7 +1260,7 @@ function makeAccountMethods(deps) {
1193
1260
  };
1194
1261
  };
1195
1262
  const deployMutex = /* @__PURE__ */ new Map();
1196
- const deploySafeImpl = async () => {
1263
+ const deploySafeImpl = async (observationSource) => {
1197
1264
  const session = await currentSession(deps.actor, deps.authCache);
1198
1265
  if (session === null) return {
1199
1266
  ok: false,
@@ -1221,7 +1288,8 @@ function makeAccountMethods(deps) {
1221
1288
  authUserId: session.authUserId,
1222
1289
  chainId: deps.chainId,
1223
1290
  signer,
1224
- smartAccountPort: deps.smartAccountPort
1291
+ smartAccountPort: deps.smartAccountPort,
1292
+ observationSource
1225
1293
  }).finally(() => {
1226
1294
  deployMutex.delete(mutexKey);
1227
1295
  });
@@ -1345,11 +1413,11 @@ async function runBackendClaim(input) {
1345
1413
  error: Errors.providerError("signer", "getAddress", cause)
1346
1414
  };
1347
1415
  }
1348
- const claimed = await runPortEffect(input.smartAccountPort.claim({
1416
+ const claimed = await runPortEffect(input.smartAccountPort.claim(copyInvocationObservation(input.observationSource, {
1349
1417
  authUserId: input.authUserId,
1350
1418
  chainId,
1351
1419
  signerAddress
1352
- }));
1420
+ })));
1353
1421
  if (!claimed.ok) return claimed;
1354
1422
  return {
1355
1423
  ok: true,
@@ -1624,7 +1692,7 @@ async function recoverRawDigestSigner(input) {
1624
1692
  }
1625
1693
  //#endregion
1626
1694
  //#region package.json
1627
- var version = "1.0.0-alpha.19";
1695
+ var version = "1.0.0-alpha.21";
1628
1696
  //#endregion
1629
1697
  //#region src/ports/auth-client.ts
1630
1698
  var AuthClientError = class extends Data.TaggedError("AuthClientError") {};
@@ -1710,6 +1778,10 @@ const FIELD_RULES = {
1710
1778
  maxLength: 128,
1711
1779
  pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
1712
1780
  },
1781
+ journeyId: {
1782
+ maxLength: 128,
1783
+ pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
1784
+ },
1713
1785
  correlationId: {
1714
1786
  maxLength: 128,
1715
1787
  pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
@@ -2983,48 +3055,10 @@ function convexCallErrorFromCapxul(operation, error) {
2983
3055
  }
2984
3056
  var ConvexCallPortTag = class extends Context.Tag("@capxul/sdk/ports/ConvexCallPort")() {};
2985
3057
  //#endregion
2986
- //#region src/internal/invocation-observation.ts
2987
- const INVOCATION_OBSERVATION = Symbol("capxul.invocation-observation");
2988
- const FAILURE_INVOCATION_SNAPSHOT = Symbol("capxul.failure-invocation-snapshot");
2989
- /** @internal Attach one immutable, non-wire invocation snapshot to an SDK-owned object. */
2990
- function attachInvocationObservation(target, context) {
2991
- const snapshot = Object.freeze(context === void 0 ? {} : { context: Object.freeze({ ...context }) });
2992
- Object.defineProperty(target, INVOCATION_OBSERVATION, {
2993
- configurable: false,
2994
- enumerable: false,
2995
- value: snapshot,
2996
- writable: false
2997
- });
2998
- return target;
2999
- }
3000
- /** @internal Read the snapshot without exposing its symbol or adding a wire field. */
3001
- function readInvocationObservation(source) {
3002
- if (typeof source !== "object" || source === null) return void 0;
3003
- return source[INVOCATION_OBSERVATION];
3004
- }
3005
- /** @internal Carry a snapshot across an SDK adapter projection without resolving again. */
3006
- function copyInvocationObservation(source, target) {
3007
- const snapshot = readInvocationObservation(source);
3008
- return snapshot === void 0 ? target : attachInvocationObservation(target, snapshot.context);
3009
- }
3010
- /** @internal Mark a failure envelope as already resolved at the public invocation boundary. */
3011
- function markFailureInvocationSnapshot(failure) {
3012
- Object.defineProperty(failure, FAILURE_INVOCATION_SNAPSHOT, {
3013
- configurable: false,
3014
- enumerable: false,
3015
- value: true,
3016
- writable: false
3017
- });
3018
- return failure;
3019
- }
3020
- /** @internal Distinguish public-boundary failures from direct adapter calls. */
3021
- function hasFailureInvocationSnapshot(failure) {
3022
- return typeof failure === "object" && failure !== null && failure[FAILURE_INVOCATION_SNAPSHOT] === true;
3023
- }
3024
- //#endregion
3025
3058
  //#region src/adapters/convex-call/ConvexCallAdapter.ts
3026
3059
  /** Exact floor-first allowlist; every additional handler must migrate its validator first. */
3027
- const OBSERVED_CONVEX_ACTIONS = new Set(["subAccount/actions:transfer"]);
3060
+ const OBSERVED_CONVEX_ACTIONS = new Set(["subAccount/actions:transfer", "smartAccount/actions:claim"]);
3061
+ const OBSERVED_CONVEX_MUTATIONS = new Set(["org/lifecycle:startOrResume", "org/lifecycle:retry"]);
3028
3062
  var ConvexCallAdapter = class {
3029
3063
  #client;
3030
3064
  #tokenProvider;
@@ -3047,20 +3081,21 @@ var ConvexCallAdapter = class {
3047
3081
  });
3048
3082
  }
3049
3083
  mutation(fn, args) {
3084
+ const path = getFunctionName(fn);
3050
3085
  return Effect.tryPromise({
3051
- try: () => this.#client.mutation(fn, args),
3052
- catch: (cause) => mapToConvexCallError(getFunctionName(fn), cause)
3086
+ try: () => this.#client.mutation(fn, this.#observedArgs(OBSERVED_CONVEX_MUTATIONS, path, args)),
3087
+ catch: (cause) => mapToConvexCallError(path, cause)
3053
3088
  });
3054
3089
  }
3055
3090
  action(fn, args) {
3056
3091
  const path = getFunctionName(fn);
3057
3092
  return Effect.tryPromise({
3058
- try: () => this.#client.action(fn, this.#observedActionArgs(path, args)),
3093
+ try: () => this.#client.action(fn, this.#observedArgs(OBSERVED_CONVEX_ACTIONS, path, args)),
3059
3094
  catch: (cause) => mapToConvexCallError(path, cause)
3060
3095
  });
3061
3096
  }
3062
- #observedActionArgs(path, args) {
3063
- if (!OBSERVED_CONVEX_ACTIONS.has(path)) return args;
3097
+ #observedArgs(allowlist, path, args) {
3098
+ if (!allowlist.has(path)) return args;
3064
3099
  let hostContext;
3065
3100
  const invocationSnapshot = readInvocationObservation(args);
3066
3101
  if (invocationSnapshot !== void 0) hostContext = invocationSnapshot.context;
@@ -3650,6 +3685,8 @@ function brandProfile(raw) {
3650
3685
  email: toEmail(raw.email),
3651
3686
  displayName: raw.displayName,
3652
3687
  country: raw.country === null ? null : toCountryCode(raw.country),
3688
+ onboarded: raw.onboarded ?? false,
3689
+ withdrawalAddress: raw.withdrawalAddress === null || raw.withdrawalAddress === void 0 ? null : toAddress(raw.withdrawalAddress),
3653
3690
  kycTier: toKycTier(raw.kycTier),
3654
3691
  createdAt: toEpochMs(raw.createdAt),
3655
3692
  updatedAt: toEpochMs(raw.updatedAt)
@@ -3909,11 +3946,11 @@ var ConvexSmartAccountAdapter = class {
3909
3946
  })), Effect.catchAllDefect((cause) => Effect.fail(smartAccountErrorFromUnknown("confirmDeployment", cause))));
3910
3947
  }
3911
3948
  claim(input) {
3912
- return this.#convex.action(this.#fns.claim, {
3949
+ return this.#convex.action(this.#fns.claim, copyInvocationObservation(input, {
3913
3950
  chainId: wireChainId(input.chainId),
3914
3951
  signerAddress: input.signerAddress,
3915
3952
  ...input.telemetryRunId === void 0 ? {} : { telemetryRunId: input.telemetryRunId }
3916
- }).pipe(Effect.mapError((error) => smartAccountErrorFromCapxul("claim", error.publicError, error)), Effect.flatMap((row) => Effect.try({
3953
+ })).pipe(Effect.mapError((error) => smartAccountErrorFromCapxul("claim", error.publicError, error)), Effect.flatMap((row) => Effect.try({
3917
3954
  try: () => brandProvisionedSmartAccount(input.authUserId, row),
3918
3955
  catch: (cause) => smartAccountErrorFromUnknown("claim", cause)
3919
3956
  })), Effect.catchAllDefect((cause) => Effect.fail(smartAccountErrorFromUnknown("claim", cause))));
@@ -4175,14 +4212,19 @@ const DEFAULT_FUNCTIONS$1 = {
4175
4212
  var ConvexOrganizationSetupAdapter = class {
4176
4213
  #convex;
4177
4214
  #signer;
4215
+ #chainId;
4178
4216
  #fns;
4179
4217
  constructor(input) {
4180
4218
  this.#convex = input.convex;
4181
4219
  this.#signer = input.signer;
4220
+ this.#chainId = input.chainId;
4182
4221
  this.#fns = input.functions ?? DEFAULT_FUNCTIONS$1;
4183
4222
  }
4184
4223
  async startOrResume(input) {
4185
- const result = await runCall("startOrResume", this.#convex.mutation(this.#fns.startOrResume, input));
4224
+ const result = await runCall("startOrResume", this.#convex.mutation(this.#fns.startOrResume, copyInvocationObservation(input, {
4225
+ ...input,
4226
+ chainId: this.#chainId
4227
+ })));
4186
4228
  if (!result.ok) return result;
4187
4229
  const lifecycle = parseLifecycle("startOrResume", result.value.lifecycle);
4188
4230
  if (!lifecycle.ok) return lifecycle;
@@ -4198,17 +4240,17 @@ var ConvexOrganizationSetupAdapter = class {
4198
4240
  };
4199
4241
  }
4200
4242
  prepareFounderAccount(input) {
4201
- return this.#lifecycleAction("prepareFounderAccount", input, () => this.#convex.action(this.#fns.prepareFounderAccount, { orgId: input.orgId }));
4243
+ return this.#lifecycleAction("prepareFounderAccount", input, () => this.#convex.action(this.#fns.prepareFounderAccount, copyInvocationObservation(input, { orgId: input.orgId })));
4202
4244
  }
4203
4245
  async authorizeAndSubmitBootstrap(input) {
4204
4246
  const cancelled = cancellation(input.signal);
4205
4247
  if (cancelled !== void 0) return cancelled;
4206
4248
  const signerAddress = await signerResult("getAddress", () => this.#signer.getAddress());
4207
4249
  if (!signerAddress.ok) return signerAddress;
4208
- const prepared = await runCall("prepareBootstrap", this.#convex.action(this.#fns.prepareBootstrap, {
4250
+ const prepared = await runCall("prepareBootstrap", this.#convex.action(this.#fns.prepareBootstrap, copyInvocationObservation(input, {
4209
4251
  orgId: input.orgId,
4210
4252
  signerAddress: signerAddress.value
4211
- }));
4253
+ })));
4212
4254
  if (!prepared.ok) return prepared;
4213
4255
  const authority = validatePreparedAuthorities(prepared.value, signerAddress.value);
4214
4256
  if (!authority.ok) return authority;
@@ -4218,25 +4260,25 @@ var ConvexOrganizationSetupAdapter = class {
4218
4260
  if (!signature.ok) return signature;
4219
4261
  const cancelledAfterSign = cancellation(input.signal);
4220
4262
  if (cancelledAfterSign !== void 0) return cancelledAfterSign;
4221
- const submitted = await runCall("submitBootstrap", this.#convex.action(this.#fns.submitBootstrap, {
4263
+ const submitted = await runCall("submitBootstrap", this.#convex.action(this.#fns.submitBootstrap, copyInvocationObservation(input, {
4222
4264
  orgId: input.orgId,
4223
4265
  signerAddress: signerAddress.value,
4224
4266
  signature: signature.value,
4225
4267
  userOp: prepared.value.userOp
4226
- }));
4268
+ })));
4227
4269
  if (!submitted.ok) return submitted;
4228
4270
  return parseLifecycle("submitBootstrap", submitted.value);
4229
4271
  }
4230
4272
  resumeSubmittedBootstrap(input) {
4231
- return this.#lifecycleAction("resumeBootstrapSubmission", input, () => this.#convex.action(this.#fns.resumeBootstrapSubmission, { orgId: input.orgId }));
4273
+ return this.#lifecycleAction("resumeBootstrapSubmission", input, () => this.#convex.action(this.#fns.resumeBootstrapSubmission, copyInvocationObservation(input, { orgId: input.orgId })));
4232
4274
  }
4233
4275
  confirmSubmittedBootstrap(input) {
4234
- return this.#lifecycleAction("confirmBootstrap", input, () => this.#convex.action(this.#fns.confirmBootstrap, { orgId: input.orgId }));
4276
+ return this.#lifecycleAction("confirmBootstrap", input, () => this.#convex.action(this.#fns.confirmBootstrap, copyInvocationObservation(input, { orgId: input.orgId })));
4235
4277
  }
4236
4278
  async recordFailure(input) {
4237
4279
  const errorProvider = input.error.details?.provider;
4238
4280
  const errorOperation = input.error.details?.operation;
4239
- const result = await runCall("recordFailure", this.#convex.mutation(this.#fns.recordFailure, {
4281
+ const result = await runCall("recordFailure", this.#convex.mutation(this.#fns.recordFailure, copyInvocationObservation(input, {
4240
4282
  orgId: input.orgId,
4241
4283
  errorCode: input.error.code,
4242
4284
  ...typeof errorProvider === "string" && typeof errorOperation === "string" ? {
@@ -4244,7 +4286,7 @@ var ConvexOrganizationSetupAdapter = class {
4244
4286
  errorOperation
4245
4287
  } : {},
4246
4288
  retryable: input.retryable
4247
- }));
4289
+ })));
4248
4290
  return result.ok ? parseLifecycle("recordFailure", result.value) : result;
4249
4291
  }
4250
4292
  async loadLifecycle(input) {
@@ -4262,7 +4304,7 @@ var ConvexOrganizationSetupAdapter = class {
4262
4304
  const reset = resetSignerSession(this.#signer);
4263
4305
  if (!reset.ok) return reset;
4264
4306
  }
4265
- const result = await runCall("retry", this.#convex.mutation(this.#fns.retry, { orgId: input.orgId }));
4307
+ const result = await runCall("retry", this.#convex.mutation(this.#fns.retry, copyInvocationObservation(input, { orgId: input.orgId })));
4266
4308
  if (!result.ok) return result;
4267
4309
  return parseLifecycle("retry", result.value);
4268
4310
  }
@@ -4447,6 +4489,7 @@ const PayeeIdTelemetrySchema = Schema.String.pipe(Schema.filter((value) => PAYEE
4447
4489
  const DocumentHashSchema = Schema.String.pipe(Schema.filter((value) => BYTES32_RE.test(value), { message: () => "must be 0x + 64 hex chars" }));
4448
4490
  const TelemetryEnvelopeProps = {
4449
4491
  capxul_e2e_run_id: OptionalString,
4492
+ journeyId: OptionalString,
4450
4493
  correlationId: OptionalString,
4451
4494
  capxulEnv: OptionalString,
4452
4495
  sdkVersion: OptionalString,
@@ -4578,6 +4621,46 @@ const TransferFailedProps = Schema.Struct({
4578
4621
  const ORG_ID_TELEMETRY_RE = /^org_[0-9A-Za-z]+$/;
4579
4622
  const OrgIdTelemetrySchema = Schema.String.pipe(Schema.filter((value) => ORG_ID_TELEMETRY_RE.test(value), { message: () => "must be org_ plus an alphanumeric id" }));
4580
4623
  const OptionalOrgId = Schema.optional(OrgIdTelemetrySchema);
4624
+ const AttemptNumberSchema = Schema.Number.pipe(Schema.filter((value) => Number.isSafeInteger(value) && value > 0, { message: () => "must be a positive safe integer" }));
4625
+ const OnboardingStageSchema = Schema.Literal("profile", "accountProvisioning", "accountClaim", "preparingFounderAccount", "awaitingFounderAuthorization", "submittingBootstrap", "confirmingBootstrap");
4626
+ const MemberActivationStartedProps = Schema.Struct({
4627
+ $insert_id: Schema.String,
4628
+ producer: Schema.Literal("server")
4629
+ });
4630
+ const MemberActivationReadyProps = Schema.Struct({
4631
+ $insert_id: Schema.String,
4632
+ duration_ms: DurationMsSchema,
4633
+ producer: Schema.Literal("server")
4634
+ });
4635
+ const MemberActivationFailedProps = Schema.Struct({
4636
+ $insert_id: Schema.String,
4637
+ stage: OnboardingStageSchema,
4638
+ error_code: Schema.String,
4639
+ retryable: Schema.Boolean,
4640
+ producer: Schema.Literal("server")
4641
+ });
4642
+ const OrganizationCreationStartedProps = Schema.Struct({
4643
+ $insert_id: Schema.String,
4644
+ organization_id: OrgIdTelemetrySchema,
4645
+ attempt_number: AttemptNumberSchema,
4646
+ producer: Schema.Literal("server")
4647
+ });
4648
+ const OrganizationCreationReadyProps = Schema.Struct({
4649
+ $insert_id: Schema.String,
4650
+ organization_id: OrgIdTelemetrySchema,
4651
+ attempt_number: AttemptNumberSchema,
4652
+ duration_ms: DurationMsSchema,
4653
+ producer: Schema.Literal("server")
4654
+ });
4655
+ const OrganizationCreationFailedProps = Schema.Struct({
4656
+ $insert_id: Schema.String,
4657
+ organization_id: OrgIdTelemetrySchema,
4658
+ attempt_number: AttemptNumberSchema,
4659
+ stage: OnboardingStageSchema,
4660
+ error_code: Schema.String,
4661
+ retryable: Schema.Boolean,
4662
+ producer: Schema.Literal("server")
4663
+ });
4581
4664
  const OrgCreateStartedProps = Schema.Struct({
4582
4665
  ...TelemetryEnvelopeProps,
4583
4666
  org_id: OptionalOrgId,
@@ -4739,6 +4822,30 @@ Schema.Struct({
4739
4822
  name: Schema.Literal("bootstrap_failed"),
4740
4823
  props: Schema.optional(BootstrapFailedProps)
4741
4824
  });
4825
+ Schema.Struct({
4826
+ name: Schema.Literal("member_activation_started"),
4827
+ props: MemberActivationStartedProps
4828
+ });
4829
+ Schema.Struct({
4830
+ name: Schema.Literal("member_activation_ready"),
4831
+ props: MemberActivationReadyProps
4832
+ });
4833
+ Schema.Struct({
4834
+ name: Schema.Literal("member_activation_failed"),
4835
+ props: MemberActivationFailedProps
4836
+ });
4837
+ Schema.Struct({
4838
+ name: Schema.Literal("organization_creation_started"),
4839
+ props: OrganizationCreationStartedProps
4840
+ });
4841
+ Schema.Struct({
4842
+ name: Schema.Literal("organization_creation_ready"),
4843
+ props: OrganizationCreationReadyProps
4844
+ });
4845
+ Schema.Struct({
4846
+ name: Schema.Literal("organization_creation_failed"),
4847
+ props: OrganizationCreationFailedProps
4848
+ });
4742
4849
  Schema.Struct({
4743
4850
  name: Schema.Literal("account_balance_read"),
4744
4851
  props: Schema.optional(AccountBalanceReadProps)
@@ -5239,6 +5346,18 @@ function transportErrorFromThrown(operation, request, cause) {
5239
5346
  return transportErrorFromCapxul(operation, request, cause instanceof Error ? Errors.providerError("transport", request.name, cause) : Errors.providerError("transport", request.name, new Error(String(cause))), cause);
5240
5347
  }
5241
5348
  //#endregion
5349
+ //#region src/adapters/diagnostic/ConsoleDiagnosticAdapter.ts
5350
+ const DEFAULT_ACCOUNT_SETUP_LOG_PREFIX = "[capxul:account-setup]";
5351
+ var ConsoleDiagnosticAdapter = class {
5352
+ prefix;
5353
+ constructor(prefix = DEFAULT_ACCOUNT_SETUP_LOG_PREFIX) {
5354
+ this.prefix = prefix;
5355
+ }
5356
+ trace(scope, detail) {
5357
+ globalThis.console?.debug?.(`${this.prefix} ${scope}`, detail);
5358
+ }
5359
+ };
5360
+ //#endregion
5242
5361
  //#region src/openfort/create-openfort-browser-signer.ts
5243
5362
  function openfortProviderError(operation, cause) {
5244
5363
  return cause instanceof CapxulError ? cause : Errors.providerError("openfort", operation, cause, { failure_mode: "unknown" });
@@ -6599,10 +6718,6 @@ function makeCurrentUserMethods(deps) {
6599
6718
  deps.smartAccount.loadCurrent(options),
6600
6719
  deps.orgs(options)
6601
6720
  ]);
6602
- if (!account.ok) return {
6603
- ok: false,
6604
- error: account.error
6605
- };
6606
6721
  if (!smartAccount.ok) return {
6607
6722
  ok: false,
6608
6723
  error: smartAccount.error
@@ -6611,6 +6726,10 @@ function makeCurrentUserMethods(deps) {
6611
6726
  ok: false,
6612
6727
  error: organizations.error
6613
6728
  };
6729
+ if (!account.ok && account.error.code !== "SMART_ACCOUNT_MISSING") return {
6730
+ ok: false,
6731
+ error: account.error
6732
+ };
6614
6733
  return {
6615
6734
  ok: true,
6616
6735
  value: {
@@ -6621,10 +6740,10 @@ function makeCurrentUserMethods(deps) {
6621
6740
  handle: null,
6622
6741
  paymentLink: null
6623
6742
  },
6624
- personalAccount: {
6743
+ personalAccount: account.ok ? {
6625
6744
  id: account.value.id,
6626
6745
  address: smartAccount.value?.smartAccountAddress ?? null
6627
- },
6746
+ } : null,
6628
6747
  organizations: organizations.value.map((organization) => ({
6629
6748
  id: organization.id,
6630
6749
  name: organization.name,
@@ -7970,7 +8089,7 @@ function validateOrganizationLifecycleScope(orgId, lifecycle) {
7970
8089
  };
7971
8090
  }
7972
8091
  /** Advance only the steps still required by one durable Organization lane. */
7973
- async function advanceOrganizationSetup(setup, orgId, initial, signal) {
8092
+ async function advanceOrganizationSetup(setup, orgId, initial, signal, observationSource) {
7974
8093
  const scopedInitial = validateOrganizationLifecycleScope(orgId, initial);
7975
8094
  if (!scopedInitial.ok) return scopedInitial;
7976
8095
  let lifecycle = scopedInitial.value;
@@ -7980,19 +8099,15 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
7980
8099
  value: lifecycle
7981
8100
  };
7982
8101
  const currentStep = lifecycle.step;
7983
- if (signal?.aborted) return recordSetupFailure(setup, orgId, Errors.cancelled({ operation: "organization.setup" }), true);
7984
- const stepInput = {
8102
+ if (signal?.aborted) return recordSetupFailure(setup, orgId, Errors.cancelled({ operation: "organization.setup" }), true, observationSource);
8103
+ const stepInput = copyInvocationObservation(observationSource, {
7985
8104
  orgId,
7986
8105
  ...signal === void 0 ? {} : { signal }
7987
- };
8106
+ });
7988
8107
  const next = lifecycle.step === "preparingFounderAccount" ? await setup.prepareFounderAccount(stepInput) : lifecycle.step === "awaitingFounderAuthorization" ? await setup.authorizeAndSubmitBootstrap(stepInput) : lifecycle.step === "submittingBootstrap" ? await setup.resumeSubmittedBootstrap(stepInput) : await setup.confirmSubmittedBootstrap(stepInput);
7989
- if (!next.ok) {
7990
- if (next.error.code === "CANCELLED") return recordSetupFailure(setup, orgId, next.error, true);
7991
- if (next.error.code === "PROVIDER_ERROR") return recordSetupFailure(setup, orgId, next.error, isRetryableProviderFailure(next.error));
7992
- return next;
7993
- }
8108
+ if (!next.ok) return recordSetupFailure(setup, orgId, next.error, isRetryableOrganizationSetupFailure(next.error), observationSource);
7994
8109
  const scopedNext = validateOrganizationLifecycleScope(orgId, next.value);
7995
- if (!scopedNext.ok) return scopedNext;
8110
+ if (!scopedNext.ok) return recordSetupFailure(setup, orgId, scopedNext.error, false, observationSource);
7996
8111
  lifecycle = scopedNext.value;
7997
8112
  if (currentStep === "confirmingBootstrap") return {
7998
8113
  ok: true,
@@ -8003,7 +8118,7 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
8003
8118
  ok: true,
8004
8119
  value: lifecycle
8005
8120
  };
8006
- return fail$1(Errors.wrongState({
8121
+ return recordSetupFailure(setup, orgId, Errors.wrongState({
8007
8122
  method: "organization.setup",
8008
8123
  currentState: lifecycle.step,
8009
8124
  validStates: [
@@ -8011,23 +8126,28 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
8011
8126
  "ready",
8012
8127
  "failed"
8013
8128
  ]
8014
- }));
8129
+ }), false, observationSource);
8015
8130
  }
8016
- async function recordSetupFailure(setup, orgId, error, retryable) {
8017
- const recorded = await setup.recordFailure({
8131
+ async function recordSetupFailure(setup, orgId, error, retryable, observationSource) {
8132
+ const recorded = await setup.recordFailure(copyInvocationObservation(observationSource, {
8018
8133
  orgId,
8019
8134
  error,
8020
8135
  retryable
8021
- });
8136
+ }));
8022
8137
  if (!recorded.ok) return recorded;
8023
8138
  const scopedRecorded = validateOrganizationLifecycleScope(orgId, recorded.value);
8024
8139
  if (!scopedRecorded.ok) return scopedRecorded;
8025
- return fail$1(error);
8140
+ return scopedRecorded;
8026
8141
  }
8027
8142
  function isRetryableProviderFailure(error) {
8028
8143
  const mode = error.details?.failure_mode;
8029
8144
  return mode !== "auth-origin-mismatch" && mode !== "app-env-allowlist" && mode !== "no-secure-context";
8030
8145
  }
8146
+ function isRetryableOrganizationSetupFailure(error) {
8147
+ if (error.code === "CANCELLED" || error.code === "SIGNER_REJECTED") return true;
8148
+ if (error.code === "PROVIDER_ERROR") return isRetryableProviderFailure(error);
8149
+ return error.code === "NETWORK_ERROR" || error.code === "UNKNOWN";
8150
+ }
8031
8151
  //#endregion
8032
8152
  //#region src/client/org.ts
8033
8153
  /**
@@ -8100,12 +8220,12 @@ function makeOrgMethods(deps) {
8100
8220
  ok: false,
8101
8221
  error: Errors.notImplemented("organizationSetup", "retrySetup")
8102
8222
  };
8103
- const retried = await setup.retry({
8223
+ const retried = await setup.retry(copyInvocationObservation(options, {
8104
8224
  orgId,
8105
8225
  ...options?.signal === void 0 ? {} : { signal: options.signal }
8106
- });
8226
+ }));
8107
8227
  if (!retried.ok) return retried;
8108
- return advanceOrganizationSetup(setup, orgId, retried.value, options?.signal);
8228
+ return advanceOrganizationSetup(setup, orgId, retried.value, options?.signal, options);
8109
8229
  },
8110
8230
  profile: {
8111
8231
  get(_options) {
@@ -8366,17 +8486,21 @@ async function runCompleteOrganizationOnboarding(ops, input, options) {
8366
8486
  const written = await ops.completeIdentityOnboarding({
8367
8487
  authUserId: session.authUserId,
8368
8488
  email: session.email,
8369
- displayName: validated.value.ownerDisplayName,
8370
- country: validated.value.country
8489
+ displayName: validated.value.profile.displayName,
8490
+ country: validated.value.profile.country,
8491
+ ...validated.value.profile.withdrawalAddress === void 0 ? {} : { withdrawalAddress: validated.value.profile.withdrawalAddress }
8371
8492
  });
8372
8493
  if (!written.ok) return fail(written.error);
8373
- const started = await setup.startOrResume({
8374
- name: validated.value.organizationName,
8375
- handle: validated.value.handle,
8376
- country: validated.value.country
8377
- });
8494
+ const founderAccount = await ops.ensureFounderAccountReady(input);
8495
+ if (!founderAccount.ok) return fail(founderAccount.error);
8496
+ if (options?.signal?.aborted === true) return fail(Errors.cancelled({ operation: "onboarding.completeOrganization" }));
8497
+ const started = await setup.startOrResume(copyInvocationObservation(input, {
8498
+ name: validated.value.organization.name,
8499
+ handle: validated.value.organization.handle,
8500
+ country: validated.value.organization.country
8501
+ }));
8378
8502
  if (!started.ok) return fail(started.error);
8379
- const lifecycle = await advanceOrganizationSetup(setup, started.value.orgId, started.value.lifecycle, options?.signal);
8503
+ const lifecycle = await advanceOrganizationSetup(setup, started.value.orgId, started.value.lifecycle, options?.signal, input);
8380
8504
  if (!lifecycle.ok) {
8381
8505
  const error = lifecycle.error;
8382
8506
  return fail(new CapxulError(error.code, error.message, {
@@ -8398,9 +8522,36 @@ async function runCompleteOrganizationOnboarding(ops, input, options) {
8398
8522
  };
8399
8523
  }
8400
8524
  function validatePersonalInput(input) {
8401
- const displayName = requireNonEmpty(input.displayName, "displayName");
8525
+ if (!isRecord(input) || !isRecord(input.profile)) return fail(Errors.invalidInput("profile", "must be an object"));
8526
+ return validateProfileInput(input.profile);
8527
+ }
8528
+ function validateOrganizationInput(input) {
8529
+ if (!isRecord(input) || !isRecord(input.profile)) return fail(Errors.invalidInput("profile", "must be an object"));
8530
+ if (!isRecord(input.organization)) return fail(Errors.invalidInput("organization", "must be an object"));
8531
+ const profile = validateProfileInput(input.profile);
8532
+ if (!profile.ok) return profile;
8533
+ const name = requireNonEmpty(input.organization.name, "organization.name");
8534
+ if (!name.ok) return name;
8535
+ const handle = requireNonEmpty(input.organization.handle, "organization.handle");
8536
+ if (!handle.ok) return handle;
8537
+ const country = parseCountry(input.organization.country, "organization.country");
8538
+ if (!country.ok) return country;
8539
+ return {
8540
+ ok: true,
8541
+ value: {
8542
+ profile: profile.value,
8543
+ organization: {
8544
+ name: name.value,
8545
+ handle: handle.value,
8546
+ country: country.value
8547
+ }
8548
+ }
8549
+ };
8550
+ }
8551
+ function validateProfileInput(input) {
8552
+ const displayName = requireNonEmpty(input.displayName, "profile.displayName");
8402
8553
  if (!displayName.ok) return displayName;
8403
- const country = parseCountry(input.country);
8554
+ const country = parseCountry(input.country, "profile.country");
8404
8555
  if (!country.ok) return country;
8405
8556
  if (input.withdrawalAddress === void 0) return {
8406
8557
  ok: true,
@@ -8409,7 +8560,7 @@ function validatePersonalInput(input) {
8409
8560
  country: country.value
8410
8561
  }
8411
8562
  };
8412
- const withdrawalAddress = parseAddress(input.withdrawalAddress, "withdrawalAddress");
8563
+ const withdrawalAddress = parseAddress(input.withdrawalAddress, "profile.withdrawalAddress");
8413
8564
  if (!withdrawalAddress.ok) return withdrawalAddress;
8414
8565
  return {
8415
8566
  ok: true,
@@ -8420,25 +8571,6 @@ function validatePersonalInput(input) {
8420
8571
  }
8421
8572
  };
8422
8573
  }
8423
- function validateOrganizationInput(input) {
8424
- const organizationName = requireNonEmpty(input.organizationName, "organizationName");
8425
- if (!organizationName.ok) return organizationName;
8426
- const handle = requireNonEmpty(input.handle, "handle");
8427
- if (!handle.ok) return handle;
8428
- const ownerDisplayName = requireNonEmpty(input.ownerDisplayName, "ownerDisplayName");
8429
- if (!ownerDisplayName.ok) return ownerDisplayName;
8430
- const country = parseCountry(input.country);
8431
- if (!country.ok) return country;
8432
- return {
8433
- ok: true,
8434
- value: {
8435
- organizationName: organizationName.value,
8436
- handle: handle.value,
8437
- country: country.value,
8438
- ownerDisplayName: ownerDisplayName.value
8439
- }
8440
- };
8441
- }
8442
8574
  function requireNonEmpty(value, field) {
8443
8575
  const trimmed = typeof value === "string" ? value.trim() : "";
8444
8576
  if (trimmed.length === 0) return fail(Errors.invalidInput(field, "must be a non-empty string"));
@@ -8447,14 +8579,14 @@ function requireNonEmpty(value, field) {
8447
8579
  value: trimmed
8448
8580
  };
8449
8581
  }
8450
- function parseCountry(value) {
8582
+ function parseCountry(value, field = "country") {
8451
8583
  try {
8452
8584
  return {
8453
8585
  ok: true,
8454
8586
  value: toCountryCode(value)
8455
8587
  };
8456
8588
  } catch (cause) {
8457
- return fail(invalidFrom("country", cause, "must be an ISO-3166 alpha-2 code"));
8589
+ return fail(invalidFrom(field, cause, "must be an ISO-3166 alpha-2 code"));
8458
8590
  }
8459
8591
  }
8460
8592
  function parseAddress(value, field) {
@@ -8471,6 +8603,9 @@ function invalidFrom(field, cause, fallback) {
8471
8603
  const message = cause instanceof Error && cause.message.length > 0 ? cause.message : fallback;
8472
8604
  return Errors.invalidInput(field, message);
8473
8605
  }
8606
+ function isRecord(value) {
8607
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8608
+ }
8474
8609
  function fail(error) {
8475
8610
  return {
8476
8611
  ok: false,
@@ -8600,6 +8735,22 @@ function assembleCapxulClient(input) {
8600
8735
  };
8601
8736
  },
8602
8737
  completeIdentityOnboarding: (write) => runPortEffect(input.ports.identity.completeOnboarding(write)),
8738
+ ensureFounderAccountReady: async (observationSource) => {
8739
+ const deployed = await account._internal.deploySafe(observationSource);
8740
+ if (!deployed.ok) return deployed;
8741
+ if (deployed.value.deployedAt === null || deployed.value.claimedAt === null) return {
8742
+ ok: false,
8743
+ error: Errors.wrongState({
8744
+ method: "onboarding.completeOrganization",
8745
+ currentState: "founderAccountClaimPending",
8746
+ validStates: ["founderAccountDeployedAndClaimed"]
8747
+ })
8748
+ };
8749
+ return {
8750
+ ok: true,
8751
+ value: void 0
8752
+ };
8753
+ },
8603
8754
  triggerProvisioning: () => account._internal.provision(),
8604
8755
  kickProvisioning: () => kickProvisioning?.(),
8605
8756
  readLifecycle: () => account.getLifecycle(),
@@ -8762,7 +8913,7 @@ function observeSdkClient(client, adapter) {
8762
8913
  if (cached !== void 0) return cached;
8763
8914
  const wrapped = new Proxy(callable, {
8764
8915
  apply(currentTarget, _thisArg, args) {
8765
- const invocationContext = resolveAdapterContext(adapter);
8916
+ const invocationContext = invocationObservationContext(resolveAdapterContext(adapter));
8766
8917
  const invocationArgs = carryInvocationContext(operation, args, invocationContext);
8767
8918
  let output;
8768
8919
  try {
@@ -8799,9 +8950,23 @@ function observeSdkClient(client, adapter) {
8799
8950
  return wrapObject(client, []);
8800
8951
  }
8801
8952
  function carryInvocationContext(operation, args, context) {
8802
- if (operation !== "subAccounts.transfer" || !isPlainObject(args[0])) return args;
8953
+ if (!isPlainObject(args[0])) return args.length === 0 && operation === "org.retrySetup" ? [attachInvocationObservation({}, context)] : args;
8803
8954
  return [attachInvocationObservation({ ...args[0] }, context), ...args.slice(1)];
8804
8955
  }
8956
+ /** One stable correlation id per public call; the next call is an explicit retry. */
8957
+ function invocationObservationContext(context) {
8958
+ return {
8959
+ ...context,
8960
+ correlationId: createInvocationCorrelationId()
8961
+ };
8962
+ }
8963
+ function createInvocationCorrelationId() {
8964
+ if (typeof globalThis.crypto?.randomUUID === "function") return `sdk_${globalThis.crypto.randomUUID()}`;
8965
+ const bytes = new Uint8Array(16);
8966
+ if (typeof globalThis.crypto?.getRandomValues === "function") globalThis.crypto.getRandomValues(bytes);
8967
+ else for (let index = 0; index < bytes.length; index += 1) bytes[index] = Math.floor(Math.random() * 256);
8968
+ return `sdk_${Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("")}`;
8969
+ }
8805
8970
  /** @internal Reports a factory-level typed failure without changing its identity. */
8806
8971
  function observeFailedResult(result, adapter, operation) {
8807
8972
  if (adapter !== void 0 && isFailedResult(result)) report(adapter, "operation", operation, result.error, resolveAdapterContext(adapter));
@@ -8838,24 +9003,35 @@ function ignoreDeliveryFailure(delivery) {
8838
9003
  Promise.resolve(delivery).catch(() => void 0);
8839
9004
  } catch {}
8840
9005
  }
9006
+ /**
9007
+ * Map an ALREADY-sanitized observation context to the snake_case PostHog
9008
+ * property keys. Shared by the failure boundary here and the host
9009
+ * success-telemetry seam (`telemetry/from-posthog.ts`) so both attach identical
9010
+ * correlation fields from one definition.
9011
+ */
9012
+ function observationContextProps(context) {
9013
+ const props = {};
9014
+ if (context?.application !== void 0) props.application = context.application;
9015
+ if (context?.release !== void 0) props.release = context.release;
9016
+ if (context?.sessionId !== void 0) props.session_id = context.sessionId;
9017
+ if (context?.organizationId !== void 0) props.organization_id = context.organizationId;
9018
+ if (context?.journeyId !== void 0) props.journey_id = context.journeyId;
9019
+ if (context?.correlationId !== void 0) props.correlation_id = context.correlationId;
9020
+ if (context?.anonymousId !== void 0) props.anonymous_id = context.anonymousId;
9021
+ return props;
9022
+ }
8841
9023
  function postHogProperties(failure, context) {
8842
- const properties = {
8843
- sdk_version: failure.sdkVersion,
8844
- operation: failure.operation,
8845
- error_kind: failure.errorKind,
8846
- handled: true
8847
- };
8848
9024
  const merged = sanitizeObservationContext({
8849
9025
  ...context,
8850
9026
  ...failure.context
8851
9027
  });
8852
- if (merged?.application !== void 0) properties.application = merged.application;
8853
- if (merged?.release !== void 0) properties.release = merged.release;
8854
- if (merged?.sessionId !== void 0) properties.session_id = merged.sessionId;
8855
- if (merged?.organizationId !== void 0) properties.organization_id = merged.organizationId;
8856
- if (merged?.correlationId !== void 0) properties.correlation_id = merged.correlationId;
8857
- if (merged?.anonymousId !== void 0) properties.anonymous_id = merged.anonymousId;
8858
- return properties;
9028
+ return {
9029
+ sdk_version: failure.sdkVersion,
9030
+ operation: failure.operation,
9031
+ error_kind: failure.errorKind,
9032
+ handled: true,
9033
+ ...observationContextProps(merged)
9034
+ };
8859
9035
  }
8860
9036
  function resolveContext(context) {
8861
9037
  return sanitizeObservationContext(resolveRawContext(context));
@@ -8906,7 +9082,7 @@ function normalizeErrorKind(value) {
8906
9082
  return typeof value === "string" && /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/u.test(value) ? value : "Error";
8907
9083
  }
8908
9084
  function syntheticException(operation, kind) {
8909
- const error = /* @__PURE__ */ new Error("Capxul SDK operation failed");
9085
+ const error = /* @__PURE__ */ new Error(EXCEPTION_MESSAGE);
8910
9086
  error.name = kind;
8911
9087
  error.stack = `${kind}: ${error.message}\n at CapxulSdkBoundary.${operation} (capxul-sdk-observation://boundary/${operation}:1:1)`;
8912
9088
  return error;
@@ -9252,6 +9428,9 @@ async function createCapxulClient$1(input) {
9252
9428
  if (signer === void 0 && runtime === "browser") signer = createOpenfortBrowserSignerFromBootstrap({
9253
9429
  ...adapters.value.bootstrap,
9254
9430
  authBaseUrl: resolvedAuthBaseUrl
9431
+ }, {
9432
+ diagnostic: new ConsoleDiagnosticAdapter(),
9433
+ telemetry: adapters.value.ports.telemetry
9255
9434
  });
9256
9435
  const client = wireOpenfortSignerLifecycle(assembleCapxulClient({
9257
9436
  ports: adapters.value.ports,
@@ -9262,7 +9441,8 @@ async function createCapxulClient$1(input) {
9262
9441
  orgPort: new ConvexOrganizationAdapter({ convex: adapters.value.ports.convexCall }),
9263
9442
  ...signer === void 0 ? {} : { organizationSetup: new ConvexOrganizationSetupAdapter({
9264
9443
  convex: adapters.value.ports.convexCall,
9265
- signer
9444
+ signer,
9445
+ chainId: adapters.value.bootstrap.chainId
9266
9446
  }) },
9267
9447
  ...input.signal === void 0 ? {} : { signal: input.signal },
9268
9448
  ...input.otpTtlMs === void 0 ? {} : { otpTtlMs: input.otpTtlMs },
@@ -9466,6 +9646,73 @@ async function createCapxulClient(input) {
9466
9646
  return createCapxulClient$1(input);
9467
9647
  }
9468
9648
  //#endregion
9469
- export { CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, CapxulError, captureException, captureExceptionSync, createCapxulClient, deriveDevPrivateKey, devPrivateKeySigner, eip1193AccountProvider, embeddedSigner, fromPostHog, injectedWalletSigner, isCapxulError, isSettingUpLifecycle, localPrivateKeyAccountProvider, openfortEmbeddedSigner, openfortEmbeddedSignerFromWallet, openfortEmbeddedWalletPort };
9649
+ //#region src/telemetry/from-posthog.ts
9650
+ /**
9651
+ * Drop props that must never cross to a host-owned external sink. Today that is
9652
+ * the `$exception` `details` blob: `captureException` serializes
9653
+ * `CapxulError.details` (e.g. `{ asset, available, required }`, `{ name }`,
9654
+ * `{ accountId }` — errors.ts) into it, and the shared redactor has no
9655
+ * `$exception` rule, so it is stripped here at the boundary (infra#1037). The
9656
+ * safe fields (error code, operation, failure_mode, the fixed leak-safe message,
9657
+ * stack frames) are preserved.
9658
+ */
9659
+ function stripHostUnsafeProps(props) {
9660
+ if (props === void 0) return void 0;
9661
+ const { details: _details, ...safe } = props;
9662
+ return safe;
9663
+ }
9664
+ /**
9665
+ * Adapt the host's already-initialized posthog-like client into a
9666
+ * `TelemetryPort` for the `telemetry` prop / input. This port SUPPLANTS the
9667
+ * SDK's no-op default telemetry sink (`production.ts` binds it via
9668
+ * `Layer.succeed`, not `compose` — there is no client-side success relay to
9669
+ * compose with); it is additive to Capxul's backend first-party record and
9670
+ * never owns the client.
9671
+ */
9672
+ function telemetryFromPostHog(client, options = {}) {
9673
+ const active = () => {
9674
+ if (client === null || client === void 0) return false;
9675
+ try {
9676
+ return typeof options.enabled === "function" ? options.enabled() : options.enabled ?? true;
9677
+ } catch {
9678
+ return false;
9679
+ }
9680
+ };
9681
+ const contextProps = () => {
9682
+ let raw;
9683
+ try {
9684
+ raw = typeof options.context === "function" ? options.context() : options.context;
9685
+ } catch {
9686
+ return {};
9687
+ }
9688
+ return observationContextProps(sanitizeObservationContext(raw));
9689
+ };
9690
+ return new PostHogTelemetryAdapter({
9691
+ capture: (name, props) => {
9692
+ if (!active() || client === null || client === void 0) return;
9693
+ client.capture(name, {
9694
+ ...stripHostUnsafeProps(props),
9695
+ ...contextProps()
9696
+ });
9697
+ },
9698
+ identify: (input) => {
9699
+ if (!active() || client?.identify === void 0) return;
9700
+ client.identify(input.distinctId, {
9701
+ ...input.traits,
9702
+ ...input.properties
9703
+ });
9704
+ },
9705
+ group: (input) => {
9706
+ if (!active() || client?.group === void 0) return;
9707
+ client.group(input.groupType, input.groupKey, input.properties === void 0 ? void 0 : { ...input.properties });
9708
+ },
9709
+ reset: () => {
9710
+ if (!active() || client?.reset === void 0) return;
9711
+ client.reset();
9712
+ }
9713
+ });
9714
+ }
9715
+ //#endregion
9716
+ export { CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, CapxulError, captureException, captureExceptionSync, createCapxulClient, deriveDevPrivateKey, devPrivateKeySigner, eip1193AccountProvider, embeddedSigner, fromPostHog, injectedWalletSigner, isCapxulError, isSettingUpLifecycle, localPrivateKeyAccountProvider, openfortEmbeddedSigner, openfortEmbeddedSignerFromWallet, openfortEmbeddedWalletPort, telemetryFromPostHog, toCountryCode, toAddress as toEvmAddress };
9470
9717
 
9471
9718
  //# sourceMappingURL=index.mjs.map