@capxul/sdk 2.5.3 → 2.5.5

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.
@@ -1,6 +1,6 @@
1
1
  import { A as toPartyId, B as Errors, M as toPayrollRunId, P as toRoleKey, R as CapxulError, S as toCurrencyCode, V as isCapxulError, b as toChainId, c as BYTES32_RE, d as WEI_RE, f as ZERO_BYTES32, h as toAddress, j as toPayrollGroupId, k as toOrgId, l as EVM_ADDRESS_RE$1, m as toAccountId, n as BrowserAuthCacheAdapter, s as APP_ID_RE, t as InMemoryAuthCacheAdapter, u as SUPPORTED_CURRENCY_CODES, v as toAuthUserId, w as toEmail, x as toCountryCode, y as toBudgetId, z as EXPECTED_OPERATION_OUTCOMES } from "./InMemoryAuthCacheAdapter-uOcqpqu8.mjs";
2
2
  import { concat, encodeAbiParameters, encodeFunctionData, encodePacked, formatUnits, getContractAddress, keccak256, padHex, parseUnits, recoverAddress, stringToHex, toBytes, toEventSelector, toFunctionSelector, toFunctionSignature } from "viem";
3
- import { Context, Data, Deferred, Effect, Exit, Fiber, Layer, Queue, Ref, Result, Schema, SchemaGetter, Scope } from "effect";
3
+ import { Context, Data, Deferred, Duration, Effect, Exit, Fiber, Layer, Queue, Ref, Result, Schema, SchemaGetter, Scope } from "effect";
4
4
  import { makeFunctionReference } from "convex/server";
5
5
  //#region src/domain/identity/model.ts
6
6
  const WRONG = { refused: "WRONG_STATE" };
@@ -1217,6 +1217,24 @@ const CAPXUL_PAYMENTS_V2_ABI = [
1217
1217
  internalType: "bytes32"
1218
1218
  }]
1219
1219
  },
1220
+ {
1221
+ type: "error",
1222
+ name: "TokenCallReturnedFalse",
1223
+ inputs: [{
1224
+ name: "token",
1225
+ type: "address",
1226
+ internalType: "address"
1227
+ }]
1228
+ },
1229
+ {
1230
+ type: "error",
1231
+ name: "TokenHasNoCode",
1232
+ inputs: [{
1233
+ name: "token",
1234
+ type: "address",
1235
+ internalType: "address"
1236
+ }]
1237
+ },
1220
1238
  {
1221
1239
  type: "error",
1222
1240
  name: "ZeroAddress",
@@ -1239,7 +1257,7 @@ const CAPXUL_PAYMENTS_V2_ABI = [
1239
1257
  }
1240
1258
  ];
1241
1259
  /** Immutable CapxulPaymentsV2 deployment on Base Sepolia. */
1242
- const CAPXUL_PAYMENTS_V2_ADDRESS = "0xA3ACDD016f706eD432A9a0545C45F0943f996b60";
1260
+ const CAPXUL_PAYMENTS_V2_ADDRESS = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
1243
1261
  //#endregion
1244
1262
  //#region ../config/src/route.ts
1245
1263
  /** USDX on Base Sepolia — the only settlement token in v1. */
@@ -1581,7 +1599,7 @@ const EVM_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
1581
1599
  * envelopes carrying it — so it MUST stay byte-identical across both. Exported
1582
1600
  * once here to remove the drift risk of a mirrored declaration.
1583
1601
  */
1584
- const PAYMENT_DOCUMENT_VERIFYING_CONTRACT = "0xA3ACDD016f706eD432A9a0545C45F0943f996b60";
1602
+ const PAYMENT_DOCUMENT_VERIFYING_CONTRACT = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
1585
1603
  const PAYMENT_ID_RE = /^payment_[0-9A-Za-z]+$/;
1586
1604
  const PAYEE_ID_RE = /^payee_[0-9A-Za-z]+$/;
1587
1605
  const ORG_ID_RE = /^org_[0-9A-Za-z]+$/;
@@ -4549,73 +4567,8 @@ function isMoneyTelemetryDebugEnabled() {
4549
4567
  return globalThis.process?.env?.CAPXUL_DEBUG_TELEMETRY === "1";
4550
4568
  }
4551
4569
  //#endregion
