@capxul/sdk 1.0.0-alpha.20 → 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
@@ -376,6 +376,45 @@ function captureExceptionSync(telemetry, error, context) {
376
376
  } catch {}
377
377
  }
378
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
379
418
  //#region src/client/_shared/effect-actor-bridge.ts
380
419
  /**
381
420
  * Bridge an Effect whose typed failure carries `{ publicError: CapxulError }`
@@ -1221,7 +1260,7 @@ function makeAccountMethods(deps) {
1221
1260
  };
1222
1261
  };
1223
1262
  const deployMutex = /* @__PURE__ */ new Map();
1224
- const deploySafeImpl = async () => {
1263
+ const deploySafeImpl = async (observationSource) => {
1225
1264
  const session = await currentSession(deps.actor, deps.authCache);
1226
1265
  if (session === null) return {
1227
1266
  ok: false,
@@ -1249,7 +1288,8 @@ function makeAccountMethods(deps) {
1249
1288
  authUserId: session.authUserId,
1250
1289
  chainId: deps.chainId,
1251
1290
  signer,
1252
- smartAccountPort: deps.smartAccountPort
1291
+ smartAccountPort: deps.smartAccountPort,
1292
+ observationSource
1253
1293
  }).finally(() => {
1254
1294
  deployMutex.delete(mutexKey);
1255
1295
  });
@@ -1373,11 +1413,11 @@ async function runBackendClaim(input) {
1373
1413
  error: Errors.providerError("signer", "getAddress", cause)
1374
1414
  };
1375
1415
  }
1376
- const claimed = await runPortEffect(input.smartAccountPort.claim({
1416
+ const claimed = await runPortEffect(input.smartAccountPort.claim(copyInvocationObservation(input.observationSource, {
1377
1417
  authUserId: input.authUserId,
1378
1418
  chainId,
1379
1419
  signerAddress
1380
- }));
1420
+ })));
1381
1421
  if (!claimed.ok) return claimed;
1382
1422
  return {
1383
1423
  ok: true,
@@ -1652,7 +1692,7 @@ async function recoverRawDigestSigner(input) {
1652
1692
  }
1653
1693
  //#endregion
1654
1694
  //#region package.json
1655
- var version = "1.0.0-alpha.20";
1695
+ var version = "1.0.0-alpha.21";
1656
1696
  //#endregion
1657
1697
  //#region src/ports/auth-client.ts
1658
1698
  var AuthClientError = class extends Data.TaggedError("AuthClientError") {};
@@ -1738,6 +1778,10 @@ const FIELD_RULES = {
1738
1778
  maxLength: 128,
1739
1779
  pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
1740
1780
  },
1781
+ journeyId: {
1782
+ maxLength: 128,
1783
+ pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
1784
+ },
1741
1785
  correlationId: {
1742
1786
  maxLength: 128,
1743
1787
  pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
@@ -3011,48 +3055,10 @@ function convexCallErrorFromCapxul(operation, error) {
3011
3055
  }
3012
3056
  var ConvexCallPortTag = class extends Context.Tag("@capxul/sdk/ports/ConvexCallPort")() {};
3013
3057
  //#endregion
3014
- //#region src/internal/invocation-observation.ts
3015
- const INVOCATION_OBSERVATION = Symbol("capxul.invocation-observation");
3016
- const FAILURE_INVOCATION_SNAPSHOT = Symbol("capxul.failure-invocation-snapshot");
3017
- /** @internal Attach one immutable, non-wire invocation snapshot to an SDK-owned object. */
3018
- function attachInvocationObservation(target, context) {
3019
- const snapshot = Object.freeze(context === void 0 ? {} : { context: Object.freeze({ ...context }) });
3020
- Object.defineProperty(target, INVOCATION_OBSERVATION, {
3021
- configurable: false,
3022
- enumerable: false,
3023
- value: snapshot,
3024
- writable: false
3025
- });
3026
- return target;
3027
- }
3028
- /** @internal Read the snapshot without exposing its symbol or adding a wire field. */
3029
- function readInvocationObservation(source) {
3030
- if (typeof source !== "object" || source === null) return void 0;
3031
- return source[INVOCATION_OBSERVATION];
3032
- }
3033
- /** @internal Carry a snapshot across an SDK adapter projection without resolving again. */
3034
- function copyInvocationObservation(source, target) {
3035
- const snapshot = readInvocationObservation(source);
3036
- return snapshot === void 0 ? target : attachInvocationObservation(target, snapshot.context);
3037
- }
3038
- /** @internal Mark a failure envelope as already resolved at the public invocation boundary. */
3039
- function markFailureInvocationSnapshot(failure) {
3040
- Object.defineProperty(failure, FAILURE_INVOCATION_SNAPSHOT, {
3041
- configurable: false,
3042
- enumerable: false,
3043
- value: true,
3044
- writable: false
3045
- });
3046
- return failure;
3047
- }
3048
- /** @internal Distinguish public-boundary failures from direct adapter calls. */
3049
- function hasFailureInvocationSnapshot(failure) {
3050
- return typeof failure === "object" && failure !== null && failure[FAILURE_INVOCATION_SNAPSHOT] === true;
3051
- }
3052
- //#endregion
3053
3058
  //#region src/adapters/convex-call/ConvexCallAdapter.ts
3054
3059
  /** Exact floor-first allowlist; every additional handler must migrate its validator first. */
3055
- 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"]);
3056
3062
  var ConvexCallAdapter = class {
3057
3063
  #client;
3058
3064
  #tokenProvider;
@@ -3075,20 +3081,21 @@ var ConvexCallAdapter = class {
3075
3081
  });
3076
3082
  }
3077
3083
  mutation(fn, args) {
3084
+ const path = getFunctionName(fn);
3078
3085
  return Effect.tryPromise({
3079
- try: () => this.#client.mutation(fn, args),
3080
- 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)
3081
3088
  });
3082
3089
  }
3083
3090
  action(fn, args) {
3084
3091
  const path = getFunctionName(fn);
3085
3092
  return Effect.tryPromise({
3086
- try: () => this.#client.action(fn, this.#observedActionArgs(path, args)),
3093
+ try: () => this.#client.action(fn, this.#observedArgs(OBSERVED_CONVEX_ACTIONS, path, args)),
3087
3094
  catch: (cause) => mapToConvexCallError(path, cause)
3088
3095
  });
3089
3096
  }
3090
- #observedActionArgs(path, args) {
3091
- if (!OBSERVED_CONVEX_ACTIONS.has(path)) return args;
3097
+ #observedArgs(allowlist, path, args) {
3098
+ if (!allowlist.has(path)) return args;
3092
3099
  let hostContext;
3093
3100
  const invocationSnapshot = readInvocationObservation(args);
3094
3101
  if (invocationSnapshot !== void 0) hostContext = invocationSnapshot.context;
@@ -3678,6 +3685,8 @@ function brandProfile(raw) {
3678
3685
  email: toEmail(raw.email),
3679
3686
  displayName: raw.displayName,
3680
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),
3681
3690
  kycTier: toKycTier(raw.kycTier),
3682
3691
  createdAt: toEpochMs(raw.createdAt),
3683
3692
  updatedAt: toEpochMs(raw.updatedAt)
@@ -3937,11 +3946,11 @@ var ConvexSmartAccountAdapter = class {
3937
3946
  })), Effect.catchAllDefect((cause) => Effect.fail(smartAccountErrorFromUnknown("confirmDeployment", cause))));
