@capxul/sdk 4.2.0-rc.8 → 4.2.0-rc.9

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.
@@ -902,6 +902,7 @@ const COUNTRY_CODE_RE = /^[A-Z]{2}$/;
902
902
  const ACCOUNT_ID_RE = /^account_[0-9A-Za-z]+$/;
903
903
  const PARTY_ID_RE = /^party_[0-9A-Za-z]+$/;
904
904
  const APP_ID_RE = /^app_[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
905
+ const TX_HASH_RE = /^0x[0-9a-f]{64}$/i;
905
906
  const WEI_RE = /^[0-9]+$/;
906
907
  Math.floor(Number.MAX_SAFE_INTEGER / 1e3);
907
908
  function toAddress(raw) {
@@ -957,6 +958,10 @@ function toPublishableKey(raw) {
957
958
  if (typeof raw !== "string" || !PUBLISHABLE_KEY_PATTERN.test(raw)) throw Errors.invalidInput("publishableKey", invalidValueReason("must match cap_pk_(test|live) plus 32 Crockford base32 chars", raw));
958
959
  return raw;
959
960
  }
961
+ function toTxHash(raw) {
962
+ if (typeof raw !== "string" || !TX_HASH_RE.test(raw)) throw Errors.invalidInput("txHash", invalidValueReason("must be 0x + 64 hex chars", raw));
963
+ return raw.toLowerCase();
964
+ }
960
965
  function toEpochMs(raw) {
961
966
  assertSafeNonNegativeInteger(raw, "epochMs");
962
967
  return raw;
@@ -1041,23 +1046,117 @@ function invalidValueReason(prefix, raw) {
1041
1046
  //#region ../config/src/tokens.ts
1042
1047
  /** `TestUSDC` ("USDX") — Base Sepolia, 6 decimals, open `mint`. (Canon §1.) */
1043
1048
  const USDX_ADDRESS_BASE_SEPOLIA = "0xf09fcbb6df9f8f918e58f9c8ab15a76ade862b77";
1049
+ const USDX_DEPLOYMENT_START_BLOCK = 39860173;
1050
+ /**
1051
+ * The ERC-20 `symbol()` the deployed `TestUSDC` contract returns
1052
+ * (`packages/contracts/src/TestUSDC.sol:10`). It travels with the address and
1053
+ * the decimals so a holdings row can never carry one token's address with
1054
+ * another token's display symbol. This is the display symbol, not the
1055
+ * currency: see `USDX_CURRENCY` below.
1056
+ */
1057
+ const USDX_SYMBOL = "USDX";
1058
+ const SYNTHETIC_TEST_ASSET_SOURCE = "synthetic-test-liquidity";
1044
1059
  const USDX_ASSET = {
1045
1060
  assetId: assetIdFor(84532, USDX_ADDRESS_BASE_SEPOLIA),
1046
1061
  chainId: toChainId(84532),
1047
- symbol: "USDX",
1062
+ symbol: USDX_SYMBOL,
1048
1063
  peg: toCurrencyCode("USD"),
1049
1064
  tokenAddress: USDX_ADDRESS_BASE_SEPOLIA,
1050
- deploymentStartBlock: 39860173,
1051
- decimals: 6
1065
+ deploymentStartBlock: USDX_DEPLOYMENT_START_BLOCK,
1066
+ decimals: 6,
1067
+ source: "settlement"
1052
1068
  };
1069
+ /**
1070
+ * The settlement tier: rows the exact-transfer path and the Movement scanner
1071
+ * admit, each carrying the legacy `currency` projection those readers expect.
1072
+ * Adding an owned test asset here would put candidate liquidity on the
1073
+ * money-write path, so M03's rows go to the candidate tier below instead.
1074
+ */
1053
1075
  const CONFIGURED_MONEY_ASSETS = [{
1054
1076
  ...USDX_ASSET,
1055
1077
  currency: USDX_ASSET.peg
1056
1078
  }];
1079
+ /**
1080
+ * The candidate tier: five owned test assets, every field read back from Base
1081
+ * Sepolia after the deployment that created it (chain 84532, blocks
1082
+ * 46,465,978–46,465,982). Real contracts, authored liquidity, no settlement
1083
+ * admission — so rollback is removing consumers, never relabelling a
1084
+ * deployed address or deleting its history.
1085
+ *
1086
+ * `symbol` is the display string the owned contract returns. A
1087
+ * provider-supported USDC would be a different contract at a different
1088
+ * address returning the same symbol, which is why the resolvers below key on
1089
+ * `assetId`, or on chain plus address, and never on a symbol.
1090
+ */
1091
+ const SYNTHETIC_TEST_ASSETS = [
1092
+ {
1093
+ assetId: assetIdFor(84532, "0xb3d8566fb90f7df939f4bc08a09b19047117f549"),
1094
+ chainId: toChainId(84532),
1095
+ tokenAddress: "0xb3d8566fb90f7df939f4bc08a09b19047117f549",
1096
+ symbol: "USDC",
1097
+ decimals: 6,
1098
+ peg: toCurrencyCode("USD"),
1099
+ deploymentStartBlock: 46465978,
1100
+ deploymentTransaction: "0xa7fb8bb9d1fd1cc5fe2fc42fa4cdccace7742efae8ea99f091a283e5709343de",
1101
+ source: SYNTHETIC_TEST_ASSET_SOURCE
1102
+ },
1103
+ {
1104
+ assetId: assetIdFor(84532, "0x7ddcfb6aaffb9908c4c2db308b784c269eec8a01"),
1105
+ chainId: toChainId(84532),
1106
+ tokenAddress: "0x7ddcfb6aaffb9908c4c2db308b784c269eec8a01",
1107
+ symbol: "USDT",
1108
+ decimals: 6,
1109
+ peg: toCurrencyCode("USD"),
1110
+ deploymentStartBlock: 46465979,
1111
+ deploymentTransaction: "0xa17ad76fe8b24cdf1fbcff245c3eb022444710cf9fa7b5ee59818be654f4ae10",
1112
+ source: SYNTHETIC_TEST_ASSET_SOURCE
1113
+ },
1114
+ {
1115
+ assetId: assetIdFor(84532, "0x1d93d525f73453fe18eebf044e8a3954bfe3721e"),
1116
+ chainId: toChainId(84532),
1117
+ tokenAddress: "0x1d93d525f73453fe18eebf044e8a3954bfe3721e",
1118
+ symbol: "WETH",
1119
+ decimals: 18,
1120
+ peg: null,
1121
+ deploymentStartBlock: 46465980,
1122
+ deploymentTransaction: "0xcb9b2d024686fac93ec1243ccf02d3567fd531da46176115660cba2ba644b09d",
1123
+ source: SYNTHETIC_TEST_ASSET_SOURCE
1124
+ },
1125
+ {
1126
+ assetId: assetIdFor(84532, "0x8fe52c70aa9f7b6d74d8bb26eca33d87413cb624"),
1127
+ chainId: toChainId(84532),
1128
+ tokenAddress: "0x8fe52c70aa9f7b6d74d8bb26eca33d87413cb624",
1129
+ symbol: "WBTC",
1130
+ decimals: 8,
1131
+ peg: null,
1132
+ deploymentStartBlock: 46465981,
1133
+ deploymentTransaction: "0x728ba7b430ffd141f83d0ed5ce429d050049d7b097c936fd11e9c572d1243854",
1134
+ source: SYNTHETIC_TEST_ASSET_SOURCE
1135
+ },
1136
+ {
1137
+ assetId: assetIdFor(84532, "0x5865fe9787ac214feb5facaebaec06969ac0a9a3"),
1138
+ chainId: toChainId(84532),
1139
+ tokenAddress: "0x5865fe9787ac214feb5facaebaec06969ac0a9a3",
1140
+ symbol: "cNGN",
1141
+ decimals: 6,
1142
+ peg: toCurrencyCode("NGN"),
1143
+ deploymentStartBlock: 46465982,
1144
+ deploymentTransaction: "0xcedf254bcef57fc64189261a5ab1161bc4fde370e470933f627c4d8ddb5a2e26",
1145
+ source: SYNTHETIC_TEST_ASSET_SOURCE
1146
+ }
1147
+ ];
1148
+ toChainId(84532);
1149
+ /**
1150
+ * Every known asset in ONE identity space. The tiers above declare admission;
1151
+ * this is the only list an identity resolves against, so an asset is never
1152
+ * two different things depending on which list a caller happened to read.
1153
+ */
1154
+ const MONEY_ASSET_REGISTRY = [...CONFIGURED_MONEY_ASSETS, ...SYNTHETIC_TEST_ASSETS];
1057
1155
  CONFIGURED_MONEY_ASSETS.map((asset) => asset.tokenAddress.toLowerCase());
1156
+ /** The registry row for `assetId` across every tier, or `null`. */
1058
1157
  function configuredMoneyAssetById(assetId) {
1059
1158
  const canonical = toAssetId(assetId);
1060
- return CONFIGURED_MONEY_ASSETS.find((asset) => asset.assetId === canonical) ?? null;
1159
+ return MONEY_ASSET_REGISTRY.find((asset) => asset.assetId === canonical) ?? null;
1061
1160
  }
1062
1161
  //#endregion
1063
1162
  //#region ../config/src/org-payments.ts
@@ -2369,4 +2468,4 @@ function readExchange(body) {
2369
2468
  };
2370
2469
  }
2371
2470
  //#endregion
2372
- export { toSessionToken as $, currencySymbolFor as A, toDurationMs as B, ASSET_ID_RE as C, WEI_RE as D, SUPPORTED_CURRENCY_CODES as E, toAuthUserId as F, toJwtToken as G, toEpochMs as H, toBudgetId as I, toPartyId as J, toKycTier as K, toChainId as L, toAddress as M, toAllowedOrigin as N, ZERO_BYTES32 as O, toAppId as P, toRoleKey as Q, toCountryCode as R, APP_ID_RE as S, redactUrlSecrets as St, EVM_ADDRESS_RE as T, toEpochSeconds as U, toEmail as V, toHandle as W, toPayrollRunId as X, toPayrollGroupId as Y, toPublishableKey as Z, normalizeBindingEmail as _, isFailureMode as _t, parseAuthSession as a, CapxulError as at, configuredMoneyAssetById as b, isCredentialField as bt, AuthCachePortTag as c, isCapxulError as ct, authClientPortFromPromiseAdapter as d, boundedResponseHeaders as dt, toTesterKind as et, AuthClientError as f, chainCauseProperties as ft, CAPXUL_PAYMENTS_V2_ADDRESS as g, isChainUpstream as gt, orgRoleKeyForLabel as h, failureFingerprint as ht, BrowserAuthCacheAdapter as i, CAPXUL_ERROR_CODES as it, toAccountId as j, assetIdFor as k, SystemClockLayer as l, CHAIN_UPSTREAMS as lt, ADMIN_ROLE_LABEL as m, decodeChainCause as mt, readClockNow as n, HANDLE_RE as nt, parseCachedJwt as o, EXPECTED_OPERATION_OUTCOMES as ot, AuthClientPortTag as p, chainEvidenceLabel as pt, toOrgId as q, InMemoryAuthCacheAdapter as r, decodeConvexError as rt, AuthCacheError as s, Errors as st, oauthBearerAuthClient as t, validateHandle as tt, ClockPortTag as u, FAILURE_MODES as ut, BASE_SEPOLIA_CHAIN_ID as v, revertSummaryText as vt, BYTES32_RE as w, ACCOUNT_ID_RE as x, redactSecrets as xt, deriveCapxulSafeAddress as y, containsSensitiveMaterial as yt, toCurrencyCode as z };
2471
+ export { toRoleKey as $, currencySymbolFor as A, toCurrencyCode as B, ASSET_ID_RE as C, redactSecrets as Ct, WEI_RE as D, SUPPORTED_CURRENCY_CODES as E, toAssetId as F, toHandle as G, toEmail as H, toAuthUserId as I, toOrgId as J, toJwtToken as K, toBudgetId as L, toAddress as M, toAllowedOrigin as N, ZERO_BYTES32 as O, toAppId as P, toPublishableKey as Q, toChainId as R, APP_ID_RE as S, isCredentialField as St, EVM_ADDRESS_RE as T, toEpochMs as U, toDurationMs as V, toEpochSeconds as W, toPayrollGroupId as X, toPartyId as Y, toPayrollRunId as Z, normalizeBindingEmail as _, failureFingerprint as _t, parseAuthSession as a, decodeConvexError as at, configuredMoneyAssetById as b, revertSummaryText as bt, AuthCachePortTag as c, EXPECTED_OPERATION_OUTCOMES as ct, authClientPortFromPromiseAdapter as d, CHAIN_UPSTREAMS as dt, toSessionToken as et, AuthClientError as f, FAILURE_MODES as ft, CAPXUL_PAYMENTS_V2_ADDRESS as g, decodeChainCause as gt, orgRoleKeyForLabel as h, chainEvidenceLabel as ht, BrowserAuthCacheAdapter as i, HANDLE_RE as it, toAccountId as j, assetIdFor as k, SystemClockLayer as l, Errors as lt, ADMIN_ROLE_LABEL as m, chainCauseProperties as mt, readClockNow as n, toTxHash as nt, parseCachedJwt as o, CAPXUL_ERROR_CODES as ot, AuthClientPortTag as p, boundedResponseHeaders as pt, toKycTier as q, InMemoryAuthCacheAdapter as r, validateHandle as rt, AuthCacheError as s, CapxulError as st, oauthBearerAuthClient as t, toTesterKind as tt, ClockPortTag as u, isCapxulError as ut, BASE_SEPOLIA_CHAIN_ID as v, isChainUpstream as vt, BYTES32_RE as w, redactUrlSecrets as wt, ACCOUNT_ID_RE as x, containsSensitiveMaterial as xt, deriveCapxulSafeAddress as y, isFailureMode as yt, toCountryCode as z };
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "source": {
3
- "commit": "29f8bbef5a60b623572ba982e895a10b47aaba27",
4
- "tree": "9d831c3273591ecc4767094f887088781e786531",
3
+ "commit": "1c96a26356e8f36402e47eb4ac60bb89d6aeed7f",
4
+ "tree": "375f49f76377eeec331fd44ce17238d4a6f02ad4",
5
5
  "branch": "codex/programme-rc",
6
6
  "repository": "https://github.com/Xelmar-tech/infrastructure",
7
7
  "lockfileSha256": "5870f53b72706d103220c1bcf733cb4fb71196aea32a9cfbdc277d73cc959264"
8
8
  },
9
9
  "name": "@capxul/sdk",
10
- "version": "4.2.0-rc.8"
10
+ "version": "4.2.0-rc.9"
11
11
  }
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { $ as PayrollGroupId, B as ChainId, Ct as ChainCause, D as Account, Dt as RevertSummary, E as CAPXUL_PAYMENTS_V2_ADDRESS, Et as FailureMode, F as AssetId, G as EVM_ADDRESS_RE, H as CurrencyCode, I as AuthSession, J as Handle, L as AuthUserId, O as AccountId, P as AssetAmount, St as CHAIN_UPSTREAMS, Tt as FAILURE_MODES, V as CountryCode, X as OrgId, Y as Money, Z as PartyId, _ as Session, _t as CapxulErrorCode, a as Eip1193RequestProvider, at as RoleKey, c as injectedWalletSigner, ct as TesterKind, d as AccountRequirement, dt as toAddress, et as PayrollRunId, f as Eip1193Provider, ft as toCountryCode, g as Profile, gt as CapxulError, h as CapxulResult, ht as CAPXUL_ERROR_CODES, i as CapxulSigner, k as Address, l as AccountProvider, m as localPrivateKeyAccountProvider, mt as toPartyId, o as SignerStatus, p as eip1193AccountProvider, pt as toHandle, r as CapxulDigestSigner, s as SignerStatusStore, u as AccountProviderSource, v as SmartAccount, vt as CapxulErrorDetails, wt as ChainUpstream, xt as isCapxulError, yt as Errors, z as BudgetId } from "./OAuthBearerAuthClient-C-ip-z8M.mjs";
2
- import { $ as OrganizationPaymentBatchInput, $n as RequestStatus, $t as Destination, A as OrgScopedMethods, An as Ref, At as AddressBookAddInput, B as AuthorizeRunOptions, Bn as SmartAccountMethods, Bt as ActivityFilter, C as CurrentUserMethods, Cn as PaymentMoney, Ct as AccountMethods, D as MemberStatus, Dn as PaymentsMethods, Dt as ActorRequest, E as InviteMemberInput, En as PaymentType, Et as ActorRelationshipMethods, F as ResendInviteTokenInput, Fn as AccountLifecycle, Ft as InboxItem, G as PayrollGroupsMethods, Gn as ActorRef, Gt as ActivityPage, H as PayrollGroup, Hn as OrgLifecycle, Ht as ActivityKind, I as RoleDefinition, In as AccountSetupStep, It as InboxMethods, J as PayrollRun, Jn as SubmittedPermissionExecution, Jt as ActivitySummary, K as PayrollMethods, Kn as CurrentHoldings, Kt as ActivityRange, L as RoleSpendCap, Ln as isSettingUpLifecycle, Lt as ActivityAnnotation, M as OrgView, Mn as TargetReference, Mt as AddressBookLabelInput, N as OrganizationAccount, Nn as TargetsMethods, Nt as AddressBookMethods, O as MemberView, On as PaymentsPayInput, Ot as ActorRequestIssueInput, P as OrganizationAuditLogItem, Pn as fingerprintPaymentIntent, Pt as InboxApproveInput, Q as PayrollTermsUnit, Qn as PaymentStatus$1, Qt as DepositInstructions, R as RoleView, Rn as CompleteProfileInput, Rt as ActivityAnnotationInput, S as CurrentUserContext, Sn as PaymentDocumentsMethods, St as ReadyAccountLifecycle, T as DetectPendingOrgInvitationsResult, Tn as PaymentTiming, Tt as ActorProfileMethods, U as PayrollGroupInput, Un as OrgSetupStep, Ut as ActivityListParams, V as PayrollEngagementTerms, Vn as AuthMethods, Vt as ActivityItem, W as PayrollGroupMember, Wn as PayoutAddress, Wt as ActivityMethods, X as PayrollRunStatus, Xn as PAYMENT_DIRECTIONS, Xt as ActivitySummaryTotal, Y as PayrollRunItemInput, Yn as InboxStatus, Yt as ActivitySummaryParams, Z as PayrollRuns, Zn as PAYMENT_STATUSES, Zt as ActorReference, _ as HoldingsMethods, _n as PaymentDirection, _t as OnboardingMethods, a as ObservationContext, an as DestinationRemoveInput, ar as IdentityEvent, at as PermissionCreateInput, b as SystemHealth, bn as PaymentDocumentRender, bt as PersonOnboarding, c as HostObservability, cn as MeMethods, cr as Readiness, ct as PermissionReplaceInput, d as postHogObservability, dn as OfframpMethods, dr as isClaimed, dt as Budget, en as DestinationAddInput, et as OrganizationPaymentInput, f as CapxulClient, fn as OfframpQuote, fr as isRestoring, ft as OrgMe, g as IdentityRuntimeSendResult, gn as PaymentActivityEvidence, gt as CompletedPersonProfile, h as IdentityRuntime, hn as Payment, ht as AccountsMethods, i as ObservationAdapter, in as DestinationRail, ir as Destination$1, it as PermissionChangeInput, j as OrgTemplate, jn as ResolvedTarget, jt as AddressBookEntry, k as OrgMethods, kn as RecipientResolution, kt as ActorRequestsMethods, l as PostHogObservabilityClient, ln as MeProfile, lr as StateLabel, lt as PermissionRevokeInput, m as IdentityProfileDetails, mn as OfframpStatus, mr as InvocationControls, mt as OrgMeOptions, nn as DestinationListInput, nt as OrganizationPaymentsMethods, o as ObservationDelivery, on as DestinationsMethods, or as IdentityState, ot as PermissionMethods, p as CreateCapxulClientInput, pn as OfframpQuoteInput, pr as IdentityTransition, pt as OrgMeMethod, q as PayrollOptions, qn as Permission, qt as ActivityReference, r as CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, rn as DestinationPayload, rr as TelemetryPort, rt as PermissionAssignInput, s as SdkFailureObservation, sn as FinancialOpsMethods, sr as OrgLane, st as PermissionOptions, t as CapxulClientInput, tn as DestinationKind, tt as OrganizationPaymentItemInput, u as PostHogObservabilityOptions, un as MovementActivityEvidence, ur as destination, ut as PermissionReadResult, v as Holding, vn as PaymentDocumentKind, vt as OrganizationOnboarding, w as CreateOrgInput, wn as PaymentStatus, wt as ActorProfile, x as MediaMethods, xn as PaymentDocumentVerification, xt as PersonOnboardingInput, y as SystemMethods, yn as PaymentDocumentRef, yt as OrganizationOnboardingInput, z as AuthorizeRunInput, zn as IdentityMethods, zt as ActivityDetail } from "./production-BOMKT0n7.mjs";
2
+ import { $ as OrganizationPaymentBatchInput, $n as RequestStatus, $t as Destination, A as OrgScopedMethods, An as Ref, At as AddressBookAddInput, B as AuthorizeRunOptions, Bn as SmartAccountMethods, Bt as ActivityFilter, C as CurrentUserMethods, Cn as PaymentMoney, Ct as AccountMethods, D as MemberStatus, Dn as PaymentsMethods, Dt as ActorRequest, E as InviteMemberInput, En as PaymentType, Et as ActorRelationshipMethods, F as ResendInviteTokenInput, Fn as AccountLifecycle, Ft as InboxItem, G as PayrollGroupsMethods, Gn as ActorRef, Gt as ActivityPage, H as PayrollGroup, Hn as OrgLifecycle, Ht as ActivityKind, I as RoleDefinition, In as AccountSetupStep, It as InboxMethods, J as PayrollRun, Jn as SubmittedPermissionExecution, Jt as ActivitySummary, K as PayrollMethods, Kn as CurrentHoldings, Kt as ActivityRange, L as RoleSpendCap, Ln as isSettingUpLifecycle, Lt as ActivityAnnotation, M as OrgView, Mn as TargetReference, Mt as AddressBookLabelInput, N as OrganizationAccount, Nn as TargetsMethods, Nt as AddressBookMethods, O as MemberView, On as PaymentsPayInput, Ot as ActorRequestIssueInput, P as OrganizationAuditLogItem, Pn as fingerprintPaymentIntent, Pt as InboxApproveInput, Q as PayrollTermsUnit, Qn as PaymentStatus$1, Qt as DepositInstructions, R as RoleView, Rn as CompleteProfileInput, Rt as ActivityAnnotationInput, S as CurrentUserContext, Sn as PaymentDocumentsMethods, St as ReadyAccountLifecycle, T as DetectPendingOrgInvitationsResult, Tn as PaymentTiming, Tt as ActorProfileMethods, U as PayrollGroupInput, Un as OrgSetupStep, Ut as ActivityListParams, V as PayrollEngagementTerms, Vn as AuthMethods, Vt as ActivityItem, W as PayrollGroupMember, Wn as PayoutAddress, Wt as ActivityMethods, X as PayrollRunStatus, Xn as PAYMENT_DIRECTIONS, Xt as ActivitySummaryTotal, Y as PayrollRunItemInput, Yn as InboxStatus, Yt as ActivitySummaryParams, Z as PayrollRuns, Zn as PAYMENT_STATUSES, Zt as ActorReference, _ as HoldingsMethods, _n as PaymentDirection, _t as OnboardingMethods, a as ObservationContext, an as DestinationRemoveInput, ar as IdentityEvent, at as PermissionCreateInput, b as SystemHealth, bn as PaymentDocumentRender, bt as PersonOnboarding, c as HostObservability, cn as MeMethods, cr as Readiness, ct as PermissionReplaceInput, d as postHogObservability, dn as OfframpMethods, dr as isClaimed, dt as Budget, en as DestinationAddInput, et as OrganizationPaymentInput, f as CapxulClient, fn as OfframpQuote, fr as isRestoring, ft as OrgMe, g as IdentityRuntimeSendResult, gn as PaymentActivityEvidence, gt as CompletedPersonProfile, h as IdentityRuntime, hn as Payment, ht as AccountsMethods, i as ObservationAdapter, in as DestinationRail, ir as Destination$1, it as PermissionChangeInput, j as OrgTemplate, jn as ResolvedTarget, jt as AddressBookEntry, k as OrgMethods, kn as RecipientResolution, kt as ActorRequestsMethods, l as PostHogObservabilityClient, ln as MeProfile, lr as StateLabel, lt as PermissionRevokeInput, m as IdentityProfileDetails, mn as OfframpStatus, mr as InvocationControls, mt as OrgMeOptions, nn as DestinationListInput, nt as OrganizationPaymentsMethods, o as ObservationDelivery, on as DestinationsMethods, or as IdentityState, ot as PermissionMethods, p as CreateCapxulClientInput, pn as OfframpQuoteInput, pr as IdentityTransition, pt as OrgMeMethod, q as PayrollOptions, qn as Permission, qt as ActivityReference, r as CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, rn as DestinationPayload, rr as TelemetryPort, rt as PermissionAssignInput, s as SdkFailureObservation, sn as FinancialOpsMethods, sr as OrgLane, st as PermissionOptions, t as CapxulClientInput, tn as DestinationKind, tt as OrganizationPaymentItemInput, u as PostHogObservabilityOptions, un as MovementActivityEvidence, ur as destination, ut as PermissionReadResult, v as Holding, vn as PaymentDocumentKind, vt as OrganizationOnboarding, w as CreateOrgInput, wn as PaymentStatus, wt as ActorProfile, x as MediaMethods, xn as PaymentDocumentVerification, xt as PersonOnboardingInput, y as SystemMethods, yn as PaymentDocumentRef, yt as OrganizationOnboardingInput, z as AuthorizeRunInput, zn as IdentityMethods, zt as ActivityDetail } from "./production-Du4Vc7YD.mjs";
3
3
  import { Hex } from "viem";
4
4
  import { Effect, Layer } from "effect";
5
5
  //#region ../errors/src/index.d.ts
@@ -7,6 +7,15 @@ import { Effect, Layer } from "effect";
7
7
  declare const HANDLE_RE: RegExp;
8
8
  //#endregion
9
9
  //#region ../config/src/tokens.d.ts
10
+ /**
11
+ * Where a registry row's liquidity comes from. `settlement` is the tier the
12
+ * exact-transfer path and the Movement scanner read;
13
+ * `synthetic-test-liquidity` marks an owned fixture whose balances and rates
14
+ * are authored inputs, never market or provider data. Every row states its
15
+ * tier, so a row that reaches a caller through the registry always carries
16
+ * that fact with it.
17
+ */
18
+ type AssetSource = "settlement" | "synthetic-test-liquidity";
10
19
  /** Canonical metadata. A missing peg does not imply a missing market price. */
11
20
  interface AssetMetadata {
12
21
  readonly assetId: AssetId;
@@ -16,6 +25,7 @@ interface AssetMetadata {
16
25
  readonly decimals: number;
17
26
  readonly peg: CurrencyCode | null;
18
27
  readonly deploymentStartBlock: number;
28
+ readonly source: AssetSource;
19
29
  }
20
30
  //#endregion
21
31
  //#region ../observability/src/operations.d.ts
@@ -60,6 +70,8 @@ declare const CAPXUL_OPERATIONS: {
60
70
  readonly emitAnnotationSaved: "activity.emitAnnotationSaved";
61
71
  readonly get: "activity.get";
62
72
  readonly list: "activity.list";
73
+ /** The SDK's live Activity read over the indexer's SSE stream. */
74
+ readonly subscribe: "activity.subscribe";
63
75
  readonly summary: "activity.summary";
64
76
  };
65
77
  readonly addressBook: {
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { A as signerFailure, B as isRestoring, C as normalizeExceptionErrorKind, E as safeExceptionLabel, F as CAPXUL_OPERATIONS, I as isCapxulOperation, L as normalizeCapxulOperation, M as PAYMENT_DIRECTIONS, N as PAYMENT_STATUSES, O as isSettingUpLifecycle, R as destination, S as SDK_VERSION, T as projectSdkException, _ as fingerprintPaymentIntent, b as failureDetail, d as embeddedSigner, f as openfortEmbeddedSigner, g as devPrivateKeySigner, h as deriveDevPrivateKey, j as resolveFailureMode, k as injectedWalletSigner, m as openfortEmbeddedWalletPort, p as openfortEmbeddedSignerFromWallet, r as postHogObservability, t as createCapxulClient$1, w as normalizeExceptionOperation, x as EXCEPTION_MESSAGE, y as CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, z as isClaimed } from "./production-Y3yqeOSE.mjs";
2
- import { A as currencySymbolFor, J as toPartyId, M as toAddress, R as toCountryCode, T as EVM_ADDRESS_RE, W as toHandle, at as CapxulError, b as configuredMoneyAssetById, ct as isCapxulError, g as CAPXUL_PAYMENTS_V2_ADDRESS, it as CAPXUL_ERROR_CODES, k as assetIdFor, lt as CHAIN_UPSTREAMS, nt as HANDLE_RE, st as Errors, ut as FAILURE_MODES, z as toCurrencyCode } from "./OAuthBearerAuthClient-hPwtSpEf.mjs";
1
+ import { A as signerFailure, B as isRestoring, C as normalizeExceptionErrorKind, E as safeExceptionLabel, F as CAPXUL_OPERATIONS, I as isCapxulOperation, L as normalizeCapxulOperation, M as PAYMENT_DIRECTIONS, N as PAYMENT_STATUSES, O as isSettingUpLifecycle, R as destination, S as SDK_VERSION, T as projectSdkException, _ as fingerprintPaymentIntent, b as failureDetail, d as embeddedSigner, f as openfortEmbeddedSigner, g as devPrivateKeySigner, h as deriveDevPrivateKey, j as resolveFailureMode, k as injectedWalletSigner, m as openfortEmbeddedWalletPort, p as openfortEmbeddedSignerFromWallet, r as postHogObservability, t as createCapxulClient$1, w as normalizeExceptionOperation, x as EXCEPTION_MESSAGE, y as CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, z as isClaimed } from "./production-216hsAKc.mjs";
2
+ import { A as currencySymbolFor, B as toCurrencyCode, G as toHandle, M as toAddress, T as EVM_ADDRESS_RE, Y as toPartyId, b as configuredMoneyAssetById, dt as CHAIN_UPSTREAMS, ft as FAILURE_MODES, g as CAPXUL_PAYMENTS_V2_ADDRESS, it as HANDLE_RE, k as assetIdFor, lt as Errors, ot as CAPXUL_ERROR_CODES, st as CapxulError, ut as isCapxulError, z as toCountryCode } from "./OAuthBearerAuthClient-IB2W1Fzj.mjs";
3
3
  import { formatUnits } from "viem";
4
4
  import { Effect } from "effect";
5
5
  import { privateKeyToAccount } from "viem/accounts";
@@ -1,4 +1,4 @@
1
- import { M as toAddress, a as parseAuthSession, c as AuthCachePortTag, i as BrowserAuthCacheAdapter, o as parseCachedJwt, r as InMemoryAuthCacheAdapter, s as AuthCacheError, t as oauthBearerAuthClient } from "../OAuthBearerAuthClient-hPwtSpEf.mjs";
1
+ import { M as toAddress, a as parseAuthSession, c as AuthCachePortTag, i as BrowserAuthCacheAdapter, o as parseCachedJwt, r as InMemoryAuthCacheAdapter, s as AuthCacheError, t as oauthBearerAuthClient } from "../OAuthBearerAuthClient-IB2W1Fzj.mjs";
2
2
  import { Effect, FileSystem, Layer, Path } from "effect";
3
3
  import { privateKeyToAccount } from "viem/accounts";
4
4
  import * as os from "node:os";
@@ -1,4 +1,4 @@
1
- import { $ as toSessionToken, B as toDurationMs, C as ASSET_ID_RE, D as WEI_RE, E as SUPPORTED_CURRENCY_CODES, F as toAuthUserId, G as toJwtToken, H as toEpochMs, I as toBudgetId, J as toPartyId, K as toKycTier, L as toChainId, M as toAddress, N as toAllowedOrigin, O as ZERO_BYTES32, Q as toRoleKey, R as toCountryCode, S as APP_ID_RE, St as redactUrlSecrets, T as EVM_ADDRESS_RE$1, U as toEpochSeconds, V as toEmail, W as toHandle, X as toPayrollRunId, Y as toPayrollGroupId, Z as toPublishableKey, _ as normalizeBindingEmail, _t as isFailureMode, at as CapxulError, bt as isCredentialField, c as AuthCachePortTag, ct as isCapxulError, d as authClientPortFromPromiseAdapter, dt as boundedResponseHeaders, et as toTesterKind, f as AuthClientError, ft as chainCauseProperties, gt as isChainUpstream, h as orgRoleKeyForLabel, ht as failureFingerprint, i as BrowserAuthCacheAdapter, it as CAPXUL_ERROR_CODES, j as toAccountId, l as SystemClockLayer, lt as CHAIN_UPSTREAMS, m as ADMIN_ROLE_LABEL, mt as decodeChainCause, ot as EXPECTED_OPERATION_OUTCOMES, p as AuthClientPortTag, pt as chainEvidenceLabel, q as toOrgId, r as InMemoryAuthCacheAdapter, rt as decodeConvexError, st as Errors, tt as validateHandle, u as ClockPortTag, ut as FAILURE_MODES$1, v as BASE_SEPOLIA_CHAIN_ID, vt as revertSummaryText, w as BYTES32_RE, x as ACCOUNT_ID_RE, xt as redactSecrets, y as deriveCapxulSafeAddress, yt as containsSensitiveMaterial, z as toCurrencyCode } from "./OAuthBearerAuthClient-hPwtSpEf.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,
@@ -1396,6 +1409,10 @@ Schema.Struct({
1396
1409
  name: Schema.Literal("auth_failed"),
1397
1410
  props: AuthFailedProps
1398
1411
  });
1412
+ Schema.Struct({
1413
+ name: Schema.Literal("identity_refused"),
1414
+ props: IdentityRefusedProps
1415
+ });
1399
1416
  Schema.Struct({
1400
1417
  name: Schema.Literal("auth_signed_out"),
1401
1418
  props: AuthSignedOutProps
@@ -2214,6 +2231,8 @@ const BootstrapEnvelope = Schema.Struct({
2214
2231
  shieldPublishableKey: Schema.String,
2215
2232
  /** Which Openfort third-party auth provider the signer presents; absent means better-auth. */
2216
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),
2217
2236
  engineeringTelemetry: Schema.optional(EngineeringTelemetryBootstrapPolicy)
2218
2237
  })
2219
2238
  });
@@ -2288,6 +2307,7 @@ const CAPXUL_FUNCTIONS = {
2288
2307
  prepareOrganizationPaymentExecution: "moneyExecution/paymentCommandActions:prepareOrganizationPaymentExecution",
2289
2308
  submitPaymentCommandExecution: "moneyExecution/paymentCommandActions:submitPaymentCommandExecution"
2290
2309
  },
2310
+ "moneyExecution/providerSendWitness": { read: "moneyExecution/providerSendWitness:read" },
2291
2311
  media: {
2292
2312
  generateUploadUrl: "media:generateUploadUrl",
2293
2313
  setOrgLogo: "media:setOrgLogo",
@@ -2347,6 +2367,11 @@ const CAPXUL_FUNCTIONS = {
2347
2367
  loadByAuthUserId: "smartAccount/queries:loadByAuthUserId",
2348
2368
  loadBySmartAccountAddress: "smartAccount/queries:loadBySmartAccountAddress"
2349
2369
  },
2370
+ e2eControls: {
2371
+ holdUserOperationReceipt: "e2eControls:holdUserOperationReceipt",
2372
+ isUserOperationReceiptHeld: "e2eControls:isUserOperationReceiptHeld",
2373
+ releaseUserOperationReceipt: "e2eControls:releaseUserOperationReceipt"
2374
+ },
2350
2375
  system: { health: "system:health" }
2351
2376
  };
2352
2377
  //#endregion
@@ -5658,7 +5683,7 @@ const moneyExecutionContract = {
5658
5683
  };
5659
5684
  //#endregion
5660
5685
  //#region package.json
5661
- var version = "4.2.0-rc.8";
5686
+ var version = "4.2.0-rc.9";
5662
5687
  //#endregion
5663
5688
  //#region src/telemetry/exception-projection.ts
5664
5689
  /** Fixed fallback for failures that have no safe message. */
@@ -5851,6 +5876,17 @@ function observeFailedResult(result, adapter, operation, origin) {
5851
5876
  return result;
5852
5877
  }
5853
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
+ /**
5854
5890
  * One failure, one event. The identity machine reports a failed transition
5855
5891
  * first; when the same `CapxulError` then surfaces as a public method result
5856
5892
  * (directly or down its `cause` chain), the boundary drops that second report.
@@ -8674,7 +8710,7 @@ function isTransientBootstrapFailure(error) {
8674
8710
  const status = error.details?.httpStatus;
8675
8711
  return typeof status === "number" && isTransientHttpStatus(status);
8676
8712
  }
8677
- async function safeText(res) {
8713
+ async function safeText$1(res) {
8678
8714
  try {
8679
8715
  return await res.text();
8680
8716
  } catch {
@@ -8748,6 +8784,7 @@ var HttpBootstrapAdapter = class {
8748
8784
  openfortPublishableKey: decodedState.openfortPublishableKey,
8749
8785
  shieldPublishableKey: decodedState.shieldPublishableKey,
8750
8786
  ...decodedState.openfortAuthProvider === void 0 ? {} : { openfortAuthProvider: decodedState.openfortAuthProvider },
8787
+ ...decodedState.indexerUrl === void 0 ? {} : { indexerUrl: decodedState.indexerUrl },
8751
8788
  ...decodedEngineeringTelemetry !== void 0 && Result.isSuccess(decodedEngineeringTelemetry) ? { engineeringTelemetry: decodedEngineeringTelemetry.success } : {}
8752
8789
  };
8753
8790
  },
@@ -8756,7 +8793,7 @@ var HttpBootstrapAdapter = class {
8756
8793
  return bootstrapErrorFromCapxul("malformedBody", Errors.providerError("convex", "bootstrap", cause instanceof Error ? cause : new Error(String(cause))));
8757
8794
  }
8758
8795
  });
8759
- return Effect.promise(() => safeText(res)).pipe(Effect.flatMap((body) => {
8796
+ return Effect.promise(() => safeText$1(res)).pipe(Effect.flatMap((body) => {
8760
8797
  if (res.status === 401 || body.startsWith("NOT_AUTHENTICATED")) return Effect.fail(bootstrapErrorFromCapxul("notAuthenticated", Errors.notAuthenticated()));
8761
8798
  if (res.status === 400 || body.startsWith("INVALID_INPUT")) return Effect.fail(bootstrapErrorFromCapxul("invalidInput", Errors.invalidInput("publishableKey", "rejected by bootstrap")));
8762
8799
  const responseBody = body.slice(0, 300);
@@ -8986,6 +9023,12 @@ function makeConnectionId() {
8986
9023
  }
8987
9024
  //#endregion
8988
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;
8989
9032
  /** Exact floor-first allowlist; every additional handler must migrate its validator first. */
8990
9033
  const OBSERVED_CONVEX_ACTIONS = /* @__PURE__ */ new Set([
8991
9034
  "payroll/actions:authorizeRun",
@@ -9054,7 +9097,9 @@ var ConvexCallAdapter = class {
9054
9097
  #applicationId;
9055
9098
  #observation;
9056
9099
  #connectionMonitor;
9100
+ #closeTimeoutMs;
9057
9101
  constructor(deps) {
9102
+ this.#closeTimeoutMs = deps.closeTimeoutMs ?? DEFAULT_CLOSE_TIMEOUT_MS;
9058
9103
  this.#connectionMonitor = new ConvexConnectionMonitor();
9059
9104
  const webSocketConstructor = this.#connectionMonitor.observedWebSocketConstructor();
9060
9105
  this.#client = deps.client ?? new ConvexClient(deps.convexUrl, webSocketConstructor === void 0 ? {} : { webSocketConstructor });
@@ -9153,11 +9198,33 @@ var ConvexCallAdapter = class {
9153
9198
  callback({ status: "loading" });
9154
9199
  })));
9155
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
+ */
9156
9213
  async close() {
9157
9214
  this.#connectionMonitor.close();
9158
- await this.#client.close();
9215
+ await settledWithin(this.#client.close(), this.#closeTimeoutMs);
9159
9216
  }
9160
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
+ }
9161
9228
  function ConvexCallLayer(deps) {
9162
9229
  return Layer.effect(ConvexCallPortTag, Effect.acquireRelease(Effect.sync(() => new ConvexCallAdapter(deps)), (adapter) => Effect.promise(() => adapter.close()).pipe(Effect.orDie)));
9163
9230
  }
@@ -13338,11 +13405,28 @@ const authFailure = (record, reason, mode) => ({
13338
13405
  ...linkage(record)
13339
13406
  }
13340
13407
  });
13408
+ const REFUSAL_EVENTS = /* @__PURE__ */ new Set([
13409
+ "ClaimAccount",
13410
+ "RetryAccount",
13411
+ "CreateOrganization",
13412
+ "AttachOrganization",
13413
+ "RetryOrganization"
13414
+ ]);
13341
13415
  function mapIdentityProductObservation(record, state) {
13342
13416
  if (record.machine !== "identity" || !IDENTITY_EVENT_TAG_SET.has(record.event)) return NONE;
13343
13417
  if (record.outcome === "cancelled") return NONE;
13344
13418
  if (record.slot === "identity:auth" && record.outcome === "refused") return authFailure(record, record.refusal_code, void 0);
13345
13419
  if (record.slot === "identity:auth" && record.outcome === "failed") return authFailure(record, record.error_code, record.failure?.mode);
13420
+ if (record.outcome === "refused" && REFUSAL_EVENTS.has(record.event)) return {
13421
+ name: "identity_refused",
13422
+ props: {
13423
+ event: record.event,
13424
+ refusal_code: record.refusal_code,
13425
+ slot: record.slot,
13426
+ state: record.state,
13427
+ ...linkage(record)
13428
+ }
13429
+ };
13346
13430
  if (record.outcome !== "applied") return NONE;
13347
13431
  switch (APPLIED_ACTION_BY_EVENT[record.event]) {
13348
13432
  case "none": return NONE;
@@ -13668,6 +13752,7 @@ function assembleCapxulClient(input) {
13668
13752
  identity: identityRuntime,
13669
13753
  bootstrap: input.bootstrap,
13670
13754
  accounts: { fund: accounts.fund },
13755
+ ...input.ports.indexerRead === void 0 ? {} : { indexer: input.ports.indexerRead },
13671
13756
  organizationSetup: { getProofReceipt: (orgId) => runPortEffect(input.ports.convexCall.query(organizationSetupProofReceiptQuery, { orgId })) },
13672
13757
  telemetry: input.ports.telemetry,
13673
13758
  captureExternalAddressAcknowledged: (address, organizationId) => {
@@ -13869,6 +13954,382 @@ function snapshotHostObservability(observability) {
13869
13954
  function isPromiseLike(value) {
13870
13955
  return (typeof value === "object" && value !== null || typeof value === "function") && "then" in value;
13871
13956
  }
13957
+ //#endregion
13958
+ //#region src/ports/indexer-read.ts
13959
+ /** The indexer's own page bound. Exceeding it is a caller defect, not a refusal. */
13960
+ const INDEXER_MAX_LIMIT = 1e3;
13961
+ const LOWER_CASE_ADDRESS = /^0x[0-9a-f]{40}$/;
13962
+ /**
13963
+ * Refuse a page the indexer would refuse, before any implementation spends a
13964
+ * round trip on it. Every implementation calls this, so a consumer test written
13965
+ * against the hermetic adapter cannot pass on input production rejects. Throws
13966
+ * a `CapxulError`; callers convert it to an `IndexerReadError`.
13967
+ */
13968
+ function assertIndexerPage(input) {
13969
+ const safe = String(input.safe).toLowerCase();
13970
+ if (!LOWER_CASE_ADDRESS.test(safe)) throw Errors.invalidInput("safe", "must be a lower-case EVM address");
13971
+ 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}`);
13972
+ const offset = input.offset ?? 0;
13973
+ if (!Number.isSafeInteger(offset) || offset < 0) throw Errors.invalidInput("offset", "must be a non-negative integer");
13974
+ return safe;
13975
+ }
13976
+ var IndexerReadError = class extends Data.TaggedError("IndexerReadError") {};
13977
+ function indexerReadErrorFromCapxul(operation, error, cause = error) {
13978
+ return new IndexerReadError({
13979
+ operation,
13980
+ publicCode: error.code,
13981
+ publicError: error,
13982
+ cause,
13983
+ ...error.details === void 0 ? {} : { details: error.details }
13984
+ });
13985
+ }
13986
+ Context.Service()("@capxul/sdk/ports/IndexerReadPort");
13987
+ //#endregion
13988
+ //#region src/adapters/ponder/decode.ts
13989
+ /**
13990
+ * Decode the indexer's rows at the trust boundary.
13991
+ *
13992
+ * Ponder returns the raw PostgreSQL result: `integer` arrives as a number,
13993
+ * `numeric(78)` and `text` arrive as strings. Amounts, block numbers and
13994
+ * timestamps are `numeric(78)`, so they become `bigint` here and never pass
13995
+ * through `Number`. Every decoder throws a `CapxulError`; the adapter turns
13996
+ * that into a typed `IndexerReadError`.
13997
+ */
13998
+ const HEX = /^0x[0-9a-fA-F]+$/;
13999
+ function field(row, key) {
14000
+ if (!(key in row)) throw Errors.invalidInput(key, "missing from the indexer row");
14001
+ return row[key];
14002
+ }
14003
+ function text(row, key) {
14004
+ const value = field(row, key);
14005
+ if (typeof value !== "string") throw Errors.invalidInput(key, "must be a string");
14006
+ return value;
14007
+ }
14008
+ function hex(row, key) {
14009
+ const value = text(row, key);
14010
+ if (!HEX.test(value)) throw Errors.invalidInput(key, "must be a hex string");
14011
+ return value.toLowerCase();
14012
+ }
14013
+ function integer(row, key) {
14014
+ const value = field(row, key);
14015
+ const parsed = typeof value === "string" ? Number(value) : value;
14016
+ if (typeof parsed !== "number" || !Number.isSafeInteger(parsed)) throw Errors.invalidInput(key, "must be an integer");
14017
+ return parsed;
14018
+ }
14019
+ /** `numeric(78)` crosses the wire as a decimal string; keep every digit. */
14020
+ function big(row, key) {
14021
+ const value = field(row, key);
14022
+ if (typeof value === "bigint") return value;
14023
+ const raw = typeof value === "number" ? String(value) : value;
14024
+ if (typeof raw !== "string" || !/^-?[0-9]+$/.test(raw)) throw Errors.invalidInput(key, "must be an exact integer amount");
14025
+ return BigInt(raw);
14026
+ }
14027
+ function asRow(value) {
14028
+ if (typeof value !== "object" || value === null || Array.isArray(value)) throw Errors.invalidInput("row", "must be an object");
14029
+ return value;
14030
+ }
14031
+ function identity(row) {
14032
+ return {
14033
+ id: text(row, "id"),
14034
+ chainId: toChainId(integer(row, "chain_id")),
14035
+ txHash: toTxHash(hex(row, "tx_hash")),
14036
+ transactionLogOrdinal: integer(row, "transaction_log_ordinal"),
14037
+ blockNumber: big(row, "block_number"),
14038
+ blockHash: hex(row, "block_hash"),
14039
+ timestamp: big(row, "timestamp")
14040
+ };
14041
+ }
14042
+ function decodeTransfer(value) {
14043
+ const row = asRow(value);
14044
+ return {
14045
+ ...identity(row),
14046
+ assetId: toAssetId(text(row, "asset_id")),
14047
+ token: toAddress(hex(row, "token")),
14048
+ from: toAddress(hex(row, "from")),
14049
+ to: toAddress(hex(row, "to")),
14050
+ amount: big(row, "amount")
14051
+ };
14052
+ }
14053
+ function decodePayment(value) {
14054
+ const row = asRow(value);
14055
+ return {
14056
+ ...identity(row),
14057
+ contract: toAddress(hex(row, "contract")),
14058
+ settlementId: hex(row, "settlement_id"),
14059
+ sender: toAddress(hex(row, "sender")),
14060
+ recipient: toAddress(hex(row, "recipient")),
14061
+ assetId: toAssetId(text(row, "asset_id")),
14062
+ token: toAddress(hex(row, "token")),
14063
+ amount: big(row, "amount"),
14064
+ kind: integer(row, "kind"),
14065
+ documentHash: hex(row, "document_hash")
14066
+ };
14067
+ }
14068
+ /** The `balance` view exposes the signed sum under the underlying column name `to`. */
14069
+ function decodeBalance(value) {
14070
+ const row = asRow(value);
14071
+ return {
14072
+ chainId: toChainId(integer(row, "chain_id")),
14073
+ assetId: toAssetId(text(row, "asset_id")),
14074
+ address: toAddress(hex(row, "to")),
14075
+ amount: big(row, "amount")
14076
+ };
14077
+ }
14078
+ const DECODERS = {
14079
+ transfer: decodeTransfer,
14080
+ payment: decodePayment,
14081
+ balance: decodeBalance
14082
+ };
14083
+ /** Decode one `/sql/db` or `/sql/live` payload. Ponder returns `{ rows: [...] }`. */
14084
+ function decodeRows(table, body) {
14085
+ const rows = asRow(body).rows;
14086
+ if (!Array.isArray(rows)) throw Errors.invalidInput("rows", "must be an array");
14087
+ const decode = DECODERS[table];
14088
+ return rows.map(decode);
14089
+ }
14090
+ /** Decode Ponder's native `/status`: `{ [chainName]: { id, block: { number, timestamp } } }`. */
14091
+ function decodeStatus(body) {
14092
+ const chains = asRow(body);
14093
+ return Object.entries(chains).map(([chain, value]) => {
14094
+ const entry = asRow(value);
14095
+ const block = asRow(field(entry, "block"));
14096
+ return {
14097
+ chain,
14098
+ chainId: toChainId(integer(entry, "id")),
14099
+ blockNumber: big(block, "number"),
14100
+ blockTimestamp: big(block, "timestamp")
14101
+ };
14102
+ });
14103
+ }
14104
+ //#endregion
14105
+ //#region src/adapters/ponder/statements.ts
14106
+ /**
14107
+ * The exact statements the indexer accepts.
14108
+ *
14109
+ * `apps/indexer/src/queries.ts` compiles its allowlist with `@ponder/client`
14110
+ * and compares `sql`, `params` and `typings` byte for byte against the caller's
14111
+ * statement. Anything else gets 403. The SDK therefore reproduces the compiled
14112
+ * text here rather than pulling Ponder and Drizzle into a published browser
14113
+ * bundle to regenerate three fixed statements.
14114
+ *
14115
+ * `statements.test.ts` pins the text. When the indexer schema or a query in
14116
+ * that allowlist changes, this file changes with it or every read fails 403.
14117
+ */
14118
+ const HEADS = {
14119
+ 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",
14120
+ 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",
14121
+ balance: "select \"chain_id\", \"asset_id\", \"to\", \"amount\" from \"balance\" where \"balance\".\"to\" = $1"
14122
+ };
14123
+ /** How many times the statement binds the Safe address. */
14124
+ const ACTOR_PARAMS = {
14125
+ transfer: 2,
14126
+ payment: 2,
14127
+ balance: 1
14128
+ };
14129
+ /**
14130
+ * Build the compiled query for one table and page. Throws a `CapxulError` for
14131
+ * a page or address the indexer would refuse, so the caller never spends a
14132
+ * round trip to learn it built the request wrong.
14133
+ */
14134
+ function ponderQuery(table, input) {
14135
+ const safe = assertIndexerPage(input);
14136
+ const offset = input.offset ?? 0;
14137
+ const actors = ACTOR_PARAMS[table];
14138
+ const params = [];
14139
+ for (let i = 0; i < actors; i++) params.push(safe);
14140
+ params.push(input.limit);
14141
+ let sql = `${HEADS[table]} limit $${actors + 1}`;
14142
+ if (offset > 0) {
14143
+ params.push(offset);
14144
+ sql = `${sql} offset $${actors + 2}`;
14145
+ }
14146
+ return {
14147
+ sql,
14148
+ params,
14149
+ typings: params.map(() => "none")
14150
+ };
14151
+ }
14152
+ /**
14153
+ * The `?sql=` value. `@ponder/client` sends `superjson.stringify(query)`; for a
14154
+ * payload of strings and numbers superjson emits no `meta`, so the wire form is
14155
+ * exactly this envelope.
14156
+ */
14157
+ function ponderQueryParam(query) {
14158
+ return JSON.stringify({ json: query });
14159
+ }
14160
+ //#endregion
14161
+ //#region src/adapters/ponder/sse.ts
14162
+ /**
14163
+ * The smallest SSE reader that can carry an `Authorization` header.
14164
+ *
14165
+ * `@ponder/client` opens its live query with `EventSource`, which accepts no
14166
+ * headers, so it cannot reach the guarded indexer at all. The indexer's CORS
14167
+ * policy allows exactly one request header (`Authorization`), so this reader
14168
+ * sends nothing else. Ponder writes one `data:` line per frame.
14169
+ */
14170
+ async function readEventStream(body, onData, stopped) {
14171
+ const reader = body.getReader();
14172
+ const decoder = new TextDecoder();
14173
+ let buffer = "";
14174
+ try {
14175
+ for (;;) {
14176
+ const { done, value } = await reader.read();
14177
+ if (done || stopped()) return;
14178
+ buffer += decoder.decode(value, { stream: true });
14179
+ let split = buffer.indexOf("\n\n");
14180
+ while (split !== -1) {
14181
+ const frame = buffer.slice(0, split);
14182
+ buffer = buffer.slice(split + 2);
14183
+ const data = frameData(frame);
14184
+ if (data !== void 0) onData(data);
14185
+ if (stopped()) return;
14186
+ split = buffer.indexOf("\n\n");
14187
+ }
14188
+ }
14189
+ } finally {
14190
+ await reader.cancel().catch(() => void 0);
14191
+ }
14192
+ }
14193
+ function frameData(frame) {
14194
+ const lines = [];
14195
+ for (const line of frame.split("\n")) {
14196
+ if (!line.startsWith("data:")) continue;
14197
+ lines.push(line.slice(line.startsWith("data: ") ? 6 : 5));
14198
+ }
14199
+ return lines.length === 0 ? void 0 : lines.join("\n");
14200
+ }
14201
+ //#endregion
14202
+ //#region src/adapters/ponder/PonderIndexerAdapter.ts
14203
+ var PonderIndexerAdapter = class {
14204
+ #baseUrl;
14205
+ #token;
14206
+ #fetch;
14207
+ #observation;
14208
+ constructor(deps) {
14209
+ this.#baseUrl = deps.baseUrl.replace(/\/$/, "");
14210
+ this.#token = deps.token;
14211
+ this.#observation = deps.observation;
14212
+ this.#fetch = deps.fetch ?? ((input, init) => globalThis.fetch(input, init));
14213
+ }
14214
+ read(table, input) {
14215
+ const operation = `indexer.read.${table}`;
14216
+ return Effect.tryPromise({
14217
+ try: async () => {
14218
+ return decodeRows(table, await (await this.#request("db", table, input, operation)).json());
14219
+ },
14220
+ catch: (cause) => toIndexerReadError(operation, cause)
14221
+ });
14222
+ }
14223
+ subscribe(table, input, callback) {
14224
+ const operation = CAPXUL_OPERATIONS.activity.subscribe;
14225
+ return Effect.sync(() => {
14226
+ let stopped = false;
14227
+ const unsubscribe = () => {
14228
+ stopped = true;
14229
+ };
14230
+ callback({ status: "loading" });
14231
+ this.#stream(table, input, operation, callback, () => stopped).catch(() => void 0);
14232
+ return unsubscribe;
14233
+ });
14234
+ }
14235
+ status = Effect.tryPromise({
14236
+ try: async () => {
14237
+ const response = await this.#fetch(`${this.#baseUrl}/status`, { method: "GET" });
14238
+ if (!response.ok) throw httpError("indexer.status", response.status, await safeText(response));
14239
+ return decodeStatus(await response.json());
14240
+ },
14241
+ catch: (cause) => toIndexerReadError("indexer.status", cause)
14242
+ });
14243
+ /** One authenticated `/sql/:method` call. Throws a `CapxulError` on refusal. */
14244
+ async #request(method, table, input, operation) {
14245
+ const query = ponderQuery(table, input);
14246
+ const token = await this.#token({ forceRefreshToken: false });
14247
+ if (token === null || token === "") throw Errors.notAuthenticated();
14248
+ const url = `${this.#baseUrl}/sql/${method}?sql=${encodeURIComponent(ponderQueryParam(query))}`;
14249
+ const headers = { authorization: `Bearer ${token}` };
14250
+ if (method === "live") headers.accept = "text/event-stream";
14251
+ let response;
14252
+ try {
14253
+ response = await this.#fetch(url, {
14254
+ method: "GET",
14255
+ headers
14256
+ });
14257
+ } catch (cause) {
14258
+ throw Errors.networkError(operation, cause, {
14259
+ provider: "indexer",
14260
+ failure_mode: "upstream-down"
14261
+ });
14262
+ }
14263
+ if (!response.ok) throw httpError(operation, response.status, await safeText(response));
14264
+ return response;
14265
+ }
14266
+ /**
14267
+ * Follow the live stream until the caller unsubscribes or the indexer closes
14268
+ * it. The indexer closes the stream on token expiry or revoked authority
14269
+ * with no frame, so any end the caller did not ask for is a teardown: it
14270
+ * reaches `captureException` under `activity.subscribe` and the caller sees
14271
+ * one `error` snapshot.
14272
+ */
14273
+ async #stream(table, input, operation, callback, stopped) {
14274
+ let failure;
14275
+ try {
14276
+ const response = await this.#request("live", table, input, operation);
14277
+ if (response.body === null) throw Errors.providerError("indexer", operation, "empty stream");
14278
+ await readEventStream(response.body, (data) => {
14279
+ try {
14280
+ callback({
14281
+ status: "ok",
14282
+ value: decodeRows(table, JSON.parse(data))
14283
+ });
14284
+ } catch (cause) {
14285
+ failure = toPublicError$1(operation, cause);
14286
+ }
14287
+ }, () => stopped() || failure !== void 0);
14288
+ } catch (cause) {
14289
+ failure = toPublicError$1(operation, cause);
14290
+ }
14291
+ if (stopped()) return;
14292
+ const error = failure ?? Errors.capabilityUnavailable("indexer", operation);
14293
+ observeStreamFailure(this.#observation, CAPXUL_OPERATIONS.activity.subscribe, error);
14294
+ callback({
14295
+ status: "error",
14296
+ error
14297
+ });
14298
+ }
14299
+ };
14300
+ /**
14301
+ * Map an indexer refusal into the shared error vocabulary.
14302
+ *
14303
+ * 401 is the expected outcome of an expired or revoked session. 403 is not:
14304
+ * the indexer accepts only its own compiled statements for a Safe in the
14305
+ * claim, so a refusal means this SDK and that deployment disagree, or the
14306
+ * session gained a Safe and still holds the older token. Both must be loud.
14307
+ */
14308
+ function httpError(operation, status, body) {
14309
+ if (status === 401) return Errors.notAuthenticated();
14310
+ if (status === 429) return Errors.rateLimited({ resource: "indexer" });
14311
+ if (status === 503) return Errors.capabilityUnavailable("indexer", operation);
14312
+ return Errors.providerError("indexer", operation, body, {
14313
+ httpStatus: status,
14314
+ ...status >= 500 ? { failure_mode: "upstream-down" } : {},
14315
+ details: { reason: status === 403 ? "scope-refused" : "http-status" }
14316
+ });
14317
+ }
14318
+ function toPublicError$1(operation, cause) {
14319
+ if (cause instanceof CapxulError) return cause;
14320
+ return Errors.providerError("indexer", operation, cause);
14321
+ }
14322
+ function toIndexerReadError(operation, cause) {
14323
+ if (cause instanceof IndexerReadError) return cause;
14324
+ return indexerReadErrorFromCapxul(operation, toPublicError$1(operation, cause), cause);
14325
+ }
14326
+ async function safeText(response) {
14327
+ try {
14328
+ return await response.text();
14329
+ } catch {
14330
+ return "";
14331
+ }
14332
+ }
13872
14333
  const SDK_VERSION = version;
13873
14334
  /**
13874
14335
  * Project the built graph into the flat `FlowPorts` record the method bundles
@@ -14118,7 +14579,16 @@ async function createProductionAdapters(input) {
14118
14579
  }));
14119
14580
  const applicationLayer = Layer.merge(portsLayer, optionalEngineeringTelemetryLayer(bootstrapResult.value.engineeringTelemetry, resolvedInput.value.runtime));
14120
14581
  const context = await Effect.runPromise(Layer.buildWithScope(applicationLayer, scope));
14121
- const ports = await Effect.runPromise(collectProductionFlowPorts.pipe(Effect.provide(context)));
14582
+ const collected = await Effect.runPromise(collectProductionFlowPorts.pipe(Effect.provide(context)));
14583
+ const indexerUrl = input.indexerUrl ?? bootstrapResult.value.indexerUrl;
14584
+ const indexerRead = productionIndexerReadPort(indexerUrl === void 0 ? input : {
14585
+ ...input,
14586
+ indexerUrl
14587
+ }, collected, observation);
14588
+ const ports = indexerRead === void 0 ? collected : {
14589
+ ...collected,
14590
+ indexerRead
14591
+ };
14122
14592
  const stopConnectionObservation = observeProductionConvexConnection(ports.convexCall, context);
14123
14593
  const close = idempotentClose(async () => {
14124
14594
  try {
@@ -14450,5 +14920,27 @@ function idempotentClose(close) {
14450
14920
  await close();
14451
14921
  };
14452
14922
  }
14923
+ /**
14924
+ * Build the Ponder read port for this client, or `undefined` when no indexer
14925
+ * origin was supplied. The token provider is the same
14926
+ * `AuthClientPort.getConvexJwt` closure `ConvexCallPort` uses, so the indexer
14927
+ * and Convex see one session with one scope.
14928
+ */
14929
+ function productionIndexerReadPort(input, ports, observation) {
14930
+ if (input.indexerUrl === void 0 || input.indexerUrl === "") return void 0;
14931
+ return new PonderIndexerAdapter({
14932
+ baseUrl: normalizeHttpUrl("indexerUrl", input.indexerUrl),
14933
+ token: async ({ forceRefreshToken }) => {
14934
+ const token = await Effect.runPromise(Effect.result(ports.authClient.getConvexJwt({
14935
+ forceRefresh: forceRefreshToken,
14936
+ ...input.signal === void 0 ? {} : { signal: input.signal }
14937
+ })));
14938
+ if (Result.isFailure(token)) return null;
14939
+ return String(token.success.token);
14940
+ },
14941
+ ...input.fetch === void 0 ? {} : { fetch: input.fetch },
14942
+ ...observation === void 0 ? {} : { observation }
14943
+ });
14944
+ }
14453
14945
  //#endregion
14454
14946
  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 };
@@ -1,4 +1,4 @@
1
- import { $ as PayrollGroupId, A as AllowanceKey, B as ChainId, C as AuthCachePort, D as Account$1, Et as FailureMode, H as CurrencyCode, I as AuthSession, K as Email, L as AuthUserId, M as AnonymousDistinctId, N as AppId, Q as PaymentCommandId, R as BlockNumber, U as DocumentHash, V as CountryCode, W as DurationMs, X as OrgId, Y as Money, Z as PartyId, _ as Session$1, _t as CapxulErrorCode, at as RoleKey, b as AuthClientPort, bt as Failure, ct as TesterKind, d as AccountRequirement, et as PayrollRunId, g as Profile$1, gt as CapxulError, h as CapxulResult, i as CapxulSigner, it as PublishableKey, j as AllowedOrigin, k as Address$1, lt as TxHash, nt as PermissionId, ot as SessionToken, q as EpochMs, rt as Profile, s as SignerStatusStore, st as SmartAccount, tt as PermissionAssignmentId, u as AccountProviderSource, ut as WeiAmount, v as SmartAccount$1, vt as CapxulErrorDetails, x as CanSendOtpStatus, y as ClockPort, z as BudgetId } from "./OAuthBearerAuthClient-C-ip-z8M.mjs";
1
+ import { $ as PayrollGroupId, A as AllowanceKey, B as ChainId, C as AuthCachePort, D as Account$1, Et as FailureMode, F as AssetId, H as CurrencyCode, I as AuthSession, K as Email, L as AuthUserId, M as AnonymousDistinctId, N as AppId, Q as PaymentCommandId, R as BlockNumber, U as DocumentHash, V as CountryCode, W as DurationMs, X as OrgId, Y as Money, Z as PartyId, _ as Session$1, _t as CapxulErrorCode, at as RoleKey, b as AuthClientPort, bt as Failure, ct as TesterKind, d as AccountRequirement, et as PayrollRunId, g as Profile$1, gt as CapxulError, h as CapxulResult, i as CapxulSigner, it as PublishableKey, j as AllowedOrigin, k as Address$1, lt as TxHash, nt as PermissionId, ot as SessionToken, q as EpochMs, rt as Profile, s as SignerStatusStore, st as SmartAccount, tt as PermissionAssignmentId, u as AccountProviderSource, ut as WeiAmount, v as SmartAccount$1, vt as CapxulErrorDetails, x as CanSendOtpStatus, y as ClockPort, z as BudgetId } from "./OAuthBearerAuthClient-C-ip-z8M.mjs";
2
2
  import { Hex } from "viem";
3
3
  import { Context, Effect, Layer, Schema, Scope, Tracer } from "effect";
4
4
  import { FunctionReference } from "convex/server";
@@ -284,7 +284,7 @@ interface TelemetryPort {
284
284
  }
285
285
  //#endregion
286
286
  //#region ../observability/src/index.d.ts
287
- 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", "chain_upstream_fallback", "bundler_error", "receipt_pending", "operation_retried", "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", "payment_verification_retry", "payment_lifecycle_transition", "quick_pay_external_address_acknowledged", "deposit_initiated", "deposit_settled", "permission_mirror_verification", "movement_scan_window", "movement_scan_checkpoint", "movement_scan_incident", "activity_annotation_saved", "ui_activity_action_completed", "contact_relationship_changed", "ui_contact_action_completed", "access_recovery_completed", "ui_access_step_completed", "org_invite_progressed", "invoice_issued", "invoice_request_transitioned", "ui_invoice_step_completed", "ui_treasury_step_completed", "ui_receive_step_completed", "payroll_group_changed", "payroll_run_transitioned", "ui_payroll_action_completed"];
287
+ declare const TELEMETRY_EVENT_NAMES: readonly ["auth_otp_requested", "auth_otp_delivered", "auth_otp_expired", "auth_verified", "auth_failed", "identity_refused", "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", "chain_upstream_fallback", "bundler_error", "receipt_pending", "operation_retried", "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", "payment_verification_retry", "payment_lifecycle_transition", "quick_pay_external_address_acknowledged", "deposit_initiated", "deposit_settled", "permission_mirror_verification", "movement_scan_window", "movement_scan_checkpoint", "movement_scan_incident", "activity_annotation_saved", "ui_activity_action_completed", "contact_relationship_changed", "ui_contact_action_completed", "access_recovery_completed", "ui_access_step_completed", "org_invite_progressed", "invoice_issued", "invoice_request_transitioned", "ui_invoice_step_completed", "ui_treasury_step_completed", "ui_receive_step_completed", "payroll_group_changed", "payroll_run_transitioned", "ui_payroll_action_completed"];
288
288
  type TelemetryEventName = (typeof TELEMETRY_EVENT_NAMES)[number];
289
289
  type TelemetryProps = Record<string, unknown>;
290
290
  type TelemetryEvent = {
@@ -613,6 +613,8 @@ type BootstrapResolution = {
613
613
  readonly shieldPublishableKey: string;
614
614
  /** Openfort third-party auth provider the signer presents; absent means better-auth. */
615
615
  readonly openfortAuthProvider?: "better-auth" | "oidc";
616
+ /** Origin of the Ponder indexer the SDK reads directly; absent means no indexer reads. */
617
+ readonly indexerUrl?: string;
616
618
  readonly engineeringTelemetry?: EngineeringTelemetryBootstrapPolicyV1;
617
619
  };
618
620
  type BootstrapErrorKind = "notAuthenticated" | "network" | "provider" | "malformedBody" | "invalidInput" | "rateLimited";
@@ -906,6 +908,118 @@ interface AccountReadPort {
906
908
  fundFromFaucet(input: FundFromFaucetInput): Effect.Effect<FundFromFaucetResult, AccountReadError, never>;
907
909
  }
908
910
  //#endregion
911
+ //#region src/ports/indexer-read.d.ts
912
+ /**
913
+ * IndexerReadPort is the SDK's read seam onto the Ponder read model
914
+ * (`apps/indexer`). Ponder holds what the chain said; Convex holds what the
915
+ * user meant. Nothing here is copied into Convex, nothing waits for a
916
+ * finality tag, and no write path may read through this port.
917
+ *
918
+ * Every read is scoped to one Safe and one page. The indexer accepts only the
919
+ * exact compiled statements in `apps/indexer/src/queries.ts`, so the adapter
920
+ * that implements this port reproduces those statements byte for byte and the
921
+ * service refuses anything else with 403.
922
+ */
923
+ /** One page of rows for one Safe. `offset` defaults to 0 (the first page). */
924
+ interface IndexerReadInput {
925
+ /** The Safe the caller owns. The indexer refuses a Safe outside the session claim. */
926
+ readonly safe: Address$1;
927
+ /** 1 to 1000 inclusive — the indexer's own bound. */
928
+ readonly limit: number;
929
+ readonly offset?: number;
930
+ }
931
+ /**
932
+ * The chain evidence every indexed row carries. `id` is the logical event id
933
+ * `chainId:txHash:transactionLogOrdinal`; it survives a reorg, so it is the
934
+ * key a Convex intent row stitches against.
935
+ */
936
+ interface IndexerEventIdentity {
937
+ readonly id: string;
938
+ readonly chainId: ChainId;
939
+ readonly txHash: TxHash;
940
+ readonly transactionLogOrdinal: number;
941
+ readonly blockNumber: bigint;
942
+ readonly blockHash: string;
943
+ /** Block timestamp in epoch seconds. */
944
+ readonly timestamp: bigint;
945
+ }
946
+ interface IndexerTransferRow extends IndexerEventIdentity {
947
+ readonly assetId: AssetId;
948
+ readonly token: Address$1;
949
+ readonly from: Address$1;
950
+ readonly to: Address$1;
951
+ /**
952
+ * Raw token units, exact. This is an evidence boundary, so the row never
953
+ * carries Money or AssetAmount: the reader owns the asset's decimals.
954
+ */
955
+ readonly amount: bigint;
956
+ }
957
+ interface IndexerPaymentRow extends IndexerEventIdentity {
958
+ readonly contract: Address$1;
959
+ /** The protocol settlement id a Convex Payment command stitches against. */
960
+ readonly settlementId: string;
961
+ readonly sender: Address$1;
962
+ readonly recipient: Address$1;
963
+ readonly assetId: AssetId;
964
+ readonly token: Address$1;
965
+ /** Raw token units, exact. */
966
+ readonly amount: bigint;
967
+ readonly kind: number;
968
+ readonly documentHash: string;
969
+ }
970
+ /** A row of the indexer's signed-transfer `balance` view. */
971
+ interface IndexerBalanceRow {
972
+ readonly chainId: ChainId;
973
+ readonly assetId: AssetId;
974
+ readonly address: Address$1;
975
+ /** Raw token units, exact. */
976
+ readonly amount: bigint;
977
+ }
978
+ /** One chain's sync position, from the indexer's native `/status` route. */
979
+ interface IndexerChainStatus {
980
+ readonly chain: string;
981
+ readonly chainId: ChainId;
982
+ readonly blockNumber: bigint;
983
+ /** Block timestamp in epoch seconds. Its age is the freshness label. */
984
+ readonly blockTimestamp: bigint;
985
+ }
986
+ /**
987
+ * The tables this seam reads today. P04 adds the authority rows (`safe`,
988
+ * `safe_event`, `roles_module`) and P05 adds `commitment`: each is one more
989
+ * entry here plus its statement and decoder.
990
+ */
991
+ interface IndexerRowsByTable {
992
+ readonly transfer: readonly IndexerTransferRow[];
993
+ readonly payment: readonly IndexerPaymentRow[];
994
+ readonly balance: readonly IndexerBalanceRow[];
995
+ }
996
+ type IndexerTable = keyof IndexerRowsByTable;
997
+ declare const IndexerReadError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
998
+ readonly _tag: "IndexerReadError";
999
+ } & Readonly<A>;
1000
+ declare class IndexerReadError extends IndexerReadError_base<{
1001
+ readonly operation: string;
1002
+ readonly publicCode: CapxulErrorCode;
1003
+ readonly publicError: CapxulError;
1004
+ readonly cause: unknown;
1005
+ readonly details?: CapxulErrorDetails;
1006
+ }> {}
1007
+ interface IndexerReadPort {
1008
+ /** One page of rows, newest block first. An empty page is a value, not an error. */
1009
+ read<T extends IndexerTable>(table: T, input: IndexerReadInput): Effect.Effect<IndexerRowsByTable[T], IndexerReadError>;
1010
+ /**
1011
+ * The same page over the indexer's live stream. The first snapshot is
1012
+ * `loading`; each later snapshot carries the whole page again. The indexer
1013
+ * closes the stream on token expiry or revoked authority, which arrives as
1014
+ * one `error` snapshot — the caller re-reads with a refreshed token.
1015
+ *
1016
+ * @internal-use — substrate reactive transport, like `ConvexCallPort.subscribe`.
1017
+ */
1018
+ subscribe<T extends IndexerTable>(table: T, input: IndexerReadInput, callback: (snapshot: Snapshot<IndexerRowsByTable[T]>) => void): Effect.Effect<Unsubscribe, IndexerReadError>;
1019
+ /** Sync position per chain. Unauthenticated: a stale index is not a refusal. */
1020
+ readonly status: Effect.Effect<readonly IndexerChainStatus[], IndexerReadError>;
1021
+ }
1022
+ //#endregion
909
1023
  //#region src/flows/types.d.ts
910
1024
  /** The runtime port bundle that `assembleCapxulClient` uses. */
911
1025
  interface FlowPorts {
@@ -918,6 +1032,11 @@ interface FlowPorts {
918
1032
  readonly clock: ClockPort;
919
1033
  readonly telemetry: TelemetryPort;
920
1034
  readonly convexCall: ConvexCallPort;
1035
+ /**
1036
+ * The Ponder read seam (P02). Optional: it is present only when the client
1037
+ * was given an indexer origin, and every existing flow works without it.
1038
+ */
1039
+ readonly indexerRead?: IndexerReadPort;
921
1040
  }
922
1041
  /** Legacy method input retained by the imperative auth surface. */
923
1042
  interface ExternalSigner {
@@ -2671,6 +2790,13 @@ interface CapxulClient {
2671
2790
  * NOT on the public `client.accounts` surface.
2672
2791
  */
2673
2792
  readonly accounts: AccountsFaucetMethods;
2793
+ /**
2794
+ * Ponder read seam (P02). Present only when the client was built with an
2795
+ * indexer origin, so every reader treats it as optional. Ponder holds what
2796
+ * the chain said; Convex holds what the user meant. Reads here never run
2797
+ * inside a write path and never wait for a finality tag.
2798
+ */
2799
+ readonly indexer?: IndexerReadPort;
2674
2800
  /** Quarantined Reference-harness evidence; never a product Organization method. */
2675
2801
  readonly organizationSetup: OrganizationSetupProofMethods;
2676
2802
  /** Product telemetry projection for internal composition and test harnesses. */
@@ -1,10 +1,85 @@
1
1
  import { h as CapxulResult } from "../OAuthBearerAuthClient-C-ip-z8M.mjs";
2
- import { er as TelemetryEvent, f as CapxulClient, i as ObservationAdapter, n as ProductionSignerControls, nr as TelemetryIdentifyInput, pr as IdentityTransition, t as CapxulClientInput, tr as TelemetryGroupInput } from "../production-BOMKT0n7.mjs";
2
+ import { er as TelemetryEvent, f as CapxulClient, i as ObservationAdapter, n as ProductionSignerControls, nr as TelemetryIdentifyInput, pr as IdentityTransition, t as CapxulClientInput, tr as TelemetryGroupInput } from "../production-Du4Vc7YD.mjs";
3
3
  import { Effect, Layer } from "effect";
4
4
  //#region src/testing/production-client.d.ts
5
5
  /** Create the one production client with per-client controls at its signing boundaries. */
6
6
  declare function createCapxulProductionTestClient(input: CapxulClientInput, controls: ProductionSignerControls): Promise<CapxulResult<CapxulClient>>;
7
7
  //#endregion
8
+ //#region src/testing/signer-faults.d.ts
9
+ /**
10
+ * Which provider refusal to inject. The codes are the ones the SDK's own
11
+ * classifiers decode (`src/signer.ts`), so a fault reaches the public error
12
+ * contract through the real decode path rather than a shortcut.
13
+ *
14
+ * - `missing-signer` — Openfort's typed not-ready code. `openfortSignerNotReadyCode`
15
+ * decodes it, so the production recovery wrapper runs its single retry (A02).
16
+ * - `user-rejected` — the EIP-1193 4001 result. `signerFailure` decodes it to
17
+ * `SIGNER_REJECTED`, an expected refusal (A08).
18
+ * - `unexpected` — no provider code at all, so it stays an unexpected
19
+ * `PROVIDER_ERROR` (A09).
20
+ */
21
+ type SignerFaultKind = "missing-signer" | "user-rejected" | "unexpected";
22
+ /** The value a controlled fault throws. Named so a test can assert its origin. */
23
+ declare class ControlledSignerFault extends Error {
24
+ readonly kind: SignerFaultKind;
25
+ /** Provider code the SDK classifiers read; absent for `unexpected`. */
26
+ readonly code: string | number | undefined;
27
+ constructor(kind: SignerFaultKind);
28
+ }
29
+ /** Build one fault value without the harness, for a caller that writes its own control. */
30
+ declare function signerFaultCause(kind: SignerFaultKind): ControlledSignerFault;
31
+ interface SignerFaultPlan {
32
+ /**
33
+ * Fault the next embedded signature ONCE, beneath the production recovery
34
+ * wrapper, then delegate every later call to the real signer. The address
35
+ * read and the readiness cycle still run first, so the fault lands at the
36
+ * actual final signing boundary after the prepared-command equality checks.
37
+ */
38
+ readonly signOnce?: SignerFaultKind;
39
+ /**
40
+ * Call the production signer's own `resetSession()` ONCE, immediately before
41
+ * the next signature and after the command is prepared. The delegate then
42
+ * re-runs the real readiness cycle, so the configure request under test is
43
+ * the first one the browser observes after the `reset-session` record (A03).
44
+ *
45
+ * Throws when the composed signer owns no session — a silently skipped reset
46
+ * would leave the run looking green while proving nothing.
47
+ */
48
+ readonly resetSessionBeforeNextSign?: boolean;
49
+ }
50
+ /** What the seam did. JSON-serializable, so a browser test can read it back. */
51
+ interface SignerSeamRecord {
52
+ readonly boundary: "reset-session" | "embedded-sign";
53
+ /** 1-based count of calls at that boundary. */
54
+ readonly attempt: number;
55
+ readonly hash?: string;
56
+ /** Present only on the call that actually threw. */
57
+ readonly fault?: SignerFaultKind;
58
+ readonly atMs: number;
59
+ }
60
+ interface ArmedSignerSeam {
61
+ /** Hand these to `createCapxulProductionTestClient`. */
62
+ readonly controls: ProductionSignerControls;
63
+ /** Oldest first. Empty until the client reaches a signing boundary. */
64
+ readonly records: () => readonly SignerSeamRecord[];
65
+ /** True once every armed one-shot has fired. */
66
+ readonly spent: () => boolean;
67
+ }
68
+ /**
69
+ * Arm one-shot faults on the production embedded signer.
70
+ *
71
+ * ```ts
72
+ * const seam = armSignerFaults({ signOnce: "user-rejected" });
73
+ * const client = await createCapxulProductionTestClient(input, seam.controls);
74
+ * const result = await client.org(orgId).permissions.create(command);
75
+ * // result.error.code === "SIGNER_REJECTED"; nothing was submitted.
76
+ * // seam.records() names the boundary that refused.
77
+ * ```
78
+ *
79
+ * An empty plan installs no controls, which composes the ordinary client.
80
+ */
81
+ declare function armSignerFaults(plan?: SignerFaultPlan): ArmedSignerSeam;
82
+ //#endregion
8
83
  //#region src/testing/telemetry/RecordingTelemetryAdapter.d.ts
9
84
  type RecordingTelemetryOperation = {
10
85
  readonly type: "emit";
@@ -56,4 +131,4 @@ interface CapxulTestObservation {
56
131
  */
57
132
  declare function createCapxulTestClient(options?: CreateCapxulTestClientOptions): CapxulTestClient;
58
133
  //#endregion
59
- export { CapxulTestClient, CapxulTestClock, CapxulTestObservation, CreateCapxulTestClientOptions, type ProductionSignerControls, SeedTestIdentityInput, createCapxulProductionTestClient, createCapxulTestClient };
134
+ export { type ArmedSignerSeam, CapxulTestClient, CapxulTestClock, CapxulTestObservation, ControlledSignerFault, CreateCapxulTestClientOptions, type ProductionSignerControls, SeedTestIdentityInput, type SignerFaultKind, type SignerFaultPlan, type SignerSeamRecord, armSignerFaults, createCapxulProductionTestClient, createCapxulTestClient, signerFaultCause };
@@ -1,5 +1,5 @@
1
- import { D as fromWei, P as redactTelemetryEvent, a as smartAccountErrorFromCapxul, c as identityErrorFromCapxul, i as assembleCapxulClient, l as convexCallErrorFromCapxul, n as createCapxulClientWithSignerControls, o as accountReadErrorFromCapxul, s as wireChainId, u as bootstrapErrorFromCapxul, v as toWei } from "../production-Y3yqeOSE.mjs";
2
- import { $ as toSessionToken, B as toDurationMs, F as toAuthUserId, G as toJwtToken, H as toEpochMs, K as toKycTier, L as toChainId, M as toAddress, N as toAllowedOrigin, P as toAppId, R as toCountryCode, U as toEpochSeconds, V as toEmail, W as toHandle, Z as toPublishableKey, at as CapxulError, d as authClientPortFromPromiseAdapter, j as toAccountId, n as readClockNow, r as InMemoryAuthCacheAdapter, st as Errors, tt as validateHandle, y as deriveCapxulSafeAddress } from "../OAuthBearerAuthClient-hPwtSpEf.mjs";
1
+ import { D as fromWei, P as redactTelemetryEvent, a as smartAccountErrorFromCapxul, c as identityErrorFromCapxul, i as assembleCapxulClient, l as convexCallErrorFromCapxul, n as createCapxulClientWithSignerControls, o as accountReadErrorFromCapxul, s as wireChainId, u as bootstrapErrorFromCapxul, v as toWei } from "../production-216hsAKc.mjs";
2
+ import { G as toHandle, H as toEmail, I as toAuthUserId, K as toJwtToken, M as toAddress, N as toAllowedOrigin, P as toAppId, Q as toPublishableKey, R as toChainId, U as toEpochMs, V as toDurationMs, W as toEpochSeconds, d as authClientPortFromPromiseAdapter, et as toSessionToken, j as toAccountId, lt as Errors, n as readClockNow, q as toKycTier, r as InMemoryAuthCacheAdapter, rt as validateHandle, st as CapxulError, y as deriveCapxulSafeAddress, z as toCountryCode } from "../OAuthBearerAuthClient-IB2W1Fzj.mjs";
3
3
  import { keccak256 } from "viem";
4
4
  import { Effect, Result, Semaphore } from "effect";
5
5
  import { getFunctionName } from "convex/server";
@@ -9,6 +9,97 @@ function createCapxulProductionTestClient(input, controls) {
9
9
  return createCapxulClientWithSignerControls(input, controls);
10
10
  }
11
11
  //#endregion
12
+ //#region src/testing/signer-faults.ts
13
+ const FAULT_CODES = {
14
+ "missing-signer": "MISSING_SIGNER",
15
+ "user-rejected": 4001,
16
+ unexpected: void 0
17
+ };
18
+ /** The value a controlled fault throws. Named so a test can assert its origin. */
19
+ var ControlledSignerFault = class extends Error {
20
+ kind;
21
+ /** Provider code the SDK classifiers read; absent for `unexpected`. */
22
+ code;
23
+ constructor(kind) {
24
+ super(`controlled signer fault (${kind})`);
25
+ this.name = "ControlledSignerFault";
26
+ this.kind = kind;
27
+ this.code = FAULT_CODES[kind];
28
+ }
29
+ };
30
+ /** Build one fault value without the harness, for a caller that writes its own control. */
31
+ function signerFaultCause(kind) {
32
+ return new ControlledSignerFault(kind);
33
+ }
34
+ /**
35
+ * Arm one-shot faults on the production embedded signer.
36
+ *
37
+ * ```ts
38
+ * const seam = armSignerFaults({ signOnce: "user-rejected" });
39
+ * const client = await createCapxulProductionTestClient(input, seam.controls);
40
+ * const result = await client.org(orgId).permissions.create(command);
41
+ * // result.error.code === "SIGNER_REJECTED"; nothing was submitted.
42
+ * // seam.records() names the boundary that refused.
43
+ * ```
44
+ *
45
+ * An empty plan installs no controls, which composes the ordinary client.
46
+ */
47
+ function armSignerFaults(plan = {}) {
48
+ const records = [];
49
+ let pendingFault = plan.signOnce;
50
+ let pendingReset = plan.resetSessionBeforeNextSign === true;
51
+ let resetCalls = 0;
52
+ let embeddedCalls = 0;
53
+ function record(entry) {
54
+ records.push({
55
+ ...entry,
56
+ atMs: Date.now()
57
+ });
58
+ }
59
+ const resetThenSign = async (hash, signer) => {
60
+ if (pendingReset) {
61
+ pendingReset = false;
62
+ resetCalls += 1;
63
+ if (signer.resetSession === void 0) throw new Error("armSignerFaults: resetSessionBeforeNextSign needs the embedded browser signer; this client composed a signer with no session");
64
+ signer.resetSession();
65
+ record({
66
+ boundary: "reset-session",
67
+ attempt: resetCalls,
68
+ hash
69
+ });
70
+ }
71
+ return signer.signUserOpHash(hash);
72
+ };
73
+ const faultThenDelegate = async (hash, delegate) => {
74
+ embeddedCalls += 1;
75
+ const fault = pendingFault;
76
+ if (fault === void 0) {
77
+ record({
78
+ boundary: "embedded-sign",
79
+ attempt: embeddedCalls,
80
+ hash
81
+ });
82
+ return delegate(hash);
83
+ }
84
+ pendingFault = void 0;
85
+ record({
86
+ boundary: "embedded-sign",
87
+ attempt: embeddedCalls,
88
+ hash,
89
+ fault
90
+ });
91
+ throw signerFaultCause(fault);
92
+ };
93
+ return {
94
+ controls: {
95
+ ...plan.resetSessionBeforeNextSign === true ? { signUserOpHash: resetThenSign } : {},
96
+ ...plan.signOnce === void 0 ? {} : { signEmbeddedUserOpHash: faultThenDelegate }
97
+ },
98
+ records: () => records.slice(),
99
+ spent: () => pendingFault === void 0 && !pendingReset
100
+ };
101
+ }
102
+ //#endregion
12
103
  //#region src/testing/account/InMemoryAccountReadAdapter.ts
13
104
  var InMemoryAccountReadAdapter = class {
14
105
  #deps;
@@ -915,4 +1006,4 @@ function createCapxulTestClient(options = {}) {
915
1006
  };
916
1007
  }
917
1008
  //#endregion
918
- export { createCapxulProductionTestClient, createCapxulTestClient };
1009
+ export { ControlledSignerFault, armSignerFaults, createCapxulProductionTestClient, createCapxulTestClient, signerFaultCause };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capxul/sdk",
3
- "version": "4.2.0-rc.8",
3
+ "version": "4.2.0-rc.9",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/Xelmar-tech/infrastructure.git",
@@ -48,10 +48,10 @@
48
48
  "vite-plus": "0.3.0",
49
49
  "vitest": "4.1.11",
50
50
  "@capxul/config": "0.3.0",
51
- "@capxul/observability": "4.2.0-rc.8",
51
+ "@capxul/observability": "4.2.0-rc.9",
52
52
  "@capxul/errors": "0.3.0",
53
- "@capxul/types": "0.3.0",
54
53
  "@capxul/wire": "0.7.0",
54
+ "@capxul/types": "0.3.0",
55
55
  "@capxul/typescript-config": "0.0.0"
56
56
  },
57
57
  "_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.",