4552
- //#region src/surface/payment-execution.ts
4553
- function mismatch(field, message) {
4554
- return {
4555
- ok: false,
4556
- error: Errors.invalidInput(field, message)
4557
- };
4558
- }
4559
- function cancelled(operation) {
4560
- return {
4561
- ok: false,
4562
- error: Errors.cancelled({ operation })
4563
- };
4564
- }
4565
- function isAborted$2(signal) {
4566
- return signal?.aborted === true;
4567
- }
4568
- async function signerCall(source, operation, run) {
4569
- try {
4570
- return {
4571
- ok: true,
4572
- value: await run()
4573
- };
4574
- } catch (cause) {
4575
- return {
4576
- ok: false,
4577
- error: signerFailure(source, operation, cause)
4578
- };
4579
- }
4580
- }
4581
- async function executePersonalPayment(deps, payment, signal, requestKey) {
4582
- if (isAborted$2(signal)) return cancelled("payments.pay");
4583
- if (deps.signer === void 0) return mismatch("signer", "payments.pay requires a configured CapxulSigner");
4584
- const session = deps.actor.authSession();
4585
- if (session === null) return {
4586
- ok: false,
4587
- error: Errors.notAuthenticated()
4588
- };
4589
- const signerAddress = await signerCall(deps.signer.source, "getAddress", () => deps.signer.getAddress());
4590
- if (!signerAddress.ok) return signerAddress;
4591
- const expectedSafe = deriveCapxulSafeAddress({ email: session.email });
4592
- const resolvedRequestKey = requestKey ?? `pay_${crypto.randomUUID()}`;
4593
- const prepared = await runIfActive(signal, "payments.prepareExecution", () => deps.convexCall.action(deps.functions.preparePaymentExecution, { input: {
4594
- requestKey: resolvedRequestKey,
4595
- signerAddress: signerAddress.value,
4596
- payment
4597
- } }));
4598
- if (!prepared.ok) return prepared;
4599
- if (prepared.value.requestKey !== resolvedRequestKey || JSON.stringify(prepared.value.payment) !== JSON.stringify(payment)) return mismatch("payment", "prepared Payment execution uses another request");
4600
- if (prepared.value.chainId !== deps.chainId) return mismatch("chainId", "prepared Payment execution uses another chain");
4601
- if (prepared.value.signerAddress.toLowerCase() !== signerAddress.value.toLowerCase()) return mismatch("signerAddress", "prepared Payment execution uses another signer");
4602
- if (prepared.value.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return mismatch("userOpSenderSafe", "prepared Payment execution uses another Account Safe");
4603
- if (prepared.value.emitPaymentInitiated) await emitPaymentInitiated(deps.telemetry, {
4604
- kind: prepared.value.purposeKind,
4605
- paymentId: prepared.value.paymentId
4606
- });
4607
- if (isAborted$2(signal)) return cancelled("payments.pay");
4608
- const signature = await signerCall(deps.signer.source, "signUserOpHash", () => deps.signer.signUserOpHash(prepared.value.digest));
4609
- if (!signature.ok) return signature;
4610
- if (isAborted$2(signal)) return cancelled("payments.pay");
4611
- return runIfActive(void 0, "payments.submitExecution", () => deps.convexCall.action(deps.functions.submitPaymentExecution, { input: {
4612
- executionId: prepared.value.executionId,
4613
- signature: signature.value
4614
- } }));
4615
- }
4616
- //#endregion
4617
4570
  //#region src/surface/payment-command-execution.ts
4618
- function isAborted$1(signal) {
4571
+ function isAborted$2(signal) {
4619
4572
  return signal?.aborted === true;
4620
4573
  }
4621
4574
  function canonicalJson(value) {
@@ -4631,7 +4584,7 @@ function matchesIntent(expected) {
4631
4584
  return async (request) => await fingerprintPaymentIntent(request) === await fingerprintPaymentIntent(expected);
4632
4585
  }
4633
4586
  async function executePrepared(deps, prepare, isExpectedRequest, signal) {
4634
- if (isAborted$1(signal)) return {
4587
+ if (isAborted$2(signal)) return {
4635
4588
  ok: false,
4636
4589
  error: Errors.cancelled({ operation: "payments" })
4637
4590
  };
@@ -4660,7 +4613,7 @@ async function executePrepared(deps, prepare, isExpectedRequest, signal) {
4660
4613
  ok: false,
4661
4614
  error: Errors.invalidInput("payment", "prepared authority mismatch")
4662
4615
  };
4663
- if (isAborted$1(signal)) return {
4616
+ if (isAborted$2(signal)) return {
4664
4617
  ok: false,
4665
4618
  error: Errors.cancelled({ operation: "payments" })
4666
4619
  };
@@ -4673,7 +4626,7 @@ async function executePrepared(deps, prepare, isExpectedRequest, signal) {
4673
4626
  error: signerFailure(deps.signer.source, "signUserOpHash", cause)
4674
4627
  };
4675
4628
  }
4676
- if (isAborted$1(signal)) return {
4629
+ if (isAborted$2(signal)) return {
4677
4630
  ok: false,
4678
4631
  error: Errors.cancelled({ operation: "payments" })
4679
4632
  };
@@ -4695,6 +4648,71 @@ function executeOrganizationPayment(deps, input, signal) {
4695
4648
  } })), matchesIntent(input), signal);
4696
4649
  }
4697
4650
  //#endregion
4651
+ //#region src/surface/payment-execution.ts
4652
+ function mismatch(field, message) {
4653
+ return {
4654
+ ok: false,
4655
+ error: Errors.invalidInput(field, message)
4656
+ };
4657
+ }
4658
+ function cancelled(operation) {
4659
+ return {
4660
+ ok: false,
4661
+ error: Errors.cancelled({ operation })
4662
+ };
4663
+ }
4664
+ function isAborted$1(signal) {
4665
+ return signal?.aborted === true;
4666
+ }
4667
+ async function signerCall(source, operation, run) {
4668
+ try {
4669
+ return {
4670
+ ok: true,
4671
+ value: await run()
4672
+ };
4673
+ } catch (cause) {
4674
+ return {
4675
+ ok: false,
4676
+ error: signerFailure(source, operation, cause)
4677
+ };
4678
+ }
4679
+ }
4680
+ async function executePersonalPayment(deps, payment, signal, requestKey) {
4681
+ if (isAborted$1(signal)) return cancelled("payments.pay");
4682
+ if (deps.signer === void 0) return mismatch("signer", "payments.pay requires a configured CapxulSigner");
4683
+ const session = deps.actor.authSession();
4684
+ if (session === null) return {
4685
+ ok: false,
4686
+ error: Errors.notAuthenticated()
4687
+ };
4688
+ const signerAddress = await signerCall(deps.signer.source, "getAddress", () => deps.signer.getAddress());
4689
+ if (!signerAddress.ok) return signerAddress;
4690
+ const expectedSafe = deriveCapxulSafeAddress({ email: session.email });
4691
+ const resolvedRequestKey = requestKey ?? `pay_${crypto.randomUUID()}`;
4692
+ const prepared = await runIfActive(signal, "payments.prepareExecution", () => deps.convexCall.action(deps.functions.preparePaymentExecution, { input: {
4693
+ requestKey: resolvedRequestKey,
4694
+ signerAddress: signerAddress.value,
4695
+ payment
4696
+ } }));
4697
+ if (!prepared.ok) return prepared;
4698
+ if (prepared.value.requestKey !== resolvedRequestKey || canonicalJson(prepared.value.payment) !== canonicalJson(payment)) return mismatch("payment", "prepared Payment execution uses another request");
4699
+ if (prepared.value.chainId !== deps.chainId) return mismatch("chainId", "prepared Payment execution uses another chain");
4700
+ if (prepared.value.signerAddress.toLowerCase() !== signerAddress.value.toLowerCase()) return mismatch("signerAddress", "prepared Payment execution uses another signer");
4701
+ if (prepared.value.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return mismatch("userOpSenderSafe", "prepared Payment execution uses another Account Safe");
4702
+ if (prepared.value.emitPaymentInitiated) await emitPaymentInitiated(deps.telemetry, {
4703
+ kind: prepared.value.purposeKind,
4704
+ paymentId: prepared.value.paymentId
4705
+ });
4706
+ if (isAborted$1(signal)) return cancelled("payments.pay");
4707
+ const signature = await signerCall(deps.signer.source, "signUserOpHash", () => deps.signer.signUserOpHash(prepared.value.digest));
4708
+ if (!signature.ok) return signature;
4709
+ if (isAborted$1(signal)) return cancelled("payments.pay");
4710
+ return runIfActive(void 0, "payments.submitExecution", () => deps.convexCall.action(deps.functions.submitPaymentExecution, { input: {
4711
+ executionId: prepared.value.executionId,
4712
+ signature: signature.value
4713
+ } }));
4714
+ }
4715
+ //#endregion
4698
4716
  //#region src/surface/money.ts
4699
4717
  function actorReferenceToBackend(actor) {
4700
4718
  if (actor === void 0) return void 0;
@@ -5541,7 +5559,7 @@ function mapOk(result, f) {
5541
5559
  }
5542
5560
  //#endregion
5543
5561
  //#region package.json
5544
- var version = "2.5.3";
5562
+ var version = "2.5.5";
5545
5563
  //#endregion
5546
5564
  //#region src/ports/auth-client.ts
5547
5565
  var AuthClientError = class extends Data.TaggedError("AuthClientError") {};
@@ -5828,6 +5846,28 @@ const FaucetFailedProps = Schema.Struct({
5828
5846
  ...TelemetryEnvelopeProps,
5829
5847
  reason: OptionalString
5830
5848
  });
5849
+ const AaGatewayUpstreamFallbackProps = Schema.Struct({
5850
+ ...TelemetryEnvelopeProps,
5851
+ method: Schema.String,
5852
+ from_upstream: Schema.Literals([
5853
+ "alchemy",
5854
+ "infura",
5855
+ "public"
5856
+ ]),
5857
+ to_upstream: Schema.optional(Schema.Literals([
5858
+ "alchemy",
5859
+ "infura",
5860
+ "public"
5861
+ ])),
5862
+ failure: Schema.Literals([
5863
+ "http-429",
5864
+ "http-5xx",
5865
+ "rpc-rate-limit",
5866
+ "timeout",
5867
+ "network"
5868
+ ]),
5869
+ status: Schema.optional(Schema.Number)
5870
+ });
5831
5871
  const ORG_ID_TELEMETRY_RE = /^org_[0-9A-Za-z]+$/;
5832
5872
  const OrgIdTelemetrySchema = Schema.String.pipe(Schema.refine((value) => ORG_ID_TELEMETRY_RE.test(value), { message: "must be org_ plus an alphanumeric id" }));
5833
5873
  const OptionalOrgId = Schema.optional(OrgIdTelemetrySchema);
@@ -5878,6 +5918,8 @@ const OrganizationCreationFailedProps = Schema.Struct({
5878
5918
  stage: OnboardingStageSchema,
5879
5919
  error_code: Schema.String,
5880
5920
  retryable: Schema.Boolean,
5921
+ /** #1655: the SDK's backoff before this attempt. Absent on the first attempt. */
5922
+ backoff_ms: Schema.optional(DurationMsSchema),
5881
5923
  failure_reason: Schema.optional(Schema.Literals([
5882
5924
  "deterministic_address_mismatch",
5883
5925
  "receipt_provider_unavailable",
@@ -6128,6 +6170,10 @@ Schema.Struct({
6128
6170
  name: Schema.Literal("faucet_failed"),
6129
6171
  props: FaucetFailedProps
6130
6172
  });
6173
+ Schema.Struct({
6174
+ name: Schema.Literal("aa_gateway_upstream_fallback"),
6175
+ props: AaGatewayUpstreamFallbackProps
6176
+ });
6131
6177
  Schema.Struct({
6132
6178
  name: Schema.Literal("org_create_started"),
6133
6179
  props: OrgCreateStartedProps
@@ -6518,6 +6564,29 @@ const IDENTITY_SLOT_BY_EVENT = {
6518
6564
  OrgFailed: IDENTITY_SLOT.org
6519
6565
  };
6520
6566
  const identitySlot = (event) => IDENTITY_SLOT_BY_EVENT[event._tag];
6567
+ /** 2 s, 4 s, 8 s, 16 s, 32 s, 60 s, 60 s: about three minutes, then the user decides. */
6568
+ const DEFAULT_CONFIRMATION_BACKOFF = {
6569
+ initialDelayMs: 2e3,
6570
+ maxDelayMs: 6e4,
6571
+ maxRetries: 7
6572
+ };
6573
+ /**
6574
+ * A public partial override must not bring the tight loop back: a zero,
6575
+ * negative, or non-finite delay, or a non-integer or infinite retry count,
6576
+ * falls back to the default for that field. `maxDelayMs` is never below
6577
+ * `initialDelayMs`.
6578
+ */
6579
+ const positiveMs = (value, fallback) => value !== void 0 && Number.isFinite(value) && value > 0 ? value : fallback;
6580
+ function normalizeConfirmationBackoff(override) {
6581
+ const initialDelayMs = positiveMs(override?.initialDelayMs, DEFAULT_CONFIRMATION_BACKOFF.initialDelayMs);
6582
+ const maxDelayMs = Math.max(initialDelayMs, positiveMs(override?.maxDelayMs, DEFAULT_CONFIRMATION_BACKOFF.maxDelayMs));
6583
+ const retries = override?.maxRetries;
6584
+ return {
6585
+ initialDelayMs,
6586
+ maxDelayMs,
6587
+ maxRetries: retries !== void 0 && Number.isSafeInteger(retries) && retries >= 0 ? retries : DEFAULT_CONFIRMATION_BACKOFF.maxRetries
6588
+ };
6589
+ }
6521
6590
  const failureOf = (error) => {
6522
6591
  if (error instanceof CapxulError) {
6523
6592
  const mode = error.details?.failure_mode;
@@ -6626,7 +6695,7 @@ const orgEngineeringContext = (controls, parent) => {
6626
6695
  ...traceparent === void 0 ? {} : { traceparent }
6627
6696
  };
6628
6697
  };
6629
- const runOrgStep = (setup, orgId, step, controls) => {
6698
+ const runOrgStep = (setup, orgId, step, controls, retryDelayMs) => {
6630
6699
  const [name, invoke] = step === "preparingFounderAccount" ? ["organization-setup.prepare-founder-account", (parent) => setup.prepareFounderAccount({
6631
6700
  orgId,
6632
6701
  observationContext: orgEngineeringContext(controls, parent)
@@ -6638,11 +6707,12 @@ const runOrgStep = (setup, orgId, step, controls) => {
6638
6707
  observationContext: orgEngineeringContext(controls, parent)
6639
6708
  })] : ["organization-setup.confirm-submitted-bootstrap", (parent) => setup.confirmSubmittedBootstrap({
6640
6709
  orgId,
6641
- observationContext: orgEngineeringContext(controls, parent)
6710
+ observationContext: orgEngineeringContext(controls, parent),
6711
+ ...retryDelayMs === void 0 ? {} : { retryDelayMs }
6642
6712
  })];
6643
6713
  return resultEffect(name, invoke);
6644
6714
  };
6645
- const orgLane = (setup, start, send, controls) => Effect.gen(function* () {
6715
+ const orgLane = (setup, start, send, controls, backoff) => Effect.gen(function* () {
6646
6716
  let orgId;
6647
6717
  let lifecycle;
6648
6718
  if (start.kind === "create") {
@@ -6705,9 +6775,12 @@ const orgLane = (setup, start, send, controls) => Effect.gen(function* () {
6705
6775
  orgId,
6706
6776
  step
6707
6777
  });
6778
+ let retries = 0;
6779
+ let retryDelayMs;
6708
6780
  while (step !== "ready") {
6709
6781
  const current = step;
6710
- const advanced = yield* Effect.result(runOrgStep(setup, orgId, current, controls));
6782
+ const advanced = yield* Effect.result(runOrgStep(setup, orgId, current, controls, retryDelayMs));
6783
+ retryDelayMs = void 0;
6711
6784
  if (Result.isFailure(advanced)) {
6712
6785
  yield* send({
6713
6786
  _tag: "OrgFailed",
@@ -6719,6 +6792,38 @@ const orgLane = (setup, start, send, controls) => Effect.gen(function* () {
6719
6792
  }
6720
6793
  lifecycle = advanced.success;
6721
6794
  if (lifecycle.status === "failed") {
6795
+ if (lifecycle.at === "confirmingBootstrap" && lifecycle.retryable && retries < backoff.maxRetries) {
6796
+ const delayMs = Math.min(backoff.initialDelayMs * 2 ** retries, backoff.maxDelayMs);
6797
+ retries += 1;
6798
+ yield* Effect.sleep(Duration.millis(delayMs));
6799
+ const reset = yield* Effect.result(resultEffect("organization-setup.retry", (parent) => setup.retry({
6800
+ orgId,
6801
+ observationContext: orgEngineeringContext(controls, parent)
6802
+ })));
6803
+ if (Result.isFailure(reset)) {
6804
+ yield* send({
6805
+ _tag: "OrgFailed",
6806
+ orgId,
6807
+ step: current,
6808
+ failure: reset.failure
6809
+ });
6810
+ return yield* Effect.fail(reset.failure);
6811
+ }
6812
+ lifecycle = reset.success;
6813
+ if (lifecycle.status !== "failed") {
6814
+ retryDelayMs = delayMs;
6815
+ step = orgStep(lifecycle);
6816
+ yield* step === "ready" ? send({
6817
+ _tag: "OrgReady",
6818
+ orgId
6819
+ }) : send({
6820
+ _tag: "OrgAt",
6821
+ orgId,
6822
+ step
6823
+ });
6824
+ continue;
6825
+ }
6826
+ }
6722
6827
  const failure = failureOf(lifecycle.error);
6723
6828
  yield* send({
6724
6829
  _tag: "OrgFailed",
@@ -6797,6 +6902,7 @@ const identitySpec = (input, sessionStore = { current: null }) => {
6797
6902
  hasSigner: input.signer !== void 0,
6798
6903
  ...input.otpTtlMs === void 0 ? {} : { otpTtlMs: input.otpTtlMs }
6799
6904
  };
6905
+ const backoff = normalizeConfirmationBackoff(input.confirmationBackoff);
6800
6906
  return {
6801
6907
  machine: "identity",
6802
6908
  initial: RESTORING,
@@ -6902,7 +7008,7 @@ const identitySpec = (input, sessionStore = { current: null }) => {
6902
7008
  run: (send, controls) => orgLane(input.organizationSetup, {
6903
7009
  kind: "create",
6904
7010
  draft: event.draft
6905
- }, send, controls)
7011
+ }, send, controls, backoff)
6906
7012
  };
6907
7013
  case "AttachOrganization": return input.organizationSetup === void 0 || org?.at !== "loading" ? void 0 : {
6908
7014
  slot: IDENTITY_SLOT.org,
@@ -6910,7 +7016,7 @@ const identitySpec = (input, sessionStore = { current: null }) => {
6910
7016
  run: (send, controls) => orgLane(input.organizationSetup, {
6911
7017
  kind: "attach",
6912
7018
  orgId: org.orgId
6913
- }, send, controls)
7019
+ }, send, controls, backoff)
6914
7020
  };
6915
7021
  case "RetryOrganization": return input.organizationSetup === void 0 || org?.at !== "settingUp" ? void 0 : {
6916
7022
  slot: IDENTITY_SLOT.org,
@@ -6918,7 +7024,7 @@ const identitySpec = (input, sessionStore = { current: null }) => {
6918
7024
  run: (send, controls) => orgLane(input.organizationSetup, {
6919
7025
  kind: "retry",
6920
7026
  orgId: org.orgId
6921
- }, send, controls)
7027
+ }, send, controls, backoff)
6922
7028
  };
6923
7029
  default: return;
6924
7030
  }
@@ -9313,6 +9419,43 @@ function executeIdentityProductObservation(telemetry, record, state) {
9313
9419
  }
9314
9420
  //#endregion
9315
9421
  //#region src/surface/create-capxul-client.ts
9422
+ /**
9423
+ * Start the signer readiness cycle when the identity becomes claimed (#1667).
9424
+ *
9425
+ * The cycle used to run only from the embedded-wallet port's `getAddress` and
9426
+ * `signRawDigest`. Nothing calls those after a sign-in or a session restore,
9427
+ * and `resetSession`, which every OTP verify performs, sets the status back to
9428
+ * `unknown`. Thus `client.signer.status()` never left `unknown` on a fresh
9429
+ * session, and each `.Actions` gate that requires `ready` stayed closed. A
9430
+ * claimed identity is the first point where the browser signer has a session to
9431
+ * recover. A signed-out client starts no cycle and reports `unknown`.
9432
+ *
9433
+ * The assembly does not await the call, on purpose: readiness must converge
9434
+ * without a signature. The cycle reports its own failure. It writes
9435
+ * `unavailable` to the same store the gate reads, and adds a DiagnosticPort
9436
+ * breadcrumb, and the next `getAddress` retries it, as before. The rejection is
9437
+ * thus observed and not discarded. A throw here would only cause an unhandled
9438
+ * rejection, and the actor shell removes an observer that throws.
9439
+ *
9440
+ * The `unknown` test holds this to ONE cycle per session. The call sets the
9441
+ * status to `recovering` synchronously, so the later claimed transitions of the
9442
+ * same session, such as the org lane, start no second cycle, and a
9443
+ * `resetSession` that sets the status back to `unknown` permits one more.
9444
+ *
9445
+ * ponytail: one cycle per claim. A cycle that fails stays `unavailable` until
9446
+ * a `getAddress` or a new claim, so a gate that refuses to sign while
9447
+ * `unavailable` needs a reload. Give the action part an explicit retry if that
9448
+ * becomes the common failure.
9449
+ */
9450
+ function startSignerReadinessOnClaim(actor, signer) {
9451
+ if (signer?.statusStore === void 0 || signer.ensureWalletReady === void 0) return () => {};
9452
+ const browserSigner = signer;
9453
+ return actor.subscribe((state) => {
9454
+ if (state.phase !== "authenticated" || state.account.at !== "claimed") return;
9455
+ if (browserSigner.statusStore?.status() !== "unknown") return;
9456
+ browserSigner.ensureWalletReady?.().catch(() => {});
9457
+ });
9458
+ }
9316
9459
  function assembleCapxulClient(input) {
9317
9460
  const observation = input;
9318
9461
  const authCache = input.authCache ?? detectAuthCacheAdapter();
@@ -9340,11 +9483,13 @@ function assembleCapxulClient(input) {
9340
9483
  error: transitionError(record)
9341
9484
  }, failureObservation, `identity.${record.event}`, "machine");
9342
9485
  });
9486
+ const unsubscribeSignerReadiness = startSignerReadinessOnClaim(actor, input.signer);
9343
9487
  let stopPromise = null;
9344
9488
  const stopActor = () => {
9345
9489
  if (stopPromise === null) {
9346
9490
  unsubscribeProductTelemetry();
9347
9491
  unsubscribeFailureObservation();
9492
+ unsubscribeSignerReadiness();
9348
9493
  stopPromise = effectRunner.runPromise(Scope.close(scope, Exit.void));
9349
9494
  }
9350
9495
  return stopPromise;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { B as OrgId, C as Address, N as CountryCode, O as AuthSession, S as AccountId, U as PayrollGroupId, V as PartyId, W as PayrollRunId, Y as RoleKey, a as SignerStatusStore, at as CapxulErrorDetails, c as AccountProviderSource, ct as FailureMode, d as eip1193AccountProvider, et as toAddress, f as localPrivateKeyAccountProvider, g as SmartAccount, h as Session, i as SignerStatus, it as CapxulErrorCode, j as BudgetId, k as AuthUserId, l as AccountRequirement, lt as isCapxulError, m as Profile, n as CapxulSigner, nt as CAPXUL_ERROR_CODES, o as injectedWalletSigner, ot as Errors, p as CapxulResult, r as Eip1193RequestProvider, rt as CapxulError, s as AccountProvider, t as CapxulDigestSigner, tt as toCountryCode, u as Eip1193Provider, x as Account, z as Money } from "./signer-BSEG9xgN.mjs";
2
- import { $ as PermissionChangeInput, $n as Readiness, $t as MovementActivityEvidence, A as OrgView, An as IdentityMethods, At as ActivityKind, B as PayrollGroupMember, Bn as PAYMENT_DIRECTIONS, Bt as DepositInstructions, C as DetectPendingOrgInvitationsResult, Cn as ResolvedTarget, Ct as InboxItem, D as OrgMethods, Dn as AccountLifecycle, Dt as ActivityDetail, E as MemberView, En as fingerprintPaymentIntent, Et as ActivityAnnotationInput, F as RoleSpendCap, Fn as ActorRef, Ft as ActivityReference, G as PayrollRunItemInput, Gt as DestinationPayload, H as PayrollMethods, Hn as PaymentStatus$1, Ht as DestinationAddInput, I as RoleView, In as CurrentHoldings, It as ActivitySummary, J as OrganizationPaymentBatchInput, Jn as CAPXUL_PAYMENTS_V2_ADDRESS, Jt as DestinationsMethods, K as PayrollRunStatus, Kt as DestinationRail, L as AuthorizeRunInput, Ln as Permission, Lt as ActivitySummaryParams, M as OrganizationAuditLogItem, Mn as AuthMethods, Mt as ActivityMethods, N as ResendInviteTokenInput, Nn as OrgLifecycle, Nt as ActivityPage, O as OrgScopedMethods, On as AccountSetupStep, Ot as ActivityFilter, P as RoleDefinition, Pn as OrgSetupStep, Pt as ActivityRange, Q as PermissionAssignInput, Qn as OrgLane, Qt as MeProfile, R as PayrollGroup, Rn as SubmittedPermissionExecution, Rt as ActivitySummaryTotal, S as CreateOrgInput, Sn as Ref, St as InboxApproveInput, T as MemberStatus, Tn as TargetsMethods, Tt as ActivityAnnotation, U as PayrollOptions, Un as RequestStatus, Ut as DestinationKind, V as PayrollGroupsMethods, Vn as PAYMENT_STATUSES, Vt as Destination, W as PayrollRun, Wt as DestinationListInput, X as OrganizationPaymentItemInput, Xn as IdentityEvent, Xt as HandlesMethods, Y as OrganizationPaymentInput, Yn as Destination$1, Yt as FinancialOpsMethods, Z as OrganizationPaymentsMethods, Zn as IdentityState, Zt as MeMethods, _ as SystemMethods, _n as PaymentType, _t as ActorRequestsMethods, a as SdkFailureObservation, an as PayeesMethods, ar as InvocationControls, at as PermissionReadResult, b as CurrentUserContext, bn as RecipientResolution, bt as AddressBookLabelInput, c as PostHogObservabilityOptions, cn as PaymentDirection, ct as OrgMeMethod, d as CreateCapxulClientInput, dn as PaymentDocumentRender, dt as AccountMethods, en as OfframpMethods, er as StateLabel, et as PermissionCreateInput, f as IdentityProfileDetails, fn as PaymentDocumentVerification, ft as ActorProfile, g as Holding, gn as PaymentTiming, gt as ActorRequestIssueInput, h as HoldingsMethods, hn as PaymentStatus, ht as ActorRequest, i as ObservationDelivery, in as Payee, ir as IdentityTransition, it as PermissionRevokeInput, j as OrganizationAccount, jn as SmartAccountMethods, jt as ActivityListParams, k as OrgTemplate, kn as isSettingUpLifecycle, kt as ActivityItem, l as postHogObservability, ln as PaymentDocumentKind, lt as OrgMeOptions, m as IdentityRuntimeSendResult, mn as PaymentMoney, mt as ActorRelationshipMethods, n as ObservationAdapter, nn as OfframpQuoteInput, nr as isClaimed, nt as PermissionOptions, o as HostObservability, on as Payment, ot as Budget, p as IdentityRuntime, pn as PaymentDocumentsMethods, pt as ActorProfileMethods, q as PayrollRuns, qn as TelemetryPort, qt as DestinationRemoveInput, r as ObservationContext, rn as OfframpStatus, rr as isRestoring, rt as PermissionReplaceInput, s as PostHogObservabilityClient, sn as PaymentActivityEvidence, st as OrgMe, t as CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, tn as OfframpQuote, tr as destination, tt as PermissionMethods, u as CapxulClient, un as PaymentDocumentRef, ut as AccountsMethods, v as SystemHealth, vn as PaymentsMethods, vt as AddressBookAddInput, w as InviteMemberInput, wn as TargetReference, wt as InboxMethods, x as CurrentUserMethods, xn as RecipientResolutionKind, xt as AddressBookMethods, y as MediaMethods, yn as PaymentsPayInput, yt as AddressBookEntry, z as PayrollGroupInput, zn as InboxStatus, zt as ActorReference } from "./observation-BQ2VKWH5.mjs";
1
+ import { B as OrgId, C as Address, N as CountryCode, O as AuthSession, S as AccountId, U as PayrollGroupId, V as PartyId, W as PayrollRunId, Y as RoleKey, a as SignerStatusStore, at as CapxulErrorDetails, c as AccountProviderSource, ct as FailureMode, d as eip1193AccountProvider, et as toAddress, f as localPrivateKeyAccountProvider, g as SmartAccount, h as Session, i as SignerStatus, it as CapxulErrorCode, j as BudgetId, k as AuthUserId, l as AccountRequirement, lt as isCapxulError, m as Profile, n as CapxulSigner, nt as CAPXUL_ERROR_CODES, o as injectedWalletSigner, ot as Errors, p as CapxulResult, r as Eip1193RequestProvider, rt as CapxulError, s as AccountProvider, t as CapxulDigestSigner, tt as toCountryCode, u as Eip1193Provider, x as Account, z as Money } from "./signer-DIZRkFHh.mjs";
2
+ import { $ as PermissionChangeInput, $n as Readiness, $t as MovementActivityEvidence, A as OrgView, An as IdentityMethods, At as ActivityKind, B as PayrollGroupMember, Bn as PAYMENT_DIRECTIONS, Bt as DepositInstructions, C as DetectPendingOrgInvitationsResult, Cn as ResolvedTarget, Ct as InboxItem, D as OrgMethods, Dn as AccountLifecycle, Dt as ActivityDetail, E as MemberView, En as fingerprintPaymentIntent, Et as ActivityAnnotationInput, F as RoleSpendCap, Fn as ActorRef, Ft as ActivityReference, G as PayrollRunItemInput, Gt as DestinationPayload, H as PayrollMethods, Hn as PaymentStatus$1, Ht as DestinationAddInput, I as RoleView, In as CurrentHoldings, It as ActivitySummary, J as OrganizationPaymentBatchInput, Jn as CAPXUL_PAYMENTS_V2_ADDRESS, Jt as DestinationsMethods, K as PayrollRunStatus, Kt as DestinationRail, L as AuthorizeRunInput, Ln as Permission, Lt as ActivitySummaryParams, M as OrganizationAuditLogItem, Mn as AuthMethods, Mt as ActivityMethods, N as ResendInviteTokenInput, Nn as OrgLifecycle, Nt as ActivityPage, O as OrgScopedMethods, On as AccountSetupStep, Ot as ActivityFilter, P as RoleDefinition, Pn as OrgSetupStep, Pt as ActivityRange, Q as PermissionAssignInput, Qn as OrgLane, Qt as MeProfile, R as PayrollGroup, Rn as SubmittedPermissionExecution, Rt as ActivitySummaryTotal, S as CreateOrgInput, Sn as Ref, St as InboxApproveInput, T as MemberStatus, Tn as TargetsMethods, Tt as ActivityAnnotation, U as PayrollOptions, Un as RequestStatus, Ut as DestinationKind, V as PayrollGroupsMethods, Vn as PAYMENT_STATUSES, Vt as Destination, W as PayrollRun, Wt as DestinationListInput, X as OrganizationPaymentItemInput, Xn as IdentityEvent, Xt as HandlesMethods, Y as OrganizationPaymentInput, Yn as Destination$1, Yt as FinancialOpsMethods, Z as OrganizationPaymentsMethods, Zn as IdentityState, Zt as MeMethods, _ as SystemMethods, _n as PaymentType, _t as ActorRequestsMethods, a as SdkFailureObservation, an as PayeesMethods, ar as InvocationControls, at as PermissionReadResult, b as CurrentUserContext, bn as RecipientResolution, bt as AddressBookLabelInput, c as PostHogObservabilityOptions, cn as PaymentDirection, ct as OrgMeMethod, d as CreateCapxulClientInput, dn as PaymentDocumentRender, dt as AccountMethods, en as OfframpMethods, er as StateLabel, et as PermissionCreateInput, f as IdentityProfileDetails, fn as PaymentDocumentVerification, ft as ActorProfile, g as Holding, gn as PaymentTiming, gt as ActorRequestIssueInput, h as HoldingsMethods, hn as PaymentStatus, ht as ActorRequest, i as ObservationDelivery, in as Payee, ir as IdentityTransition, it as PermissionRevokeInput, j as OrganizationAccount, jn as SmartAccountMethods, jt as ActivityListParams, k as OrgTemplate, kn as isSettingUpLifecycle, kt as ActivityItem, l as postHogObservability, ln as PaymentDocumentKind, lt as OrgMeOptions, m as IdentityRuntimeSendResult, mn as PaymentMoney, mt as ActorRelationshipMethods, n as ObservationAdapter, nn as OfframpQuoteInput, nr as isClaimed, nt as PermissionOptions, o as HostObservability, on as Payment, ot as Budget, p as IdentityRuntime, pn as PaymentDocumentsMethods, pt as ActorProfileMethods, q as PayrollRuns, qn as TelemetryPort, qt as DestinationRemoveInput, r as ObservationContext, rn as OfframpStatus, rr as isRestoring, rt as PermissionReplaceInput, s as PostHogObservabilityClient, sn as PaymentActivityEvidence, st as OrgMe, t as CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, tn as OfframpQuote, tr as destination, tt as PermissionMethods, u as CapxulClient, un as PaymentDocumentRef, ut as AccountsMethods, v as SystemHealth, vn as PaymentsMethods, vt as AddressBookAddInput, w as InviteMemberInput, wn as TargetReference, wt as InboxMethods, x as CurrentUserMethods, xn as RecipientResolutionKind, xt as AddressBookMethods, y as MediaMethods, yn as PaymentsPayInput, yt as AddressBookEntry, z as PayrollGroupInput, zn as InboxStatus, zt as ActorReference } from "./observation-E28xIx4S.mjs";
3
3
  import { Hex } from "viem";
4
4
  import { Context, Effect, Layer } from "effect";
5
5
  import { FunctionReference } from "convex/server";
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as AuthClientPortTag, B as injectedWalletSigner, C as convexCallErrorFromCapxul, D as bootstrapErrorFromCapxul, E as BootstrapPortTag, F as isSettingUpLifecycle, G as PAYMENT_DIRECTIONS, H as OBSERVATION_CONTEXT_HEADER, I as formatTraceparent, J as BootstrapEnvelope, K as PAYMENT_STATUSES, L as copyInvocationObservation, M as fingerprintPaymentIntent, N as toWei, O as authClientPortFromPromiseAdapter, P as fromWei, Q as BASE_SEPOLIA_CHAIN_ID, R as readInvocationObservation, S as ConvexCallPortTag, T as ClockPortTag, U as encodeObservationContextHeader, V as signerFailure, W as sanitizeObservationContext, X as CAPXUL_PAYMENTS_V2_ADDRESS, Y as EngineeringTelemetryBootstrapPolicy, Z as normalizeBindingEmail, _ as AccountReadPortTag, a as failureEvidenceProps, b as IdentityPortTag, c as postHogFailureObservation, d as detectAuthCacheAdapter, et as destination, f as PostHogTelemetryLayer, g as smartAccountErrorFromCapxul, h as SmartAccountPortTag, i as failureDetail, j as version, k as AuthClientError, l as captureException, n as postHogProductTelemetry, nt as isRestoring, o as observationContextProps, p as TelemetryPortTag, q as CAPXUL_FUNCTIONS, r as CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, s as observeFailedResult, t as assembleCapxulClient, tt as isClaimed, u as captureExceptionSync, v as accountReadErrorFromCapxul, w as ClockError, x as identityErrorFromCapxul, y as wireChainId, z as causeChain } from "./create-capxul-client-DkAxmhLG.mjs";
1
+ import { A as AuthClientPortTag, B as injectedWalletSigner, C as convexCallErrorFromCapxul, D as bootstrapErrorFromCapxul, E as BootstrapPortTag, F as isSettingUpLifecycle, G as PAYMENT_DIRECTIONS, H as OBSERVATION_CONTEXT_HEADER, I as formatTraceparent, J as BootstrapEnvelope, K as PAYMENT_STATUSES, L as copyInvocationObservation, M as fingerprintPaymentIntent, N as toWei, O as authClientPortFromPromiseAdapter, P as fromWei, Q as BASE_SEPOLIA_CHAIN_ID, R as readInvocationObservation, S as ConvexCallPortTag, T as ClockPortTag, U as encodeObservationContextHeader, V as signerFailure, W as sanitizeObservationContext, X as CAPXUL_PAYMENTS_V2_ADDRESS, Y as EngineeringTelemetryBootstrapPolicy, Z as normalizeBindingEmail, _ as AccountReadPortTag, a as failureEvidenceProps, b as IdentityPortTag, c as postHogFailureObservation, d as detectAuthCacheAdapter, et as destination, f as PostHogTelemetryLayer, g as smartAccountErrorFromCapxul, h as SmartAccountPortTag, i as failureDetail, j as version, k as AuthClientError, l as captureException, n as postHogProductTelemetry, nt as isRestoring, o as observationContextProps, p as TelemetryPortTag, q as CAPXUL_FUNCTIONS, r as CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, s as observeFailedResult, t as assembleCapxulClient, tt as isClaimed, u as captureExceptionSync, v as accountReadErrorFromCapxul, w as ClockError, x as identityErrorFromCapxul, y as wireChainId, z as causeChain } from "./create-capxul-client-CpBVKg10.mjs";
2
2
  import { B as Errors, C as toDurationMs, D as toJwtToken, E as toEpochSeconds, F as toSessionToken, I as decodeConvexError, L as CAPXUL_ERROR_CODES, N as toPublishableKey, O as toKycTier, P as toRoleKey, R as CapxulError, S as toCurrencyCode, T as toEpochMs, V as isCapxulError, b as toChainId, g as toAllowedOrigin, h as toAddress, k as toOrgId, m as toAccountId, o as AuthCachePortTag, p as currencySymbolFor, v as toAuthUserId, w as toEmail, x as toCountryCode } from "./InMemoryAuthCacheAdapter-uOcqpqu8.mjs";
3
3
  import { keccak256, recoverAddress, stringToHex } from "viem";
4
4
  import { Cause, Context, Data, Duration, Effect, Exit, Layer, Result, Schedule, SchemaIssue, SchemaParser, Scope, Tracer } from "effect";
@@ -2061,7 +2061,8 @@ var ConvexOrganizationSetupAdapter = class {
2061
2061
  confirmSubmittedBootstrap(input) {
2062
2062
  return this.#lifecycleAction("confirmBootstrap", input, () => this.#convex.action(this.#fns.confirmBootstrap, copyInvocationObservation(input, {
2063
2063
  orgId: input.orgId,
2064
- ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext }
2064
+ ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext },
2065
+ ...input.retryDelayMs === void 0 ? {} : { retryDelayMs: input.retryDelayMs }
2065
2066
  })));
2066
2067
  }
2067
2068
  async recordFailure(input) {
@@ -2566,6 +2567,7 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
2566
2567
  return {
2567
2568
  ...signer,
2568
2569
  statusStore,
2570
+ ensureWalletReady: ensureOpenfortWalletReady,
2569
2571
  getAddress: async () => {
2570
2572
  try {
2571
2573
  const address = await signer.getAddress();
@@ -1,4 +1,4 @@
1
- import { O as AuthSession, _ as AuthCacheError, b as CachedJwt, n as CapxulSigner, v as AuthCachePort, y as AuthCachePortTag } from "../signer-BSEG9xgN.mjs";
1
+ import { O as AuthSession, _ as AuthCacheError, b as CachedJwt, n as CapxulSigner, v as AuthCachePort, y as AuthCachePortTag } from "../signer-DIZRkFHh.mjs";
2
2
  import { Hex } from "viem";
3
3
  import { Effect, FileSystem, Layer, Path } from "effect";
4
4
 
@@ -1,4 +1,4 @@
1
- import { $ as WeiAmount, A as BlockNumber, B as OrgId, C as Address$1, D as AppId, E as AnonymousDistinctId, F as DocumentHash, G as PermissionAssignmentId, H as PaymentCommandId, I as DurationMs, J as PublishableKey, K as PermissionId, L as Email, M as ChainId, N as CountryCode, O as AuthSession, P as CurrencyCode, Q as TxHash, R as EpochMs, T as AllowedOrigin, U as PayrollGroupId, V as PartyId, W as PayrollRunId, X as SessionToken, Y as RoleKey, Z as SmartAccount, a as SignerStatusStore, at as CapxulErrorDetails, b as CachedJwt, c as AccountProviderSource, ct as FailureMode, g as SmartAccount$1, h as Session$1, it as CapxulErrorCode, j as BudgetId, k as AuthUserId, l as AccountRequirement, m as Profile$1, n as CapxulSigner, p as CapxulResult, q as Profile, rt as CapxulError, st as Failure, v as AuthCachePort, w as AllowanceKey, x as Account$1, z as Money } from "./signer-BSEG9xgN.mjs";
1
+ import { $ as WeiAmount, A as BlockNumber, B as OrgId, C as Address$1, D as AppId, E as AnonymousDistinctId, F as DocumentHash, G as PermissionAssignmentId, H as PaymentCommandId, I as DurationMs, J as PublishableKey, K as PermissionId, L as Email, M as ChainId, N as CountryCode, O as AuthSession, P as CurrencyCode, Q as TxHash, R as EpochMs, T as AllowedOrigin, U as PayrollGroupId, V as PartyId, W as PayrollRunId, X as SessionToken, Y as RoleKey, Z as SmartAccount, a as SignerStatusStore, at as CapxulErrorDetails, b as CachedJwt, c as AccountProviderSource, ct as FailureMode, g as SmartAccount$1, h as Session$1, it as CapxulErrorCode, j as BudgetId, k as AuthUserId, l as AccountRequirement, m as Profile$1, n as CapxulSigner, p as CapxulResult, q as Profile, rt as CapxulError, st as Failure, v as AuthCachePort, w as AllowanceKey, x as Account$1, z as Money } from "./signer-DIZRkFHh.mjs";
2
2
  import { Address, Hex } from "viem";
3
3
  import { Context, Effect, Layer, Schema, Scope, Tracer } from "effect";
4
4
  import { FunctionReference } from "convex/server";
@@ -340,7 +340,7 @@ interface TelemetryPort {
340
340
  }
341
341
  //#endregion
342
342
  //#region ../observability/src/index.d.ts
343
- declare const TELEMETRY_EVENT_NAMES: readonly ["auth_otp_requested", "auth_otp_delivered", "auth_otp_expired", "auth_verified", "auth_failed", "auth_signed_out", "onboarding_intent_selected", "onboarding_profile_submitted", "onboarding_organization_submitted", "onboarding_dashboard_reached", "provisioning_safe_created", "provisioning_safe_confirmed", "bootstrap_resolved", "bootstrap_failed", "member_activation_started", "member_activation_ready", "member_activation_failed", "organization_creation_started", "organization_creation_ready", "organization_creation_failed", "account_balance_read", "account_balance_failed", "faucet_requested", "faucet_confirmed", "faucet_failed", "org_create_started", "org_safe_created", "org_safe_confirmed", "org_roles_seeded", "org_created", "org_create_failed", "org_invite_sent", "org_invite_accepted", "org_invite_expired", "payment_initiated", "payment_settled", "payment_failed", "deposit_initiated", "deposit_settled", "permission_mirror_verification", "movement_scan_window", "movement_scan_checkpoint", "movement_scan_incident"];
343
+ declare const TELEMETRY_EVENT_NAMES: readonly ["auth_otp_requested", "auth_otp_delivered", "auth_otp_expired", "auth_verified", "auth_failed", "auth_signed_out", "onboarding_intent_selected", "onboarding_profile_submitted", "onboarding_organization_submitted", "onboarding_dashboard_reached", "provisioning_safe_created", "provisioning_safe_confirmed", "bootstrap_resolved", "bootstrap_failed", "member_activation_started", "member_activation_ready", "member_activation_failed", "organization_creation_started", "organization_creation_ready", "organization_creation_failed", "aa_gateway_upstream_fallback", "account_balance_read", "account_balance_failed", "faucet_requested", "faucet_confirmed", "faucet_failed", "org_create_started", "org_safe_created", "org_safe_confirmed", "org_roles_seeded", "org_created", "org_create_failed", "org_invite_sent", "org_invite_accepted", "org_invite_expired", "payment_initiated", "payment_settled", "payment_failed", "deposit_initiated", "deposit_settled", "permission_mirror_verification", "movement_scan_window", "movement_scan_checkpoint", "movement_scan_incident"];
344
344
  type TelemetryEventName = (typeof TELEMETRY_EVENT_NAMES)[number];
345
345
  type TelemetryProps = Record<string, unknown>;
346
346
  type TelemetryEvent = {
@@ -410,7 +410,7 @@ declare const AttachablePaymentDocumentEnvelope: Schema.Union<readonly [Schema.S
410
410
  readonly name: Schema.Literal<"CapxulPayments">;
411
411
  readonly version: Schema.Literal<"1">;
412
412
  readonly chainId: Schema.Codec<ChainId, number, never, never>;
413
- readonly verifyingContract: Schema.Literal<"0xA3ACDD016f706eD432A9a0545C45F0943f996b60">;
413
+ readonly verifyingContract: Schema.Literal<"0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4">;
414
414
  }>;
415
415
  readonly primaryType: Schema.Literal<"Memo">;
416
416
  readonly message: Schema.Struct<{
@@ -426,7 +426,7 @@ declare const AttachablePaymentDocumentEnvelope: Schema.Union<readonly [Schema.S
426
426
  readonly name: Schema.Literal<"CapxulPayments">;
427
427
  readonly version: Schema.Literal<"1">;
428
428
  readonly chainId: Schema.Codec<ChainId, number, never, never>;
429
- readonly verifyingContract: Schema.Literal<"0xA3ACDD016f706eD432A9a0545C45F0943f996b60">;
429
+ readonly verifyingContract: Schema.Literal<"0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4">;
430
430
  }>;
431
431
  readonly primaryType: Schema.Literal<"Invoice">;
432
432
  readonly message: Schema.Struct<{
@@ -448,7 +448,7 @@ declare const AttachablePaymentDocumentEnvelope: Schema.Union<readonly [Schema.S
448
448
  readonly name: Schema.Literal<"CapxulPayments">;
449
449
  readonly version: Schema.Literal<"1">;
450
450
  readonly chainId: Schema.Codec<ChainId, number, never, never>;
451
- readonly verifyingContract: Schema.Literal<"0xA3ACDD016f706eD432A9a0545C45F0943f996b60">;
451
+ readonly verifyingContract: Schema.Literal<"0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4">;
452
452
  }>;
453
453
  readonly primaryType: Schema.Literal<"Payslip">;
454
454
  readonly message: Schema.Struct<{
@@ -469,7 +469,7 @@ declare const AttachablePaymentDocumentEnvelope: Schema.Union<readonly [Schema.S
469
469
  readonly name: Schema.Literal<"CapxulPayments">;
470
470
  readonly version: Schema.Literal<"1">;
471
471
  readonly chainId: Schema.Codec<ChainId, number, never, never>;
472
- readonly verifyingContract: Schema.Literal<"0xA3ACDD016f706eD432A9a0545C45F0943f996b60">;
472
+ readonly verifyingContract: Schema.Literal<"0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4">;
473
473
  }>;
474
474
  readonly primaryType: Schema.Literal<"Receipt">;
475
475
  readonly message: Schema.Struct<{
@@ -974,6 +974,12 @@ type OrganizationSetupStepInput = {
974
974
  readonly orgId: OrgId;
975
975
  readonly signal?: AbortSignal; /** @internal Safe trace/correlation carriage owned by the identity flow. */
976
976
  readonly observationContext?: WireObservationContext;
977
+ /**
978
+ * @internal #1655: milliseconds the identity flow waited before this
979
+ * confirmation attempt. Absent on the first attempt. The backend copies it
980
+ * onto `organization_creation_failed` as `backoff_ms`.
981
+ */
982
+ readonly retryDelayMs?: number;
977
983
  };
978
984
  type RecordOrganizationSetupFailureInput = {
979
985
  readonly orgId: OrgId;
@@ -21,7 +21,7 @@ type CapxulErrorCode = (typeof CAPXUL_ERROR_CODES)[number];
21
21
  * into `unknown`; the signer's secure-context probe now names it.
22
22
  * - `unknown`: catch-all when no cause could be determined.
23
23
  */
24
- type FailureMode = "auth-origin-mismatch" | "stale-openfort-cache" | "app-env-allowlist" | "no-secure-context" | "unknown";
24
+ type FailureMode = "auth-origin-mismatch" | "stale-openfort-cache" | "app-env-allowlist" | "no-secure-context" /** #1684: an upstream RPC provider throttled the call (HTTP 429 or JSON-RPC -32005). Retryable. */ | "rate-limited" | "unknown";
25
25
  /**
26
26
  * The one failure representation carried by domain state, actor work, and
27
27
  * public error projection. Keeping it beside the canonical error catalog
@@ -378,6 +378,14 @@ interface CapxulSigner extends CapxulDigestSigner {
378
378
  * `client.signer`, and substitutes `UNOBSERVABLE_SIGNER_STATUS` when absent.
379
379
  */
380
380
  readonly statusStore?: SignerStatusStore;
381
+ /**
382
+ * Start this signer's readiness cycle, or join the one already running,
383
+ * without signing anything. `assembleCapxulClient` calls it when the
384
+ * identity is claimed, so the status converges on `ready` or `unavailable`
385
+ * on its own (#1667). A signer that runs no cycle omits this, and keeps
386
+ * reporting `unknown`.
387
+ */
388
+ readonly ensureWalletReady?: () => Promise<void>;
381
389
  }
382
390
  /**
383
391
  * Observable signer readiness (ACCESS #1520 · C12). `unknown` means the
@@ -1,4 +1,4 @@
1
- import { Gn as TelemetryGroupInput, Kn as TelemetryIdentifyInput, Wn as TelemetryEvent, ir as IdentityTransition, n as ObservationAdapter, u as CapxulClient } from "../observation-BQ2VKWH5.mjs";
1
+ import { Gn as TelemetryGroupInput, Kn as TelemetryIdentifyInput, Wn as TelemetryEvent, ir as IdentityTransition, n as ObservationAdapter, u as CapxulClient } from "../observation-E28xIx4S.mjs";
2
2
  import { Effect, Layer } from "effect";
3
3
 
4
4
  //#region src/testing/telemetry/RecordingTelemetryAdapter.d.ts
@@ -1,4 +1,4 @@
1
- import { $ as deriveCapxulSafeAddress, C as convexCallErrorFromCapxul, D as bootstrapErrorFromCapxul, N as toWei, O as authClientPortFromPromiseAdapter, P as fromWei, g as smartAccountErrorFromCapxul, m as redactTelemetryEvent, t as assembleCapxulClient, v as accountReadErrorFromCapxul, x as identityErrorFromCapxul, y as wireChainId } from "../create-capxul-client-DkAxmhLG.mjs";
1
+ import { $ as deriveCapxulSafeAddress, C as convexCallErrorFromCapxul, D as bootstrapErrorFromCapxul, N as toWei, O as authClientPortFromPromiseAdapter, P as fromWei, g as smartAccountErrorFromCapxul, m as redactTelemetryEvent, t as assembleCapxulClient, v as accountReadErrorFromCapxul, x as identityErrorFromCapxul, y as wireChainId } from "../create-capxul-client-CpBVKg10.mjs";
2
2
  import { B as Errors, C as toDurationMs, D as toJwtToken, E as toEpochSeconds, F as toSessionToken, N as toPublishableKey, O as toKycTier, R as CapxulError, T as toEpochMs, _ as toAppId, b as toChainId, g as toAllowedOrigin, h as toAddress, m as toAccountId, t as InMemoryAuthCacheAdapter, v as toAuthUserId, w as toEmail, x as toCountryCode } from "../InMemoryAuthCacheAdapter-uOcqpqu8.mjs";
3
3
  import { keccak256 } from "viem";
4
4
  import { Effect, Result, Semaphore } from "effect";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capxul/sdk",
3
- "version": "2.5.3",
3
+ "version": "2.5.5",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/Xelmar-tech/infrastructure.git",
@@ -46,12 +46,12 @@
46
46
  "typescript": "npm:@typescript/typescript6@6.0.2",
47
47
  "vite-plus": "0.1.23",
48
48
  "vitest": "npm:@voidzero-dev/vite-plus-test@0.1.23",
49
- "@capxul/config": "0.2.1",
50
49
  "@capxul/errors": "0.0.2",
50
+ "@capxul/config": "0.2.1",
51
51
  "@capxul/types": "0.2.1",
52
- "@capxul/observability": "2.5.3",
52
+ "@capxul/wire": "0.5.1",
53
53
  "@capxul/typescript-config": "0.0.0",
54
- "@capxul/wire": "0.5.1"
54
+ "@capxul/observability": "2.5.5"
55
55
  },
56
56
  "_permissionlessPinReason": "permissionless.toSafeSmartAccount is pinned to 0.3.4 for live Safe deployment E2E. Counterfactual address fixtures captured 2026-05-17 in packages/backend/convex/_shared/__tests__/counterfactual.test.ts and packages/config/tests/safe.test.ts must be re-verified before upgrading.",
57
57
  "scripts": {