@capxul/sdk 2.7.0 → 2.8.2

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.
@@ -12,6 +12,7 @@ const FAILURE_MODES = [
12
12
  "stale-openfort-cache",
13
13
  "app-env-allowlist",
14
14
  "no-secure-context",
15
+ "signer-not-ready",
15
16
  "rate-limited",
16
17
  "timeout",
17
18
  "upstream-down",
@@ -121,6 +122,58 @@ function chainCauseProperties(chain) {
121
122
  };
122
123
  }
123
124
  /**
125
+ * Safe (safe-contracts v1.4.1) revert codes. The contracts revert with these
126
+ * short strings to save gas; the sentence lives in the Safe docs
127
+ * (`docs/error_codes.md`). Every Safe on the Capxul rail is this version.
128
+ */
129
+ const SAFE_REVERT_REASONS = {
130
+ GS000: "could not finish initialization",
131
+ GS001: "threshold needs to be defined",
132
+ GS010: "not enough gas to execute Safe transaction",
133
+ GS011: "could not pay gas costs with ether",
134
+ GS012: "could not pay gas costs with token",
135
+ GS013: "Safe transaction failed when gasPrice and safeTxGas were 0",
136
+ GS020: "signatures data too short",
137
+ GS021: "invalid contract signature location: inside static part",
138
+ GS022: "invalid contract signature location: length not present",
139
+ GS023: "invalid contract signature location: data not complete",
140
+ GS024: "invalid contract signature provided",
141
+ GS025: "hash has not been approved",
142
+ GS026: "invalid owner provided",
143
+ GS030: "only owners can approve a hash",
144
+ GS031: "method can only be called from this contract",
145
+ GS100: "modules have already been initialized",
146
+ GS101: "invalid module address provided",
147
+ GS102: "module has already been added",
148
+ GS103: "invalid prevModule, module pair provided",
149
+ GS104: "method can only be called from an enabled module",
150
+ GS105: "invalid starting point for fetching paginated modules",
151
+ GS106: "invalid page size for fetching paginated modules",
152
+ GS200: "owners have already been set up",
153
+ GS201: "threshold cannot exceed owner count",
154
+ GS202: "threshold needs to be greater than 0",
155
+ GS203: "invalid owner address provided",
156
+ GS204: "address is already an owner",
157
+ GS205: "invalid prevOwner, owner pair provided",
158
+ GS300: "guard does not implement IERC165",
159
+ GS400: "fallback handler cannot be set to self"
160
+ };
161
+ /**
162
+ * `Error(GS205: invalid prevOwner, owner pair provided)`, or the bare selector
163
+ * when the name is unknown. Safe codes travel only as the `message` of an
164
+ * `Error(string)` revert, so only that argument is expanded from
165
+ * {@link SAFE_REVERT_REASONS}; every other argument reads `name=value`, even
166
+ * when a custom error's field happens to hold a `GS` string.
167
+ */
168
+ function revertSummaryText(revert) {
169
+ if (revert.name === null) return revert.selector === "0x" ? "empty revert" : `unknown selector ${revert.selector}`;
170
+ const args = Object.entries(revert.args).map(([name, value]) => {
171
+ const reason = revert.name === "Error" && name === "message" ? SAFE_REVERT_REASONS[value] : void 0;
172
+ return reason === void 0 ? `${name}=${value}` : `${value}: ${reason}`;
173
+ }).join(", ");
174
+ return `${revert.name}(${args})`;
175
+ }
176
+ /**
124
177
  * The error-tracking fingerprint for a failure: the code, the one-word cause,
125
178
  * and the operation. PostHog groups `$exception` rows by this value, so one
126
179
  * issue is one cause at one operation instead of every provider failure in
@@ -138,6 +191,7 @@ const CAPXUL_ERROR_CODES = [
138
191
  "SMART_ACCOUNT_MISSING",
139
192
  "PLAYER_NOT_FOUND",
140
193
  "ACCOUNT_NOT_FOUND",
194
+ "ACCOUNT_CLAIMED_BY_OTHER_SIGNER",
141
195
  "PROVIDER_ERROR",
142
196
  "CAPABILITY_UNAVAILABLE",
143
197
  "INVALID_INPUT",
@@ -172,6 +226,7 @@ const EXPECTED_OPERATION_OUTCOMES = /* @__PURE__ */ new Set([
172
226
  "INVALID_INPUT",
173
227
  "NOT_AUTHENTICATED",
174
228
  "SMART_ACCOUNT_MISSING",
229
+ "ACCOUNT_CLAIMED_BY_OTHER_SIGNER",
175
230
  "CANCELLED",
176
231
  "SIGNER_REJECTED",
177
232
  "VERIFICATION_REQUIRED",
@@ -230,6 +285,46 @@ function compactErrorOptions(options) {
230
285
  if (options.chain !== void 0) result.chain = options.chain;
231
286
  return result;
232
287
  }
288
+ const NETWORK_DETAIL_LABEL_RE = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/u;
289
+ const NETWORK_TARGET_HOST_RE = /^[A-Za-z0-9.[\]:-]{1,253}$/u;
290
+ const DOCUMENT_VISIBILITY = /* @__PURE__ */ new Set(["hidden", "visible"]);
291
+ const BROWSER_LIFECYCLE_EVENTS = /* @__PURE__ */ new Set([
292
+ "visibility-visible",
293
+ "visibility-hidden",
294
+ "pagehide",
295
+ "pageshow",
296
+ "online",
297
+ "offline"
298
+ ]);
299
+ function networkErrorDetails(operation, options) {
300
+ const details = { operation };
301
+ if (options === void 0) return details;
302
+ if (typeof options.provider === "string" && NETWORK_DETAIL_LABEL_RE.test(options.provider)) details.provider = options.provider;
303
+ if (typeof options.target_host === "string" && NETWORK_TARGET_HOST_RE.test(options.target_host)) details.target_host = options.target_host;
304
+ if (isFailureMode(options.failure_mode)) details.failure_mode = options.failure_mode;
305
+ if (options.reason === "connection-lost-in-flight") details.reason = options.reason;
306
+ if (typeof options.connection_id === "string" && NETWORK_DETAIL_LABEL_RE.test(options.connection_id)) details.connection_id = options.connection_id;
307
+ for (const key of [
308
+ "connection_count",
309
+ "connection_retries",
310
+ "close_code",
311
+ "ms_since_browser_event"
312
+ ]) {
313
+ const value = options[key];
314
+ if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && (key !== "close_code" || value <= 4999)) details[key] = value;
315
+ }
316
+ for (const key of [
317
+ "close_was_clean",
318
+ "close_reason_present",
319
+ "navigator_online"
320
+ ]) {
321
+ const value = options[key];
322
+ if (typeof value === "boolean") details[key] = value;
323
+ }
324
+ if (DOCUMENT_VISIBILITY.has(options.document_visibility ?? "")) details.document_visibility = options.document_visibility;
325
+ if (BROWSER_LIFECYCLE_EVENTS.has(options.last_browser_event ?? "")) details.last_browser_event = options.last_browser_event;
326
+ return details;
327
+ }
233
328
  const Errors = {
234
329
  notAuthenticated: (message, opts) => new CapxulError("NOT_AUTHENTICATED", message ?? "Not authenticated", opts?.failure_mode ? { details: { failure_mode: opts.failure_mode } } : void 0),
235
330
  emailDeliveryFailed: (detail) => new CapxulError("EMAIL_DELIVERY_FAILED", "Failed to send email", { details: { detail } }),
@@ -237,6 +332,14 @@ const Errors = {
237
332
  smartAccountMissing: (authUserId) => new CapxulError("SMART_ACCOUNT_MISSING", "Smart account not provisioned", { details: { authUserId } }),
238
333
  playerNotFound: (playerId) => new CapxulError("PLAYER_NOT_FOUND", playerId ? `Openfort player ${playerId} not found` : "Openfort player not found", playerId === void 0 ? void 0 : { details: { playerId } }),
239
334
  accountNotFound: (accountId) => new CapxulError("ACCOUNT_NOT_FOUND", accountId ? `Openfort account ${accountId} not found` : "Openfort account not found", accountId === void 0 ? void 0 : { details: { accountId } }),
335
+ /**
336
+ * The Safe at this email's address is deployed and its owner is neither the
337
+ * Capxul bootstrap owner nor the caller's signer. The claim
338
+ * `swapOwner(bootstrap → signer)` cannot succeed: only the on-chain owner
339
+ * can hand the account over. Read from `getOwners()` before any
340
+ * UserOperation is built (2026-09-02), so no simulation and no retry.
341
+ */
342
+ accountClaimedByOtherSigner: (details) => new CapxulError("ACCOUNT_CLAIMED_BY_OTHER_SIGNER", "This account is already owned by a different signer.", { details }),
240
343
  providerError: (provider, operation, cause, opts) => {
241
344
  const details = {
242
345
  ...opts?.details,
@@ -320,10 +423,14 @@ const Errors = {
320
423
  }
321
424
  }),
322
425
  rateLimited: (details) => new CapxulError("RATE_LIMITED", "Rate limit exceeded", details === void 0 ? void 0 : { details: { ...details } }),
323
- networkError: (operation, cause) => new CapxulError("NETWORK_ERROR", `Network error during ${operation}`, {
324
- cause,
325
- details: { operation }
326
- }),
426
+ networkError: (operation, cause, opts) => {
427
+ const mode = isFailureMode(opts?.failure_mode) ? opts.failure_mode : void 0;
428
+ return new CapxulError("NETWORK_ERROR", `Network error during ${operation}`, {
429
+ cause,
430
+ details: networkErrorDetails(operation, opts),
431
+ ...mode === void 0 ? {} : { mode }
432
+ });
433
+ },
327
434
  unknown: (cause) => new CapxulError("UNKNOWN", "Unknown error", { cause }),
328
435
  otpExpired: (details) => new CapxulError("OTP_EXPIRED", "Verification code has expired. Request a new one.", details === void 0 ? void 0 : { details: { ...details } }),
329
436
  signerRejected: (details) => new CapxulError("SIGNER_REJECTED", "Signer rejected the request.", {
@@ -333,6 +440,11 @@ const Errors = {
333
440
  reason: details.reason
334
441
  }
335
442
  }),
443
+ superseded: (details) => new CapxulError("SUPERSEDED", "Operation was superseded.", { details: {
444
+ operation: details.operation,
445
+ reason: details.reason,
446
+ ...details.executionId === void 0 ? {} : { executionId: details.executionId }
447
+ } }),
336
448
  cancelled: (details) => new CapxulError("CANCELLED", "Operation was cancelled.", details === void 0 ? void 0 : { details: { ...details } }),
337
449
  /**
338
450
  * Method called from a flow state where its precondition fails (TA16). The
@@ -648,4 +760,4 @@ Layer.effect(AuthCachePortTag, Effect.sync(() => new InMemoryAuthCacheAdapter())
648
760
  cause
649
761
  }))));
650
762
  //#endregion
651
- export { toPartyId as A, Errors as B, toDurationMs as C, toJwtToken as D, toEpochSeconds as E, toSessionToken as F, failureFingerprint as G, CHAIN_UPSTREAMS as H, decodeConvexError as I, isFailureMode as K, CAPXUL_ERROR_CODES as L, toPayrollRunId as M, toPublishableKey as N, toKycTier as O, toRoleKey as P, CapxulError as R, toCurrencyCode as S, toEpochMs as T, FAILURE_MODES as U, isCapxulError as V, chainCauseProperties as W, toAppId as _, AuthCacheError as a, toChainId as b, BYTES32_RE as c, WEI_RE as d, ZERO_BYTES32 as f, toAllowedOrigin as g, toAddress as h, parseCachedJwt as i, toPayrollGroupId as j, toOrgId as k, EVM_ADDRESS_RE as l, toAccountId as m, BrowserAuthCacheAdapter as n, AuthCachePortTag as o, currencySymbolFor as p, parseAuthSession as r, APP_ID_RE as s, InMemoryAuthCacheAdapter as t, SUPPORTED_CURRENCY_CODES as u, toAuthUserId as v, toEmail as w, toCountryCode as x, toBudgetId as y, EXPECTED_OPERATION_OUTCOMES as z };
763
+ export { toPartyId as A, Errors as B, toDurationMs as C, toJwtToken as D, toEpochSeconds as E, toSessionToken as F, decodeChainCause as G, CHAIN_UPSTREAMS as H, decodeConvexError as I, revertSummaryText as J, failureFingerprint as K, CAPXUL_ERROR_CODES as L, toPayrollRunId as M, toPublishableKey as N, toKycTier as O, toRoleKey as P, CapxulError as R, toCurrencyCode as S, toEpochMs as T, FAILURE_MODES as U, isCapxulError as V, chainCauseProperties as W, toAppId as _, AuthCacheError as a, toChainId as b, BYTES32_RE as c, WEI_RE as d, ZERO_BYTES32 as f, toAllowedOrigin as g, toAddress as h, parseCachedJwt as i, toPayrollGroupId as j, toOrgId as k, EVM_ADDRESS_RE as l, toAccountId as m, BrowserAuthCacheAdapter as n, AuthCachePortTag as o, currencySymbolFor as p, isFailureMode as q, parseAuthSession as r, APP_ID_RE as s, InMemoryAuthCacheAdapter as t, SUPPORTED_CURRENCY_CODES as u, toAuthUserId as v, toEmail as w, toCountryCode as x, toBudgetId as y, EXPECTED_OPERATION_OUTCOMES as z };