3938
3947
  }
3939
3948
  claim(input) {
3940
- return this.#convex.action(this.#fns.claim, {
3949
+ return this.#convex.action(this.#fns.claim, copyInvocationObservation(input, {
3941
3950
  chainId: wireChainId(input.chainId),
3942
3951
  signerAddress: input.signerAddress,
3943
3952
  ...input.telemetryRunId === void 0 ? {} : { telemetryRunId: input.telemetryRunId }
3944
- }).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({
3945
3954
  try: () => brandProvisionedSmartAccount(input.authUserId, row),
3946
3955
  catch: (cause) => smartAccountErrorFromUnknown("claim", cause)
3947
3956
  })), Effect.catchAllDefect((cause) => Effect.fail(smartAccountErrorFromUnknown("claim", cause))));
@@ -4203,14 +4212,19 @@ const DEFAULT_FUNCTIONS$1 = {
4203
4212
  var ConvexOrganizationSetupAdapter = class {
4204
4213
  #convex;
4205
4214
  #signer;
4215
+ #chainId;
4206
4216
  #fns;
4207
4217
  constructor(input) {
4208
4218
  this.#convex = input.convex;
4209
4219
  this.#signer = input.signer;
4220
+ this.#chainId = input.chainId;
4210
4221
  this.#fns = input.functions ?? DEFAULT_FUNCTIONS$1;
4211
4222
  }
4212
4223
  async startOrResume(input) {
4213
- 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
+ })));
4214
4228
  if (!result.ok) return result;
