@capxul/sdk 4.20.0-beta.24 → 4.20.0-beta.27

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 { Cause, Clock, Context, Data, Deferred, Effect, Exit, Fiber, Layer, Predicate, Queue, Ref, Result, Schema, SchemaGetter, SchemaParser } from "effect";
1
+ import { Cause, Clock, Context, Data, Deferred, Effect, Exit, Fiber, Layer, Option, Predicate, Queue, Ref, Result, Schema, SchemaGetter, SchemaParser } from "effect";
2
2
  import { makeFunctionReference } from "convex/server";
3
3
  import { bytesToHex, concat, decodeErrorResult, encodeAbiParameters, encodeFunctionData, encodePacked, formatUnits, getContractAddress, hashTypedData, isAddress, isHex, keccak256, pad, padHex, parseAbiParameters, recoverAddress, recoverTypedDataAddress, toBytes, toFunctionSignature, toHex } from "viem";
4
4
  import { getUserOperationHash } from "viem/account-abstraction";
@@ -218,12 +218,17 @@ const Errors = {
218
218
  * a PERMISSION denial — explicitly NOT an `INSUFFICIENT_BALANCE` (the treasury
219
219
  * held the funds; the role's authority is what bound). `reason` discriminates
220
220
  * the violated condition (`over_cap` / `daily_cap` / `not_member` /
221
- * `disallowed_recipient` / `condition_violation`); leak-safe — no on-chain
222
- * identifiers ever enter the details.
221
+ * `disallowed_recipient` / `condition_violation` / `budget_exhausted`);
222
+ * no Safe, Roles module or role key enters the details.
223
+ * `budget_exhausted` carries what the Budget's allowance still holds and
224
+ * what the spend needs, as asset amounts in major units (#2297); the asset
225
+ * id names the public token contract.
223
226
  */
224
- rolePermissionDenied: (details) => new CapxulError("ROLE_PERMISSION_DENIED", `Org role denied this spend on-chain (${details.reason}).`, { details: details.operation === void 0 ? { reason: details.reason } : {
227
+ rolePermissionDenied: (details) => new CapxulError("ROLE_PERMISSION_DENIED", `Org role denied this spend on-chain (${details.reason}).`, { details: {
225
228
  reason: details.reason,
226
- operation: details.operation
229
+ ...details.operation === void 0 ? {} : { operation: details.operation },
230
+ ...details.remaining === void 0 ? {} : { remaining: details.remaining },
231
+ ...details.required === void 0 ? {} : { required: details.required }
227
232
  } }),
228
233
  /**
229
234
  * A transaction (or sponsored UserOp) failed. `details.reason` discriminates
@@ -3552,7 +3557,7 @@ const ActivityItemSchema = Schema.Union([Schema.Struct({
3552
3557
  }), Schema.Struct({
3553
3558
  kind: Schema.Literal("movement"),
3554
3559
  id: Schema.String,
3555
- classification: Schema.Literal("movement_only_outflow"),
3560
+ classification: Schema.Literals(["deposit", "movement_only_outflow"]),
3556
3561
  amount: Amount,
3557
3562
  direction: Direction,
3558
3563
  counterpartyLabel: Schema.String,
@@ -4818,10 +4823,19 @@ const ApprovalNetworkSchema = Schema.Struct({
4818
4823
  name: Schema.String,
4819
4824
  explorerUrl: Schema.String
4820
4825
  });
4826
+ /**
4827
+ * Whose money the operation moves: the person's own, or an Organization's,
4828
+ * which a reader follows through that Organization's scope.
4829
+ */
4830
+ const ApprovalActorSchema = Schema.Union([Schema.Struct({ kind: Schema.Literal("personal") }), Schema.Struct({
4831
+ kind: Schema.Literal("organization"),
4832
+ orgId: Schema.NonEmptyString
4833
+ })]);
4821
4834
  /** What the person reads before they sign. */
4822
4835
  const ApprovalSummarySchema = Schema.Struct({
4823
4836
  title: Schema.String,
4824
4837
  from: Schema.Struct({
4838
+ kind: Schema.Literals(["personal", "organization"]),
4825
4839
  label: Schema.String,
4826
4840
  address: AddressSchema$1
4827
4841
  }),
@@ -4843,6 +4857,7 @@ const ApprovalSchema = Schema.Struct({
4843
4857
  url: Schema.String,
4844
4858
  kind: Schema.Literals(APPROVAL_KINDS),
4845
4859
  state: Schema.Literals(APPROVAL_STATES),
4860
+ actor: ApprovalActorSchema,
4846
4861
  summary: ApprovalSummarySchema,
4847
4862
  operation: ApprovalOperationSchema,
4848
4863
  /** Who must sign: the owner key of the paying Safe. */
@@ -5075,7 +5090,44 @@ const approvals = {
5075
5090
  ]
5076
5091
  })
5077
5092
  };
5093
+ /**
5094
+ * The home screen in one read. A section whose read failed is null, so the
5095
+ * caller shows it as unavailable, never as empty.
5096
+ */
5097
+ const HomeSchema = Schema.Struct({
5098
+ email: Schema.String,
5099
+ actingAs: Schema.Union([Schema.Struct({ kind: Schema.Literal("personal") }), Schema.Struct({
5100
+ kind: Schema.Literal("organization"),
5101
+ orgId: Schema.String
5102
+ })]),
5103
+ /** The acting Safe's position in each settlement asset of its chain. */
5104
+ balances: Schema.NullOr(Schema.Array(AssetPositionSchema)),
5105
+ /** The ids of what waits on the caller, newest first. */
5106
+ needsYou: Schema.NullOr(Schema.Struct({
5107
+ requestsToPay: Schema.Array(Schema.String),
5108
+ payrollToApprove: Schema.Array(Schema.String),
5109
+ paymentsToRetry: Schema.Array(Schema.String)
5110
+ })),
5111
+ /** The newest rows of the actor's activity. */
5112
+ recentActivity: Schema.NullOr(Schema.Array(ActivityItemSchema))
5113
+ });
5078
5114
  const summaries = {
5115
+ /**
5116
+ * Where the caller acts, its balances, what needs it and its newest activity,
5117
+ * for the person or for an Organization they take part in. One round trip.
5118
+ */
5119
+ home: Operation.action("accounts.summaries.home", {
5120
+ input: Schema.Struct({
5121
+ chainId: ChainIdSchema$1,
5122
+ orgId: Schema.optionalKey(Schema.NonEmptyString)
5123
+ }),
5124
+ output: HomeSchema,
5125
+ errors: [
5126
+ ...CALL$10,
5127
+ ...DEFECTS,
5128
+ "ROLE_PERMISSION_DENIED"
5129
+ ]
5130
+ }),
5079
5131
  /** The signed-in person: id, verified email and Profile display name. */
5080
5132
  me: Operation.query("accounts.summaries.me", {
5081
5133
  input: Schema.Struct({}),
@@ -7167,7 +7219,11 @@ const OrgId$2 = Schema.NonEmptyString;
7167
7219
  const CALL$4 = ["NOT_AUTHENTICATED", "INVALID_INPUT"];
7168
7220
  /** The caller's own Account and Safe, which a Payment is signed from. */
7169
7221
  const ACCOUNT$1 = ["SMART_ACCOUNT_MISSING", "ACCOUNT_NOT_FOUND"];
7170
- /** Not a participant of the Organization, or no Budget in it that may pay for this. */
7222
+ /**
7223
+ * Not a participant of the Organization, no Budget in it that may pay for
7224
+ * this, or a Budget whose on-chain allowance holds less than the batch spends
7225
+ * (`budget_exhausted`, naming what is left).
7226
+ */
7171
7227
  const DENIED$1 = ["ROLE_PERMISSION_DENIED"];
7172
7228
  /** The command, its Payment or its execution is not in a state this applies to. */
7173
7229
  const STATE$3 = ["WRONG_STATE"];
@@ -7478,7 +7534,9 @@ const OneOrganization = Schema.Struct({ orgId: OrgId$1 });
7478
7534
  const CALL$3 = ["NOT_AUTHENTICATED", "INVALID_INPUT"];
7479
7535
  /**
7480
7536
  * The caller does not take part in the Organization, or holds no Budget in it
7481
- * that may pay for this. A caller outside the Organization learns nothing more.
7537
+ * that may pay for this, or the Budget's on-chain allowance holds less than the
7538
+ * run pays (`budget_exhausted`, naming what is left). A caller outside the
7539
+ * Organization learns nothing more.
7482
7540
  */
7483
7541
  const DENIED = ["ROLE_PERMISSION_DENIED"];
7484
7542
  /**
@@ -9087,7 +9145,11 @@ const ORGANIZATION_OPERATIONS = {
9087
9145
  seedNativeReadiness: "operator.fixtures.seedNativeReadiness",
9088
9146
  seedPrerequisites: "operator.fixtures.seedPrerequisites"
9089
9147
  },
9090
- identities: { purgeByEmail: "operator.identities.purgeByEmail" }
9148
+ identities: {
9149
+ purgeByEmail: "operator.identities.purgeByEmail",
9150
+ /** One Account and every row that refers to it, unless it has Payments or an Organization tie. */
9151
+ purgeAccount: "operator.identities.purgeAccount"
9152
+ }
9091
9153
  },
9092
9154
  /** Organizations' internal functions; its public rows join from `OPERATIONS`. */
9093
9155
  organizations: {
@@ -9181,7 +9243,9 @@ emitSaved: "activity.annotations.emitSaved" },
9181
9243
  linkObservation: "payments.commands.linkObservation",
9182
9244
  failPrepared: "payments.commands.failPrepared",
9183
9245
  loadContext: "payments.commands.loadContext",
9184
- loadExecutionContext: "payments.commands.loadExecutionContext"
9246
+ loadExecutionContext: "payments.commands.loadExecutionContext",
9247
+ /** The capped Budget a prepared Organization command spends from, before its allowance is read on chain. */
9248
+ loadBudgetAllowance: "payments.commands.loadBudgetAllowance"
9185
9249
  },
9186
9250
  lifecycles: { prepareIntent: "payments.lifecycles.prepareIntent" },
9187
9251
  /** The stored UserOperation of every money command: Payment, Permission and configuration. */
@@ -9335,7 +9399,11 @@ const PLATFORM_OPERATIONS = {
9335
9399
  recordUse: "applications.bootstraps.recordUse",
9336
9400
  resolve: "applications.bootstraps.resolve"
9337
9401
  },
9338
- keys: { issue: "applications.keys.issue" },
9402
+ keys: {
9403
+ issue: "applications.keys.issue",
9404
+ /** Operator-only: revoke one key by its id, whoever owns it. */
9405
+ revokeById: "applications.keys.revokeById"
9406
+ },
9339
9407
  quickstarts: {
9340
9408
  claim: "applications.quickstarts.claim",
9341
9409
  mint: "applications.quickstarts.mint"
@@ -10692,95 +10760,83 @@ Schema.Struct({
10692
10760
  });
10693
10761
  //#endregion
10694
10762
  //#region ../observability/src/catalog/cli.ts
10695
- /** One completed online CLI diagnostic. No command input or provider text. */
10763
+ /** Every command path of the `capxul` tree, dot-separated, plus the root and `unknown`. */
10696
10764
  const CLI_COMMAND_NAMES = [
10697
- "status",
10698
- "request",
10699
- "request.list",
10700
- "request.get",
10701
- "request.cancel",
10702
- "offer",
10703
- "offer.create",
10704
- "offer.list",
10705
- "offer.get",
10706
- "offer.revise",
10707
- "offer.deactivate",
10708
- "org.offer",
10709
- "org.offer.create",
10710
- "org.offer.list",
10711
- "org.offer.get",
10712
- "org.offer.revise",
10713
- "org.offer.deactivate",
10714
- "request.issue",
10715
- "inbox",
10716
- CAPXUL_OPERATIONS.inbox.list,
10717
- "inbox.get",
10718
- "inbox.pay",
10719
- CAPXUL_OPERATIONS.inbox.decline,
10720
- "org.request",
10721
- "org.request.list",
10722
- "org.request.get",
10723
- "org.request.cancel",
10724
- "org.request.issue",
10725
- "org.inbox",
10726
- CAPXUL_OPERATIONS.org.inbox.list,
10727
- "org.inbox.get",
10728
- "org.inbox.pay",
10729
- CAPXUL_OPERATIONS.org.inbox.decline,
10730
10765
  "capxul",
10766
+ "home",
10731
10767
  "whoami",
10732
10768
  "use",
10733
10769
  "use.personal",
10734
10770
  "use.org",
10735
10771
  "use.env",
10736
- "doctor",
10737
- "telemetry",
10738
- "telemetry.status",
10739
- "telemetry.enable",
10740
- "telemetry.disable",
10741
10772
  "auth",
10742
10773
  "auth.login",
10743
- "auth.signup",
10744
- "auth.send",
10745
10774
  "auth.verify",
10746
10775
  "auth.switch",
10747
- "auth.profile",
10748
- "auth.status",
10749
10776
  "auth.logout",
10750
10777
  "account",
10751
- CAPXUL_OPERATIONS.account.status,
10752
- CAPXUL_OPERATIONS.account.balance,
10753
- "account.deposit",
10778
+ "account.show",
10754
10779
  "account.retry",
10755
- "document",
10756
- "document.get",
10757
- "document.verify",
10758
- "document.render",
10759
- "document.export",
10780
+ "balance",
10781
+ "address",
10760
10782
  "payment",
10783
+ "payment.send",
10761
10784
  "payment.list",
10762
10785
  "payment.get",
10763
10786
  "payment.wait",
10764
- "payment.send",
10765
10787
  "payment.retry",
10766
- "activity",
10767
- "activity.list",
10768
- "activity.get",
10769
- "activity.summary",
10770
- "activity.annotate",
10788
+ "inbox",
10789
+ CAPXUL_OPERATIONS.inbox.list,
10790
+ "inbox.get",
10791
+ "inbox.pay",
10792
+ CAPXUL_OPERATIONS.inbox.decline,
10793
+ "request",
10794
+ "request.issue",
10795
+ "request.list",
10796
+ "request.get",
10797
+ "request.cancel",
10798
+ "offer",
10799
+ "offer.create",
10800
+ "offer.list",
10801
+ "offer.get",
10802
+ "offer.revise",
10803
+ "offer.deactivate",
10771
10804
  "contact",
10805
+ "contact.add",
10772
10806
  "contact.list",
10773
10807
  "contact.get",
10774
- "contact.add",
10775
10808
  "contact.label",
10776
10809
  "contact.hide",
10777
10810
  "contact.unhide",
10811
+ "document",
10812
+ "document.get",
10813
+ "document.render",
10814
+ "document.export",
10815
+ "document.verify",
10816
+ "activity",
10817
+ "activity.list",
10818
+ "activity.get",
10819
+ "activity.summary",
10820
+ "activity.annotate",
10821
+ "invite",
10822
+ "invite.list",
10823
+ "invite.accept",
10824
+ "invite.decline",
10778
10825
  "org",
10779
10826
  CAPXUL_OPERATIONS.org.list,
10780
- "org.status",
10827
+ CAPXUL_OPERATIONS.org.create,
10828
+ "org.show",
10781
10829
  CAPXUL_OPERATIONS.org.me,
10782
- "org.balance",
10783
- "org.deposit",
10830
+ "org.wait",
10831
+ CAPXUL_OPERATIONS.org.retry,
10832
+ "org.member",
10833
+ "org.member.list",
10834
+ "org.member.get",
10835
+ "org.member.invite",
10836
+ CAPXUL_OPERATIONS.org.invite,
10837
+ "org.invite.list",
10838
+ "org.invite.cancel",
10839
+ "org.invite.resend",
10784
10840
  "org.permission",
10785
10841
  "org.permission.list",
10786
10842
  "org.permission.get",
@@ -10792,46 +10848,32 @@ const CLI_COMMAND_NAMES = [
10792
10848
  "org.permission.command",
10793
10849
  "org.permission.command.get",
10794
10850
  "org.permission.command.wait",
10795
- CAPXUL_OPERATIONS.org.payment,
10796
- "org.payment.list",
10797
- "org.payment.get",
10798
- "org.payment.wait",
10799
- "org.payment.retry",
10800
- "org.payment.send",
10801
10851
  "org.payroll",
10852
+ "org.payroll.run",
10853
+ "org.payroll.list",
10854
+ "org.payroll.get",
10855
+ "org.payroll.wait",
10856
+ CAPXUL_OPERATIONS.org.payroll.terms,
10802
10857
  "org.payroll.groups",
10803
10858
  CAPXUL_OPERATIONS.org.payroll.groups.list,
10804
10859
  CAPXUL_OPERATIONS.org.payroll.groups.save,
10805
10860
  CAPXUL_OPERATIONS.org.payroll.groups.remove,
10806
- CAPXUL_OPERATIONS.org.payroll.terms,
10807
- "org.payroll.list",
10808
- "org.payroll.run",
10809
- "org.payroll.get",
10810
- "org.payroll.wait",
10811
- CAPXUL_OPERATIONS.org.members,
10812
- "org.member",
10813
- "org.member.get",
10814
- "org.member.invite",
10815
- "org.contact",
10816
- "org.contact.list",
10817
- "org.contact.get",
10818
- "org.contact.add",
10819
- "org.contact.label",
10820
- "org.contact.hide",
10821
- "org.contact.unhide",
10822
- CAPXUL_OPERATIONS.org.invite,
10823
- "org.invite.list",
10861
+ "config",
10862
+ "config.telemetry",
10863
+ "config.telemetry.on",
10864
+ "config.telemetry.off",
10865
+ "config.telemetry.status",
10866
+ "invite.get",
10867
+ "invite.review",
10868
+ "invite.wait",
10824
10869
  "org.invite.get",
10825
10870
  "org.invite.wait",
10826
- "org.invite.review",
10827
- "org.invite.accept",
10828
- "org.invite.decline",
10829
- "org.invite.cancel",
10830
- "org.invite.resend",
10831
10871
  "org.invite.retry",
10832
- "org.wait",
10833
- CAPXUL_OPERATIONS.org.create,
10834
- CAPXUL_OPERATIONS.org.retry,
10872
+ "schema",
10873
+ "doctor",
10874
+ "dev",
10875
+ "dev.key",
10876
+ "dev.fund",
10835
10877
  "unknown"
10836
10878
  ];
10837
10879
  const CLI_CAPABILITIES = [
@@ -12525,7 +12567,7 @@ function mapAccountLifecycle(input) {
12525
12567
  }
12526
12568
  //#endregion
12527
12569
  //#region package.json
12528
- var version = "4.20.0-beta.24";
12570
+ var version = "4.20.0-beta.27";
12529
12571
  //#endregion
12530
12572
  //#region src/observability/telemetry/exception-projection.ts
12531
12573
  /** Fixed fallback for failures that have no safe message. */
@@ -16726,6 +16768,13 @@ function subscribeFreshQuery(deps, args, listener, operation, projection, option
16726
16768
  }
16727
16769
  //#endregion
16728
16770
  //#region src/payments/lifecycle-execution.ts
16771
+ /**
16772
+ * The prepared command is this lifecycle intent; a retry also names the
16773
+ * original birth command of the scope it was asked for.
16774
+ */
16775
+ const lifecycleCommandCheck = (intent, expectedOrganizationId) => async (request, evidence) => await matchesIntent(intent)(request, evidence) && (intent.kind !== "retry" || (expectedOrganizationId === void 0 ? evidence.sourceCommand?.kind === "birth" && evidence.sourceCommand.actor.kind === "account" : evidence.sourceCommand?.kind === "birth" && evidence.sourceCommand.actor.kind === "organization" && evidence.sourceCommand.actor.orgId === expectedOrganizationId));
16776
+ /** The prepared command pays exactly the request the payer confirmed. */
16777
+ const requestPaymentCheck = (confirmation) => async (request) => "kind" in request && request.kind === "payment_request" && canonicalJson(request.confirmation) === canonicalJson(confirmation);
16729
16778
  function executePaymentLifecycle(deps, intent, signal, controls, expectedOrganizationId, onPrepared) {
16730
16779
  return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.payments.prepareLifecycleExecution, () => withInvocationParentSpan(Effect.suspend(() => callOperation(deps.convexCall, lifecycles.prepareScoped, copyInvocationObservation(controls, {
16731
16780
  signerAddress,
@@ -16734,13 +16783,13 @@ function executePaymentLifecycle(deps, intent, signal, controls, expectedOrganiz
16734
16783
  kind: "organization",
16735
16784
  orgId: expectedOrganizationId
16736
16785
  }
16737
- })).pipe(Effect.mapError((publicError) => ({ publicError })))), controls), deps.runPromise), async (request, evidence) => await matchesIntent(intent)(request, evidence) && (intent.kind !== "retry" || (expectedOrganizationId === void 0 ? evidence.sourceCommand?.kind === "birth" && evidence.sourceCommand.actor.kind === "account" : evidence.sourceCommand?.kind === "birth" && evidence.sourceCommand.actor.kind === "organization" && evidence.sourceCommand.actor.orgId === expectedOrganizationId)), false, void 0, signal, controls, onPrepared);
16786
+ })).pipe(Effect.mapError((publicError) => ({ publicError })))), controls), deps.runPromise), lifecycleCommandCheck(intent, expectedOrganizationId), false, void 0, signal, controls, onPrepared);
16738
16787
  }
