@capxul/sdk 4.2.0-rc.1 → 4.2.0-rc.10

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,4 +1,4 @@
1
- import { $ as toTesterKind, A as toAccountId, B as toEmail, C as BYTES32_RE, D as ZERO_BYTES32, E as WEI_RE, F as toBudgetId, G as toKycTier, H as toEpochSeconds, I as toChainId, J as toPayrollGroupId, K as toOrgId, L as toCountryCode, M as toAllowedOrigin, P as toAuthUserId, Q as toSessionToken, R as toCurrencyCode, S as ASSET_ID_RE, T as SUPPORTED_CURRENCY_CODES, U as toHandle, V as toEpochMs, W as toJwtToken, X as toPublishableKey, Y as toPayrollRunId, Z as toRoleKey, _ as BASE_SEPOLIA_CHAIN_ID, _t as revertSummaryText, at as EXPECTED_OPERATION_OUTCOMES, b as ACCOUNT_ID_RE, bt as redactSecrets, c as AuthCachePortTag, ct as CHAIN_UPSTREAMS, d as authClientPortFromPromiseAdapter, dt as chainCauseProperties, et as validateHandle, f as AuthClientError, ft as chainEvidenceLabel, g as normalizeBindingEmail, gt as isFailureMode, ht as isChainUpstream, i as BrowserAuthCacheAdapter, it as CapxulError, j as toAddress, l as SystemClockLayer, lt as FAILURE_MODES$1, m as orgRoleKeyForLabel, mt as failureFingerprint, nt as decodeConvexError, ot as Errors, p as AuthClientPortTag, pt as decodeChainCause, q as toPartyId, r as InMemoryAuthCacheAdapter, rt as CAPXUL_ERROR_CODES, st as isCapxulError, u as ClockPortTag, ut as boundedResponseHeaders, v as deriveCapxulSafeAddress, vt as containsSensitiveMaterial, w as EVM_ADDRESS_RE$1, x as APP_ID_RE, xt as redactUrlSecrets, yt as isCredentialField, z as toDurationMs } from "./OAuthBearerAuthClient-BrbXrndM.mjs";
1
+ import { $ as toRoleKey, B as toCurrencyCode, C as ASSET_ID_RE, Ct as redactSecrets, D as WEI_RE, E as SUPPORTED_CURRENCY_CODES, F as toAssetId, G as toHandle, H as toEmail, I as toAuthUserId, J as toOrgId, K as toJwtToken, L as toBudgetId, M as toAddress, N as toAllowedOrigin, O as ZERO_BYTES32, Q as toPublishableKey, R as toChainId, S as APP_ID_RE, St as isCredentialField, T as EVM_ADDRESS_RE$1, U as toEpochMs, V as toDurationMs, W as toEpochSeconds, X as toPayrollGroupId, Y as toPartyId, Z as toPayrollRunId, _ as normalizeBindingEmail, _t as failureFingerprint, at as decodeConvexError, bt as revertSummaryText, c as AuthCachePortTag, ct as EXPECTED_OPERATION_OUTCOMES, d as authClientPortFromPromiseAdapter, dt as CHAIN_UPSTREAMS, et as toSessionToken, f as AuthClientError, ft as FAILURE_MODES$1, gt as decodeChainCause, h as orgRoleKeyForLabel, ht as chainEvidenceLabel, i as BrowserAuthCacheAdapter, j as toAccountId, l as SystemClockLayer, lt as Errors, m as ADMIN_ROLE_LABEL, mt as chainCauseProperties, nt as toTxHash, ot as CAPXUL_ERROR_CODES, p as AuthClientPortTag, pt as boundedResponseHeaders, q as toKycTier, r as InMemoryAuthCacheAdapter, rt as validateHandle, st as CapxulError, tt as toTesterKind, u as ClockPortTag, ut as isCapxulError, v as BASE_SEPOLIA_CHAIN_ID, vt as isChainUpstream, w as BYTES32_RE, wt as redactUrlSecrets, x as ACCOUNT_ID_RE, xt as containsSensitiveMaterial, y as deriveCapxulSafeAddress, yt as isFailureMode, z as toCountryCode } from "./OAuthBearerAuthClient-IB2W1Fzj.mjs";
2
2
  import { formatUnits, keccak256, parseUnits, recoverAddress, stringToHex, toBytes } from "viem";
3
3
  import { Cause, Clock, Context, Data, Deferred, Duration, Effect, Exit, Fiber, FiberSet, Layer, Option, Queue, Ref, Result, Schedule, Schema, SchemaGetter, SchemaIssue, SchemaParser, Scope, Stream, Tracer } from "effect";
4
4
  import { getFunctionName, makeFunctionReference } from "convex/server";
@@ -448,6 +448,8 @@ const CAPXUL_OPERATIONS = {
448
448
  emitAnnotationSaved: "activity.emitAnnotationSaved",
449
449
  get: "activity.get",
450
450
  list: "activity.list",
451
+ /** The SDK's live Activity read over the indexer's SSE stream. */
452
+ subscribe: "activity.subscribe",
451
453
  summary: "activity.summary"
452
454
  },