4215
4229
  const lifecycle = parseLifecycle("startOrResume", result.value.lifecycle);
4216
4230
  if (!lifecycle.ok) return lifecycle;
@@ -4226,17 +4240,17 @@ var ConvexOrganizationSetupAdapter = class {
4226
4240
  };
4227
4241
  }
4228
4242
  prepareFounderAccount(input) {
4229
- 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 })));
4230
4244
  }
4231
4245
  async authorizeAndSubmitBootstrap(input) {
4232
4246
  const cancelled = cancellation(input.signal);
4233
4247
  if (cancelled !== void 0) return cancelled;
4234
4248
  const signerAddress = await signerResult("getAddress", () => this.#signer.getAddress());
4235
4249
  if (!signerAddress.ok) return signerAddress;
4236
- 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, {
4237
4251
  orgId: input.orgId,
4238
4252
  signerAddress: signerAddress.value
4239
- }));
4253
+ })));
4240
4254
  if (!prepared.ok) return prepared;
4241
4255
  const authority = validatePreparedAuthorities(prepared.value, signerAddress.value);
4242
4256
  if (!authority.ok) return authority;
@@ -4246,25 +4260,25 @@ var ConvexOrganizationSetupAdapter = class {
4246
4260
  if (!signature.ok) return signature;
4247
4261
  const cancelledAfterSign = cancellation(input.signal);
4248
4262
  if (cancelledAfterSign !== void 0) return cancelledAfterSign;
4249
- 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, {
4250
4264
  orgId: input.orgId,
4251
4265
  signerAddress: signerAddress.value,
4252
4266
  signature: signature.value,
4253
4267
  userOp: prepared.value.userOp
4254
- }));
4268
+ })));
4255
4269
  if (!submitted.ok) return submitted;
4256
4270
  return parseLifecycle("submitBootstrap", submitted.value);
4257
4271
  }
4258
4272
  resumeSubmittedBootstrap(input) {
4259
- 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 })));
4260
4274
  }
4261
4275
  confirmSubmittedBootstrap(input) {
4262
- 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 })));
4263
4277
  }
4264
4278
  async recordFailure(input) {
4265
4279
  const errorProvider = input.error.details?.provider;
4266
4280
  const errorOperation = input.error.details?.operation;
4267
- 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, {
4268
4282
  orgId: input.orgId,
4269
4283
  errorCode: input.error.code,
4270
4284
  ...typeof errorProvider === "string" && typeof errorOperation === "string" ? {
@@ -4272,7 +4286,7 @@ var ConvexOrganizationSetupAdapter = class {
4272
4286
  errorOperation
4273
4287
  } : {},
4274
4288
  retryable: input.retryable
4275
- }));
4289
+ })));
4276
4290
  return result.ok ? parseLifecycle("recordFailure", result.value) : result;