16739
16788
  function executeRequestPayment(deps, confirmation, controls, onPrepared) {
16740
16789
  return executePrepared(deps, (signerAddress) => runIfActive(controls?.signal, commands$1.prepareRequest.name, () => withInvocationParentSpan(Effect.suspend(() => callOperation(deps.convexCall, commands$1.prepareRequest, copyInvocationObservation(controls, {
16741
16790
  confirmation,
16742
16791
  signerAddress
16743
- })).pipe(Effect.mapError((publicError) => ({ publicError })))), controls), deps.runPromise), async (request) => "kind" in request && request.kind === "payment_request" && canonicalJson(request.confirmation) === canonicalJson(confirmation), false, void 0, controls?.signal, controls, onPrepared);
16792
+ })).pipe(Effect.mapError((publicError) => ({ publicError })))), controls), deps.runPromise), requestPaymentCheck(confirmation), false, void 0, controls?.signal, controls, onPrepared);
16744
16793
  }
16745
16794
  function executeOrganizationPayment(deps, input, signal, onPreparedClosed, controls, onPrepared) {
16746
16795
  return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.organizationPayments.prepareExecution, () => withInvocationParentSpan(Effect.suspend(() => callOperation(deps.convexCall, commands$1.prepareOrganization, copyInvocationObservation(controls, {
@@ -18224,63 +18273,6 @@ function makeOfframpMethods() {
18224
18273
  };
18225
18274
  }
18226
18275
  //#endregion
18227
- //#region src/payments/organization-payment-reads.ts
18228
- const exactPaymentId = (value) => Schema.decodeEffect(PaymentIdSchema)(value).pipe(Effect.mapError(() => Errors.invalidInput("paymentId", "Provide one exact Payment ID")));
18229
- /** Read the backend-authorized Organization wrapper before projecting any Payment. */
18230
- function makeOrganizationPaymentReadMethods(deps, orgId) {
18231
- return {
18232
- previewRetry(paymentId, options) {
18233
- const controls = deps.invocationControls?.(options) ?? options;
18234
- return runCapxulEffect(Effect.gen(function* () {
18235
- const id = yield* exactPaymentId(paymentId);
18236
- const preview = yield* callOperation(deps.convexCall, lifecycles.previewRetry, copyInvocationObservation(controls, {
18237
- orgId,
18238
- paymentId: id
18239
- }));
18240
- if (preview.orgId !== orgId || !preview.paymentIds.includes(id) || new Set(preview.paymentIds).size !== preview.paymentIds.length || preview.payments.length !== preview.paymentIds.length || preview.payments.some((payment, index) => payment.id !== preview.paymentIds[index] || payment.direction !== "out")) return yield* Effect.fail(Errors.invalidInput("paymentId", "Invalid Organization retry preview"));
18241
- return {
18242
- ...preview,
18243
- paymentIds: [...preview.paymentIds],
18244
- payments: preview.payments.map((payment) => normalizePaymentTiming(payment))
18245
- };
18246
- }), controls, lifecycles.previewRetry.name, deps.runPromise);
18247
- },
18248
- list(options) {
18249
- const controls = deps.invocationControls?.(options) ?? options;
18250
- return runCapxulEffect(callOperation(deps.convexCall, records.listForOrganization, copyInvocationObservation(controls, { orgId })).pipe(Effect.filterOrFail((result) => result.orgId === orgId, () => Errors.invalidInput("orgId", "Invalid Organization Payment list")), Effect.map((result) => mapPage(result, (payment) => normalizePaymentTiming(payment)))), controls, records.listForOrganization.name, deps.runPromise);
18251
- },
18252
- get(paymentId, options) {
18253
- const controls = deps.invocationControls?.(options) ?? options;
18254
- return runCapxulEffect(Effect.gen(function* () {
18255
- const id = yield* exactPaymentId(paymentId);
18256
- const response = yield* callOperation(deps.convexCall, records.getForOrganization, copyInvocationObservation(controls, {
18257
- orgId,
18258
- paymentId: id
18259
- }));
18260
- if (response.orgId !== orgId) return yield* Effect.fail(Errors.invalidInput("orgId", "Payment read scope does not match"));
18261
- const decoded = response.payment;
18262
- if (decoded === null) return null;
18263
- if (decoded.id !== id) return yield* Effect.fail(Errors.invalidInput("paymentId", "Invalid Organization Payment response"));
18264
- return normalizePaymentTiming(decoded);
18265
- }), controls, records.getForOrganization.name, deps.runPromise);
18266
- },
18267
- subscribe(paymentId, listener, options) {
18268
- const parsed = Schema.decodeResult(PaymentIdSchema)(paymentId);
18269
- if (parsed._tag === "Failure") return Promise.resolve({
18270
- ok: false,
18271
- error: Errors.invalidInput("paymentId", "Provide one exact Payment ID")
18272
- });
18273
- return subscribeOrganizationPayment({
18274
- actor: deps.actor,
18275
- convexCall: deps.convexCall,
18276
- getPayment: reference(records.getForOrganization),
18277
- runPromise: deps.runPromise,
18278
- invocationControls: deps.invocationControls
18279
- }, orgId, parsed.success, listener, options);
18280
- }
18281
- };
18282
- }
18283
- //#endregion
18284
18276
  //#region src/payments/organization-payment-requests.ts
18285
18277
  const organizationPaymentIntentSchema = Schema.Struct({
18286
18278
  orgId: PrepareOrganizationPaymentExecutionInputSchema.fields.orgId,
@@ -18341,8 +18333,65 @@ async function organizationPaymentRequest(scope, actor, intent, providedKey) {
18341
18333
  }
18342
18334
  }
18343
18335
  //#endregion
18336
+ //#region src/payments/organization-payment-reads.ts
18337
+ const exactPaymentId = (value) => Schema.decodeEffect(PaymentIdSchema)(value).pipe(Effect.mapError(() => Errors.invalidInput("paymentId", "Provide one exact Payment ID")));
18338
+ /** Read the backend-authorized Organization wrapper before projecting any Payment. */
18339
+ function makeOrganizationPaymentReadMethods(deps, orgId) {
18340
+ return {
18341
+ previewRetry(paymentId, options) {
18342
+ const controls = deps.invocationControls?.(options) ?? options;
18343
+ return runCapxulEffect(Effect.gen(function* () {
18344
+ const id = yield* exactPaymentId(paymentId);
18345
+ const preview = yield* callOperation(deps.convexCall, lifecycles.previewRetry, copyInvocationObservation(controls, {
18346
+ orgId,
18347
+ paymentId: id
18348
+ }));
18349
+ if (preview.orgId !== orgId || !preview.paymentIds.includes(id) || new Set(preview.paymentIds).size !== preview.paymentIds.length || preview.payments.length !== preview.paymentIds.length || preview.payments.some((payment, index) => payment.id !== preview.paymentIds[index] || payment.direction !== "out")) return yield* Effect.fail(Errors.invalidInput("paymentId", "Invalid Organization retry preview"));
18350
+ return {
18351
+ ...preview,
18352
+ paymentIds: [...preview.paymentIds],
18353
+ payments: preview.payments.map((payment) => normalizePaymentTiming(payment))
18354
+ };
18355
+ }), controls, lifecycles.previewRetry.name, deps.runPromise);
18356
+ },
18357
+ list(options) {
18358
+ const controls = deps.invocationControls?.(options) ?? options;
18359
+ return runCapxulEffect(callOperation(deps.convexCall, records.listForOrganization, copyInvocationObservation(controls, { orgId })).pipe(Effect.filterOrFail((result) => result.orgId === orgId, () => Errors.invalidInput("orgId", "Invalid Organization Payment list")), Effect.map((result) => mapPage(result, (payment) => normalizePaymentTiming(payment)))), controls, records.listForOrganization.name, deps.runPromise);
18360
+ },
18361
+ get(paymentId, options) {
18362
+ const controls = deps.invocationControls?.(options) ?? options;
18363
+ return runCapxulEffect(Effect.gen(function* () {
18364
+ const id = yield* exactPaymentId(paymentId);
18365
+ const response = yield* callOperation(deps.convexCall, records.getForOrganization, copyInvocationObservation(controls, {
18366
+ orgId,
18367
+ paymentId: id
18368
+ }));
18369
+ if (response.orgId !== orgId) return yield* Effect.fail(Errors.invalidInput("orgId", "Payment read scope does not match"));
18370
+ const decoded = response.payment;
18371
+ if (decoded === null) return null;
18372
+ if (decoded.id !== id) return yield* Effect.fail(Errors.invalidInput("paymentId", "Invalid Organization Payment response"));
18373
+ return normalizePaymentTiming(decoded);
18374
+ }), controls, records.getForOrganization.name, deps.runPromise);
18375
+ },
18376
+ subscribe(paymentId, listener, options) {
18377
+ const parsed = Schema.decodeResult(PaymentIdSchema)(paymentId);
18378
+ if (parsed._tag === "Failure") return Promise.resolve({
18379
+ ok: false,
18380
+ error: Errors.invalidInput("paymentId", "Provide one exact Payment ID")
18381
+ });
18382
+ return subscribeOrganizationPayment({
18383
+ actor: deps.actor,
18384
+ convexCall: deps.convexCall,
18385
+ getPayment: reference(records.getForOrganization),
18386
+ runPromise: deps.runPromise,
18387
+ invocationControls: deps.invocationControls
18388
+ }, orgId, parsed.success, listener, options);
18389
+ }
18390
+ };
18391
+ }
18392
+ //#endregion
18344
18393
  //#region src/payments/organization-flights.ts
18345
- function executionDependencies(input) {
18394
+ function executionDependencies$1(input) {
18346
18395
  return input.actor === void 0 || input.chainId === void 0 || input.signer === void 0 ? null : {
18347
18396
  actor: input.actor,
18348
18397
  chainId: input.chainId,
@@ -18363,7 +18412,7 @@ async function executeOrganizationBatch(scope, input, signal, operation, control
18363
18412
  };
18364
18413
  const intent = organizationPaymentIntent(scope.orgId, input);
18365
18414
  if (!intent.ok) return intent;
18366
- const execution = executionDependencies(scope.deps);
18415
+ const execution = executionDependencies$1(scope.deps);
18367
18416
  if (execution === null) return {
18368
18417
  ok: false,
18369
18418
  error: Errors.notImplemented("organizationPayments", "executionComposition")
@@ -18487,7 +18536,7 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
18487
18536
  const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
18488
18537
  const captured = carryInvocationParentSpan(controls, parent);
18489
18538
  return yield* awaitCapxulResult(async () => {
18490
- const execution = executionDependencies(deps);
18539
+ const execution = executionDependencies$1(deps);
18491
18540
  if (execution === null) return {
18492
18541
  ok: false,
18493
18542
  error: Errors.notImplemented("organizationPayments", "executionComposition")
@@ -19251,50 +19300,650 @@ function sleep(ms, signal) {
19251
19300
  });
19252
19301
  }
19253
19302
  //#endregion
19254
- //#region src/accounts/approvals.ts
19255
- function makeApprovalsMethods(deps) {
19256
- const call = (name, row, args, signal) => runIfActive(signal, name, () => callOperation(deps.convexCall, row, args, { fresh: true }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
19257
- const get = (approvalId) => call(approvals.get.name, approvals.get, { approvalId });
19258
- const prepare = async (input, options) => {
19259
- const signal = options?.signal;
19260
- const intent = paymentExecutionIntent(input);
19261
- if (!intent.ok) return intent;
19262
- const { actor, chainId } = deps;
19263
- if (actor === void 0 || chainId === void 0) return {
19264
- ok: false,
19265
- error: Errors.notImplemented("approvals", "prepareComposition")
19266
- };
19267
- const session = actor.authSession();
19268
- if (session === null) return {
19269
- ok: false,
19270
- error: Errors.notAuthenticated()
19271
- };
19272
- const safe = await call(CAPXUL_OPERATIONS.approvals.prepare, safes.loadByAuthUserId, { authUserId: session.authUserId }, signal);
19273
- if (!safe.ok) return safe;
19274
- if (safe.value === null) return {
19275
- ok: false,
19276
- error: Errors.smartAccountMissing(session.authUserId)
19277
- };
19278
- if (safe.value.signerAddress === null) return {
19279
- ok: false,
19280
- error: Errors.wrongState({
19303
+ //#region ../protocol/src/payroll/model.ts
19304
+ function toPayrollRunId(raw) {
19305
+ return toNonEmptyStringBrand(raw, "payrollRunId", (value) => isNonEmptyString(value));
19306
+ }
19307
+ function toPayrollGroupId(raw) {
19308
+ return toNonEmptyStringBrand(raw, "payrollGroupId", (value) => isNonEmptyString(value));
19309
+ }
19310
+ //#endregion
19311
+ //#region src/payroll/run-checks.ts
19312
+ /** Match the caller's compensation to the committed V3 Payslip. */
19313
+ function payslipIdentityMatches(message, item, index, runId, period) {
19314
+ return message.runId === runId && message.itemIndex === index && message.employeeRef === item.partyId && message.periodStart === period.start && message.periodEnd === period.end && message.adjustmentsHash === hashAdjustmentsV3(item.adjustments);
19315
+ }
19316
+ function payslipAmountMatches(message, item) {
19317
+ const exact = toExactAssetAmount(item.amount, CONFIGURED_MONEY_ASSETS);
19318
+ return message.gross.asset === exact.asset && message.gross.minorUnits === item.gross && message.gross.decimals === exact.decimals && message.net.asset === exact.asset && message.net.minorUnits === item.net && message.net.decimals === exact.decimals;
19319
+ }
19320
+ function isRunItem(prepared, item, evidence, index, runId, period) {
19321
+ if (prepared === void 0) return false;
19322
+ const bundle = evidence.preparedCommand?.documentBundles?.[index];
19323
+ const preparedItem = evidence.preparedCommand?.items[index];
19324
+ const payslip = bundle?.envelope;
19325
+ if (bundle === void 0 || payslip?.primaryType !== "Payslip") return false;
19326
+ return canonicalJson(prepared.to) === canonicalJson(item.to) && prepared.paymentType === "payroll" && canonicalJson(prepared.amount) === canonicalJson(item.amount) && bundle.adjustments !== void 0 && canonicalJson(bundle.adjustments) === canonicalJson(item.adjustments) && payslipIdentityMatches(payslip.message, item, index, runId, period) && payslipAmountMatches(payslip.message, item) && (preparedItem?.operation === "send" || preparedItem?.operation === "create_commitment") && preparedItem.documentHash === evidence.preparedCommand?.instructionDocuments?.[index]?.documentHash;
19327
+ }
19328
+ /**
19329
+ * The batch the backend derived from a payroll intent must be the batch this
19330
+ * caller asked for, checked before the digest is signed.
19331
+ *
19332
+ * The payslip envelope on each item is server-built and carries the run row's
19333
+ * own `issuedAt`, so the batch cannot be fingerprinted against a local copy
19334
+ * (`matchesIntent` is unavailable here). What CAN be verified is every field
19335
+ * the caller supplied — the org, the Budget, the request key, and per item the
19336
+ * recipient, the amount and the payslip figures — plus the lineage binding the
19337
+ * batch to the run just written. A prepared command that pays a different
19338
+ * person, a different amount, from a different Budget, or under a different
19339
+ * run never reaches the signer.
19340
+ */
19341
+ function isRunBatch(input) {
19342
+ return (batch, evidence) => Promise.resolve(!("kind" in batch) && batch.orgId === input.orgId && batch.permissionId === input.permissionId && batch.requestKey === input.requestKey && batch.lineage?.kind === "payroll" && batch.lineage.runId === input.runId && batch.items.length === input.items.length && batch.items.every((item) => item.amount.asset === input.asset) && input.items.every((item, index) => isRunItem(batch.items[index], item, evidence, index, input.runId, input.period)));
19343
+ }
19344
+ /**
19345
+ * The batch is `isRunBatch` for the run the backend just wrote, and that run
19346
+ * is the period the caller asked for: the payslip's `period` is a
19347
+ * server-formatted label, so the stored run is where the caller's own two
19348
+ * numbers are checkable.
19349
+ */
19350
+ function isAuthorizedRunBatch(input, run) {
19351
+ return (request, evidence) => run === void 0 || run.periodStart !== input.period.start || run.periodEnd !== input.period.end ? Promise.resolve(false) : isRunBatch({
19352
+ ...input,
19353
+ runId: run.id
19354
+ })(request, evidence);
19355
+ }
19356
+ /** A decoded detail is the run asked for, whole: its scope, membership and quantities agree. */
19357
+ function checkPayrollRunDetail(value, orgId, runId) {
19358
+ if (value === null) return {
19359
+ ok: true,
19360
+ value: null
19361
+ };
19362
+ if (value.orgId !== orgId || value.run.id !== runId || value.items.length === 0 || value.items.length !== value.run.recipientCount || new Set(value.items.map((item) => item.payment.id)).size !== value.items.length || value.items.some((item, index) => item.itemIndex !== index || item.amount.asset !== value.run.total.asset || item.payment.amount.asset !== item.amount.asset || item.payment.paymentType !== "payroll")) return {
19363
+ ok: false,
19364
+ error: Errors.invalidInput("run", "Payroll run scope or membership does not match")
19365
+ };
19366
+ try {
19367
+ const total = toExactAssetAmount(value.run.total, CONFIGURED_MONEY_ASSETS);
19368
+ let rawTotal = 0n;
19369
+ for (const item of value.items) {
19370
+ const amount = toExactAssetAmount(item.amount, CONFIGURED_MONEY_ASSETS);
19371
+ const payment = toExactAssetAmount(item.payment.amount, CONFIGURED_MONEY_ASSETS);
19372
+ if (amount.minorUnits !== payment.minorUnits) return {
19373
+ ok: false,
19374
+ error: Errors.invalidInput("run", "Payroll item quantity does not match its Payment")
19375
+ };
19376
+ rawTotal += BigInt(amount.minorUnits);
19377
+ }
19378
+ if (rawTotal !== BigInt(total.minorUnits)) return {
19379
+ ok: false,
19380
+ error: Errors.invalidInput("run", "Payroll run total does not match its items")
19381
+ };
19382
+ } catch {
19383
+ return {
19384
+ ok: false,
19385
+ error: Errors.invalidInput("run", "Payroll run quantities are invalid")
19386
+ };
19387
+ }
19388
+ return {
19389
+ ok: true,
19390
+ value
19391
+ };
19392
+ }
19393
+ //#endregion
19394
+ //#region src/payroll/run-decoding.ts
19395
+ function toPayrollRun(wire) {
19396
+ return {
19397
+ id: toPayrollRunId(wire.id),
19398
+ status: wire.status,
19399
+ periodStart: wire.periodStart,
19400
+ periodEnd: wire.periodEnd,
19401
+ total: wire.total,
19402
+ recipientCount: wire.recipientCount
19403
+ };
19404
+ }
19405
+ function toPayrollRuns(wire) {
19406
+ return {
19407
+ ...mapPage(wire, toPayrollRun),
19408
+ settledThisMonth: wire.settledThisMonth
19409
+ };
19410
+ }
19411
+ function toPayrollGroup(wire) {
19412
+ return {
19413
+ id: toPayrollGroupId(wire.id),
19414
+ name: wire.name,
19415
+ tone: wire.tone,
19416
+ members: wire.members.map((member) => ({
19417
+ partyId: member.partyId,
19418
+ amount: member.amount,
19419
+ currency: member.currency
19420
+ }))
19421
+ };
19422
+ }
19423
+ function validateRunItems(input) {
19424
+ for (const [index, item] of input.items.entries()) {
19425
+ if (Schema.decodeResult(PayrollRunItemInputSchema, { onExcessProperty: "error" })(item)._tag === "Failure") return Errors.invalidInput(`items.${index}`, "invalid Payroll item");
19426
+ try {
19427
+ const exact = toExactAssetAmount(item.amount, CONFIGURED_MONEY_ASSETS);
19428
+ const net = BigInt(item.net);
19429
+ const gross = BigInt(item.gross);
19430
+ const adjustments = item.adjustments.reduce((sum, row) => sum + BigInt(row.amount), 0n);
19431
+ if (item.amount.asset !== input.asset || item.net !== exact.minorUnits || gross + adjustments !== net) return Errors.invalidInput(`items.${index}`, "invalid Payroll units");
19432
+ } catch {
19433
+ return Errors.invalidInput(`items.${index}`, "invalid Payroll units");
19434
+ }
19435
+ }
19436
+ return null;
19437
+ }
19438
+ const RunInputSchema = Schema.Struct({
19439
+ permissionId: AuthorizePayrollRunExecutionInputSchema.fields.permissionId,
19440
+ asset: AuthorizePayrollRunExecutionInputSchema.fields.asset,
19441
+ period: AuthorizePayrollRunExecutionInputSchema.fields.period,
19442
+ items: AuthorizePayrollRunExecutionInputSchema.fields.items,
19443
+ requestKey: Schema.optional(AuthorizePayrollRunExecutionInputSchema.fields.requestKey)
19444
+ });
19445
+ /** Decode caller input before session or signer work. Keep routing outside the input. */
19446
+ function decodePayrollRunInput(value) {
19447
+ try {
19448
+ const decoded = Schema.decodeUnknownSync(RunInputSchema, { onExcessProperty: "error" })(value);
19449
+ const input = {
19450
+ permissionId: decoded.permissionId,
19451
+ asset: decoded.asset,
19452
+ period: decoded.period,
19453
+ ...decoded.requestKey === void 0 ? {} : { requestKey: decoded.requestKey },
19454
+ items: decoded.items.map((item) => ({
19455
+ amount: item.amount,
19456
+ gross: item.gross,
19457
+ net: item.net,
19458
+ adjustments: item.adjustments,
19459
+ partyId: toPartyId(item.partyId),
19460
+ to: item.to.kind === "party" ? {
19461
+ kind: "party",
19462
+ partyId: toPartyId(item.to.partyId)
19463
+ } : item.to.kind === "address" ? {
19464
+ kind: "address",
19465
+ address: toAddress(item.to.address)
19466
+ } : item.to
19467
+ }))
19468
+ };
19469
+ if (input.items.length === 0 || input.period.start > input.period.end) throw Errors.invalidInput("input", "Payroll requires items and an ordered period");
19470
+ const error = validateRunItems(input);
19471
+ if (error !== null) throw error;
19472
+ return input;
19473
+ } catch (cause) {
19474
+ throw cause instanceof CapxulError ? cause : Errors.invalidInput("input", "Invalid Payroll input");
19475
+ }
19476
+ }
19477
+ /** Read only the exact backend prepare receipt, never an arbitrary signer failure. */
19478
+ function payrollResolution(error, requestKey) {
19479
+ const details = error.details;
19480
+ if (error.code !== "WRONG_STATE" || details?.method !== runs.authorize.name || details.requestKey !== requestKey || typeof details.commandId !== "string" || typeof details.runId !== "string") return void 0;
19481
+ return details.payrollResolution === "failed" || details.payrollResolution === "settled" ? details.payrollResolution : void 0;
19482
+ }
19483
+ function validatePayrollRunLookup(orgId, runId) {
19484
+ return !Schema.is(PayrollRunIdSchema)(runId) || orgId.length === 0 ? {
19485
+ ok: false,
19486
+ error: Errors.invalidInput("runId", "Organization and run ID must be valid")
19487
+ } : {
19488
+ ok: true,
19489
+ value: void 0
19490
+ };
19491
+ }
19492
+ /** Strict saved detail decoder shared by the read and fresh stream. */
19493
+ function decodePayrollRunDetail(raw, orgId, runId) {
19494
+ const decoded = Schema.decodeUnknownResult(Schema.NullOr(PayrollRunDetailSchema), { onExcessProperty: "error" })(raw);
19495
+ if (decoded._tag === "Failure") return {
19496
+ ok: false,
19497
+ error: Errors.invalidInput("run", "Invalid Payroll run detail")
19498
+ };
19499
+ return checkPayrollRunDetail(decoded.success, orgId, runId);
19500
+ }
19501
+ //#endregion
19502
+ //#region src/payroll/run-subscription.ts
19503
+ function detailValue(result) {
19504
+ if (!result.ok) throw result.error;
19505
+ return result.value;
19506
+ }
19507
+ function subscribePayrollRun(deps, orgId, runId, listener, options) {
19508
+ const operation = CAPXUL_OPERATIONS.org.payroll.subscribeRun;
19509
+ const valid = deps.validate(orgId, runId);
19510
+ if (!valid.ok) return runCapxulEffect(Effect.fail(valid.error), observationOnlyControls(deps.invocationControls?.(options) ?? options), operation, deps.runPromise);
19511
+ const decode = (raw) => detailValue(deps.decode(raw, orgId, runId));
19512
+ return subscribeFreshQuery(deps, {
19513
+ orgId,
19514
+ runId
19515
+ }, listener, operation, {
19516
+ decode,
19517
+ validateCached: (raw) => {
19518
+ decode(raw);
19519
+ },
19520
+ invalidValue: (cause) => isCapxulError(cause) ? cause : Errors.invalidInput("run", "Invalid Payroll run detail"),
19521
+ invalidScope: () => Errors.invalidInput("run", "Payroll run subscription scope does not match"),
19522
+ lostValue: () => Errors.invalidInput("run", "Payroll run is no longer readable"),
19523
+ unavailable: () => Errors.notImplemented("payroll", "subscribeRun")
19524
+ }, options);
19525
+ }
19526
+ //#endregion
19527
+ //#region src/payroll/run-authorization.ts
19528
+ /**
19529
+ * Authorize one payroll run: a stable request key, the prepared batch checked
19530
+ * against the run the caller asked for, the signature, and the submission.
19531
+ */
19532
+ async function authorizePayrollRun(scope, input, controls, onRequestKey, onResolved) {
19533
+ const { deps, orgId, requestKeyScope } = scope;
19534
+ const signal = controls?.signal;
19535
+ const execution = executionDependencies(deps);
19536
+ if (execution === null) return {
19537
+ ok: false,
19538
+ error: Errors.notImplemented("payroll", "executionComposition")
19539
+ };
19540
+ try {
19541
+ input = decodePayrollRunInput(input);
19542
+ } catch (cause) {
19543
+ return {
19544
+ ok: false,
19545
+ error: asCapxulError(cause)
19546
+ };
19547
+ }
19548
+ const { requestKey: provided, ...canonicalInput } = input;
19549
+ const actorId = onRequestKey === void 0 ? void 0 : execution.actor.authSession()?.authUserId;
19550
+ if (onRequestKey !== void 0 && actorId === void 0) return {
19551
+ ok: false,
19552
+ error: Errors.notAuthenticated()
19553
+ };
19554
+ const requestKey = await paymentRequestKeyLifecycle(`${requestKeyScope}:${AUTHORIZE_RUN}`, onRequestKey === void 0 ? {
19555
+ orgId,
19556
+ input
19557
+ } : {
19558
+ actorId,
19559
+ orgId,
19560
+ input: canonicalInput
19561
+ }, provided, onRequestKey === void 0 ? void 0 : { manageProvidedKey: true });
19562
+ try {
19563
+ await onRequestKey?.(requestKey.key);
19564
+ if (onRequestKey !== void 0 && execution.actor.authSession()?.authUserId !== actorId) {
19565
+ await requestKey.finish(false).catch(() => void 0);
19566
+ return {
19567
+ ok: false,
19568
+ error: Errors.notAuthenticated()
19569
+ };
19570
+ }
19571
+ } catch (cause) {
19572
+ await requestKey.finish(false).catch(() => void 0);
19573
+ return {
19574
+ ok: false,
19575
+ error: asCapxulError(cause)
19576
+ };
19577
+ }
19578
+ let authorized;
19579
+ let acceptedReplay;
19580
+ let preparedClosed = false;
19581
+ let terminalReplay;
19582
+ const submitted = await executePrepared(execution, async (signerAddress) => {
19583
+ const prepared = await runIfActive(signal, AUTHORIZE_RUN, () => withInvocationParentSpan(Effect.suspend(() => callOperation(deps.convexCall, runs.authorize, copyInvocationObservation(controls, {
19584
+ orgId,
19585
+ permissionId: input.permissionId,
19586
+ asset: input.asset,
19587
+ requestKey: requestKey.key,
19588
+ signerAddress,
19589
+ period: input.period,
19590
+ items: input.items
19591
+ }))).pipe(Effect.mapError((publicError) => ({ publicError }))), controls), deps.runPromise);
19592
+ if (!prepared.ok) {
19593
+ terminalReplay = payrollResolution(prepared.error, requestKey.key);
19594
+ return prepared;
19595
+ }
19596
+ authorized = prepared.value.run;
19597
+ acceptedReplay = prepared.value.replay.kind === "accepted" ? prepared.value.replay.submission : void 0;
19598
+ return {
19599
+ ok: true,
19600
+ value: prepared.value.execution
19601
+ };
19602
+ }, (request, evidence) => isAuthorizedRunBatch({
19603
+ orgId,
19604
+ permissionId: input.permissionId,
19605
+ requestKey: requestKey.key,
19606
+ asset: input.asset,
19607
+ period: input.period,
19608
+ items: input.items
19609
+ }, authorized)(request, evidence), true, () => preparedClosed = true, signal, controls, void 0, () => acceptedReplay);
19610
+ const resolution = preparedClosed ? "failed" : terminalReplay;
19611
+ if (resolution !== void 0) try {
19612
+ await onResolved?.(resolution);
19613
+ } catch {}
19614
+ try {
19615
+ await requestKey.finish(submitted.ok || resolution !== void 0);
19616
+ } catch {}
19617
+ if (!submitted.ok) return submitted;
19618
+ return authorized === void 0 ? {
19619
+ ok: false,
19620
+ error: Errors.unknown()
19621
+ } : {
19622
+ ok: true,
19623
+ value: toPayrollRun(authorized)
19624
+ };
19625
+ }
19626
+ const AUTHORIZE_RUN = runs.authorize.name;
19627
+ function executionDependencies(deps) {
19628
+ return deps.actor === void 0 || deps.chainId === void 0 || deps.signer === void 0 ? null : {
19629
+ actor: deps.actor,
19630
+ chainId: deps.chainId,
19631
+ convexCall: deps.convexCall,
19632
+ runPromise: deps.runPromise,
19633
+ signer: deps.signer,
19634
+ ...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
19635
+ };
19636
+ }
19637
+ //#endregion
19638
+ //#region src/payroll/runs.ts
19639
+ function makePayrollMethods(deps, orgId) {
19640
+ const requestKeyScope = deps.requestKeyScope ?? `client-${crypto.randomUUID()}`;
19641
+ /** One observed call of one payroll row, its reply projected inside the call, under the row's name. */
19642
+ const call = (row, args, options, project) => {
19643
+ const controls = deps.invocationControls?.(options) ?? options;
19644
+ return runPortEffect(callOperation(deps.convexCall, row, copyInvocationObservation(controls, args)).pipe(Effect.map(project), Effect.mapError((publicError) => ({ publicError }))), controls, row.name, deps.runPromise);
19645
+ };
19646
+ return {
19647
+ subscribeRun: (runId, listener, options) => subscribePayrollRun({
19648
+ actor: deps.actor,
19649
+ convexCall: deps.convexCall,
19650
+ query: reference(runs.get),
19651
+ runPromise: deps.runPromise,
19652
+ invocationControls: deps.invocationControls,
19653
+ decode: decodePayrollRunDetail,
19654
+ validate: validatePayrollRunLookup
19655
+ }, orgId, runId, listener, options),
19656
+ getRun: (runId, options) => {
19657
+ const controls = deps.invocationControls?.(options) ?? options;
19658
+ const lifetime = deps.actor?.authLifetime();
19659
+ const operation = runs.get.name;
19660
+ return runCapxulEffect(Effect.gen(function* () {
19661
+ const lookup = validatePayrollRunLookup(orgId, runId);
19662
+ if (!lookup.ok) return yield* Effect.fail(lookup.error);
19663
+ if (lifetime === void 0 || lifetime.authUserId === null || deps.actor === void 0) return yield* Effect.fail(Errors.notAuthenticated());
19664
+ const current = () => deps.actor?.matchesAuthLifetime(lifetime, lifetime.authUserId) === true;
19665
+ if (!current()) return yield* Effect.fail(Errors.notAuthenticated());
19666
+ const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
19667
+ const captured = carryInvocationParentSpan(controls, parent);
19668
+ const run = yield* awaitCapxulResult(() => runIfActive(controls?.signal, operation, () => withInvocationParentSpan(Effect.suspend(() => callOperation(deps.convexCall, runs.get, copyInvocationObservation(captured, {
19669
+ orgId,
19670
+ runId
19671
+ }))).pipe(Effect.mapError((publicError) => ({ publicError }))), captured), deps.runPromise));
19672
+ if (!current()) return yield* Effect.fail(Errors.cancelled({ operation }));
19673
+ const checked = checkPayrollRunDetail(run, orgId, runId);
19674
+ return yield* checked.ok ? Effect.succeed(checked.value) : Effect.fail(checked.error);
19675
+ }), observationOnlyControls(controls), operation, deps.runPromise);
19676
+ },
19677
+ runs: (options) => call(runs.list, { orgId }, options, toPayrollRuns),
19678
+ authorizeRun: (input, options) => {
19679
+ const controls = deps.invocationControls?.(options) ?? options;
19680
+ return runCapxulEffect(Effect.gen(function* () {
19681
+ if (controls?.signal?.aborted === true) return yield* Effect.fail(Errors.cancelled({ operation: AUTHORIZE_RUN }));
19682
+ const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
19683
+ return yield* awaitCapxulResult(() => authorizePayrollRun({
19684
+ deps,
19685
+ orgId,
19686
+ requestKeyScope
19687
+ }, input, carryInvocationParentSpan(controls, parent), options?.onRequestKey, options?.onResolved));
19688
+ }), observationOnlyControls(controls), AUTHORIZE_RUN, deps.runPromise);
19689
+ },
19690
+ terms: (options) => call(terms.list, { orgId }, options, (rates) => rates),
19691
+ groups: {
19692
+ list: (options) => call(groups.list, { orgId }, options, (saved) => mapPage(saved, toPayrollGroup)),
19693
+ save: (input, options) => call(groups.save, {
19694
+ orgId,
19695
+ ...input.id === void 0 ? {} : { id: String(input.id) },
19696
+ name: input.name,
19697
+ tone: input.tone,
19698
+ members: input.members
19699
+ }, options, toPayrollGroup),
19700
+ remove: (id, options) => call(groups.remove, {
19701
+ orgId,
19702
+ id
19703
+ }, options, () => void 0)
19704
+ }
19705
+ };
19706
+ }
19707
+ const payrollUnavailable = () => Promise.resolve({
19708
+ ok: false,
19709
+ error: Errors.notImplemented("payroll", "executionComposition")
19710
+ });
19711
+ /** The bundle an unconfigured client exposes — every verb refuses, none throws. */
19712
+ function makeUnavailablePayrollMethods() {
19713
+ return {
19714
+ getRun: payrollUnavailable,
19715
+ subscribeRun: payrollUnavailable,
19716
+ runs: payrollUnavailable,
19717
+ authorizeRun: payrollUnavailable,
19718
+ terms: payrollUnavailable,
19719
+ groups: {
19720
+ list: payrollUnavailable,
19721
+ save: payrollUnavailable,
19722
+ remove: payrollUnavailable
19723
+ }
19724
+ };
19725
+ }
19726
+ //#endregion
19727
+ //#region src/accounts/command-approvals.ts
19728
+ /**
19729
+ * Keep a prepared command only when it is the one asked for and its operation
19730
+ * is the person's own. A mismatch is closed unsent when `close`, as the signed
19731
+ * path closes a new Payment; a retry or a request keeps its Payment open.
19732
+ */
19733
+ async function checked(deps, signerAddress, prepared, expected, close) {
19734
+ if (!prepared.ok) return prepared;
19735
+ const session = deps.actor?.authSession() ?? null;
19736
+ if (session === null || deps.chainId === void 0) return {
19737
+ ok: false,
19738
+ error: Errors.notAuthenticated()
19739
+ };
19740
+ const evidence = prepared.value;
19741
+ if (await expected(evidence.request, evidence) && await verifiedPreparedCommand(evidence, session.email, signerAddress, deps.chainId)) return prepared;
19742
+ const refused = {
19743
+ ok: false,
19744
+ error: Errors.invalidInput("execution", "prepared command mismatch")
19745
+ };
19746
+ return close ? abandonPrepared(deps, evidence.executionId, "prepared_mismatch", refused) : refused;
19747
+ }
19748
+ /** A retry, a request payment or a payroll run, rather than a new Payment. */
19749
+ const isCommandApproval = (input) => "retry" in input || "request" in input || "payrollRun" in input;
19750
+ /** Prepare a retry, a request payment or a payroll run for `signerAddress`, checked. */
19751
+ function prepareVerifiedCommand(deps, input, signerAddress, signal) {
19752
+ if ("retry" in input) return prepareVerifiedRetry(deps, input, signerAddress, signal);
19753
+ if ("request" in input) return prepareVerifiedRequestPayment(deps, input, signerAddress, signal);
19754
+ return prepareVerifiedPayrollRun(deps, input, signerAddress, signal);
19755
+ }
19756
+ /** The retry of one Payment, prepared in the scope that paid it. */
19757
+ async function prepareVerifiedRetry(deps, input, signerAddress, signal) {
19758
+ const intent = {
19759
+ kind: "retry",
19760
+ paymentId: input.retry
19761
+ };
19762
+ return checked(deps, signerAddress, await runIfActive(signal, CAPXUL_OPERATIONS.payments.prepareLifecycleExecution, () => callOperation(deps.convexCall, lifecycles.prepareScoped, {
19763
+ signerAddress,
19764
+ intent,
19765
+ expectedScope: input.organizationId === void 0 ? { kind: "account" } : {
19766
+ kind: "organization",
19767
+ orgId: input.organizationId
19768
+ }
19769
+ }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise), lifecycleCommandCheck(intent, input.organizationId), false);
19770
+ }
19771
+ /** The Payment of one request, exactly as the request froze it. */
19772
+ async function prepareVerifiedRequestPayment(deps, input, signerAddress, signal) {
19773
+ const decoded = Schema.decodeResult(RequestPaymentConfirmationSchema, { onExcessProperty: "error" })(input.request);
19774
+ if (decoded._tag === "Failure") return {
19775
+ ok: false,
19776
+ error: Errors.invalidInput("confirmation", "invalid request confirmation")
19777
+ };
19778
+ const confirmation = decoded.success;
19779
+ return checked(deps, signerAddress, await runIfActive(signal, commands$1.prepareRequest.name, () => callOperation(deps.convexCall, commands$1.prepareRequest, {
19780
+ confirmation,
19781
+ signerAddress
19782
+ }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise), requestPaymentCheck(confirmation), false);
19783
+ }
19784
+ /** One payroll run: the run the backend writes and the batch that pays it, checked together. */
19785
+ async function prepareVerifiedPayrollRun(deps, input, signerAddress, signal) {
19786
+ let run;
19787
+ try {
19788
+ run = decodePayrollRunInput(input.payrollRun);
19789
+ } catch (cause) {
19790
+ return {
19791
+ ok: false,
19792
+ error: asCapxulError(cause)
19793
+ };
19794
+ }
19795
+ const orgId = input.organizationId;
19796
+ const requestKey = run.requestKey ?? `payroll_${crypto.randomUUID()}`;
19797
+ const { permissionId, asset, period, items } = run;
19798
+ const authorized = await runIfActive(signal, runs.authorize.name, () => callOperation(deps.convexCall, runs.authorize, {
19799
+ orgId,
19800
+ permissionId,
19801
+ asset,
19802
+ requestKey,
19803
+ signerAddress,
19804
+ period,
19805
+ items
19806
+ }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
19807
+ if (!authorized.ok) return authorized;
19808
+ return checked(deps, signerAddress, {
19809
+ ok: true,
19810
+ value: authorized.value.execution
19811
+ }, isAuthorizedRunBatch({
19812
+ orgId,
19813
+ permissionId,
19814
+ requestKey,
19815
+ asset,
19816
+ period,
19817
+ items
19818
+ }, authorized.value.run), authorized.value.replay.kind !== "accepted");
19819
+ }
19820
+ //#endregion
19821
+ //#region src/accounts/organization-approvals.ts
19822
+ /** The Organization Payment prepared for `signerAddress` and checked, before any approval. */
19823
+ async function prepareVerifiedOrganizationPayment(deps, input, signerAddress, signal) {
19824
+ const { organizationId, permissionId, requestKey, lineage, ...item } = input;
19825
+ const intent = organizationPaymentIntent(organizationId, {
19826
+ permissionId,
19827
+ items: [item],
19828
+ ...lineage === void 0 ? {} : { lineage },
19829
+ ...requestKey === void 0 ? {} : { requestKey }
19830
+ });
19831
+ if (!intent.ok) return intent;
19832
+ const session = deps.actor?.authSession() ?? null;
19833
+ if (session === null || deps.chainId === void 0) return {
19834
+ ok: false,
19835
+ error: Errors.notAuthenticated()
19836
+ };
19837
+ const expected = {
19838
+ ...intent.value,
19839
+ requestKey: requestKey ?? `pay_${crypto.randomUUID()}`
19840
+ };
19841
+ const prepared = await runIfActive(signal, CAPXUL_OPERATIONS.organizationPayments.prepareExecution, () => callOperation(deps.convexCall, commands$1.prepareOrganization, {
19842
+ ...expected,
19843
+ signerAddress
19844
+ }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
19845
+ if (!prepared.ok) return prepared;
19846
+ const evidence = prepared.value;
19847
+ return await matchesIntent(expected)(evidence.request, evidence) && await verifiedPreparedCommand(evidence, session.email, signerAddress, deps.chainId) ? {
19848
+ ok: true,
19849
+ value: evidence
19850
+ } : abandonPrepared(deps, evidence.executionId, "prepared_mismatch", {
19851
+ ok: false,
19852
+ error: Errors.invalidInput("execution", "prepared Organization Payment mismatch")
19853
+ });
19854
+ }
19855
+ /** One fresh Payment read: the caller's own, or one in the Organization's scope. */
19856
+ const readPayment = (deps, paymentId, organizationId, signal) => organizationId === void 0 ? runIfActive(signal, records.get.name, () => callOperation(deps.convexCall, records.get, { paymentId }, { fresh: true }).pipe(Effect.map((payment) => ({ payment })), Effect.mapError((publicError) => ({ publicError }))), deps.runPromise) : runIfActive(signal, records.getForOrganization.name, () => callOperation(deps.convexCall, records.getForOrganization, {
19857
+ orgId: organizationId,
19858
+ paymentId
19859
+ }, { fresh: true }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
19860
+ /**
19861
+ * The Payments an approval carries, as they stand. A personal read names only
19862
+ * the caller's own Account's Payments, so an Organization's is read with its
19863
+ * `organizationId`; one that cannot be read is refused, never taken as ended.
19864
+ */
19865
+ async function readApprovalPayments(deps, paymentIds, organizationId, signal) {
19866
+ const reads = await Promise.all(paymentIds.map((paymentId) => readPayment(deps, paymentId, organizationId, signal)));
19867
+ const payments = [];
19868
+ for (const [index, read] of reads.entries()) {
19869
+ if (!read.ok) return read;
19870
+ const { orgId, payment } = read.value;
19871
+ if (payment === null && organizationId === void 0) return {
19872
+ ok: false,
19873
+ error: Errors.invalidInput("organizationId", "this approval pays from an Organization: wait with its organizationId")
19874
+ };
19875
+ if (payment === null || payment.id !== paymentIds[index] || orgId !== organizationId) return {
19876
+ ok: false,
19877
+ error: Errors.invalidInput("paymentId", "the approval's Payments are not this scope's")
19878
+ };
19879
+ payments.push(normalizePaymentTiming(payment));
19880
+ }
19881
+ return {
19882
+ ok: true,
19883
+ value: payments
19884
+ };
19885
+ }
19886
+ //#endregion
19887
+ //#region src/accounts/approvals.ts
19888
+ function makeApprovalsMethods(deps) {
19889
+ const call = (name, row, args, signal) => runIfActive(signal, name, () => callOperation(deps.convexCall, row, args, { fresh: true }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
19890
+ const get = (approvalId) => call(approvals.get.name, approvals.get, { approvalId });
19891
+ /**
19892
+ * Prepare for the signer the backend recorded when the Safe was claimed (the
19893
+ * person's own key signs later, on the approval page) and open the approval.
19894
+ */
19895
+ const openApproval = async (signal, prepareFor) => {
19896
+ const session = deps.actor?.authSession() ?? null;
19897
+ if (deps.actor === void 0 || deps.chainId === void 0) return {
19898
+ ok: false,
19899
+ error: Errors.notImplemented("approvals", "prepareComposition")
19900
+ };
19901
+ if (session === null) return {
19902
+ ok: false,
19903
+ error: Errors.notAuthenticated()
19904
+ };
19905
+ const safe = await call(CAPXUL_OPERATIONS.approvals.prepare, safes.loadByAuthUserId, { authUserId: session.authUserId }, signal);
19906
+ if (!safe.ok) return safe;
19907
+ if (safe.value === null) return {
19908
+ ok: false,
19909
+ error: Errors.smartAccountMissing(session.authUserId)
19910
+ };
19911
+ if (safe.value.signerAddress === null) return {
19912
+ ok: false,
19913
+ error: Errors.wrongState({
19281
19914
  method: CAPXUL_OPERATIONS.approvals.prepare,
19282
19915
  currentState: "unclaimed",
19283
19916
  validStates: ["claimed"]
19284
19917
  })
19285
19918
  };
19286
- const prepared = await prepareVerifiedPersonalPayment({
19287
- actor,
19288
- chainId,
19289
- convexCall: deps.convexCall,
19290
- runPromise: deps.runPromise
19291
- }, intent.value, safe.value.signerAddress, input.requestKey ?? `pay_${crypto.randomUUID()}`, signal);
19919
+ const prepared = await prepareFor(safe.value.signerAddress);
19292
19920
  if (!prepared.ok) return prepared;
19293
- await emitPreparedPaymentInitiated(deps, prepared.value);
19294
19921
  const { executionId } = prepared.value;
19295
19922
  const opened = await call(approvals.request.name, approvals.request, { executionId });
19296
19923
  return opened.ok ? opened : abandonPrepared(deps, executionId, "cancelled", opened);
19297
19924
  };
19925
+ const prepare = async (input, options) => {
19926
+ const signal = options?.signal;
19927
+ if (isCommandApproval(input)) return openApproval(signal, (signerAddress) => prepareVerifiedCommand(deps, input, signerAddress, signal));
19928
+ if ("organizationId" in input) return openApproval(signal, (signerAddress) => prepareVerifiedOrganizationPayment(deps, input, signerAddress, signal));
19929
+ const intent = paymentExecutionIntent(input);
19930
+ if (!intent.ok) return intent;
19931
+ const { actor, chainId } = deps;
19932
+ return openApproval(signal, async (signerAddress) => {
19933
+ if (actor === void 0 || chainId === void 0) return {
19934
+ ok: false,
19935
+ error: Errors.notImplemented("approvals", "prepareComposition")
19936
+ };
19937
+ const prepared = await prepareVerifiedPersonalPayment({
19938
+ actor,
19939
+ chainId,
19940
+ convexCall: deps.convexCall,
19941
+ runPromise: deps.runPromise
19942
+ }, intent.value, signerAddress, input.requestKey ?? `pay_${crypto.randomUUID()}`, signal);
19943
+ if (prepared.ok) await emitPreparedPaymentInitiated(deps, prepared.value);
19944
+ return prepared;
19945
+ });
19946
+ };
19298
19947
  const approve = async (approvalId) => {
19299
19948
  const { signer } = deps;
19300
19949
  if (signer === void 0) return {
@@ -19355,28 +20004,12 @@ function makeApprovalsMethods(deps) {
19355
20004
  }
19356
20005
  };
19357
20006
  };
19358
- const readPayments = async (approval, signal) => {
19359
- const reads = await Promise.all(approval.operation.paymentIds.map((paymentId) => call(records.get.name, records.get, { paymentId }, signal)));
19360
- const payments = [];
19361
- for (const read of reads) {
19362
- if (!read.ok) return read;
19363
- if (read.value === null) return {
19364
- ok: false,
19365
- error: Errors.notImplemented("approvals", "wait.organizationPayment")
19366
- };
19367
- payments.push(normalizePaymentTiming(read.value));
19368
- }
19369
- return {
19370
- ok: true,
19371
- value: payments
19372
- };
19373
- };
19374
20007
  /**
19375
20008
  * One read of the approval: its outcome when it has ended, or null to read
19376
20009
  * again. The Payments are read before anything is sent, so a send is never
19377
20010
  * made for Payments this caller cannot follow.
19378
20011
  */
19379
- const step = async (approvalId, signal) => {
20012
+ const step = async (approvalId, signal, organizationId) => {
19380
20013
  const read = await call(approvals.get.name, approvals.get, { approvalId }, signal);
19381
20014
  if (!read.ok) return read;
19382
20015
  const approval = read.value;
@@ -19384,7 +20017,7 @@ function makeApprovalsMethods(deps) {
19384
20017
  ok: true,
19385
20018
  value: null
19386
20019
  };
19387
- const payments = await readPayments(approval, signal);
20020
+ const payments = await readApprovalPayments(deps, approval.operation.paymentIds, organizationId ?? (approval.actor.kind === "organization" ? approval.actor.orgId : void 0), signal);
19388
20021
  if (!payments.ok) return payments;
19389
20022
  if (unsent(approval, payments.value)) {
19390
20023
  const sent = await submit(approvalId);
@@ -19405,7 +20038,7 @@ function makeApprovalsMethods(deps) {
19405
20038
  const signal = options?.signal;
19406
20039
  const intervalMs = options?.intervalMs ?? 2e3;
19407
20040
  const poll = async () => {
19408
- const stepped = await step(approvalId, signal);
20041
+ const stepped = await step(approvalId, signal, options?.organizationId);
19409
20042
  if (!stepped.ok) return stepped;
19410
20043
  if (stepped.value !== null) return {
19411
20044
  ok: true,
@@ -20608,10 +21241,803 @@ function makeSmartAccountMethods(deps) {
20608
21241
  };
20609
21242
  }
20610
21243
  //#endregion
21244
+ //#region src/activity/documents.ts
21245
+ /** A reply its row does not admit is refused without the document body its decode error would carry. */
21246
+ function withoutDocumentBody(error) {
21247
+ return error.details?.step === "decodeOutput" ? Errors.invalidInput("documentHash", "invalid document read") : error;
21248
+ }
21249
+ /** Schema errors must not retain document bodies. */
21250
+ function decodeDocumentRead(schema, input) {
21251
+ return Effect.fromOption(Schema.decodeUnknownOption(schema)(input)).pipe(Effect.mapError(() => ({ publicError: Errors.invalidInput("documentHash", "invalid document read") })));
21252
+ }
21253
+ function makePaymentDocumentsMethods(deps) {
21254
+ /**
21255
+ * One document read by its row. The pair is decoded before anything is sent,
21256
+ * and a reply the row does not admit is refused without the body it carried.
21257
+ */
21258
+ const readDocument = (row, ref, options) => {
21259
+ const controls = deps.invocationControls?.(options) ?? options;
21260
+ return runPortEffect(Effect.gen(function* () {
21261
+ const pair = yield* decodeDocumentRead(PaymentDocumentReadRefSchema, ref);
21262
+ return yield* callOperation(deps.convexCall, row, copyInvocationObservation(controls, pair)).pipe(Effect.mapError((error) => ({ publicError: withoutDocumentBody(error) })));
21263
+ }), controls, row.name, deps.runPromise);
21264
+ };
21265
+ return {
21266
+ get: (ref, options) => readDocument(documents.get, ref, options),
21267
+ verify: (ref, options) => readDocument(documents.verify, ref, options),
21268
+ render: (ref, options) => readDocument(documents.render, ref, options)
21269
+ };
21270
+ }
21271
+ //#endregion
21272
+ //#region src/activity/stitching.ts
21273
+ /** Epoch milliseconds of the block that carried the row. */
21274
+ function blockMillis(row) {
21275
+ return Number(row.timestamp) * 1e3;
21276
+ }
21277
+ /** `0x1234…abcd` — the counterparty of an unclaimed transfer is an address. */
21278
+ function shortAddressLabel(address) {
21279
+ return address.length <= 12 ? address : `${address.slice(0, 6)}…${address.slice(-4)}`;
21280
+ }
21281
+ function directionFor(safe, transfer) {
21282
+ const from = transfer.from.toLowerCase();
21283
+ const to = transfer.to.toLowerCase();
21284
+ if (from === safe && to === safe) return "self";
21285
+ return to === safe ? "in" : "out";
21286
+ }
21287
+ function withAnnotation(item, annotation) {
21288
+ return annotation?.counterpartyLabel === void 0 ? item : {
21289
+ ...item,
21290
+ counterpartyLabel: annotation.counterpartyLabel
21291
+ };
21292
+ }
21293
+ /**
21294
+ * An indexed settlement confirms the intent. A missing row can be outside
21295
+ * this page or still backfilling; only the correction owner can prove rollback.
21296
+ */
21297
+ function confirmPayment(intent, chain, expected) {
21298
+ if (chain !== void 0 && matchesPaymentFact(chain, expected)) return {
21299
+ ...intent,
21300
+ status: "settled",
21301
+ ...intent.execution === void 0 ? {} : { execution: {
21302
+ status: "settled",
21303
+ retryRequired: false
21304
+ } },
21305
+ receipt: {
21306
+ chainId: chain.chainId,
21307
+ transactionHash: chain.txHash
21308
+ },
21309
+ updatedAt: blockMillis(chain)
21310
+ };
21311
+ return intent;
21312
+ }
21313
+ function matchesPaymentFact(chain, expected) {
21314
+ return chain !== void 0 && expected !== void 0 && chain.chainId === expected.chainId && chain.contract.toLowerCase() === expected.contract.toLowerCase() && chain.sender.toLowerCase() === expected.sender.toLowerCase() && chain.recipient.toLowerCase() === expected.recipient.toLowerCase() && chain.token.toLowerCase() === expected.token.toLowerCase() && chain.amount.toString() === expected.rawAmount && chain.documentHash.toLowerCase() === expected.documentHash.toLowerCase() && chain.kind === expected.kind;
21315
+ }
21316
+ /**
21317
+ * One unclaimed Transfer as an Activity row, or `null` when this SDK cannot
21318
+ * denominate its asset. The indexer serves only configured assets, so a row
21319
+ * the registry does not know means the SDK and that deployment disagree; it is
21320
+ * dropped rather than shown with a guessed currency.
21321
+ */
21322
+ function isActivityVisible(item) {
21323
+ return !(item.kind === "payment" && item.direction === "in" && item.execution?.notSent);
21324
+ }
21325
+ function transferItem(safe, transfer, annotation) {
21326
+ const asset = configuredMoneyAssetById(transfer.assetId);
21327
+ if (asset === null) return null;
21328
+ const direction = directionFor(safe.toLowerCase(), transfer);
21329
+ const counterparty = direction === "in" ? transfer.from : transfer.to;
21330
+ const at = blockMillis(transfer);
21331
+ return withAnnotation({
21332
+ kind: "movement",
21333
+ id: transfer.id,
21334
+ classification: direction === "in" ? "deposit" : "movement_only_outflow",
21335
+ amount: {
21336
+ asset: asset.assetId,
21337
+ value: formatUnits(transfer.amount, asset.decimals)
21338
+ },
21339
+ direction,
21340
+ counterpartyLabel: shortAddressLabel(counterparty),
21341
+ receipt: {
21342
+ chainId: transfer.chainId,
21343
+ transactionHash: transfer.txHash
21344
+ },
21345
+ createdAt: at,
21346
+ updatedAt: at
21347
+ }, annotation);
21348
+ }
21349
+ /**
21350
+ * Money in, money out and the pending share, one bucket per exact asset.
21351
+ */
21352
+ function summarizeItems(items) {
21353
+ const buckets = /* @__PURE__ */ new Map();
21354
+ for (const item of items) {
21355
+ const metadata = configuredMoneyAssetById(item.amount.asset);
21356
+ if (metadata === null) continue;
21357
+ const key = item.amount.asset;
21358
+ const bucket = buckets.get(key) ?? {
21359
+ asset: item.amount.asset,
21360
+ in: 0n,
21361
+ out: 0n,
21362
+ pendingIn: 0n
21363
+ };
21364
+ const raw = rawUnits(item.amount.value, metadata.decimals);
21365
+ if (item.kind === "payment" && item.status !== "settled") {
21366
+ if (item.direction === "in" && item.status !== "cancelled" && item.status !== "failed" && !item.execution?.notSent) bucket.pendingIn += raw;
21367
+ } else if (item.direction === "in") bucket.in += raw;
21368
+ else if (item.direction === "out") bucket.out += raw;
21369
+ buckets.set(key, bucket);
21370
+ }
21371
+ return [...buckets.values()].map((bucket) => ({
21372
+ asset: bucket.asset,
21373
+ in: bucket.in.toString(),
21374
+ out: bucket.out.toString(),
21375
+ net: (bucket.in - bucket.out).toString(),
21376
+ pendingIn: bucket.pendingIn.toString()
21377
+ }));
21378
+ }
21379
+ /** The inverse of `formatUnits`, kept exact: `"1.25"` at 6 decimals is `1250000n`. */
21380
+ function rawUnits(value, decimals) {
21381
+ const negative = value.startsWith("-");
21382
+ const [whole = "0", fraction = ""] = (negative ? value.slice(1) : value).split(".");
21383
+ const raw = BigInt(`${whole}${fraction.padEnd(decimals, "0").slice(0, decimals)}`);
21384
+ return negative ? -raw : raw;
21385
+ }
21386
+ //#endregion
21387
+ //#region src/activity/cursor.ts
21388
+ function actorKey(actor) {
21389
+ return actor.kind === "account" ? `account:${actor.accountId}` : `organization:${actor.orgId}`;
21390
+ }
21391
+ function scopeKey(scope) {
21392
+ return `${scope.principalAccountId}|${actorKey(scope.actor)}|${scope.safe?.toLowerCase() ?? "none"}`;
21393
+ }
21394
+ function selectionKey(params) {
21395
+ const filter = params?.filter;
21396
+ return JSON.stringify([
21397
+ params?.range?.from ?? null,
21398
+ params?.range?.to ?? null,
21399
+ filter?.kind ?? null,
21400
+ filter?.direction ?? null,
21401
+ filter?.status === void 0 ? null : [...new Set(filter.status)].sort()
21402
+ ]);
21403
+ }
21404
+ function validString(value, max) {
21405
+ return typeof value === "string" && value.length <= max;
21406
+ }
21407
+ function validPosition(position) {
21408
+ return position === null || typeof position === "object" && "timestamp" in position && typeof position.timestamp === "number" && Number.isSafeInteger(position.timestamp) && position.timestamp >= 0 && "id" in position && typeof position.id === "string" && /^[1-9][0-9]{0,9}:0x[0-9a-f]{64}:[0-9]{1,10}$/.test(position.id);
21409
+ }
21410
+ function isActivityCursor(cursor, scope, selection) {
21411
+ return typeof cursor === "object" && cursor !== null && cursorScopeMatches(cursor, scope, selection) && cursorProgressIsValid(cursor);
21412
+ }
21413
+ /** The cursor was issued for this scope and filter selection, at a valid checkpoint. */
21414
+ function cursorScopeMatches(cursor, scope, selection) {
21415
+ return "version" in cursor && cursor.version === 1 && "scope" in cursor && cursor.scope === scope && "selection" in cursor && cursor.selection === selection && "checkpoint" in cursor && typeof cursor.checkpoint === "number" && Number.isSafeInteger(cursor.checkpoint) && cursor.checkpoint >= 0 && "source" in cursor && (cursor.source === "indexed" || cursor.source === "fallback");
21416
+ }
21417
+ /** Each source's progress is well-formed and bounded. */
21418
+ function cursorProgressIsValid(cursor) {
21419
+ return "paymentCursor" in cursor && (cursor.paymentCursor === null || validString(cursor.paymentCursor, 2048)) && "paymentDone" in cursor && typeof cursor.paymentDone === "boolean" && "transferDone" in cursor && typeof cursor.transferDone === "boolean" && "degraded" in cursor && typeof cursor.degraded === "boolean" && "paymentPending" in cursor && Array.isArray(cursor.paymentPending) && cursor.paymentPending.length <= 100 && new Set(cursor.paymentPending).size === cursor.paymentPending.length && cursor.paymentPending.every((id) => validString(id, 256)) && "transferBefore" in cursor && validPosition(cursor.transferBefore);
21420
+ }
21421
+ function parseCursor(value, scope, selection) {
21422
+ if (value === void 0) return null;
21423
+ if (value.length > 4e4) throw Errors.invalidInput("cursor", "invalid Activity cursor");
21424
+ const cursor = JSON.parse(value);
21425
+ if (!isActivityCursor(cursor, scope, selection)) throw Errors.invalidInput("cursor", "Activity scope or filters changed; restart from the first page");
21426
+ return cursor;
21427
+ }
21428
+ function requireParams(params) {
21429
+ const limit = params?.limit ?? 25;
21430
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100) throw Errors.invalidInput("limit", "must be an integer from 1 to 100");
21431
+ for (const value of [params?.range?.from, params?.range?.to]) if (value !== void 0 && !Number.isSafeInteger(value)) throw Errors.invalidInput("range", "must contain integer epoch milliseconds");
21432
+ const f = params?.filter;
21433
+ if (f?.kind !== void 0 && f.kind !== "payment" && f.kind !== "movement" || f?.direction !== void 0 && ![
21434
+ "in",
21435
+ "out",
21436
+ "self"
21437
+ ].includes(f.direction) || f?.status !== void 0 && (!Array.isArray(f.status) || !f.status.every((status) => PAYMENT_STATUSES.includes(status)))) throw Errors.invalidInput("filter", "invalid Activity filter");
21438
+ }
21439
+ function matchesFilter(item, filter) {
21440
+ return (filter?.kind === void 0 || item.kind === filter.kind) && (filter?.direction === void 0 || item.direction === filter.direction) && (filter?.status === void 0 || item.kind === "payment" && filter.status.includes(item.status));
21441
+ }
21442
+ //#endregion
21443
+ //#region src/activity/indexed-pages.ts
21444
+ function chainRead(deps, table, input) {
21445
+ return deps.indexer.read(table, input).pipe(Effect.catch((error) => {
21446
+ if (error.publicError.details?.reason === "scope-refused" || ![
21447
+ "NETWORK_ERROR",
21448
+ "RATE_LIMITED",
21449
+ "PROVIDER_ERROR",
21450
+ "CAPABILITY_UNAVAILABLE",
21451
+ "TIMEOUT"
21452
+ ].includes(error.publicCode)) return Effect.fail({ publicError: error.publicError });
21453
+ return Effect.succeed(null);
21454
+ }));
21455
+ }
21456
+ function boundedRange(range, checkpoint) {
21457
+ return {
21458
+ ...range?.from === void 0 ? {} : { from: range.from },
21459
+ to: Math.min(checkpoint, range?.to ?? checkpoint)
21460
+ };
21461
+ }
21462
+ function unavailablePage(deps, scope, controls, params, state, first) {
21463
+ if (first) return fallbackPage(deps, scope, controls, params, state, true);
21464
+ return Effect.annotateCurrentSpan({
21465
+ read_source: "indexer",
21466
+ read_warning: "indexer-unavailable"
21467
+ }).pipe(Effect.as({
21468
+ items: [],
21469
+ nextCursor: null,
21470
+ checkpoint: state.checkpoint,
21471
+ observedAt: Date.now(),
21472
+ readWarning: "indexer-unavailable"
21473
+ }));
21474
+ }
21475
+ function readTransfers(deps, safe, range, state, wanted, first) {
21476
+ const from = Math.max(0, Math.ceil((range.from ?? 0) / 1e3));
21477
+ const to = Math.floor(range.to / 1e3);
21478
+ if (state.transferDone || from > to || !wanted && !first) return Effect.succeed([]);
21479
+ return chainRead(deps, "transfer", {
21480
+ safe: toAddress(safe),
21481
+ limit: wanted ? 100 : 1,
21482
+ timeline: {
21483
+ from,
21484
+ to,
21485
+ ...state.transferBefore === null ? {} : { before: state.transferBefore }
21486
+ }
21487
+ });
21488
+ }
21489
+ function readPayments(deps, scope, controls, range, state, wanted) {
21490
+ const done = state.paymentDone || !wanted;
21491
+ if (state.paymentPending.length > 0 || done) return Effect.succeed({
21492
+ items: [],
21493
+ pending: state.paymentPending,
21494
+ cursor: state.paymentCursor,
21495
+ done
21496
+ });
21497
+ return convexPage(deps, scope.actor, controls, {
21498
+ limit: 100,
21499
+ range,
21500
+ filter: { kind: "payment" },
21501
+ ...state.paymentCursor === null ? {} : { cursor: state.paymentCursor }
21502
+ }).pipe(Effect.map((page) => ({
21503
+ items: page.items,
21504
+ pending: page.items.map((item) => item.id),
21505
+ cursor: page.nextCursor,
21506
+ done: page.nextCursor === null
21507
+ })));
21508
+ }
21509
+ function readPaymentFacts(deps, safe, settlements) {
21510
+ const offsets = Array.from({ length: Math.ceil(settlements.length / 50) }, (_, i) => i * 50);
21511
+ return Effect.forEach(offsets, (offset) => chainRead(deps, "payment", {
21512
+ safe: toAddress(safe),
21513
+ limit: 50,
21514
+ settlements: settlements.slice(offset, offset + 50)
21515
+ }), { concurrency: 2 }).pipe(Effect.map((pages) => pages.some((page) => page === null) ? null : pages.flatMap((page) => page ?? [])));
21516
+ }
21517
+ function indexedPage(deps, scope, controls, params, state, first) {
21518
+ return Effect.gen(function* () {
21519
+ const range = boundedRange(params?.range, state.checkpoint);
21520
+ const wantsTransfers = params?.filter?.kind !== "payment" && params?.filter?.status === void 0;
21521
+ const found = yield* readTransfers(deps, scope.safe, range, state, wantsTransfers, first);
21522
+ if (found === null) return yield* unavailablePage(deps, scope, controls, params, state, first);
21523
+ const transfers = wantsTransfers ? found : [];
21524
+ const page = yield* readPayments(deps, scope, controls, range, state, params?.filter?.kind !== "movement");
21525
+ const decoration = yield* decoratePage(deps, scope, controls, transfers, page, range);
21526
+ if (decoration === null) return yield* unavailablePage(deps, scope, controls, params, state, first);
21527
+ const { items, next } = mergePage(scope.safe, params?.filter, params?.limit ?? 25, state, page, decoration, transfers, wantsTransfers);
21528
+ const cursor = next.paymentDone && next.paymentPending.length === 0 && next.transferDone ? null : JSON.stringify(next);
21529
+ if (cursor !== null && cursor === params?.cursor) return yield* Effect.fail({ publicError: Errors.invalidInput("cursor", "Activity source did not advance") });
21530
+ yield* Effect.annotateCurrentSpan({ read_source: "indexer" });
21531
+ return {
21532
+ items,
21533
+ nextCursor: cursor,
21534
+ checkpoint: state.checkpoint,
21535
+ observedAt: Date.now()
21536
+ };
21537
+ });
21538
+ }
21539
+ //#endregion
21540
+ //#region src/activity/page-overlay.ts
21541
+ const MAX_OVERLAY_IDS = 200;
21542
+ function overlay(deps, actor, controls, input) {
21543
+ const count = Math.max(input.references?.length ?? 0, input.settlementIds?.length ?? 0);
21544
+ const offsets = Array.from({ length: Math.max(1, Math.ceil(count / MAX_OVERLAY_IDS)) }, (_, i) => i * MAX_OVERLAY_IDS);
21545
+ return Effect.forEach(offsets, (offset) => callOperation(deps.convexCall, overlays.get, copyInvocationObservation(controls, {
21546
+ ...actor === void 0 ? {} : { actor },
21547
+ ...input.references === void 0 ? {} : { references: input.references.slice(offset, offset + MAX_OVERLAY_IDS) },
21548
+ ...input.settlementIds === void 0 ? {} : { settlementIds: input.settlementIds.slice(offset, offset + MAX_OVERLAY_IDS) }
21549
+ })).pipe(Effect.mapError((publicError) => ({ publicError }))), { concurrency: 2 }).pipe(Effect.flatMap((pages) => {
21550
+ const first = pages[0];
21551
+ if (pages.some((page) => scopeKey(page) !== scopeKey(first))) return Effect.fail({ publicError: Errors.invalidInput("actor", "Activity scope changed during the read") });
21552
+ return Effect.succeed({
21553
+ ...first,
21554
+ links: pages.flatMap((page) => page.links),
21555
+ annotations: pages.flatMap((page) => page.annotations),
21556
+ payments: pages.flatMap((page) => page.payments)
21557
+ });
21558
+ }));
21559
+ }
21560
+ function decoratePage(deps, scope, controls, transfers, page, range) {
21561
+ return Effect.gen(function* () {
21562
+ const decoration = yield* overlay(deps, scope.actor, controls, {
21563
+ references: [...page.pending.map((id) => ({
21564
+ kind: "payment",
21565
+ id
21566
+ })), ...transfers.map((row) => ({
21567
+ kind: "movement",
21568
+ id: row.id
21569
+ }))],
21570
+ settlementIds: [...new Set(transfers.flatMap((row) => row.paymentSettlementId ? [row.paymentSettlementId] : []))]
21571
+ });
21572
+ if (scopeKey(decoration) !== scopeKey(scope)) return yield* Effect.fail({ publicError: Errors.invalidInput("actor", "Activity scope changed during the read") });
21573
+ const byId = new Map([...page.items, ...decoration.payments].map((item) => [item.id, item]));
21574
+ const settlements = [...new Set(decoration.links.map((link) => link.settlementId))];
21575
+ const facts = yield* readPaymentFacts(deps, scope.safe, settlements);
21576
+ if (facts === null) return null;
21577
+ const bySettlement = new Map(facts.map((row) => [row.settlementId, row]));
21578
+ const byPayment = new Map(decoration.links.map((link) => [link.paymentId, {
21579
+ fact: bySettlement.get(link.settlementId),
21580
+ expected: link.expected
21581
+ }]));
21582
+ const annotations = new Map(decoration.annotations.map((annotation) => [`${annotation.reference.kind}:${annotation.reference.id}`, annotation]));
21583
+ return {
21584
+ payments: page.pending.flatMap((id) => {
21585
+ const item = byId.get(id);
21586
+ if (item === void 0 || item.kind !== "payment" || item.createdAt > range.to || range.from !== void 0 && item.createdAt < range.from) return [];
21587
+ const confirmed = withAnnotation(confirmPayment(item, byPayment.get(id)?.fact, byPayment.get(id)?.expected), annotations.get(`payment:${id}`));
21588
+ return isActivityVisible(confirmed) ? [confirmed] : [];
21589
+ }),
21590
+ annotations,
21591
+ linked: new Set(decoration.links.filter((link) => matchesPaymentFact(bySettlement.get(link.settlementId), link.expected)).map((link) => link.settlementId))
21592
+ };
21593
+ });
21594
+ }
21595
+ function mergePage(safe, filter, limit, state, page, decoration, transfers, wantsTransfers) {
21596
+ const { payments, annotations, linked } = decoration;
21597
+ let pi = 0;
21598
+ let ti = 0;
21599
+ const items = [];
21600
+ const transferEnd = !wantsTransfers || transfers.length < 100;
21601
+ let transferBefore = state.transferBefore;
21602
+ while (items.length < limit) {
21603
+ if (pi === payments.length && !page.done || ti === transfers.length && !transferEnd) break;
21604
+ const payment = payments[pi];
21605
+ const row = transfers[ti];
21606
+ if (payment === void 0 && row === void 0) break;
21607
+ if (payment !== void 0 && (row === void 0 || payment.createdAt >= Number(row.timestamp) * 1e3)) {
21608
+ pi += 1;
21609
+ if (matchesFilter(payment, filter)) items.push(payment);
21610
+ } else if (row !== void 0) {
21611
+ ti += 1;
21612
+ transferBefore = {
21613
+ timestamp: Number(row.timestamp),
21614
+ id: row.id
21615
+ };
21616
+ if (row.paymentSettlementId && linked.has(row.paymentSettlementId)) continue;
21617
+ const item = transferItem(safe, row, annotations.get(`movement:${row.id}`));
21618
+ if (item !== null && matchesFilter(item, filter)) items.push(item);
21619
+ }
21620
+ }
21621
+ return {
21622
+ items,
21623
+ next: {
21624
+ ...state,
21625
+ paymentCursor: page.cursor,
21626
+ paymentDone: page.done,
21627
+ paymentPending: payments.slice(pi).map((item) => item.id),
21628
+ transferBefore,
21629
+ transferDone: ti === transfers.length && transferEnd
21630
+ }
21631
+ };
21632
+ }
21633
+ function convexPage(deps, actor, controls, input) {
21634
+ return callOperation(deps.convexCall, items.list, copyInvocationObservation(controls, {
21635
+ ...input,
21636
+ actor
21637
+ })).pipe(Effect.mapError((publicError) => ({ publicError })));
21638
+ }
21639
+ function fallbackPage(deps, scope, controls, params, state, degraded) {
21640
+ return Effect.gen(function* () {
21641
+ const page = yield* convexPage(deps, scope.actor, controls, {
21642
+ limit: params?.limit ?? 25,
21643
+ ...state.paymentCursor === null ? {} : { cursor: state.paymentCursor },
21644
+ range: {
21645
+ ...params?.range?.from === void 0 ? {} : { from: params.range.from },
21646
+ to: Math.min(state.checkpoint, params?.range?.to ?? state.checkpoint)
21647
+ },
21648
+ ...params?.filter === void 0 ? {} : { filter: params.filter }
21649
+ });
21650
+ const decoration = yield* overlay(deps, scope.actor, controls, { references: page.items.map((item) => ({
21651
+ kind: item.kind,
21652
+ id: item.id
21653
+ })) });
21654
+ if (scopeKey(decoration) !== scopeKey(scope)) return yield* Effect.fail({ publicError: Errors.invalidInput("actor", "Activity scope changed during fallback") });
21655
+ const annotations = new Map(decoration.annotations.map((annotation) => [`${annotation.reference.kind}:${annotation.reference.id}`, annotation]));
21656
+ yield* Effect.annotateCurrentSpan({
21657
+ read_source: "convex",
21658
+ ...degraded ? { read_warning: "indexer-unavailable" } : {}
21659
+ });
21660
+ return {
21661
+ ...page,
21662
+ items: page.items.filter(isActivityVisible).map((item) => withAnnotation(item, annotations.get(`${item.kind}:${item.id}`))),
21663
+ checkpoint: state.checkpoint,
21664
+ nextCursor: page.nextCursor === null ? null : JSON.stringify({
21665
+ ...state,
21666
+ source: "fallback",
21667
+ paymentCursor: page.nextCursor,
21668
+ degraded
21669
+ }),
21670
+ ...degraded ? { readWarning: "indexer-unavailable" } : {}
21671
+ };
21672
+ });
21673
+ }
21674
+ function readActivityPage(deps, actor, controls, params) {
21675
+ return Effect.gen(function* () {
21676
+ yield* Effect.try({
21677
+ try: () => requireParams(params),
21678
+ catch: (cause) => ({ publicError: asCapxulError(cause) })
21679
+ });
21680
+ const scope = yield* overlay(deps, actor, controls, {});
21681
+ const selection = selectionKey(params);
21682
+ const cursor = yield* Effect.try({
21683
+ try: () => parseCursor(params?.cursor, scopeKey(scope), selection),
21684
+ catch: () => ({ publicError: Errors.invalidInput("cursor", "invalid or obsolete Activity cursor; restart the read") })
21685
+ });
21686
+ const state = cursor ?? {
21687
+ version: 1,
21688
+ scope: scopeKey(scope),
21689
+ selection,
21690
+ checkpoint: Date.now(),
21691
+ source: "indexed",
21692
+ paymentCursor: null,
21693
+ paymentDone: false,
21694
+ paymentPending: [],
21695
+ transferBefore: null,
21696
+ transferDone: false,
21697
+ degraded: false
21698
+ };
21699
+ const range = boundedRange(params?.range, state.checkpoint);
21700
+ if (range.from !== void 0 && range.from > range.to) return {
21701
+ items: [],
21702
+ nextCursor: null,
21703
+ checkpoint: state.checkpoint,
21704
+ observedAt: Date.now()
21705
+ };
21706
+ if (state.source === "fallback" || scope.safe === null) return yield* fallbackPage(deps, scope, controls, params, state, state.degraded);
21707
+ return yield* indexedPage(deps, scope, controls, params, state, cursor === null);
21708
+ });
21709
+ }
21710
+ function readActivitySummary(deps, actor, controls, params) {
21711
+ return Effect.gen(function* () {
21712
+ const totals = /* @__PURE__ */ new Map();
21713
+ let cursor;
21714
+ let count = 0;
21715
+ let readWarning;
21716
+ do {
21717
+ const page = yield* readActivityPage(deps, actor, controls, {
21718
+ limit: 100,
21719
+ ...cursor === void 0 ? {} : { cursor },
21720
+ ...params?.window === void 0 ? {} : { range: params.window }
21721
+ });
21722
+ count += page.items.length;
21723
+ readWarning ??= page.readWarning;
21724
+ for (const total of summarizeItems(page.items)) {
21725
+ const key = total.asset;
21726
+ const old = totals.get(key);
21727
+ totals.set(key, old === void 0 ? total : {
21728
+ ...total,
21729
+ in: String(BigInt(old.in) + BigInt(total.in)),
21730
+ out: String(BigInt(old.out) + BigInt(total.out)),
21731
+ net: String(BigInt(old.net) + BigInt(total.net)),
21732
+ pendingIn: String(BigInt(old.pendingIn) + BigInt(total.pendingIn))
21733
+ });
21734
+ }
21735
+ cursor = page.nextCursor ?? void 0;
21736
+ } while (cursor !== void 0);
21737
+ return {
21738
+ window: {
21739
+ from: params?.window?.from ?? null,
21740
+ to: params?.window?.to ?? null
21741
+ },
21742
+ totals: [...totals.values()],
21743
+ count,
21744
+ observedAt: Date.now(),
21745
+ ...readWarning === void 0 ? {} : { readWarning }
21746
+ };
21747
+ });
21748
+ }
21749
+ function subscribeActivity(deps, actor, controls, onChange) {
21750
+ return Effect.gen(function* () {
21751
+ const scope = yield* overlay(deps, actor, controls, {});
21752
+ if (scope.safe === null) return () => {};
21753
+ let delivered = false;
21754
+ return yield* deps.indexer.subscribe("transfer", {
21755
+ safe: toAddress(scope.safe),
21756
+ limit: 100
21757
+ }, (snapshot) => {
21758
+ if (snapshot.status === "ok") {
21759
+ if (delivered) onChange();
21760
+ delivered = true;
21761
+ }
21762
+ if (snapshot.status === "error") {
21763
+ delivered = true;
21764
+ onChange();
21765
+ }
21766
+ });
21767
+ });
21768
+ }
21769
+ //#endregion
21770
+ //#region src/activity/movement-detail.ts
21771
+ /** An indexed Movement has no Convex materialization. Read its exact native row. */
21772
+ function readIndexedMovement(deps, actor, controls, eventId) {
21773
+ return Effect.gen(function* () {
21774
+ const scope = yield* overlay(deps, actor, controls, { references: [{
21775
+ kind: "movement",
21776
+ id: eventId
21777
+ }] });
21778
+ if (scope.safe === null) return null;
21779
+ const safe = scope.safe.toLowerCase();
21780
+ const row = (yield* deps.indexer.read("transfer", {
21781
+ safe: toAddress(safe),
21782
+ limit: 1,
21783
+ eventId
21784
+ }).pipe(Effect.mapError((error) => ({ publicError: error.publicError }))))[0];
21785
+ if (row === void 0) return null;
21786
+ const blockNumber = Number(row.blockNumber);
21787
+ if (row.id !== eventId || row.from.toLowerCase() !== safe && row.to.toLowerCase() !== safe || !Number.isSafeInteger(blockNumber) || blockNumber < 0 || !Number.isSafeInteger(row.logIndex) || row.logIndex < 0) return yield* Effect.fail({ publicError: Errors.invalidInput("activity", "indexed Movement does not match the requested scope or evidence") });
21788
+ yield* Effect.annotateCurrentSpan({ read_source: "indexer" });
21789
+ const documentSet = scope.movementDocuments.find((set) => set.movementId === row.id);
21790
+ return {
21791
+ kind: "movement",
21792
+ movementId: row.id,
21793
+ documents: documentSet?.documents ?? [],
21794
+ documentState: documentSet?.state ?? "pending",
21795
+ viewer: scope.actor,
21796
+ annotation: scope.annotations.find((annotation) => annotation.reference.kind === "movement" && annotation.reference.id === row.id) ?? null,
21797
+ evidence: {
21798
+ chainId: row.chainId,
21799
+ contractAddress: row.token,
21800
+ tokenAddress: row.token,
21801
+ transactionHash: row.txHash,
21802
+ blockNumber,
21803
+ blockHash: row.blockHash,
21804
+ inclusion: "included",
21805
+ verification: "verified",
21806
+ canonicalState: "finalized",
21807
+ transferLogIndex: row.logIndex,
21808
+ source: row.from,
21809
+ destination: row.to,
21810
+ rawAmount: row.amount.toString(),
21811
+ link: {
21812
+ movementId: row.id,
21813
+ depositPaymentId: null
21814
+ }
21815
+ }
21816
+ };
21817
+ });
21818
+ }
21819
+ //#endregion
21820
+ //#region src/activity/scope.ts
21821
+ /**
21822
+ * The activity backend gives its actor a different name than the other
21823
+ * financialOps functions: `{kind: "organization", orgId}`, and not
21824
+ * `{kind: "org", orgId}`. Thus it does not use `actorReferenceToBackend`.
21825
+ *
21826
+ * The `personal` case sends NO actor. This is correct, and it does not lose
21827
+ * data. `requireActivityActor` uses the signed-in Account when the actor is
21828
+ * absent, and `canReadActor` refuses all other account identifiers
21829
+ * (`packages/backend/convex/movement/activityAuth.ts`). Thus "personal" and
21830
+ * "absent" both name the one Account that an SDK caller can read. The SDK does
21831
+ * not hold an account identifier to send.
21832
+ *
21833
+ * The `switch` is exhaustive. A new `ActorReference` variant is a compile error
21834
+ * here. The conditional expression that this function replaced removed each
21835
+ * value that was not an organization.
21836
+ */
21837
+ function activityActorField(actor) {
21838
+ if (actor === void 0 || actor.kind === "personal") return {};
21839
+ return { actor: {
21840
+ kind: "organization",
21841
+ orgId: actor.organizationId
21842
+ } };
21843
+ }
21844
+ /** Capture scope now; let the observed result boundary handle a malformed caller value. */
21845
+ function captureActivityInput(prepare) {
21846
+ try {
21847
+ return prepare();
21848
+ } catch (cause) {
21849
+ return Effect.die(cause);
21850
+ }
21851
+ }
21852
+ function observeActivityScope(actor) {
21853
+ const organizationId = actor?.kind === "organization" || actor?.kind === "org" ? safeEngineeringIdentifier(actor.orgId) : void 0;
21854
+ return Effect.annotateCurrentSpan({
21855
+ scope_kind: actor?.kind === "organization" || actor?.kind === "org" ? "organization" : "account",
21856
+ ...organizationId === void 0 ? {} : { verified_organization_id: organizationId }
21857
+ });
21858
+ }
21859
+ function decodeActivityViewer(value) {
21860
+ const viewer = Option.getOrUndefined(Schema.decodeUnknownOption(ActorRefSchema)(value));
21861
+ if (viewer === void 0) return void 0;
21862
+ const id = viewer.kind === "organization" ? viewer.orgId : viewer.accountId;
21863
+ return safeEngineeringIdentifier(id) === void 0 ? void 0 : viewer;
21864
+ }
21865
+ /** The detail without the scope it was read for, which the SDK reports as telemetry instead. */
21866
+ function normalizeActivityDetail(response) {
21867
+ if (response === null) return null;
21868
+ const { viewer: _viewer, ...detail } = response;
21869
+ return detail;
21870
+ }
21871
+ //#endregion
21872
+ //#region src/activity/methods.ts
21873
+ function makeActivityMethods(deps) {
21874
+ const indexerDeps = deps.indexerRead === void 0 ? void 0 : {
21875
+ indexer: deps.indexerRead,
21876
+ convexCall: deps.convexCall
21877
+ };
21878
+ /** One public call for the caller's chosen actor, read once at call start. */
21879
+ const forActor = (actorRef, options, operation, program) => {
21880
+ const controls = deps.invocationControls?.(options) ?? options;
21881
+ return runPortEffect(captureActivityInput(() => Effect.succeed(activityActorField(actorRef).actor)).pipe(Effect.flatMap((actor) => program(actor, controls))), controls, operation, deps.runPromise);
21882
+ };
21883
+ return {
21884
+ subscribe: (onChange, params, options) => forActor(params?.actor, options, CAPXUL_OPERATIONS.activity.subscribe, (actor, controls) => indexerDeps === void 0 ? Effect.succeed(() => {}) : Effect.suspend(() => subscribeActivity(indexerDeps, actor, controls, onChange)).pipe(Effect.tap(() => observeActivityScope(actor)))),
21885
+ list: (params, options) => forActor(params?.actor, options, items.list.name, (actor, controls) => Effect.suspend(() => indexerDeps === void 0 ? callOperation(deps.convexCall, items.list, copyInvocationObservation(controls, {
21886
+ ...actor === void 0 ? {} : { actor },
21887
+ ...params?.cursor === void 0 ? {} : { cursor: params.cursor },
21888
+ ...params?.limit === void 0 ? {} : { limit: params.limit },
21889
+ ...params?.range === void 0 ? {} : { range: params.range },
21890
+ ...params?.filter === void 0 ? {} : { filter: params.filter }
21891
+ })).pipe(Effect.mapError((publicError) => ({ publicError }))) : readActivityPage(indexerDeps, actor, controls, params)).pipe(Effect.map((page) => ({
21892
+ ...page,
21893
+ items: page.items.filter(isActivityVisible)
21894
+ })), Effect.tap(() => observeActivityScope(actor)))),
21895
+ summary: (params, options) => forActor(params?.actor, options, items.summary.name, (actor, controls) => Effect.suspend(() => indexerDeps === void 0 ? callOperation(deps.convexCall, items.summary, copyInvocationObservation(controls, {
21896
+ ...actor === void 0 ? {} : { actor },
21897
+ ...params?.window === void 0 ? {} : { window: params.window }
21898
+ })).pipe(Effect.mapError((publicError) => ({ publicError }))) : readActivitySummary(indexerDeps, actor, controls, params)).pipe(Effect.tap(() => observeActivityScope(actor)))),
21899
+ get: (reference, options) => {
21900
+ const controls = deps.invocationControls?.(options) ?? options;
21901
+ const requestedActor = actorReferenceToBackend(options?.actor);
21902
+ return runPortEffect(captureActivityInput(() => {
21903
+ const scope = requestedActor === void 0 ? void 0 : requestedActor.kind === "org" ? {
21904
+ kind: "org",
21905
+ orgId: requestedActor.orgId
21906
+ } : { kind: "account" };
21907
+ return Effect.succeed({
21908
+ actor: scope,
21909
+ referenceActor: reference.kind === "payment" ? activityActorField(reference.actor).actor : void 0
21910
+ });
21911
+ }).pipe(Effect.flatMap(({ actor, referenceActor }) => Effect.suspend(() => indexerDeps !== void 0 && reference.kind === "movement" && /^[1-9][0-9]{0,9}:0x[0-9a-f]{64}:[0-9]{1,10}$/.test(reference.id) ? readIndexedMovement(indexerDeps, actor?.kind === "org" ? {
21912
+ kind: "organization",
21913
+ orgId: actor.orgId
21914
+ } : void 0, controls, reference.id) : callOperation(deps.convexCall, items.get, copyInvocationObservation(controls, {
21915
+ reference: {
21916
+ kind: reference.kind,
21917
+ id: reference.id,
21918
+ ...referenceActor === void 0 ? {} : { actor: referenceActor }
21919
+ },
21920
+ ...actor === void 0 ? {} : { actor }
21921
+ })).pipe(Effect.mapError((publicError) => ({ publicError })))).pipe(Effect.flatMap((response) => {
21922
+ const detail = normalizeActivityDetail(response);
21923
+ if (response === null) return Effect.succeed(detail);
21924
+ const viewer = response.viewer === void 0 ? actor ?? referenceActor : decodeActivityViewer(response.viewer);
21925
+ return viewer === void 0 ? Effect.succeed(detail) : observeActivityScope(viewer).pipe(Effect.as(detail));
21926
+ })))), controls, items.get.name, deps.runPromise);
21927
+ },
21928
+ annotate: (input, options) => {
21929
+ const controls = deps.invocationControls?.(options) ?? options;
21930
+ return runPortEffect(captureActivityInput(() => {
21931
+ const actor = activityActorField(input.actor).actor;
21932
+ if (input.actor !== void 0 && input.reference.kind === "payment" && input.reference.actor !== void 0 && !sameActor(input.actor, input.reference.actor)) return Effect.fail({ publicError: Errors.invalidInput("reference.actor", "must match the annotation actor") });
21933
+ return Effect.succeed({
21934
+ actor,
21935
+ referenceActor: input.reference.kind === "payment" ? activityActorField(input.reference.actor).actor : void 0
21936
+ });
21937
+ }).pipe(Effect.flatMap(({ actor, referenceActor }) => Effect.suspend(() => callOperation(deps.convexCall, annotations.save, copyInvocationObservation(controls, {
21938
+ ...actor === void 0 ? {} : { actor },
21939
+ reference: input.reference.kind === "payment" && referenceActor !== void 0 ? {
21940
+ kind: "payment",
21941
+ id: input.reference.id,
21942
+ actor: referenceActor
21943
+ } : {
21944
+ kind: input.reference.kind,
21945
+ id: input.reference.id
21946
+ },
21947
+ ...input.counterpartyLabel === void 0 ? {} : { counterpartyLabel: input.counterpartyLabel },
21948
+ ...input.accountingCategory === void 0 ? {} : { accountingCategory: input.accountingCategory },
21949
+ ...input.memo === void 0 ? {} : { memo: input.memo }
21950
+ })).pipe(Effect.mapError((publicError) => ({ publicError })))).pipe(Effect.tap((annotation) => {
21951
+ const scope = decodeActivityViewer(annotation.actor);
21952
+ return scope === void 0 ? Effect.void : observeActivityScope(scope);
21953
+ })))), controls, annotations.save.name, deps.runPromise);
21954
+ }
21955
+ };
21956
+ }
21957
+ //#endregion
21958
+ //#region src/activity/phases.ts
21959
+ const PENDING = Object.freeze({
21960
+ terminal: false,
21961
+ outcome: null,
21962
+ needsAction: false
21963
+ });
21964
+ const AWAITING_ACTOR = Object.freeze({
21965
+ terminal: false,
21966
+ outcome: null,
21967
+ needsAction: true
21968
+ });
21969
+ const COMPLETED = Object.freeze({
21970
+ terminal: true,
21971
+ outcome: "good",
21972
+ needsAction: false
21973
+ });
21974
+ const FAILED = Object.freeze({
21975
+ terminal: true,
21976
+ outcome: "bad",
21977
+ needsAction: false
21978
+ });
21979
+ const WITHDRAWN = Object.freeze({
21980
+ terminal: true,
21981
+ outcome: "neutral",
21982
+ needsAction: false
21983
+ });
21984
+ /** Interpret a Payment status. `pending_claim` waits for the actor who reads it. */
21985
+ function paymentPhase(status) {
21986
+ switch (status) {
21987
+ case "pending":
21988
+ case "settling":
21989
+ case "scheduled":
21990
+ case "streaming": return PENDING;
21991
+ case "pending_claim": return AWAITING_ACTOR;
21992
+ case "settled": return COMPLETED;
21993
+ case "cancelled": return WITHDRAWN;
21994
+ case "failed":
21995
+ case "unresolved": return FAILED;
21996
+ default: return absurd(status);
21997
+ }
21998
+ }
21999
+ /** Interpret a payment Request as its ISSUER sees it. An issuer does not wait for itself. */
22000
+ function requestPhase(status) {
22001
+ switch (status) {
22002
+ case "draft":
22003
+ case "sent":
22004
+ case "viewed":
22005
+ case "pending_settlement": return PENDING;
22006
+ case "paid": return COMPLETED;
22007
+ case "declined":
22008
+ case "expired": return FAILED;
22009
+ case "cancelled": return WITHDRAWN;
22010
+ default: return absurd(status);
22011
+ }
22012
+ }
22013
+ /** Interpret the same request as its RECIPIENT sees it. `open` waits for the recipient. */
22014
+ function inboxPhase(status) {
22015
+ switch (status) {
22016
+ case "open": return AWAITING_ACTOR;
22017
+ case "approved": return PENDING;
22018
+ case "paid": return COMPLETED;
22019
+ case "declined":
22020
+ case "expired": return FAILED;
22021
+ case "cancelled": return WITHDRAWN;
22022
+ default: return absurd(status);
22023
+ }
22024
+ }
22025
+ //#endregion
20611
22026
  //#region src/accounts/summaries.ts
20612
22027
  function makeMeMethods(deps) {
20613
22028
  return {
20614
22029
  get: (options) => runIfActive(options?.signal, summaries.me.name, () => callOperation(deps.convexCall, summaries.me, {}).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise),
22030
+ home: (options) => runIfActive(options?.signal, summaries.home.name, () => (deps.chainId === void 0 ? Effect.fail(Errors.notImplemented("accounts", "me.home")) : callOperation(deps.convexCall, summaries.home, {
22031
+ chainId: deps.chainId,
22032
+ ...options?.orgId === void 0 ? {} : { orgId: options.orgId }
22033
+ })).pipe(Effect.flatMap((wire) => Effect.try({
22034
+ try: () => ({
22035
+ ...wire,
22036
+ balances: wire.balances === null ? null : accountPositionsFromWire(wire.balances),
22037
+ recentActivity: wire.recentActivity?.filter(isActivityVisible) ?? null
22038
+ }),
22039
+ catch: asCapxulError
22040
+ })), Effect.mapError((publicError) => ({ publicError }))), deps.runPromise),
20615
22041
  depositInstructions: (options) => {
20616
22042
  const controls = deps.invocationControls?.(options) ?? options;
20617
22043
  return runPortEffect(callOperation(deps.convexCall, summaries.depositInstructions, copyInvocationObservation(controls, {})).pipe(Effect.mapError((publicError) => ({ publicError })), Effect.tap((instructions) => emitDepositInitiated(deps.telemetry, instructions, controls))), controls, summaries.depositInstructions.name, deps.runPromise);
@@ -21520,4 +22946,4 @@ function executeIdentityProductObservation(telemetry, record, state) {
21520
22946
  return ignoreTransportFailure(() => invocationTelemetry.emit(mapped), "emit", mapped.name).pipe(Effect.andThen(ignoreTransportFailure(after, mapped.name === "auth_signed_out" ? "reset" : "identify", mapped.name)));
21521
22947
  }
21522
22948
  //#endregion
21523
- export { moneySafeOpDigest as $, actorReferenceToBackend as $i, CHAIN_UPSTREAMS as $n, runIfActive as $r, injectedWalletSigner as $t, logDroppedEvent as A, globalLocalStorage as Ai, configurations as An, ChainIdSchema$1 as Ar, SAFE_SENTINEL_OWNERS as At, makeTargetsMethods as B, toJwtToken as Bi, PayrollRunDetailSchema as Bn, absurd as Br, observeSdkClient as Bt, retryIdempotentRead as C, toAllowedOrigin as Ci, isCapxulOperation as Cn, EpochMsSchema$1 as Cr, deriveCapxulSafeAddress as Ct, makeApprovalsMethods as D, AuthClientError as Di, onboardings as Dn, toPermissionId as Dr, buildSafeMultiSendExecTransactionCall as Dt, wireChainId as E, authClientPortFromPromiseAdapter as Ei, details as En, toPermissionAssignmentId as Er, safe4337MultiSendUserOpCallData as Et, paymentRequestKeyLifecycle as F, toDurationMs as Fi, runs as Fn, EVM_ADDRESS_RE$1 as Fr, failureDetail as Ft, formatAssetAmount as G, CapxulError as Gi, members as Gn, runIdentityFacade as Gr, normalizeExceptionErrorKind as Gt, executePrepared as H, isNonEmptyString as Hi, PayrollRunItemInputSchema as Hn, makeAuthMethods as Hr, withCapturedAttemptContext as Ht, makeDestinationsMethods as I, toEpochMs as Ii, terms as In, isEvmAddress as Ir, failureEvidenceProps as It, toRaw as J, isFailureMode as Ji, treasuries as Jn, observationOnlyControls as Jr, safeExceptionLabel as Jt, parseAssetAmount as K, isCapxulError as Ki, roles as Kn, runPortEffect as Kr, normalizeExceptionOperation as Kt, makeActorRelationshipMethods as L, toEpochSeconds as Li, AuthorizePayrollRunExecutionInputSchema as Ln, toAddress as Lr, CAPXUL_SDK_EXPECTED_OUTCOME_EVENT as Lt, makeOfframpMethods as M, BrowserAuthCacheAdapter as Mi, PreparedPermissionExecutionSchema as Mn, toAssetId as Mr, asCapxulError as Mt, makePaymentsMethods as N, parseAuthSession as Ni, PermissionCommandViewSchema as Nn, toCurrencyCode as Nr, mapPage as Nt, makeAccountMethods as O, AuthClientPortTag as Oi, authorities as On, toRoleKey as Or, BASE_SEPOLIA_CHAIN_ID as Ot, waitForPaymentSubmission as P, parseCachedJwt as Pi, groups as Pn, toExactAssetAmount as Pr, toPublicError$1 as Pt, fingerprintPaymentIntent as Q, AuthCachePortTag as Qi, ORGANIZATION_SETUP_STATUSES as Qn, defectAsCapxulError as Qr, causeChain as Qt, makeCheckoutMethods as R, toAuthUserId as Ri, PayrollGroupIdSchema as Rn, toChainId as Rr, postHogFailureObservation as Rt, convexCallErrorFromCapxul as S, isCredentialField as Si, CAPXUL_OPERATIONS as Sn, DurationMsSchema$1 as Sr, configuredMoneyAssetById as St, registerProductTelemetryInvocation as T, toPublishableKey as Ti, OPERATIONS as Tn, toBudgetId as Tr, safe4337ExecuteUserOpCallData as Tt, assetAmountFromRaw as U, toNonEmptyStringBrand as Ui, FixedOfferDraftSchema as Un, askIdentity as Ur, EXCEPTION_MESSAGE as Ut, subscribeFreshQuery as V, toSessionToken as Vi, PayrollRunIdSchema as Vn, reference as Vr, observationContextProps as Vt, assetSymbolFor as W, Errors as Wi, invitations as Wn, publicIdentityFailure as Wr, SDK_VERSION as Wt, parseMoney as X, readField as Xi, OrganizationSetupSchema as Xn, withVerifiedOrganizationScope as Xr, isSettingUpLifecycle as Xt, isMoneyParseError as Y, isRecord as Yi, workspaces as Yn, runCapxulEffect as Yr, version as Yt, canonicalJson as Z, AuthCacheError as Zi, ORGANIZATION_SETUP_REASONS as Zn, awaitCapxulResult as Zr, UNOBSERVABLE_SIGNER_STATUS as Zt, valueIn as _, copyInvocationObservation as _i, CLI_CAPABILITIES as _n, documents as _r, SEND_SIGNATURE as _t, ConvexSmartAccountLayer as a, ActorFailure as ai, resolveFailureMode as an, CurrentPolicySchema as ar, MODULE_PROXY_FACTORY_ABI as at, TelemetryPortTag as b, redactSecrets as bi, EXCEPTION_EVENT_NAME as bn, PAYMENT_DIRECTIONS as br, CONFIGURED_MONEY_ASSETS as bt, makeHoldingsMethods as c, oauthBearerAuthClient as ci, toCountryCode as cn, images as cr, PARAMETER_TYPE as ct, ConvexAccountLayer as d, ClockPortTag as di, HANDLE_RE as dn, isBytes32 as dr, ROLES_SET_ALLOWANCE_ABI as dt, sameActor as ea, toCapxulResult as ei, isEcdsaSignatureHex as en, decodeChainCause as er, ORG_BUDGET_ACTIONS as et, accountFromAccountPositions as f, readClockNow as fi, toHandle as fn, toExactHex as fr, ROLES_SET_TRANSACTION_UNWRAPPER_ABI as ft, valueActivitySummary as g, attachInvocationObservation as gi, redactTelemetryProps as gn, annotations as gr, SEND_BATCH_SIGNATURE as gt, MONEY_READ_RATES as h, observationRequestHeaders as hi, redactTelemetryEvent as hn, toLowerHex as hr, SAFE_ENABLE_MODULE_ABI as ht, makeSmartAccountMethods as i, EXPECTED_OPERATION_OUTCOMES as ii, signerFailure as in, decodePermissionIntent as ir, CREATE_COMMITMENT_SIGNATURE as it, makeOrganizationPaymentsMethods as j, InMemoryAuthCacheAdapter as ji, replacements as jn, currencySymbolFor as jr, callOperation as jt, emitDepositInitiated as k, detectAuthCacheAdapter as ki, commands as kn, PaymentDocumentReadRefSchema as kr, MULTI_SEND_CALL_ONLY as kt, PonderIndexerAdapter as l, SystemClockLayer as li, toKycTier as ln, toAccountId as lr, ROLES_ASSIGN_ROLES_ABI as lt, positionPeg as m, BetterAuthBrowserLayer as mi, validateHandle as mn, toLowerBytes32 as mr, ROLE_MANAGEMENT_SIGNATURES as mt, bootIdentityFlow as n, safeEngineeringIdentifier as ni, openfortSignerNotReadyCode as nn, InvitationViewSchema as nr, ZODIAC_MODULE_PROXY_FACTORY as nt, SmartAccountPortTag as o, carryInvocationParentSpan as oi, makeCurrentUserMethods as on, diagnostics as or, MULTI_SEND_SELECTOR as ot, accountPositionsFromWire as p, BetterAuthNodeLayer as pi, toPartyId as pn, toLowerAddress as pr, ROLES_SET_UP_ABI as pt, requireAsset as q, FAILURE_MODES$1 as qi, setups as qn, sessionFromActor as qr, projectSdkException as qt, makeMeMethods as r, CAPXUL_ERROR_CODES as ri, recoverRawDigestSigner as rn, hashPermissionReplacementPreview as rr, resolveOrgPermissionIdentity as rt, smartAccountErrorFromCapxul as s, withInvocationParentSpan as si, makeClientRequestMethods as sn, AppIdSchema$1 as sr, OPERATOR as st, executeIdentityProductObservation as t, formatTraceparent as ti, isSignerNotReadySignal as tn, toOrgId as tr, roleKeyForPermission as tt, makeAccountsMethods as u, ClockError as ui, toTesterKind as un, PaymentDocumentOptionsSchema as ur, ROLES_EXEC_TRANSACTION_WITH_ROLE_ABI as ut, AccountReadPortTag as v, readInvocationObservation as vi, CLI_COMMAND_NAMES as vn, items as vr, CAPXUL_PAYMENTS_V2_ADDRESS as vt, bindProductTelemetryInvocation as w, toAppId as wi, normalizeCapxulOperation as wn, ActorRefSchema as wr, normalizeSafeSaltEmail as wt, ConvexCallPortTag as x, redactUrlSecrets as xi, stampTelemetryEnvelope as xn, PAYMENT_STATUSES as xr, TOKENS as xt, accountReadErrorFromCapxul as y, sanitizeObservationContext as yi, CLI_INVOCATION_KINDS as yn, overlays as yr, hashAdjustmentsV3 as yt, isCheckoutSettlementConsumed as z, toEmail as zi, PayrollGroupInputSchema as zn, toWeiAmount as zr, observeFailedResult as zt };
22949
+ export { parseAssetAmount as $, InvitationViewSchema as $n, SystemClockLayer as $r, version as $t, registerProductTelemetryInvocation as A, toJwtToken as Ai, details as An, toWeiAmount as Ar, safe4337ExecuteUserOpCallData as At, makeOrganizationPaymentsMethods as B, AuthCachePortTag as Bi, FixedOfferDraftSchema as Bn, runCapxulEffect as Br, failureEvidenceProps as Bt, AccountReadPortTag as C, parseAuthSession as Ci, CLI_INVOCATION_KINDS as Cn, toAssetId as Cr, SEND_BATCH_SIGNATURE as Ct, convexCallErrorFromCapxul as D, toEpochSeconds as Di, isCapxulOperation as Dn, isEvmAddress as Dr, TOKENS as Dt, ConvexCallPortTag as E, toEpochMs as Ei, CAPXUL_OPERATIONS as En, EVM_ADDRESS_RE$1 as Er, CONFIGURED_MONEY_ASSETS as Et, decodePayrollRunInput as F, FAILURE_MODES$1 as Fi, replacements as Fn, publicIdentityFailure as Fr, SAFE_SENTINEL_OWNERS as Ft, makeActorRelationshipMethods as G, treasuries as Gn, toCapxulResult as Gr, observationContextProps as Gt, makePaymentsMethods as H, members as Hn, awaitCapxulResult as Hr, postHogFailureObservation as Ht, toPayrollGroupId as I, isFailureMode as Ii, PreparedPermissionExecutionSchema as In, runIdentityFacade as Ir, callOperation as It, makeTargetsMethods as J, ORGANIZATION_SETUP_REASONS as Jn, EXPECTED_OPERATION_OUTCOMES as Jr, SDK_VERSION as Jt, makeCheckoutMethods as K, workspaces as Kn, formatTraceparent as Kr, withCapturedAttemptContext as Kt, makeAccountMethods as L, isRecord as Li, PermissionCommandViewSchema as Ln, runPortEffect as Lr, asCapxulError as Lt, makeApprovalsMethods as M, Errors as Mi, authorities as Mn, reference as Mr, buildSafeMultiSendExecTransactionCall as Mt, makePayrollMethods as N, CapxulError as Ni, commands as Nn, makeAuthMethods as Nr, BASE_SEPOLIA_CHAIN_ID as Nt, retryIdempotentRead as O, toAuthUserId as Oi, normalizeCapxulOperation as On, toAddress as Or, deriveCapxulSafeAddress as Ot, makeUnavailablePayrollMethods as P, isCapxulError as Pi, configurations as Pn, askIdentity as Pr, MULTI_SEND_CALL_ONLY as Pt, formatAssetAmount as Q, toOrgId as Qn, oauthBearerAuthClient as Qr, safeExceptionLabel as Qt, emitDepositInitiated as R, readField as Ri, PayrollGroupIdSchema as Rn, sessionFromActor as Rr, toPublicError$1 as Rt, valueIn as S, BrowserAuthCacheAdapter as Si, CLI_COMMAND_NAMES as Sn, currencySymbolFor as Sr, SAFE_ENABLE_MODULE_ABI as St, TelemetryPortTag as T, toDurationMs as Ti, stampTelemetryEnvelope as Tn, toExactAssetAmount as Tr, CAPXUL_PAYMENTS_V2_ADDRESS as Tt, waitForPaymentSubmission as U, roles as Un, defectAsCapxulError as Ur, observeFailedResult as Ut, makeOfframpMethods as V, invitations as Vn, withVerifiedOrganizationScope as Vr, CAPXUL_SDK_EXPECTED_OUTCOME_EVENT as Vt, makeDestinationsMethods as W, setups as Wn, runIfActive as Wr, observeSdkClient as Wt, assetAmountFromRaw as X, CHAIN_UPSTREAMS as Xn, carryInvocationParentSpan as Xr, normalizeExceptionOperation as Xt, subscribeFreshQuery as Y, ORGANIZATION_SETUP_STATUSES as Yn, ActorFailure as Yr, normalizeExceptionErrorKind as Yt, assetSymbolFor as Z, decodeChainCause as Zn, withInvocationParentSpan as Zr, projectSdkException as Zt, accountFromAccountPositions as _, AuthClientError as _i, toPartyId as _n, toBudgetId as _r, ROLES_EXEC_TRANSACTION_WITH_ROLE_ABI as _t, paymentPhase as a, observationRequestHeaders as ai, isSignerNotReadySignal as an, images as ar, fingerprintPaymentIntent as at, MONEY_READ_RATES as b, globalLocalStorage as bi, redactTelemetryProps as bn, toRoleKey as br, ROLES_SET_UP_ABI as bt, makePaymentDocumentsMethods as c, readInvocationObservation as ci, signerFailure as cn, isBytes32 as cr, roleKeyForPermission as ct, SmartAccountPortTag as d, redactUrlSecrets as di, makeClientRequestMethods as dn, toLowerBytes32 as dr, CREATE_COMMITMENT_SIGNATURE as dt, ClockError as ei, isSettingUpLifecycle as en, hashPermissionReplacementPreview as er, requireAsset as et, smartAccountErrorFromCapxul as f, isCredentialField as fi, toCountryCode as fn, toLowerHex as fr, MODULE_PROXY_FACTORY_ABI as ft, ConvexAccountLayer as g, authClientPortFromPromiseAdapter as gi, toHandle as gn, EpochMsSchema$1 as gr, ROLES_ASSIGN_ROLES_ABI as gt, makeAccountsMethods as h, toPublishableKey as hi, HANDLE_RE as hn, DurationMsSchema$1 as hr, PARAMETER_TYPE as ht, inboxPhase as i, BetterAuthBrowserLayer as ii, isEcdsaSignatureHex as in, AppIdSchema$1 as ir, canonicalJson as it, wireChainId as j, toSessionToken as ji, onboardings as jn, absurd as jr, safe4337MultiSendUserOpCallData as jt, bindProductTelemetryInvocation as k, toEmail as ki, OPERATIONS as kn, toChainId as kr, normalizeSafeSaltEmail as kt, makeSmartAccountMethods as l, sanitizeObservationContext as li, resolveFailureMode as ln, toExactHex as lr, ZODIAC_MODULE_PROXY_FACTORY as lt, PonderIndexerAdapter as m, toAppId as mi, toTesterKind as mn, PAYMENT_STATUSES as mr, OPERATOR as mt, bootIdentityFlow as n, readClockNow as ni, causeChain as nn, CurrentPolicySchema as nr, isMoneyParseError as nt, requestPhase as o, attachInvocationObservation as oi, openfortSignerNotReadyCode as on, toAccountId as or, moneySafeOpDigest as ot, makeHoldingsMethods as p, toAllowedOrigin as pi, toKycTier as pn, PAYMENT_DIRECTIONS as pr, MULTI_SEND_SELECTOR as pt, isCheckoutSettlementConsumed as q, OrganizationSetupSchema as qn, CAPXUL_ERROR_CODES as qr, EXCEPTION_MESSAGE as qt, makeMeMethods as r, BetterAuthNodeLayer as ri, injectedWalletSigner as rn, diagnostics as rr, parseMoney as rt, makeActivityMethods as s, copyInvocationObservation as si, recoverRawDigestSigner as sn, PaymentDocumentOptionsSchema as sr, ORG_BUDGET_ACTIONS as st, executeIdentityProductObservation as t, ClockPortTag as ti, UNOBSERVABLE_SIGNER_STATUS as tn, decodePermissionIntent as tr, toRaw as tt, ConvexSmartAccountLayer as u, redactSecrets as ui, makeCurrentUserMethods as un, toLowerAddress as ur, resolveOrgPermissionIdentity as ut, accountPositionsFromWire as v, AuthClientPortTag as vi, validateHandle as vn, toPermissionAssignmentId as vr, ROLES_SET_ALLOWANCE_ABI as vt, accountReadErrorFromCapxul as w, parseCachedJwt as wi, EXCEPTION_EVENT_NAME as wn, toCurrencyCode as wr, SEND_SIGNATURE as wt, valueActivitySummary as x, InMemoryAuthCacheAdapter as xi, CLI_CAPABILITIES as xn, ChainIdSchema$1 as xr, ROLE_MANAGEMENT_SIGNATURES as xt, positionPeg as y, detectAuthCacheAdapter as yi, redactTelemetryEvent as yn, toPermissionId as yr, ROLES_SET_TRANSACTION_UNWRAPPER_ABI as yt, logDroppedEvent as z, AuthCacheError as zi, PayrollGroupInputSchema as zn, observationOnlyControls as zr, failureDetail as zt };