453
455
  addressBook: {
@@ -946,6 +948,17 @@ const AuthFailedProps = Schema.Struct({
946
948
  auth_type: OptionalString,
947
949
  reason: OptionalString
948
950
  });
951
+ const IdentityRefusedProps = Schema.Struct({
952
+ ...TelemetryEnvelopeProps,
953
+ /** The refused identity event tag, for example CreateOrganization. */
954
+ event: OptionalString,
955
+ /** The machine's refusal code: WRONG_STATE, SUPERSEDED or STALE_EPOCH. */
956
+ refusal_code: OptionalString,
957
+ /** The machine slot the request targeted, for example identity:org. */
958
+ slot: OptionalString,
959
+ /** The machine state at refusal, for example authenticated:claiming. */
960
+ state: OptionalString
961
+ });
949
962
  const AuthSignedOutProps = Schema.Struct(TelemetryEnvelopeProps);
950
963
  const ProvisioningSafeCreatedProps = Schema.Struct({
951
964
  ...TelemetryEnvelopeProps,
@@ -1333,10 +1346,24 @@ const DepositSettledProps = Schema.Struct({
1333
1346
  });
1334
1347
  const PermissionMirrorVerificationProps = Schema.Struct({
1335
1348
  ...TelemetryEnvelopeProps,
1349
+ /** The RECEIPT verification outcome. What the mirror then did is separate. */
1336
1350
  outcome: Schema.String,
1337
1351
  reason: Schema.String,
1338
1352
  chain_id: Schema.Number,
1339
- retry_count: Schema.Number
1353
+ retry_count: Schema.Number,
1354
+ /**
1355
+ * #1960 R02, consumed by R03. A verified receipt is not an applied Permission:
1356
+ * these two optional fields let the producer say what the applying mutation
1357
+ * actually returned, and which command it was, without either fact rewriting
1358
+ * the receipt outcome above. Absent when application has not happened yet.
1359
+ */
1360
+ application_result: Schema.optional(Schema.Literals([
1361
+ "applied",
1362
+ "replayed",
1363
+ "conflicting_replay",
1364
+ "revision_mismatch"
1365
+ ])),
1366
+ command_id: OptionalString
1340
1367
  });
1341
1368
  const MovementScanWindowProps = Schema.Struct({
1342
1369
  ...TelemetryEnvelopeProps,
@@ -1382,6 +1409,10 @@ Schema.Struct({
1382
1409
  name: Schema.Literal("auth_failed"),
1383
1410
  props: AuthFailedProps
1384
1411
  });
1412
+ Schema.Struct({
1413
+ name: Schema.Literal("identity_refused"),
1414
+ props: IdentityRefusedProps
1415
+ });
1385
1416
  Schema.Struct({
1386
1417
  name: Schema.Literal("auth_signed_out"),
1387
1418
  props: AuthSignedOutProps
@@ -1562,6 +1593,10 @@ Schema.Struct({
1562
1593
  name: Schema.Literal("movement_scan_incident"),
1563
1594
  props: MovementScanIncidentProps
1564
1595
  });
1596
+ /** The one spelling of "whose scope did this happen in" across every surface. */
1597
+ const ScopeKindSchema = Schema.Literals(["account", "organization"]);
1598
+ const AccountKindSchema = Schema.Literals(["personalSafe", "orgTreasury"]);
1599
+ const OptionalReasonCode = Schema.optional(Schema.Literals(CAPXUL_ERROR_CODES));
1565
1600
  const ActivityReferenceProps = {
1566
1601
  reference_kind: Schema.Literals(["payment", "movement"]),
1567
1602
  reference_id: Schema.String
@@ -1592,8 +1627,8 @@ const ActivityFilterProps = {
1592
1627
  };
1593
1628
  const ActivityActionProps = {
1594
1629
  ...TelemetryEnvelopeProps,
1595
- scope_kind: Schema.Literals(["account", "organization"]),
1596
- reason_code: Schema.optional(Schema.Literals(CAPXUL_ERROR_CODES))
1630
+ scope_kind: ScopeKindSchema,
1631
+ reason_code: OptionalReasonCode
1597
1632
  };
1598
1633
  Schema.Struct({
1599
1634
  name: Schema.Literal("contact_relationship_changed"),
@@ -1605,7 +1640,7 @@ Schema.Struct({
1605
1640
  "hidden",
1606
1641
  "restored"
1607
1642
  ]),
1608
- scope_kind: Schema.Literals(["account", "organization"]),
1643
+ scope_kind: ScopeKindSchema,
1609
1644
  scope_id: Schema.String,
1610
1645
  owner_party_id: Schema.String,
1611
1646
  party_id: Schema.String,
@@ -1621,9 +1656,9 @@ Schema.Struct({
1621
1656
  });
1622
1657
  const ContactActionProps = {
1623
1658
  ...TelemetryEnvelopeProps,
1624
- scope_kind: Schema.Literals(["account", "organization"]),
1659
+ scope_kind: ScopeKindSchema,
1625
1660
  party_id: OptionalString,
1626
- reason_code: Schema.optional(Schema.Literals(CAPXUL_ERROR_CODES))
1661
+ reason_code: OptionalReasonCode
1627
1662
  };
1628
1663
  Schema.Struct({
1629
1664
  name: Schema.Literal("ui_contact_action_completed"),
@@ -1650,7 +1685,7 @@ Schema.Struct({
1650
1685
  props: Schema.Struct({
1651
1686
  ...TelemetryEnvelopeProps,
1652
1687
  ...ActivityReferenceProps,
1653
- scope_kind: Schema.Literals(["account", "organization"]),
1688
+ scope_kind: ScopeKindSchema,
1654
1689
  scope_id: Schema.String,
1655
1690
  occurred_at: Schema.Number
1656
1691
  })
@@ -1705,6 +1740,193 @@ Schema.Struct({
1705
1740
  })
1706
1741
  ])
1707
1742
  });
1743
+ /**
1744
+ * Reliability closeout (#1960 R02) — the shape every explicit UI observation
1745
+ * below shares. `scope_kind` says whose surface the person was looking at,
1746
+ * `organization_id` is the verified Organization the producer resolved (absent
1747
+ * on a personal action), and `reason_code` is a catalog error code, never copy.
1748
+ */
1749
+ const UiStepProps = {
1750
+ ...TelemetryEnvelopeProps,
1751
+ scope_kind: ScopeKindSchema,
1752
+ organization_id: OptionalOrgId,
1753
+ reason_code: OptionalReasonCode
1754
+ };
1755
+ const AccessRecoveryCompletedProps = Schema.Union([Schema.Struct({
1756
+ ...TelemetryEnvelopeProps,
1757
+ recovery: Schema.Literal("session_restoration"),
1758
+ outcome: Schema.Literals([
1759
+ "restored",
1760
+ "absent",
1761
+ "failed"
1762
+ ]),
1763
+ reason_code: OptionalReasonCode,
1764
+ organization_id: OptionalOrgId
1765
+ }), Schema.Struct({
1766
+ ...TelemetryEnvelopeProps,
1767
+ recovery: Schema.Literal("signer_readiness"),
1768
+ outcome: Schema.Literals(["ready", "unavailable"]),
1769
+ reason_code: OptionalReasonCode,
1770
+ organization_id: OptionalOrgId
1771
+ })]);
1772
+ Schema.Struct({
1773
+ name: Schema.Literal("access_recovery_completed"),
1774
+ props: AccessRecoveryCompletedProps
1775
+ });
1776
+ Schema.Struct({
1777
+ name: Schema.Literal("ui_access_step_completed"),
1778
+ props: Schema.Struct({
1779
+ ...UiStepProps,
1780
+ step: Schema.Literals([
1781
+ "dashboard_granted",
1782
+ "redirect_completed",
1783
+ "gate_error_displayed",
1784
+ "retry_selected",
1785
+ "capability_refusal_displayed",
1786
+ "signer_refusal_displayed"
1787
+ ]),
1788
+ capability: Schema.optional(Schema.Literals(["spend", "managePeople"])),
1789
+ probe: Schema.optional(Schema.Literals([
1790
+ "session",
1791
+ "membership",
1792
+ "lifecycle"
1793
+ ])),
1794
+ reason: Schema.optional(Schema.Literals([
1795
+ "loading",
1796
+ "no-permission",
1797
+ "org-unavailable"
1798
+ ]))
1799
+ })
1800
+ });
1801
+ Schema.Struct({
1802
+ name: Schema.Literal("org_invite_progressed"),
1803
+ props: Schema.Struct({
1804
+ ...TelemetryEnvelopeProps,
1805
+ organization_id: OrgIdTelemetrySchema,
1806
+ progress: Schema.Literals([
1807
+ "account_ready",
1808
+ "permission_applied",
1809
+ "membership_activated",
1810
+ "revoked"
1811
+ ]),
1812
+ /** The invited Party. The initiating actor stays on the envelope's identity. */
1813
+ member_party_id: Schema.String,
1814
+ occurred_at: Schema.Number
1815
+ })
1816
+ });
1817
+ Schema.Struct({
1818
+ name: Schema.Literal("invoice_issued"),
1819
+ props: Schema.Struct({
1820
+ ...TelemetryEnvelopeProps,
1821
+ request_id: Schema.String,
1822
+ issuer_scope_kind: ScopeKindSchema,
1823
+ issuer_scope_id: Schema.String,
1824
+ payer_party_id: OptionalString,
1825
+ occurred_at: Schema.Number
1826
+ })
1827
+ });
1828
+ Schema.Struct({
1829
+ name: Schema.Literal("invoice_request_transitioned"),
1830
+ props: Schema.Struct({
1831
+ ...TelemetryEnvelopeProps,
1832
+ request_id: Schema.String,
1833
+ transition: Schema.Literals([
1834
+ "approval_prepared",
1835
+ "declined",
1836
+ "cancelled"
1837
+ ]),
1838
+ actor_scope_kind: ScopeKindSchema,
1839
+ actor_scope_id: Schema.String,
1840
+ occurred_at: Schema.Number
1841
+ })
1842
+ });
1843
+ Schema.Struct({
1844
+ name: Schema.Literal("ui_invoice_step_completed"),
1845
+ props: Schema.Struct({
1846
+ ...UiStepProps,
1847
+ step: Schema.Literals([
1848
+ "opened",
1849
+ "previewed",
1850
+ "dismissed",
1851
+ "submitted",
1852
+ "result_displayed",
1853
+ "refusal_displayed",
1854
+ "retry_selected"
1855
+ ]),
1856
+ request_id: OptionalString
1857
+ })
1858
+ });
1859
+ Schema.Struct({
1860
+ name: Schema.Literal("ui_treasury_step_completed"),
1861
+ props: Schema.Struct({
1862
+ ...UiStepProps,
1863
+ step: Schema.Literals([
1864
+ "balance_displayed",
1865
+ "read_refusal_displayed",
1866
+ "retry_selected",
1867
+ "recovery_completed"
1868
+ ]),
1869
+ account_kind: Schema.optional(AccountKindSchema)
1870
+ })
1871
+ });
1872
+ Schema.Struct({
1873
+ name: Schema.Literal("ui_receive_step_completed"),
1874
+ props: Schema.Struct({
1875
+ ...UiStepProps,
1876
+ step: Schema.Literals([
1877
+ "instructions_displayed",
1878
+ "address_copied",
1879
+ "copy_failed",
1880
+ "refusal_displayed",
1881
+ "retry_selected"
1882
+ ]),
1883
+ account_kind: Schema.optional(AccountKindSchema)
1884
+ })
1885
+ });
1886
+ Schema.Struct({
1887
+ name: Schema.Literal("payroll_group_changed"),
1888
+ props: Schema.Struct({
1889
+ ...TelemetryEnvelopeProps,
1890
+ organization_id: OrgIdTelemetrySchema,
1891
+ change: Schema.Literals([
1892
+ "created",
1893
+ "updated",
1894
+ "deleted"
1895
+ ]),
1896
+ group_id: Schema.String,
1897
+ member_count: Schema.Number,
1898
+ occurred_at: Schema.Number
1899
+ })
1900
+ });
1901
+ Schema.Struct({
1902
+ name: Schema.Literal("payroll_run_transitioned"),
1903
+ props: Schema.Struct({
1904
+ ...TelemetryEnvelopeProps,
1905
+ organization_id: OrgIdTelemetrySchema,
1906
+ transition: Schema.Literals([
1907
+ "prepared",
1908
+ "authorized",
1909
+ "settled"
1910
+ ]),
1911
+ run_id: Schema.String,
1912
+ payment_count: Schema.optional(Schema.Number),
1913
+ occurred_at: Schema.Number
1914
+ })
1915
+ });
1916
+ Schema.Struct({
1917
+ name: Schema.Literal("ui_payroll_action_completed"),
1918
+ props: Schema.Struct({
1919
+ ...UiStepProps,
1920
+ action: Schema.Literals([
1921
+ "opened",
1922
+ "refusal_displayed",
1923
+ "recovery_completed",
1924
+ "cancelled",
1925
+ "submitted_displayed"
1926
+ ]),
1927
+ run_id: OptionalString
1928
+ })
1929
+ });
1708
1930
  function redactTelemetryEvent(event, options = {}) {
1709
1931
  const props = redactTelemetryProps(event.name, event.props, options);
1710
1932
  return props === void 0 ? { name: event.name } : {
@@ -2007,6 +2229,10 @@ const BootstrapEnvelope = Schema.Struct({
2007
2229
  siteBaseUrl: Schema.String,
2008
2230
  openfortPublishableKey: Schema.String,
2009
2231
  shieldPublishableKey: Schema.String,
2232
+ /** Which Openfort third-party auth provider the signer presents; absent means better-auth. */
2233
+ openfortAuthProvider: Schema.optional(Schema.Literals(["better-auth", "oidc"])),
2234
+ /** Origin of the Ponder indexer the SDK reads directly; absent means no indexer reads. */
2235
+ indexerUrl: Schema.optional(Schema.String),
2010
2236
  engineeringTelemetry: Schema.optional(EngineeringTelemetryBootstrapPolicy)
2011
2237
  })
2012
2238
  });
@@ -2081,6 +2307,7 @@ const CAPXUL_FUNCTIONS = {
2081
2307
  prepareOrganizationPaymentExecution: "moneyExecution/paymentCommandActions:prepareOrganizationPaymentExecution",
2082
2308
  submitPaymentCommandExecution: "moneyExecution/paymentCommandActions:submitPaymentCommandExecution"
2083
2309
  },
2310
+ "moneyExecution/providerSendWitness": { read: "moneyExecution/providerSendWitness:read" },
2084
2311
  media: {
2085
2312
  generateUploadUrl: "media:generateUploadUrl",
2086
2313
  setOrgLogo: "media:setOrgLogo",
@@ -2140,6 +2367,11 @@ const CAPXUL_FUNCTIONS = {
2140
2367
  loadByAuthUserId: "smartAccount/queries:loadByAuthUserId",
2141
2368
  loadBySmartAccountAddress: "smartAccount/queries:loadBySmartAccountAddress"
2142
2369
  },
2370
+ e2eControls: {
2371
+ holdUserOperationReceipt: "e2eControls:holdUserOperationReceipt",
2372
+ isUserOperationReceiptHeld: "e2eControls:isUserOperationReceiptHeld",
2373
+ releaseUserOperationReceipt: "e2eControls:releaseUserOperationReceipt"
2374
+ },
2143
2375
  system: { health: "system:health" }
2144
2376
  };
2145
2377
  //#endregion
@@ -5451,7 +5683,7 @@ const moneyExecutionContract = {
5451
5683
  };
5452
5684
  //#endregion
5453
5685
  //#region package.json
5454
- var version = "4.2.0-rc.1";
5686
+ var version = "4.2.0-rc.10";
5455
5687
  //#endregion
5456
5688
  //#region src/telemetry/exception-projection.ts
5457
5689
  /** Fixed fallback for failures that have no safe message. */
@@ -5644,6 +5876,17 @@ function observeFailedResult(result, adapter, operation, origin) {
5644
5876
  return result;
5645
5877
  }
5646
5878
  /**
5879
+ * @internal Reports a failure that can never become a method result.
5880
+ *
5881
+ * A reactive stream is torn down after its call already returned, so nothing
5882
+ * downstream observes it. `captureException` is the right kind: the caller did
5883
+ * not ask for the end, so it is not an expected product outcome.
5884
+ */
5885
+ function observeStreamFailure(adapter, operation, cause) {
5886
+ if (adapter === void 0) return;
5887
+ report(adapter, "exception", operation, cause, resolveAdapterSnapshot(adapter));
5888
+ }
5889
+ /**
5647
5890
  * One failure, one event. The identity machine reports a failed transition
5648
5891
  * first; when the same `CapxulError` then surfaces as a public method result
5649
5892
  * (directly or down its `cause` chain), the boundary drops that second report.
@@ -5721,6 +5964,34 @@ function ignoreDeliveryFailure(delivery) {
5721
5964
  } catch {}
5722
5965
  }
5723
5966
  /**
5967
+ * Fold a caller-captured attempt identity into the host's resolved context.
5968
+ *
5969
+ * The host's `resolveContext` runs at the moment an SDK method is entered, so a
5970
+ * host that mints a correlation per resolve gives every operation of one user
5971
+ * attempt a different identity — and a user or Organization switch between the
5972
+ * click and the reply relabels an action that already started. When the caller
5973
+ * captured `correlation_id`/`journey_id` BEFORE the action started, that is the
5974
+ * attempt, and it replaces what the resolver returned for this one call. The
5975
+ * result is what the SDK span/Log, the failure envelope and the backend carrier
5976
+ * all read, so the three agree by construction rather than by convention.
5977
+ *
5978
+ * A caller that captured nothing gets the resolver's context unchanged, so
5979
+ * automatic reads keep their own invocation context.
5980
+ */
5981
+ function withCapturedAttemptContext(context, controls) {
5982
+ const correlationId = controls?.correlation_id;
5983
+ const journeyId = controls?.journey_id;
5984
+ if (correlationId === void 0 && journeyId === void 0) return context;
5985
+ const captured = sanitizeObservationContext({
5986
+ ...correlationId === void 0 ? {} : { correlationId },
5987
+ ...journeyId === void 0 ? {} : { journeyId }
5988
+ });
5989
+ return captured === void 0 ? context : {
5990
+ ...context,
5991
+ ...captured
5992
+ };
5993
+ }
5994
+ /**
5724
5995
  * Map an ALREADY-sanitized observation context to the snake_case PostHog
5725
5996
  * property keys. Shared by the failure boundary here and the host
5726
5997
  * success-telemetry seam (`telemetry/from-posthog.ts`) so both attach identical
@@ -7852,7 +8123,8 @@ var BetterAuthBrowserAdapter = class {
7852
8123
  try {
7853
8124
  const res = await this.fetchImpl(this.url("/api/auth/get-session"), withSignal$1({
7854
8125
  method: "GET",
7855
- credentials: "include"
8126
+ credentials: "include",
8127
+ cache: "no-store"
7856
8128
  }, options?.signal));
7857
8129
  if (options?.signal?.aborted) return {
7858
8130
  ok: false,
@@ -7924,7 +8196,8 @@ var BetterAuthBrowserAdapter = class {
7924
8196
  try {
7925
8197
  const res = await this.fetchImpl(this.url("/api/auth/convex/token"), withSignal$1({
7926
8198
  method: "GET",
7927
- credentials: "include"
8199
+ credentials: "include",
8200
+ cache: "no-store"
7928
8201
  }, options?.signal));
7929
8202
  if (options?.signal?.aborted) return {
7930
8203
  ok: false,
@@ -8437,7 +8710,7 @@ function isTransientBootstrapFailure(error) {
8437
8710
  const status = error.details?.httpStatus;
8438
8711
  return typeof status === "number" && isTransientHttpStatus(status);
8439
8712
  }
8440
- async function safeText(res) {
8713
+ async function safeText$1(res) {
8441
8714
  try {
8442
8715
  return await res.text();
8443
8716
  } catch {
@@ -8510,6 +8783,8 @@ var HttpBootstrapAdapter = class {
8510
8783
  siteBaseUrl: normalizeRuntimeUrl("siteBaseUrl", decodedState.siteBaseUrl),
8511
8784
  openfortPublishableKey: decodedState.openfortPublishableKey,
8512
8785
  shieldPublishableKey: decodedState.shieldPublishableKey,
8786
+ ...decodedState.openfortAuthProvider === void 0 ? {} : { openfortAuthProvider: decodedState.openfortAuthProvider },
8787
+ ...decodedState.indexerUrl === void 0 ? {} : { indexerUrl: decodedState.indexerUrl },
8513
8788
  ...decodedEngineeringTelemetry !== void 0 && Result.isSuccess(decodedEngineeringTelemetry) ? { engineeringTelemetry: decodedEngineeringTelemetry.success } : {}
8514
8789
  };
8515
8790
  },
@@ -8518,7 +8793,7 @@ var HttpBootstrapAdapter = class {
8518
8793
  return bootstrapErrorFromCapxul("malformedBody", Errors.providerError("convex", "bootstrap", cause instanceof Error ? cause : new Error(String(cause))));
8519
8794
  }
8520
8795
  });
8521
- return Effect.promise(() => safeText(res)).pipe(Effect.flatMap((body) => {
8796
+ return Effect.promise(() => safeText$1(res)).pipe(Effect.flatMap((body) => {
8522
8797
  if (res.status === 401 || body.startsWith("NOT_AUTHENTICATED")) return Effect.fail(bootstrapErrorFromCapxul("notAuthenticated", Errors.notAuthenticated()));
8523
8798
  if (res.status === 400 || body.startsWith("INVALID_INPUT")) return Effect.fail(bootstrapErrorFromCapxul("invalidInput", Errors.invalidInput("publishableKey", "rejected by bootstrap")));
8524
8799
  const responseBody = body.slice(0, 300);
@@ -8748,6 +9023,12 @@ function makeConnectionId() {
8748
9023
  }
8749
9024
  //#endregion
8750
9025
  //#region src/adapters/convex-call/ConvexCallAdapter.ts
9026
+ /**
9027
+ * A socket that has not emitted `close` within this window is not going to.
9028
+ * ponytail: one fixed bound; `closeTimeoutMs` is the knob if a slow runtime
9029
+ * ever needs a different one.
9030
+ */
9031
+ const DEFAULT_CLOSE_TIMEOUT_MS = 5e3;
8751
9032
  /** Exact floor-first allowlist; every additional handler must migrate its validator first. */
8752
9033
  const OBSERVED_CONVEX_ACTIONS = /* @__PURE__ */ new Set([
8753
9034
  "payroll/actions:authorizeRun",
@@ -8816,7 +9097,9 @@ var ConvexCallAdapter = class {
8816
9097
  #applicationId;
8817
9098
  #observation;
8818
9099
  #connectionMonitor;
9100
+ #closeTimeoutMs;
8819
9101
  constructor(deps) {
9102
+ this.#closeTimeoutMs = deps.closeTimeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS;
8820
9103
  this.#connectionMonitor = new ConvexConnectionMonitor();
8821
9104
  const webSocketConstructor = this.#connectionMonitor.observedWebSocketConstructor();
8822
9105
  this.#client = deps.client ?? new ConvexClient(deps.convexUrl, webSocketConstructor === void 0 ? {} : { webSocketConstructor });
@@ -8915,11 +9198,33 @@ var ConvexCallAdapter = class {
8915
9198
  callback({ status: "loading" });
8916
9199
  })));
8917
9200
  }
9201
+ /**
9202
+ * Teardown always completes. `ConvexClient.close()` resolves only when the
9203
+ * socket emits `close`, and `WebSocketManager.close()` in the `connecting`
9204
+ * state arms `ws.onopen = () => ws.close()` without ever closing the socket
9205
+ * itself — so a handshake that stalls right after a server-initiated close
9206
+ * (code 1012, which is what a Convex deploy sends) leaves that promise
9207
+ * pending for as long as the page lives. Convex marks the client closed and
9208
+ * terminates the socket manager synchronously before returning it, so
9209
+ * abandoning it drops nothing. A rejection is dropped for the same reason —
9210
+ * the layer release turns it into a defect that fails the whole scope close,
9211
+ * and teardown has no caller who can act on it.
9212
+ */
8918
9213
  async close() {
8919
9214
  this.#connectionMonitor.close();
8920
- await this.#client.close();
9215
+ await settledWithin(this.#client.close(), this.#closeTimeoutMs);
8921
9216
  }
8922
9217
  };
9218
+ function settledWithin(promise, timeoutMs) {
9219
+ return new Promise((resolve) => {
9220
+ const timer = setTimeout(resolve, timeoutMs);
9221
+ const finish = () => {
9222
+ clearTimeout(timer);
9223
+ resolve();
9224
+ };
9225
+ promise.then(finish, finish);
9226
+ });
9227
+ }
8923
9228
  function ConvexCallLayer(deps) {
8924
9229
  return Layer.effect(ConvexCallPortTag, Effect.acquireRelease(Effect.sync(() => new ConvexCallAdapter(deps)), (adapter) => Effect.promise(() => adapter.close()).pipe(Effect.orDie)));
8925
9230
  }
@@ -9872,6 +10177,32 @@ var ConsoleDiagnosticAdapter = class {
9872
10177
  }
9873
10178
  };
9874
10179
  //#endregion
10180
+ //#region src/adapters/diagnostic/EffectLogDiagnosticAdapter.ts
10181
+ /**
10182
+ * Diagnostic breadcrumbs as SDK log records. The signer's readiness cycle
10183
+ * traces (`openfort.*`) used to reach only the browser console; through this
10184
+ * adapter they run in the client's own Effect context, so the engineering
10185
+ * telemetry layer ships them to PostHog Logs beside `identity.transition`.
10186
+ * Logging never throws back into the cycle that emitted it.
10187
+ */
10188
+ var EffectLogDiagnosticAdapter = class {
10189
+ #runPromise;
10190
+ #console;
10191
+ constructor(context, consoleFallback) {
10192
+ this.#runPromise = Effect.runPromiseWith(context);
10193
+ this.#console = consoleFallback;
10194
+ }
10195
+ trace(scope, detail) {
10196
+ this.#console?.trace(scope, detail);
10197
+ try {
10198
+ this.#runPromise(Effect.logInfo(scope).pipe(Effect.annotateLogs({
10199
+ ...detail,
10200
+ diagnostic_scope: scope
10201
+ }), Effect.catchCause(() => Effect.void))).catch(() => void 0);
10202
+ } catch {}
10203
+ }
10204
+ };
10205
+ //#endregion
9875
10206
  //#region src/openfort/create-openfort-browser-signer.ts
9876
10207
  function httpStatusOf(link) {
9877
10208
  const carrier = link;
@@ -10003,15 +10334,35 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
10003
10334
  });
10004
10335
  throw failOpenfort("configure", "no-secure-context", /* @__PURE__ */ new Error("Web Crypto unavailable: browser is not a secure context"));
10005
10336
  }
10006
- function betterAuthSessionUrl() {
10007
- return `${authBaseUrl}/get-session`;
10337
+ const authProvider = bootstrap.openfortAuthProvider ?? "better-auth";
10338
+ function accessTokenUrl() {
10339
+ return authProvider === "oidc" ? `${authBaseUrl}/convex/token` : `${authBaseUrl}/get-session`;
10008
10340
  }
10009
10341
  function encryptionSessionUrl() {
10010
10342
  return `${authBaseUrl}/encryption-session`;
10011
10343
  }
10344
+ let cycleStartedAt = null;
10345
+ let stepStartedAt = 0;
10346
+ let tokenCalls = 0;
10347
+ const sinceCycleStart = () => cycleStartedAt === null ? void 0 : Date.now() - cycleStartedAt;
10348
+ const step = (name, extra = {}) => {
10349
+ const now = Date.now();
10350
+ diagnostic?.trace("openfort.step", {
10351
+ step: name,
10352
+ duration_ms: now - stepStartedAt,
10353
+ elapsed_ms: sinceCycleStart(),
10354
+ ...extra
10355
+ });
10356
+ stepStartedAt = now;
10357
+ };
10012
10358
  async function fetchBetterAuthAccessToken() {
10359
+ tokenCalls += 1;
10360
+ const tokenStartedAt = Date.now();
10013
10361
  try {
10014
- const response = await fetch(betterAuthSessionUrl(), { credentials: "include" });
10362
+ const response = await fetch(accessTokenUrl(), {
10363
+ credentials: "include",
10364
+ cache: "no-store"
10365
+ });
10015
10366
  if (!response.ok) {
10016
10367
  diagnostic?.trace("openfort.token", {
10017
10368
  ok: false,
@@ -10021,7 +10372,8 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
10021
10372
  });
10022
10373
  return null;
10023
10374
  }
10024
- const token = (await response.json()).session?.token?.trim();
10375
+ const body = await response.json();
10376
+ const token = (authProvider === "oidc" ? body.token : body.session?.token)?.trim();
10025
10377
  if (token === void 0 || token.length === 0) {
10026
10378
  diagnostic?.trace("openfort.token", {
10027
10379
  ok: false,
@@ -10032,7 +10384,11 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
10032
10384
  }
10033
10385
  diagnostic?.trace("openfort.token", {
10034
10386
  ok: true,
10035
- tokenPresent: true
10387
+ tokenPresent: true,
10388
+ provider: authProvider,
10389
+ call: tokenCalls,
10390
+ duration_ms: Date.now() - tokenStartedAt,
10391
+ elapsed_ms: sinceCycleStart()
10036
10392
  });
10037
10393
  return token;
10038
10394
  } catch (cause) {
@@ -10048,7 +10404,7 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
10048
10404
  baseConfiguration: { publishableKey: bootstrap.openfortPublishableKey },
10049
10405
  shieldConfiguration: { shieldPublishableKey: bootstrap.shieldPublishableKey },
10050
10406
  thirdPartyAuth: {
10051
- provider: ThirdPartyOAuthProvider.BETTER_AUTH,
10407
+ provider: authProvider === "oidc" ? ThirdPartyOAuthProvider.OIDC : ThirdPartyOAuthProvider.BETTER_AUTH,
10052
10408
  getAccessToken: fetchBetterAuthAccessToken
10053
10409
  }
10054
10410
  });
@@ -10088,10 +10444,16 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
10088
10444
  let walletReadyPromise = null;
10089
10445
  function startWalletReady() {
10090
10446
  return (async () => {
10447
+ const startedAt = Date.now();
10448
+ cycleStartedAt = startedAt;
10449
+ stepStartedAt = startedAt;
10450
+ tokenCalls = 0;
10091
10451
  if (isInsecureBrowserContext()) failNoSecureContext();
10092
10452
  await openfort.waitForInitialization();
10453
+ step("initialize");
10093
10454
  const accessToken = await fetchBetterAuthAccessToken();
10094
10455
  if (accessToken === null) throw openfortProviderError("token", /* @__PURE__ */ new Error("Better Auth access token unavailable for Openfort"));
10456
+ step("token");
10095
10457
  let encryptionResponse;
10096
10458
  try {
10097
10459
  encryptionResponse = await fetch(encryptionSessionUrl(), {
@@ -10134,10 +10496,12 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
10134
10496
  ok: true,
10135
10497
  httpStatus: encryptionResponse.status
10136
10498
  });
10499
+ step("encryptionSession", { httpStatus: encryptionResponse.status });
10137
10500
  let embeddedState;
10138
10501
  try {
10139
10502
  embeddedState = await openfort.embeddedWallet.getEmbeddedState();
10140
10503
  diagnostic?.trace("openfort.embeddedState", { state: embeddedState });
10504
+ step("embeddedState", { state: embeddedState });
10141
10505
  } catch (cause) {
10142
10506
  diagnostic?.trace("openfort.embeddedState", {
10143
10507
  ok: false,
@@ -10151,6 +10515,7 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
10151
10515
  try {
10152
10516
  await configureEmbeddedWallet(encryptionBody.sessionId);
10153
10517
  diagnostic?.trace("openfort.configure", { ok: true });
10518
+ step("configure");
10154
10519
  } catch (cause) {
10155
10520
  const error = openfortProviderError("configure", cause);
10156
10521
  diagnostic?.trace("openfort.configure", {
@@ -10163,6 +10528,7 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
10163
10528
  try {
10164
10529
  await openfort.embeddedWallet.get();
10165
10530
  diagnostic?.trace("openfort.get", { ok: true });
10531
+ step("get");
10166
10532
  } catch (cause) {
10167
10533
  if (!isStaleUserSignal(cause)) {
10168
10534
  diagnostic?.trace("openfort.get", {
@@ -10176,7 +10542,13 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
10176
10542
  failure_mode: "stale-openfort-cache"
10177
10543
  });
10178
10544
  await healStaleOpenfortCache(encryptionBody.sessionId);
10545
+ step("healStaleCache");
10179
10546
  }
10547
+ step("walletReady", {
10548
+ ok: true,
10549
+ total_ms: Date.now() - startedAt,
10550
+ token_calls: tokenCalls
10551
+ });
10180
10552
  })();
10181
10553
  }
10182
10554
  async function ensureOpenfortWalletReady() {
@@ -10259,9 +10631,13 @@ function createOpenfortBrowserSignerFromBootstrap(bootstrap, options = {}) {
10259
10631
  statusStore,
10260
10632
  ensureWalletReady: ensureOpenfortWalletReady,
10261
10633
  getAddress: async () => {
10634
+ const addressStartedAt = Date.now();
10262
10635
  try {
10263
10636
  const address = await signer.getAddress();
10264
- diagnostic?.trace("openfort.address", { ok: true });
10637
+ diagnostic?.trace("openfort.address", {
10638
+ ok: true,
10639
+ duration_ms: Date.now() - addressStartedAt
10640
+ });
10265
10641
  return address;
10266
10642
  } catch (cause) {
10267
10643
  diagnostic?.trace("openfort.address", {
@@ -11363,14 +11739,66 @@ function organizationWrongState(currentState, validStates) {
11363
11739
  function requestCancelled(options) {
11364
11740
  return options?.signal?.aborted === true;
11365
11741
  }
11742
+ function accountInFlight(state) {
11743
+ return state.phase === "authenticated" && (state.account.at === "deriving" || state.account.at === "claiming");
11744
+ }
11745
+ function settledAccount(deps, options) {
11746
+ return new Promise((resolve) => {
11747
+ let done = false;
11748
+ let unsubscribe = null;
11749
+ const onAbort = () => finish({
11750
+ ok: false,
11751
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completeOrganization })
11752
+ });
11753
+ const finish = (result) => {
11754
+ if (done) return;
11755
+ done = true;
11756
+ unsubscribe?.();
11757
+ options?.signal?.removeEventListener("abort", onAbort);
11758
+ resolve(result);
11759
+ };
11760
+ if (options?.signal?.aborted) {
11761
+ onAbort();
11762
+ return;
11763
+ }
11764
+ options?.signal?.addEventListener("abort", onAbort, { once: true });
11765
+ const stop = deps.subscribeIdentity((state) => {
11766
+ if (!accountInFlight(state)) finish({
11767
+ ok: true,
11768
+ value: state
11769
+ });
11770
+ });
11771
+ if (done) {
11772
+ stop();
11773
+ return;
11774
+ }
11775
+ unsubscribe = stop;
11776
+ const current = deps.snapshotIdentity();
11777
+ if (!accountInFlight(current)) finish({
11778
+ ok: true,
11779
+ value: current
11780
+ });
11781
+ });
11782
+ }
11366
11783
  async function reachClaimedAccount(deps, options) {
11367
11784
  let state = deps.snapshotIdentity();
11785
+ if (accountInFlight(state)) {
11786
+ const settled = await settledAccount(deps, options);
11787
+ if (!settled.ok) return settled;
11788
+ state = settled.value;
11789
+ }
11368
11790
  if (state.phase !== "authenticated" || state.account.at === "unknown") {
11369
11791
  const ensured = await deps.sendIdentity({ _tag: "EnsureAccount" }, options);
11370
11792
  if (!ensured.ok) return ensured;
11371
11793
  state = ensured.value;
11372
11794
  }
11373
11795
  if (state.phase !== "authenticated") return organizationWrongState(state.phase, ["authenticated:claimed"]);
11796
+ if (accountInFlight(state)) {
11797
+ const settled = await settledAccount(deps, options);
11798
+ if (!settled.ok) return settled;
11799
+ state = settled.value;
11800
+ if (state.phase !== "authenticated") return organizationWrongState(state.phase, ["authenticated:claimed"]);
11801
+ }
11374
11802
  if (state.account.at !== "claimed") {
11375
11803
  const event = state.account.at === "failed" ? { _tag: "RetryAccount" } : state.account.at === "counterfactual" ? { _tag: "ClaimAccount" } : { _tag: "EnsureAccount" };
11376
11804
  const claimed = await deps.sendIdentity(event, options);
@@ -11722,6 +12150,25 @@ const permissionContract = { read: makeFunctionReference(CAPXUL_FUNCTIONS["permi
11722
12150
  function isAborted(signal) {
11723
12151
  return signal?.aborted === true;
11724
12152
  }
12153
+ /**
12154
+ * One owning operation per public Permission method. The compound command
12155
+ * (prepare, equality checks, sign, submit) keeps owning its own cancellation;
12156
+ * the observed runner around it is what gives the attempt its
12157
+ * `capxul_sdk_operation` record, its span and its failure capture, so a signer
12158
+ * refusal or an unexpected provider error joins to the operation like every
12159
+ * other public surface.
12160
+ */
12161
+ function observed(deps, operation, options, run) {
12162
+ const controls = deps.invocationControls?.(options) ?? options;
12163
+ return runCapxulEffect(Effect.gen(function* () {
12164
+ if (controls?.signal?.aborted === true) return yield* Effect.fail(Errors.cancelled({ operation }));
12165
+ const result = yield* Effect.tryPromise({
12166
+ try: () => run(controls?.signal),
12167
+ catch: (cause) => cause instanceof CapxulError ? cause : Errors.unknown(cause)
12168
+ });
12169
+ return yield* result.ok ? Effect.succeed(result.value) : Effect.fail(result.error);
12170
+ }), observationOnlyControls(controls), operation, deps.runPromise);
12171
+ }
11725
12172
  async function execute(deps, orgId, command, signal) {
11726
12173
  if (isAborted(signal)) return {
11727
12174
  ok: false,
@@ -11781,36 +12228,37 @@ async function execute(deps, orgId, command, signal) {
11781
12228
  }
11782
12229
  function makePermissionMethods(deps, orgId) {
11783
12230
  const reads = deps.permissionFunctions ?? permissionContract;
12231
+ const ops = CAPXUL_OPERATIONS.org.permissions;
11784
12232
  return {
11785
- create: (input, options) => execute(deps, orgId, {
12233
+ create: (input, options) => observed(deps, ops.create, options, (signal) => execute(deps, orgId, {
11786
12234
  operation: "create",
11787
12235
  ...input
11788
- }, options?.signal),
11789
- change: (input, options) => execute(deps, orgId, {
12236
+ }, signal)),
12237
+ change: (input, options) => observed(deps, ops.change, options, (signal) => execute(deps, orgId, {
11790
12238
  operation: "change",
11791
12239
  ...input
11792
- }, options?.signal),
11793
- assign: (input, options) => execute(deps, orgId, {
12240
+ }, signal)),
12241
+ assign: (input, options) => observed(deps, ops.assign, options, (signal) => execute(deps, orgId, {
11794
12242
  operation: "assign",
11795
12243
  ...input
11796
- }, options?.signal),
11797
- revoke: (input, options) => execute(deps, orgId, {
12244
+ }, signal)),
12245
+ revoke: (input, options) => observed(deps, ops.revoke, options, (signal) => execute(deps, orgId, {
11798
12246
  operation: "revoke",
11799
12247
  ...input
11800
- }, options?.signal),
11801
- replace: (input, options) => execute(deps, orgId, {
12248
+ }, signal)),
12249
+ replace: (input, options) => observed(deps, ops.replace, options, (signal) => execute(deps, orgId, {
11802
12250
  operation: "replace",
11803
12251
  ...input
11804
- }, options?.signal),
11805
- list: (options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.permissions.list, () => deps.convexCall.query(reads.read, { orgId })),
11806
- get: async (permissionId, options) => {
11807
- const listed = await runIfActive(options?.signal, CAPXUL_OPERATIONS.permissions.get, () => deps.convexCall.query(reads.read, { orgId }));
12252
+ }, signal)),
12253
+ list: (options) => observed(deps, ops.list, options, (signal) => runIfActive(signal, CAPXUL_OPERATIONS.permissions.list, () => deps.convexCall.query(reads.read, { orgId }))),
12254
+ get: (permissionId, options) => observed(deps, ops.get, options, async (signal) => {
12255
+ const listed = await runIfActive(signal, CAPXUL_OPERATIONS.permissions.get, () => deps.convexCall.query(reads.read, { orgId }));
11808
12256
  if (!listed.ok) return listed;
11809
12257
  return {
11810
12258
  ok: true,
11811
12259
  value: listed.value.permissions.find((row) => row.permissionId === permissionId) ?? null
11812
12260
  };
11813
- }
12261
+ })
11814
12262
  };
11815
12263
  }
11816
12264
  //#endregion
@@ -12372,7 +12820,7 @@ function hermeticOrgView(input) {
12372
12820
  name: input.name,
12373
12821
  handle: input.handle,
12374
12822
  safeAddress: toAddress(placeholder),
12375
- role: "Owner",
12823
+ role: ADMIN_ROLE_LABEL,
12376
12824
  treasury: zeroTreasury(orgId),
12377
12825
  bio: null,
12378
12826
  size: null,
@@ -12618,6 +13066,13 @@ function isRetryableOrganizationSetupFailure(error) {
12618
13066
  * constructed for each `org(orgId)` call. It has no shared mutable active-Org
12619
13067
  * state. The closed-over `orgId` is its only entity reference.
12620
13068
  */
13069
+ /** The observed-runner pair a method bundle needs to own its operation records. */
13070
+ function observedRunnerDeps(deps) {
13071
+ return {
13072
+ ...deps.runPromise === void 0 ? {} : { runPromise: deps.runPromise },
13073
+ ...deps.invocationControls === void 0 ? {} : { invocationControls: deps.invocationControls }
13074
+ };
13075
+ }
12621
13076
  function makeOrgMethods(deps) {
12622
13077
  const orgDeps = {
12623
13078
  ...deps.orgPort === void 0 ? {} : { orgPort: deps.orgPort },
@@ -12785,6 +13240,7 @@ function makeOrgMethods(deps) {
12785
13240
  },
12786
13241
  permissions: convexCall === void 0 ? makeNotImplementedPermissionMethods() : makePermissionMethods({
12787
13242
  convexCall,
13243
+ ...observedRunnerDeps(deps),
12788
13244
  ...deps.actor === void 0 ? {} : { actor: deps.actor },
12789
13245
  ...deps.chainId === void 0 ? {} : { chainId: Number(deps.chainId) },
12790
13246
  ...deps.signer === void 0 ? {} : { signer: deps.signer }
@@ -12977,11 +13433,28 @@ const authFailure = (record, reason, mode) => ({
12977
13433
  ...linkage(record)
12978
13434
  }
12979
13435
  });
13436
+ const REFUSAL_EVENTS = /* @__PURE__ */ new Set([
13437
+ "ClaimAccount",
13438
+ "RetryAccount",
13439
+ "CreateOrganization",
13440
+ "AttachOrganization",
13441
+ "RetryOrganization"
13442
+ ]);
12980
13443
  function mapIdentityProductObservation(record, state) {
12981
13444
  if (record.machine !== "identity" || !IDENTITY_EVENT_TAG_SET.has(record.event)) return NONE;
12982
13445
  if (record.outcome === "cancelled") return NONE;
12983
13446
  if (record.slot === "identity:auth" && record.outcome === "refused") return authFailure(record, record.refusal_code, void 0);
12984
13447
  if (record.slot === "identity:auth" && record.outcome === "failed") return authFailure(record, record.error_code, record.failure?.mode);
13448
+ if (record.outcome === "refused" && REFUSAL_EVENTS.has(record.event)) return {
13449
+ name: "identity_refused",
13450
+ props: {
13451
+ event: record.event,
13452
+ refusal_code: record.refusal_code,
13453
+ slot: record.slot,
13454
+ state: record.state,
13455
+ ...linkage(record)
13456
+ }
13457
+ };
12985
13458
  if (record.outcome !== "applied") return NONE;
12986
13459
  switch (APPLIED_ACTION_BY_EVENT[record.event]) {
12987
13460
  case "none": return NONE;
@@ -13140,10 +13613,13 @@ function assembleCapxulClient(input) {
13140
13613
  ...input.invokeTimeoutMs === void 0 ? {} : { invokeTimeoutMs: input.invokeTimeoutMs },
13141
13614
  afterVerifyOtp: async () => {
13142
13615
  const browserSigner = input.signer;
13143
- if (browserSigner !== void 0 && "resetSession" in browserSigner && typeof browserSigner.resetSession === "function") try {
13144
- browserSigner.resetSession();
13145
- } catch (cause) {
13146
- throw signerFailure(browserSigner.source, "resetSession", cause);
13616
+ if (browserSigner !== void 0 && "resetSession" in browserSigner && typeof browserSigner.resetSession === "function") {
13617
+ try {
13618
+ browserSigner.resetSession();
13619
+ } catch (cause) {
13620
+ throw signerFailure(browserSigner.source, "resetSession", cause);
13621
+ }
13622
+ if (browserSigner.statusStore?.status() === "unknown" && typeof browserSigner.ensureWalletReady === "function") browserSigner.ensureWalletReady().catch(() => {});
13147
13623
  }
13148
13624
  await detectPendingOrgInvitations?.();
13149
13625
  kickProvisioning?.();
@@ -13170,6 +13646,7 @@ function assembleCapxulClient(input) {
13170
13646
  ensureAccount: account._internal.ensureReady,
13171
13647
  getLifecycle: account.getLifecycle,
13172
13648
  snapshotIdentity: actor.snapshot,
13649
+ subscribeIdentity: actor.subscribe,
13173
13650
  sendIdentity: (event, options) => runCapxulEffect(askIdentity(actor, event, options), options, CAPXUL_OPERATIONS._internal.identity.send, effectRunner.runPromise)
13174
13651
  });
13175
13652
  const system = makeSystemMethods({ convexCall: input.ports.convexCall });
@@ -13303,6 +13780,7 @@ function assembleCapxulClient(input) {
13303
13780
  identity: identityRuntime,
13304
13781
  bootstrap: input.bootstrap,
13305
13782
  accounts: { fund: accounts.fund },
13783
+ ...input.ports.indexerRead === void 0 ? {} : { indexer: input.ports.indexerRead },
13306
13784
  organizationSetup: { getProofReceipt: (orgId) => runPortEffect(input.ports.convexCall.query(organizationSetupProofReceiptQuery, { orgId })) },
13307
13785
  telemetry: input.ports.telemetry,
13308
13786
  captureExternalAddressAcknowledged: (address, organizationId) => {
@@ -13361,8 +13839,10 @@ function withHostObservationControls(snapshot, input, actorId) {
13361
13839
  const previous = readInvocationObservation(input);
13362
13840
  if (previous !== void 0) return attachInvocationObservation({ ...input }, previous);
13363
13841
  const captured = snapshot?.() ?? { active: true };
13842
+ const context = captured.active ? withCapturedAttemptContext(captured.context, input) : captured.context;
13364
13843
  return attachInvocationObservation({ ...input }, {
13365
13844
  ...captured,
13845
+ ...context === void 0 ? {} : { context },
13366
13846
  ...actorId === void 0 ? {} : { actorId }
13367
13847
  });
13368
13848
  }
@@ -13502,6 +13982,382 @@ function snapshotHostObservability(observability) {
13502
13982
  function isPromiseLike(value) {
13503
13983
  return (typeof value === "object" && value !== null || typeof value === "function") && "then" in value;
13504
13984
  }
13985
+ //#endregion
13986
+ //#region src/ports/indexer-read.ts
13987
+ /** The indexer's own page bound. Exceeding it is a caller defect, not a refusal. */
13988
+ const INDEXER_MAX_LIMIT = 1e3;
13989
+ const LOWER_CASE_ADDRESS = /^0x[0-9a-f]{40}$/;
13990
+ /**
13991
+ * Refuse a page the indexer would refuse, before any implementation spends a
13992
+ * round trip on it. Every implementation calls this, so a consumer test written
13993
+ * against the hermetic adapter cannot pass on input production rejects. Throws
13994
+ * a `CapxulError`; callers convert it to an `IndexerReadError`.
13995
+ */
13996
+ function assertIndexerPage(input) {
13997
+ const safe = String(input.safe).toLowerCase();
13998
+ if (!LOWER_CASE_ADDRESS.test(safe)) throw Errors.invalidInput("safe", "must be a lower-case EVM address");
13999
+ if (!Number.isSafeInteger(input.limit) || input.limit < 1 || input.limit > 1e3) throw Errors.invalidInput("limit", `must be an integer from 1 to ${INDEXER_MAX_LIMIT}`);
14000
+ const offset = input.offset ?? 0;
14001
+ if (!Number.isSafeInteger(offset) || offset < 0) throw Errors.invalidInput("offset", "must be a non-negative integer");
14002
+ return safe;
14003
+ }
14004
+ var IndexerReadError = class extends Data.TaggedError("IndexerReadError") {};
14005
+ function indexerReadErrorFromCapxul(operation, error, cause = error) {
14006
+ return new IndexerReadError({
14007
+ operation,
14008
+ publicCode: error.code,
14009
+ publicError: error,
14010
+ cause,
14011
+ ...error.details === void 0 ? {} : { details: error.details }
14012
+ });
14013
+ }
14014
+ Context.Service()("@capxul/sdk/ports/IndexerReadPort");
14015
+ //#endregion
14016
+ //#region src/adapters/ponder/decode.ts
14017
+ /**
14018
+ * Decode the indexer's rows at the trust boundary.
14019
+ *
14020
+ * Ponder returns the raw PostgreSQL result: `integer` arrives as a number,
14021
+ * `numeric(78)` and `text` arrive as strings. Amounts, block numbers and
14022
+ * timestamps are `numeric(78)`, so they become `bigint` here and never pass
14023
+ * through `Number`. Every decoder throws a `CapxulError`; the adapter turns
14024
+ * that into a typed `IndexerReadError`.
14025
+ */
14026
+ const HEX = /^0x[0-9a-fA-F]+$/;
14027
+ function field(row, key) {
14028
+ if (!(key in row)) throw Errors.invalidInput(key, "missing from the indexer row");
14029
+ return row[key];
14030
+ }
14031
+ function text(row, key) {
14032
+ const value = field(row, key);
14033
+ if (typeof value !== "string") throw Errors.invalidInput(key, "must be a string");
14034
+ return value;
14035
+ }
14036
+ function hex(row, key) {
14037
+ const value = text(row, key);
14038
+ if (!HEX.test(value)) throw Errors.invalidInput(key, "must be a hex string");
14039
+ return value.toLowerCase();
14040
+ }
14041
+ function integer(row, key) {
14042
+ const value = field(row, key);
14043
+ const parsed = typeof value === "string" ? Number(value) : value;
14044
+ if (typeof parsed !== "number" || !Number.isSafeInteger(parsed)) throw Errors.invalidInput(key, "must be an integer");
14045
+ return parsed;
14046
+ }
14047
+ /** `numeric(78)` crosses the wire as a decimal string; keep every digit. */
14048
+ function big(row, key) {
14049
+ const value = field(row, key);
14050
+ if (typeof value === "bigint") return value;
14051
+ const raw = typeof value === "number" ? String(value) : value;
14052
+ if (typeof raw !== "string" || !/^-?[0-9]+$/.test(raw)) throw Errors.invalidInput(key, "must be an exact integer amount");
14053
+ return BigInt(raw);
14054
+ }
14055
+ function asRow(value) {
14056
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw Errors.invalidInput("row", "must be an object");
14057
+ return value;
14058
+ }
14059
+ function identity(row) {
14060
+ return {
14061
+ id: text(row, "id"),
14062
+ chainId: toChainId(integer(row, "chain_id")),
14063
+ txHash: toTxHash(hex(row, "tx_hash")),
14064
+ transactionLogOrdinal: integer(row, "transaction_log_ordinal"),
14065
+ blockNumber: big(row, "block_number"),
14066
+ blockHash: hex(row, "block_hash"),
14067
+ timestamp: big(row, "timestamp")
14068
+ };
14069
+ }
14070
+ function decodeTransfer(value) {
14071
+ const row = asRow(value);
14072
+ return {
14073
+ ...identity(row),
14074
+ assetId: toAssetId(text(row, "asset_id")),
14075
+ token: toAddress(hex(row, "token")),
14076
+ from: toAddress(hex(row, "from")),
14077
+ to: toAddress(hex(row, "to")),
14078
+ amount: big(row, "amount")
14079
+ };
14080
+ }
14081
+ function decodePayment(value) {
14082
+ const row = asRow(value);
14083
+ return {
14084
+ ...identity(row),
14085
+ contract: toAddress(hex(row, "contract")),
14086
+ settlementId: hex(row, "settlement_id"),
14087
+ sender: toAddress(hex(row, "sender")),
14088
+ recipient: toAddress(hex(row, "recipient")),
14089
+ assetId: toAssetId(text(row, "asset_id")),
14090
+ token: toAddress(hex(row, "token")),
14091
+ amount: big(row, "amount"),
14092
+ kind: integer(row, "kind"),
14093
+ documentHash: hex(row, "document_hash")
14094
+ };
14095
+ }
14096
+ /** The `balance` view exposes the signed sum under the underlying column name `to`. */
14097
+ function decodeBalance(value) {
14098
+ const row = asRow(value);
14099
+ return {
14100
+ chainId: toChainId(integer(row, "chain_id")),
14101
+ assetId: toAssetId(text(row, "asset_id")),
14102
+ address: toAddress(hex(row, "to")),
14103
+ amount: big(row, "amount")
14104
+ };
14105
+ }
14106
+ const DECODERS = {
14107
+ transfer: decodeTransfer,
14108
+ payment: decodePayment,
14109
+ balance: decodeBalance
14110
+ };
14111
+ /** Decode one `/sql/db` or `/sql/live` payload. Ponder returns `{ rows: [...] }`. */
14112
+ function decodeRows(table, body) {
14113
+ const rows = asRow(body).rows;
14114
+ if (!Array.isArray(rows)) throw Errors.invalidInput("rows", "must be an array");
14115
+ const decode = DECODERS[table];
14116
+ return rows.map(decode);
14117
+ }
14118
+ /** Decode Ponder's native `/status`: `{ [chainName]: { id, block: { number, timestamp } } }`. */
14119
+ function decodeStatus(body) {
14120
+ const chains = asRow(body);
14121
+ return Object.entries(chains).map(([chain, value]) => {
14122
+ const entry = asRow(value);
14123
+ const block = asRow(field(entry, "block"));
14124
+ return {
14125
+ chain,
14126
+ chainId: toChainId(integer(entry, "id")),
14127
+ blockNumber: big(block, "number"),
14128
+ blockTimestamp: big(block, "timestamp")
14129
+ };
14130
+ });
14131
+ }
14132
+ //#endregion
14133
+ //#region src/adapters/ponder/statements.ts
14134
+ /**
14135
+ * The exact statements the indexer accepts.
14136
+ *
14137
+ * `apps/indexer/src/queries.ts` compiles its allowlist with `@ponder/client`
14138
+ * and compares `sql`, `params` and `typings` byte for byte against the caller's
14139
+ * statement. Anything else gets 403. The SDK therefore reproduces the compiled
14140
+ * text here rather than pulling Ponder and Drizzle into a published browser
14141
+ * bundle to regenerate three fixed statements.
14142
+ *
14143
+ * `statements.test.ts` pins the text. When the indexer schema or a query in
14144
+ * that allowlist changes, this file changes with it or every read fails 403.
14145
+ */
14146
+ const HEADS = {
14147
+ transfer: "select \"id\", \"chain_id\", \"tx_hash\", \"transaction_log_ordinal\", \"block_number\", \"block_hash\", \"timestamp\", \"asset_id\", \"token\", \"from\", \"to\", \"amount\" from \"transfer\" where (\"transfer\".\"from\" = $1 or \"transfer\".\"to\" = $2) order by \"transfer\".\"block_number\" desc, \"transfer\".\"id\" desc",
14148
+ payment: "select \"id\", \"chain_id\", \"tx_hash\", \"transaction_log_ordinal\", \"block_number\", \"block_hash\", \"timestamp\", \"contract\", \"settlement_id\", \"sender\", \"recipient\", \"asset_id\", \"token\", \"amount\", \"kind\", \"document_hash\" from \"payment\" where (\"payment\".\"sender\" = $1 or \"payment\".\"recipient\" = $2) order by \"payment\".\"block_number\" desc, \"payment\".\"id\" desc",
14149
+ balance: "select \"chain_id\", \"asset_id\", \"to\", \"amount\" from \"balance\" where \"balance\".\"to\" = $1"
14150
+ };
14151
+ /** How many times the statement binds the Safe address. */
14152
+ const ACTOR_PARAMS = {
14153
+ transfer: 2,
14154
+ payment: 2,
14155
+ balance: 1
14156
+ };
14157
+ /**
14158
+ * Build the compiled query for one table and page. Throws a `CapxulError` for
14159
+ * a page or address the indexer would refuse, so the caller never spends a
14160
+ * round trip to learn it built the request wrong.
14161
+ */
14162
+ function ponderQuery(table, input) {
14163
+ const safe = assertIndexerPage(input);
14164
+ const offset = input.offset ?? 0;
14165
+ const actors = ACTOR_PARAMS[table];
14166
+ const params = [];
14167
+ for (let i = 0; i < actors; i++) params.push(safe);
14168
+ params.push(input.limit);
14169
+ let sql = `${HEADS[table]} limit $${actors + 1}`;
14170
+ if (offset > 0) {
14171
+ params.push(offset);
14172
+ sql = `${sql} offset $${actors + 2}`;
14173
+ }
14174
+ return {
14175
+ sql,
14176
+ params,
14177
+ typings: params.map(() => "none")
14178
+ };
14179
+ }
14180
+ /**
14181
+ * The `?sql=` value. `@ponder/client` sends `superjson.stringify(query)`; for a
14182
+ * payload of strings and numbers superjson emits no `meta`, so the wire form is
14183
+ * exactly this envelope.
14184
+ */
14185
+ function ponderQueryParam(query) {
14186
+ return JSON.stringify({ json: query });
14187
+ }
14188
+ //#endregion
14189
+ //#region src/adapters/ponder/sse.ts
14190
+ /**
14191
+ * The smallest SSE reader that can carry an `Authorization` header.
14192
+ *
14193
+ * `@ponder/client` opens its live query with `EventSource`, which accepts no
14194
+ * headers, so it cannot reach the guarded indexer at all. The indexer's CORS
14195
+ * policy allows exactly one request header (`Authorization`), so this reader
14196
+ * sends nothing else. Ponder writes one `data:` line per frame.
14197
+ */
14198
+ async function readEventStream(body, onData, stopped) {
14199
+ const reader = body.getReader();
14200
+ const decoder = new TextDecoder();
14201
+ let buffer = "";
14202
+ try {
14203
+ for (;;) {
14204
+ const { done, value } = await reader.read();
14205
+ if (done || stopped()) return;
14206
+ buffer += decoder.decode(value, { stream: true });
14207
+ let split = buffer.indexOf("\n\n");
14208
+ while (split !== -1) {
14209
+ const frame = buffer.slice(0, split);
14210
+ buffer = buffer.slice(split + 2);
14211
+ const data = frameData(frame);
14212
+ if (data !== void 0) onData(data);
14213
+ if (stopped()) return;
14214
+ split = buffer.indexOf("\n\n");
14215
+ }
14216
+ }
14217
+ } finally {
14218
+ await reader.cancel().catch(() => void 0);
14219
+ }
14220
+ }
14221
+ function frameData(frame) {
14222
+ const lines = [];
14223
+ for (const line of frame.split("\n")) {
14224
+ if (!line.startsWith("data:")) continue;
14225
+ lines.push(line.slice(line.startsWith("data: ") ? 6 : 5));
14226
+ }
14227
+ return lines.length === 0 ? void 0 : lines.join("\n");
14228
+ }
14229
+ //#endregion
14230
+ //#region src/adapters/ponder/PonderIndexerAdapter.ts
14231
+ var PonderIndexerAdapter = class {
14232
+ #baseUrl;
14233
+ #token;
14234
+ #fetch;
14235
+ #observation;
14236
+ constructor(deps) {
14237
+ this.#baseUrl = deps.baseUrl.replace(/\/$/, "");
14238
+ this.#token = deps.token;
14239
+ this.#observation = deps.observation;
14240
+ this.#fetch = deps.fetch ?? ((input, init) => globalThis.fetch(input, init));
14241
+ }
14242
+ read(table, input) {
14243
+ const operation = `indexer.read.${table}`;
14244
+ return Effect.tryPromise({
14245
+ try: async () => {
14246
+ return decodeRows(table, await (await this.#request("db", table, input, operation)).json());
14247
+ },
14248
+ catch: (cause) => toIndexerReadError(operation, cause)
14249
+ });
14250
+ }
14251
+ subscribe(table, input, callback) {
14252
+ const operation = CAPXUL_OPERATIONS.activity.subscribe;
14253
+ return Effect.sync(() => {
14254
+ let stopped = false;
14255
+ const unsubscribe = () => {
14256
+ stopped = true;
14257
+ };
14258
+ callback({ status: "loading" });
14259
+ this.#stream(table, input, operation, callback, () => stopped).catch(() => void 0);
14260
+ return unsubscribe;
14261
+ });
14262
+ }
14263
+ status = Effect.tryPromise({
14264
+ try: async () => {
14265
+ const response = await this.#fetch(`${this.#baseUrl}/status`, { method: "GET" });
14266
+ if (!response.ok) throw httpError("indexer.status", response.status, await safeText(response));
14267
+ return decodeStatus(await response.json());
14268
+ },
14269
+ catch: (cause) => toIndexerReadError("indexer.status", cause)
14270
+ });
14271
+ /** One authenticated `/sql/:method` call. Throws a `CapxulError` on refusal. */
14272
+ async #request(method, table, input, operation) {
14273
+ const query = ponderQuery(table, input);
14274
+ const token = await this.#token({ forceRefreshToken: false });
14275
+ if (token === null || token === "") throw Errors.notAuthenticated();
14276
+ const url = `${this.#baseUrl}/sql/${method}?sql=${encodeURIComponent(ponderQueryParam(query))}`;
14277
+ const headers = { authorization: `Bearer ${token}` };
14278
+ if (method === "live") headers.accept = "text/event-stream";
14279
+ let response;
14280
+ try {
14281
+ response = await this.#fetch(url, {
14282
+ method: "GET",
14283
+ headers
14284
+ });
14285
+ } catch (cause) {
14286
+ throw Errors.networkError(operation, cause, {
14287
+ provider: "indexer",
14288
+ failure_mode: "upstream-down"
14289
+ });
14290
+ }
14291
+ if (!response.ok) throw httpError(operation, response.status, await safeText(response));
14292
+ return response;
14293
+ }
14294
+ /**
14295
+ * Follow the live stream until the caller unsubscribes or the indexer closes
14296
+ * it. The indexer closes the stream on token expiry or revoked authority
14297
+ * with no frame, so any end the caller did not ask for is a teardown: it
14298
+ * reaches `captureException` under `activity.subscribe` and the caller sees
14299
+ * one `error` snapshot.
14300
+ */
14301
+ async #stream(table, input, operation, callback, stopped) {
14302
+ let failure;
14303
+ try {
14304
+ const response = await this.#request("live", table, input, operation);
14305
+ if (response.body === null) throw Errors.providerError("indexer", operation, "empty stream");
14306
+ await readEventStream(response.body, (data) => {
14307
+ try {
14308
+ callback({
14309
+ status: "ok",
14310
+ value: decodeRows(table, JSON.parse(data))
14311
+ });
14312
+ } catch (cause) {
14313
+ failure = toPublicError$1(operation, cause);
14314
+ }
14315
+ }, () => stopped() || failure !== void 0);
14316
+ } catch (cause) {
14317
+ failure = toPublicError$1(operation, cause);
14318
+ }
14319
+ if (stopped()) return;
14320
+ const error = failure ?? Errors.capabilityUnavailable("indexer", operation);
14321
+ observeStreamFailure(this.#observation, CAPXUL_OPERATIONS.activity.subscribe, error);
14322
+ callback({
14323
+ status: "error",
14324
+ error
14325
+ });
14326
+ }
14327
+ };
14328
+ /**
14329
+ * Map an indexer refusal into the shared error vocabulary.
14330
+ *
14331
+ * 401 is the expected outcome of an expired or revoked session. 403 is not:
14332
+ * the indexer accepts only its own compiled statements for a Safe in the
14333
+ * claim, so a refusal means this SDK and that deployment disagree, or the
14334
+ * session gained a Safe and still holds the older token. Both must be loud.
14335
+ */
14336
+ function httpError(operation, status, body) {
14337
+ if (status === 401) return Errors.notAuthenticated();
14338
+ if (status === 429) return Errors.rateLimited({ resource: "indexer" });
14339
+ if (status === 503) return Errors.capabilityUnavailable("indexer", operation);
14340
+ return Errors.providerError("indexer", operation, body, {
14341
+ httpStatus: status,
14342
+ ...status >= 500 ? { failure_mode: "upstream-down" } : {},
14343
+ details: { reason: status === 403 ? "scope-refused" : "http-status" }
14344
+ });
14345
+ }
14346
+ function toPublicError$1(operation, cause) {
14347
+ if (cause instanceof CapxulError) return cause;
14348
+ return Errors.providerError("indexer", operation, cause);
14349
+ }
14350
+ function toIndexerReadError(operation, cause) {
14351
+ if (cause instanceof IndexerReadError) return cause;
14352
+ return indexerReadErrorFromCapxul(operation, toPublicError$1(operation, cause), cause);
14353
+ }
14354
+ async function safeText(response) {
14355
+ try {
14356
+ return await response.text();
14357
+ } catch {
14358
+ return "";
14359
+ }
14360
+ }
13505
14361
  const SDK_VERSION = version;
13506
14362
  /**
13507
14363
  * Project the built graph into the flat `FlowPorts` record the method bundles
@@ -13751,7 +14607,16 @@ async function createProductionAdapters(input) {
13751
14607
  }));
13752
14608
  const applicationLayer = Layer.merge(portsLayer, optionalEngineeringTelemetryLayer(bootstrapResult.value.engineeringTelemetry, resolvedInput.value.runtime));
13753
14609
  const context = await Effect.runPromise(Layer.buildWithScope(applicationLayer, scope));
13754
- const ports = await Effect.runPromise(collectProductionFlowPorts.pipe(Effect.provide(context)));
14610
+ const collected = await Effect.runPromise(collectProductionFlowPorts.pipe(Effect.provide(context)));
14611
+ const indexerUrl = input.indexerUrl ?? bootstrapResult.value.indexerUrl;
14612
+ const indexerRead = productionIndexerReadPort(indexerUrl === void 0 ? input : {
14613
+ ...input,
14614
+ indexerUrl
14615
+ }, collected, observation);
14616
+ const ports = indexerRead === void 0 ? collected : {
14617
+ ...collected,
14618
+ indexerRead
14619
+ };
13755
14620
  const stopConnectionObservation = observeProductionConvexConnection(ports.convexCall, context);
13756
14621
  const close = idempotentClose(async () => {
13757
14622
  try {
@@ -13878,7 +14743,7 @@ async function createCapxulClientWithSignerControls(input, controls) {
13878
14743
  ...adapters.value.bootstrap,
13879
14744
  authBaseUrl: resolvedAuthBaseUrl
13880
14745
  }, {
13881
- diagnostic: new ConsoleDiagnosticAdapter(),
14746
+ diagnostic: new EffectLogDiagnosticAdapter(adapters.value.context, new ConsoleDiagnosticAdapter()),
13882
14747
  signUserOpHash: controls.signEmbeddedUserOpHash
13883
14748
  });
13884
14749
  signer = withSignerControl(signer, controls.signUserOpHash);
@@ -14083,5 +14948,27 @@ function idempotentClose(close) {
14083
14948
  await close();
14084
14949
  };
14085
14950
  }
14951
+ /**
14952
+ * Build the Ponder read port for this client, or `undefined` when no indexer
14953
+ * origin was supplied. The token provider is the same
14954
+ * `AuthClientPort.getConvexJwt` closure `ConvexCallPort` uses, so the indexer
14955
+ * and Convex see one session with one scope.
14956
+ */
14957
+ function productionIndexerReadPort(input, ports, observation) {
14958
+ if (input.indexerUrl === void 0 || input.indexerUrl === "") return void 0;
14959
+ return new PonderIndexerAdapter({
14960
+ baseUrl: normalizeHttpUrl("indexerUrl", input.indexerUrl),
14961
+ token: async ({ forceRefreshToken }) => {
14962
+ const token = await Effect.runPromise(Effect.result(ports.authClient.getConvexJwt({
14963
+ forceRefresh: forceRefreshToken,
14964
+ ...input.signal === void 0 ? {} : { signal: input.signal }
14965
+ })));
14966
+ if (Result.isFailure(token)) return null;
14967
+ return String(token.success.token);
14968
+ },
14969
+ ...input.fetch === void 0 ? {} : { fetch: input.fetch },
14970
+ ...observation === void 0 ? {} : { observation }
14971
+ });
14972
+ }
14086
14973
  //#endregion
14087
14974
  export { signerFailure as A, isRestoring as B, normalizeExceptionErrorKind as C, fromWei as D, safeExceptionLabel as E, CAPXUL_OPERATIONS as F, isCapxulOperation as I, normalizeCapxulOperation as L, PAYMENT_DIRECTIONS as M, PAYMENT_STATUSES as N, isSettingUpLifecycle as O, redactTelemetryEvent as P, destination as R, SDK_VERSION$1 as S, projectSdkException as T, fingerprintPaymentIntent as _, smartAccountErrorFromCapxul as a, failureDetail as b, identityErrorFromCapxul as c, embeddedSigner as d, openfortEmbeddedSigner as f, devPrivateKeySigner as g, deriveDevPrivateKey as h, assembleCapxulClient as i, resolveFailureMode as j, injectedWalletSigner as k, convexCallErrorFromCapxul as l, openfortEmbeddedWalletPort as m, createCapxulClientWithSignerControls as n, accountReadErrorFromCapxul as o, openfortEmbeddedSignerFromWallet as p, postHogObservability as r, wireChainId as s, createCapxulClient as t, bootstrapErrorFromCapxul as u, toWei as v, normalizeExceptionOperation as w, EXCEPTION_MESSAGE as x, CAPXUL_SDK_EXPECTED_OUTCOME_EVENT as y, isClaimed as z };