4277
4291
  }
4278
4292
  async loadLifecycle(input) {
@@ -4290,7 +4304,7 @@ var ConvexOrganizationSetupAdapter = class {
4290
4304
  const reset = resetSignerSession(this.#signer);
4291
4305
  if (!reset.ok) return reset;
4292
4306
  }
4293
- 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 })));
4294
4308
  if (!result.ok) return result;
4295
4309
  return parseLifecycle("retry", result.value);
4296
4310
  }
@@ -4475,6 +4489,7 @@ const PayeeIdTelemetrySchema = Schema.String.pipe(Schema.filter((value) => PAYEE
4475
4489
  const DocumentHashSchema = Schema.String.pipe(Schema.filter((value) => BYTES32_RE.test(value), { message: () => "must be 0x + 64 hex chars" }));
4476
4490
  const TelemetryEnvelopeProps = {
4477
4491
  capxul_e2e_run_id: OptionalString,
4492
+ journeyId: OptionalString,
4478
4493
  correlationId: OptionalString,
4479
4494
  capxulEnv: OptionalString,
4480
4495
  sdkVersion: OptionalString,
@@ -4606,6 +4621,46 @@ const TransferFailedProps = Schema.Struct({
4606
4621
  const ORG_ID_TELEMETRY_RE = /^org_[0-9A-Za-z]+$/;
4607
4622
  const OrgIdTelemetrySchema = Schema.String.pipe(Schema.filter((value) => ORG_ID_TELEMETRY_RE.test(value), { message: () => "must be org_ plus an alphanumeric id" }));
4608
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
+ });
4609
4664
  const OrgCreateStartedProps = Schema.Struct({
4610
4665
  ...TelemetryEnvelopeProps,
4611
4666
  org_id: OptionalOrgId,
@@ -4767,6 +4822,30 @@ Schema.Struct({
4767
4822
  name: Schema.Literal("bootstrap_failed"),
4768
4823
  props: Schema.optional(BootstrapFailedProps)
4769
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
+ });
4770
4849
  Schema.Struct({
4771
4850
  name: Schema.Literal("account_balance_read"),
4772
4851
  props: Schema.optional(AccountBalanceReadProps)
@@ -8010,7 +8089,7 @@ function validateOrganizationLifecycleScope(orgId, lifecycle) {
8010
8089
  };
8011
8090
  }
8012
8091
  /** Advance only the steps still required by one durable Organization lane. */
8013
- async function advanceOrganizationSetup(setup, orgId, initial, signal) {
8092
+ async function advanceOrganizationSetup(setup, orgId, initial, signal, observationSource) {
8014
8093
  const scopedInitial = validateOrganizationLifecycleScope(orgId, initial);
8015
8094
  if (!scopedInitial.ok) return scopedInitial;
8016
8095
  let lifecycle = scopedInitial.value;
@@ -8020,19 +8099,15 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
8020
8099
  value: lifecycle
8021
8100
  };
8022
8101
  const currentStep = lifecycle.step;
8023
- if (signal?.aborted) return recordSetupFailure(setup, orgId, Errors.cancelled({ operation: "organization.setup" }), true);
8024
- const stepInput = {
8102
+ if (signal?.aborted) return recordSetupFailure(setup, orgId, Errors.cancelled({ operation: "organization.setup" }), true, observationSource);
8103
+ const stepInput = copyInvocationObservation(observationSource, {
8025
8104
  orgId,
8026
8105
  ...signal === void 0 ? {} : { signal }
8027
- };
8106
+ });
8028
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);
8029
- if (!next.ok) {
8030
- if (next.error.code === "CANCELLED") return recordSetupFailure(setup, orgId, next.error, true);
8031
- if (next.error.code === "PROVIDER_ERROR") return recordSetupFailure(setup, orgId, next.error, isRetryableProviderFailure(next.error));
8032
- return next;
8033
- }
8108
+ if (!next.ok) return recordSetupFailure(setup, orgId, next.error, isRetryableOrganizationSetupFailure(next.error), observationSource);
8034
8109
  const scopedNext = validateOrganizationLifecycleScope(orgId, next.value);
8035
- if (!scopedNext.ok) return scopedNext;
8110
+ if (!scopedNext.ok) return recordSetupFailure(setup, orgId, scopedNext.error, false, observationSource);
8036
8111
  lifecycle = scopedNext.value;
8037
8112
  if (currentStep === "confirmingBootstrap") return {
8038
8113
  ok: true,
@@ -8043,7 +8118,7 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
8043
8118
  ok: true,
8044
8119
  value: lifecycle
8045
8120
  };
8046
- return fail$1(Errors.wrongState({
8121
+ return recordSetupFailure(setup, orgId, Errors.wrongState({
8047
8122
  method: "organization.setup",
8048
8123
  currentState: lifecycle.step,
8049
8124
  validStates: [
@@ -8051,23 +8126,28 @@ async function advanceOrganizationSetup(setup, orgId, initial, signal) {
8051
8126
  "ready",
8052
8127
  "failed"
8053
8128
  ]
8054
- }));
8129
+ }), false, observationSource);
8055
8130
  }
8056
- async function recordSetupFailure(setup, orgId, error, retryable) {
8057
- const recorded = await setup.recordFailure({
8131
+ async function recordSetupFailure(setup, orgId, error, retryable, observationSource) {
8132
+ const recorded = await setup.recordFailure(copyInvocationObservation(observationSource, {
8058
8133
  orgId,
8059
8134
  error,
8060
8135
  retryable
8061
- });
8136
+ }));
8062
8137
  if (!recorded.ok) return recorded;
8063
8138
  const scopedRecorded = validateOrganizationLifecycleScope(orgId, recorded.value);
8064
8139
  if (!scopedRecorded.ok) return scopedRecorded;
8065
- return fail$1(error);
8140
+ return scopedRecorded;
8066
8141
  }
8067
8142
  function isRetryableProviderFailure(error) {
8068
8143
  const mode = error.details?.failure_mode;
8069
8144
  return mode !== "auth-origin-mismatch" && mode !== "app-env-allowlist" && mode !== "no-secure-context";
8070
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
+ }
8071
8151
  //#endregion
8072
8152
  //#region src/client/org.ts
8073
8153
  /**
@@ -8140,12 +8220,12 @@ function makeOrgMethods(deps) {
8140
8220
  ok: false,
8141
8221
  error: Errors.notImplemented("organizationSetup", "retrySetup")
8142
8222
  };
8143
- const retried = await setup.retry({
8223
+ const retried = await setup.retry(copyInvocationObservation(options, {
8144
8224
  orgId,
8145
8225
  ...options?.signal === void 0 ? {} : { signal: options.signal }
8146
- });
8226
+ }));
8147
8227
  if (!retried.ok) return retried;
8148
- return advanceOrganizationSetup(setup, orgId, retried.value, options?.signal);
8228
+ return advanceOrganizationSetup(setup, orgId, retried.value, options?.signal, options);
8149
8229
  },
8150
8230
  profile: {
8151
8231
  get(_options) {
@@ -8406,17 +8486,21 @@ async function runCompleteOrganizationOnboarding(ops, input, options) {
8406
8486
  const written = await ops.completeIdentityOnboarding({
8407
8487
  authUserId: session.authUserId,
8408
8488
  email: session.email,
8409
- displayName: validated.value.ownerDisplayName,
8410
- 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 }
8411
8492
  });
8412
8493
  if (!written.ok) return fail(written.error);
8413
- const started = await setup.startOrResume({
8414
- name: validated.value.organizationName,
8415
- handle: validated.value.handle,
8416
- country: validated.value.country
8417
- });
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
+ }));
8418
8502
  if (!started.ok) return fail(started.error);
8419
- 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);
8420
8504
  if (!lifecycle.ok) {
8421
8505
  const error = lifecycle.error;
8422
8506
  return fail(new CapxulError(error.code, error.message, {
@@ -8438,9 +8522,36 @@ async function runCompleteOrganizationOnboarding(ops, input, options) {
8438
8522
  };
8439
8523
  }
8440
8524
  function validatePersonalInput(input) {
8441
- 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");
8442
8553
  if (!displayName.ok) return displayName;
8443
- const country = parseCountry(input.country);
8554
+ const country = parseCountry(input.country, "profile.country");
8444
8555
  if (!country.ok) return country;
8445
8556
  if (input.withdrawalAddress === void 0) return {
8446
8557
  ok: true,
@@ -8449,7 +8560,7 @@ function validatePersonalInput(input) {
8449
8560
  country: country.value
8450
8561
  }
8451
8562
  };
8452
- const withdrawalAddress = parseAddress(input.withdrawalAddress, "withdrawalAddress");
8563
+ const withdrawalAddress = parseAddress(input.withdrawalAddress, "profile.withdrawalAddress");
8453
8564
  if (!withdrawalAddress.ok) return withdrawalAddress;
8454
8565
  return {
8455
8566
  ok: true,
@@ -8460,25 +8571,6 @@ function validatePersonalInput(input) {
8460
8571
  }
8461
8572
  };
8462
8573
  }
8463
- function validateOrganizationInput(input) {
8464
- const organizationName = requireNonEmpty(input.organizationName, "organizationName");
8465
- if (!organizationName.ok) return organizationName;
8466
- const handle = requireNonEmpty(input.handle, "handle");
8467
- if (!handle.ok) return handle;
8468
- const ownerDisplayName = requireNonEmpty(input.ownerDisplayName, "ownerDisplayName");
8469
- if (!ownerDisplayName.ok) return ownerDisplayName;
8470
- const country = parseCountry(input.country);
8471
- if (!country.ok) return country;
8472
- return {
8473
- ok: true,
8474
- value: {
8475
- organizationName: organizationName.value,
8476
- handle: handle.value,
8477
- country: country.value,
8478
- ownerDisplayName: ownerDisplayName.value
8479
- }
8480
- };
8481
- }
8482
8574
  function requireNonEmpty(value, field) {
8483
8575
  const trimmed = typeof value === "string" ? value.trim() : "";
8484
8576
  if (trimmed.length === 0) return fail(Errors.invalidInput(field, "must be a non-empty string"));
@@ -8487,14 +8579,14 @@ function requireNonEmpty(value, field) {
8487
8579
  value: trimmed
8488
8580
  };
8489
8581
  }
8490
- function parseCountry(value) {
8582
+ function parseCountry(value, field = "country") {
8491
8583
  try {
8492
8584
  return {
8493
8585
  ok: true,
8494
8586
  value: toCountryCode(value)
8495
8587
  };
8496
8588
  } catch (cause) {
8497
- 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"));
8498
8590
  }
8499
8591
  }
8500
8592
  function parseAddress(value, field) {
@@ -8511,6 +8603,9 @@ function invalidFrom(field, cause, fallback) {
8511
8603
  const message = cause instanceof Error && cause.message.length > 0 ? cause.message : fallback;
8512
8604
  return Errors.invalidInput(field, message);
8513
8605
  }
8606
+ function isRecord(value) {
8607
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8608
+ }
8514
8609
  function fail(error) {
8515
8610
  return {
8516
8611
  ok: false,
@@ -8640,6 +8735,22 @@ function assembleCapxulClient(input) {
8640
8735
  };
8641
8736
  },
8642
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
+ },
8643
8754
  triggerProvisioning: () => account._internal.provision(),
8644
8755
  kickProvisioning: () => kickProvisioning?.(),
8645
8756
  readLifecycle: () => account.getLifecycle(),
@@ -8802,7 +8913,7 @@ function observeSdkClient(client, adapter) {
8802
8913
  if (cached !== void 0) return cached;
8803
8914
  const wrapped = new Proxy(callable, {
8804
8915
  apply(currentTarget, _thisArg, args) {
8805
- const invocationContext = resolveAdapterContext(adapter);
8916
+ const invocationContext = invocationObservationContext(resolveAdapterContext(adapter));
8806
8917
  const invocationArgs = carryInvocationContext(operation, args, invocationContext);
8807
8918
  let output;
8808
8919
  try {
@@ -8839,9 +8950,23 @@ function observeSdkClient(client, adapter) {
8839
8950
  return wrapObject(client, []);
8840
8951
  }
8841
8952
  function carryInvocationContext(operation, args, context) {
8842
- if (operation !== "subAccounts.transfer" || !isPlainObject(args[0])) return args;
8953
+ if (!isPlainObject(args[0])) return args.length === 0 && operation === "org.retrySetup" ? [attachInvocationObservation({}, context)] : args;
8843
8954
  return [attachInvocationObservation({ ...args[0] }, context), ...args.slice(1)];
8844
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
+ }
8845
8970
  /** @internal Reports a factory-level typed failure without changing its identity. */
8846
8971
  function observeFailedResult(result, adapter, operation) {
8847
8972
  if (adapter !== void 0 && isFailedResult(result)) report(adapter, "operation", operation, result.error, resolveAdapterContext(adapter));
@@ -8890,6 +9015,7 @@ function observationContextProps(context) {
8890
9015
  if (context?.release !== void 0) props.release = context.release;
8891
9016
  if (context?.sessionId !== void 0) props.session_id = context.sessionId;
8892
9017
  if (context?.organizationId !== void 0) props.organization_id = context.organizationId;
9018
+ if (context?.journeyId !== void 0) props.journey_id = context.journeyId;
8893
9019
  if (context?.correlationId !== void 0) props.correlation_id = context.correlationId;
8894
9020
  if (context?.anonymousId !== void 0) props.anonymous_id = context.anonymousId;
8895
9021
  return props;
@@ -9315,7 +9441,8 @@ async function createCapxulClient$1(input) {
9315
9441
  orgPort: new ConvexOrganizationAdapter({ convex: adapters.value.ports.convexCall }),
9316
9442
  ...signer === void 0 ? {} : { organizationSetup: new ConvexOrganizationSetupAdapter({
9317
9443
  convex: adapters.value.ports.convexCall,
9318
- signer
9444
+ signer,
9445
+ chainId: adapters.value.bootstrap.chainId
9319
9446
  }) },
9320
9447
  ...input.signal === void 0 ? {} : { signal: input.signal },
9321
9448
  ...input.otpTtlMs === void 0 ? {} : { otpTtlMs: input.otpTtlMs },
@@ -9586,6 +9713,6 @@ function telemetryFromPostHog(client, options = {}) {
9586
9713
  });
9587
9714
  }
9588
9715
  //#endregion
9589
- export { CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, CapxulError, captureException, captureExceptionSync, createCapxulClient, deriveDevPrivateKey, devPrivateKeySigner, eip1193AccountProvider, embeddedSigner, fromPostHog, injectedWalletSigner, isCapxulError, isSettingUpLifecycle, localPrivateKeyAccountProvider, openfortEmbeddedSigner, openfortEmbeddedSignerFromWallet, openfortEmbeddedWalletPort, telemetryFromPostHog };
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 };
9590
9717
 
9591
9718
  //# sourceMappingURL=index.mjs.map