@capxul/sdk 4.20.0-beta.28 → 4.20.0-beta.29

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, Option, Predicate, Queue, Ref, Result, Schema, SchemaGetter, SchemaIssue, SchemaParser } from "effect";
1
+ import { Cause, Clock, Context, Data, Deferred, Effect, Exit, Fiber, Layer, Option, Predicate, Queue, Ref, Result, Schema, SchemaAST, SchemaGetter, SchemaIssue, 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";
@@ -936,6 +936,21 @@ function markFailureInvocationSnapshot(failure, snapshot) {
936
936
  function readFailureInvocationSnapshot(failure) {
937
937
  return isRecord(failure) ? failureInvocationSnapshots.get(failure) : void 0;
938
938
  }
939
+ /**
940
+ * The operation each failure came from, by the error it carries. A public
941
+ * method's path (`approvals.review`) is not always an operation name; the row
942
+ * it called (`accounts.approvals.review`) is. The innermost call marks first
943
+ * and keeps the mark, so the report names the row that actually failed.
944
+ */
945
+ const failureOperations = /* @__PURE__ */ new WeakMap();
946
+ /** @internal Record which operation a failure came from; the first mark is kept. */
947
+ function markFailureOperation(error, operation) {
948
+ if (isRecord(error) && !failureOperations.has(error)) failureOperations.set(error, operation);
949
+ }
950
+ /** @internal The operation a failure came from, when a runner marked it. */
951
+ function readFailureOperation(error) {
952
+ return isRecord(error) ? failureOperations.get(error) : void 0;
953
+ }
939
954
  //#endregion
940
955
  //#region src/observability/http-headers.ts
941
956
  /** Resolve one bounded pre-auth snapshot for an outbound SDK HTTP request. */
@@ -2079,7 +2094,9 @@ async function runIfActive(signal, operation, effect, runPromise, observe) {
2079
2094
  signal.addEventListener("abort", onAbort, { once: true });
2080
2095
  return Effect.sync(() => signal.removeEventListener("abort", onAbort));
2081
2096
  }));
2082
- return runProgram(observe === void 0 ? controlled : observe(controlled), runPromise);
2097
+ const result = await runProgram(observe === void 0 ? controlled : observe(controlled), runPromise);
2098
+ if (!result.ok) markFailureOperation(result.error, operation);
2099
+ return result;
2083
2100
  }
2084
2101
  //#endregion
2085
2102
  //#region src/platform/capxul-effect.ts
@@ -4688,7 +4705,9 @@ const OrganizationPaymentExecutionItemSchema = Schema.Struct({
4688
4705
  "invoice",
4689
4706
  "payroll",
4690
4707
  "reimbursement"
4691
- ]))
4708
+ ])),
4709
+ /** When the recipient gets it: instant (the default), or held until a date or over a period. */
4710
+ timing: Schema.optional(PaymentTiming)
4692
4711
  }).check(Schema.makeFilter((value) => Schema.is(PaymentDocumentOptionsSchema)(value)));
4693
4712
  const PrepareOrganizationPaymentExecutionInputSchema = Schema.Struct({
4694
4713
  orgId: nonEmpty("orgId"),
@@ -4798,11 +4817,20 @@ const PreparedPaymentCommandExecutionSchema = Schema.Struct({
4798
4817
  //#region ../protocol/src/accounts/approval-schema.ts
4799
4818
  const APPROVAL_ID_RE = /^approval_[0-9A-HJKMNP-TV-Z]{26}$/u;
4800
4819
  const ApprovalIdSchema = Schema.String.pipe(Schema.refine((value) => APPROVAL_ID_RE.test(value), { message: "must be approval_ plus a ULID" }));
4801
- /** What is being approved. */
4820
+ /**
4821
+ * What is being approved. A `permission_change` creates, changes, assigns,
4822
+ * revokes or replaces an Organization's Permissions; an `invitation` sets up
4823
+ * the rights an invitation offers. Neither moves money. A `payment_cancel`
4824
+ * returns a held Payment to whoever funded it; a `payment_redirect` sends it
4825
+ * to someone else.
4826
+ */
4802
4827
  const APPROVAL_KINDS = [
4803
4828
  "payment",
4804
4829
  "payroll_run",
4830
+ "payment_cancel",
4831
+ "payment_redirect",
4805
4832
  "permission_change",
4833
+ "invitation",
4806
4834
  "bank_payout"
4807
4835
  ];
4808
4836
  /**
@@ -5026,8 +5054,7 @@ const approvals = {
5026
5054
  errors: [
5027
5055
  ...CALL$10,
5028
5056
  ...DEFECTS,
5029
- "WRONG_STATE",
5030
- "NOT_IMPLEMENTED"
5057
+ "WRONG_STATE"
5031
5058
  ]
5032
5059
  }),
5033
5060
  /** The approval as the person reads it, with its state judged against its expiry. */
@@ -5619,6 +5646,15 @@ const PermissionSchema = Schema.Struct({
5619
5646
  limitRaw: Schema.optional(WeiAmountSchema$1),
5620
5647
  allowanceKey: Schema.optional(AllowanceKeySchema)
5621
5648
  });
5649
+ /**
5650
+ * A refilling Budget's refill (#2439): how much each one adds, every how many
5651
+ * days, and when the next one is due.
5652
+ */
5653
+ const BudgetNextRefillSchema = Schema.Struct({
5654
+ amount: AssetAmountSchema,
5655
+ everyDays: Schema.Finite,
5656
+ nextAt: EpochMsSchema$1
5657
+ });
5622
5658
  const PermissionAssignmentSchema = Schema.Struct({
5623
5659
  permissionAssignmentId: PermissionAssignmentIdSchema,
5624
5660
  permissionId: PermissionIdSchema,
@@ -8239,6 +8275,30 @@ const authorities = {
8239
8275
  "ROLE_PERMISSION_DENIED"
8240
8276
  ]
8241
8277
  }),
8278
+ /**
8279
+ * What one active Budget can still spend now: its Roles allowance, read on
8280
+ * chain at the latest block as the payment gate reads it. `left` is null for
8281
+ * a Budget with no allowance (no cap). `refill` names a refilling Budget's
8282
+ * refill and when the next one is due; null for a one-off or uncapped Budget
8283
+ * (#2439). For a participant of the Organization.
8284
+ */
8285
+ budgetLeft: Operation.action("permissions.authorities.budgetLeft", {
8286
+ input: Schema.Struct({
8287
+ orgId: OrgId,
8288
+ budgetId: PermissionIdSchema
8289
+ }),
8290
+ output: Schema.Struct({
8291
+ budgetId: PermissionIdSchema,
8292
+ left: Schema.NullOr(AssetAmountSchema),
8293
+ refill: Schema.optionalKey(Schema.NullOr(BudgetNextRefillSchema))
8294
+ }),
8295
+ errors: [
8296
+ ...CALL$2,
8297
+ ...DEFECTS,
8298
+ ...CHAIN$1,
8299
+ "ROLE_PERMISSION_DENIED"
8300
+ ]
8301
+ }),
8242
8302
  /** Whether the caller's Account may spend this amount from this Budget right now. */
8243
8303
  authorize: Operation.query("permissions.authorities.authorize", {
8244
8304
  input: MoneyAuthorizationRequestSchema,
@@ -9129,6 +9189,7 @@ const ORGANIZATION_OPERATIONS = {
9129
9189
  payment: "org.payment",
9130
9190
  permissions: {
9131
9191
  assign: "org.permissions.assign",
9192
+ budgetLeft: "org.permissions.budgetLeft",
9132
9193
  change: "org.permissions.change",
9133
9194
  create: "org.permissions.create",
9134
9195
  get: "org.permissions.get",
@@ -9375,6 +9436,9 @@ emitChanged: "payroll.groups.emitChanged" }
9375
9436
  },
9376
9437
  /** Permissions' internal functions; its public rows join from `OPERATIONS`. */
9377
9438
  permissions: {
9439
+ authorities: {
9440
+ /** The Budget-left read's participant check and the Budget's stored allowance. */
9441
+ loadBudgetLeft: "permissions.authorities.loadBudgetLeft" },
9378
9442
  commands: {
9379
9443
  /** The prepare action's transaction: authorize, plan and save the command. */
9380
9444
  prepareIntent: "permissions.commands.prepareIntent",
@@ -10570,6 +10634,14 @@ Schema.Struct({
10570
10634
  account_kind: Schema.optional(AccountKindSchema)
10571
10635
  })
10572
10636
  });
10637
+ Schema.Struct({
10638
+ name: Schema.Literal("ui_approval_sign_in_required"),
10639
+ props: Schema.Struct({
10640
+ ...TelemetryEnvelopeProps,
10641
+ approval_id: Schema.String,
10642
+ reason: Schema.Literals(["signed_out", "wrong_account"])
10643
+ })
10644
+ });
10573
10645
  Schema.Struct({
10574
10646
  name: Schema.Literal("payroll_group_changed"),
10575
10647
  props: Schema.Struct({
@@ -10825,6 +10897,8 @@ const CLI_COMMAND_NAMES = [
10825
10897
  "payment.get",
10826
10898
  "payment.wait",
10827
10899
  "payment.retry",
10900
+ "payment.cancel",
10901
+ "payment.redirect",
10828
10902
  "inbox",
10829
10903
  CAPXUL_OPERATIONS.inbox.list,
10830
10904
  "inbox.get",
@@ -12611,7 +12685,7 @@ function mapAccountLifecycle(input) {
12611
12685
  }
12612
12686
  //#endregion
12613
12687
  //#region package.json
12614
- var version = "4.20.0-beta.28";
12688
+ var version = "4.20.0-beta.29";
12615
12689
  //#endregion
12616
12690
  //#region src/observability/telemetry/exception-projection.ts
12617
12691
  /** Fixed fallback for failures that have no safe message. */
@@ -12663,7 +12737,7 @@ function report(adapter, kind, operation, cause, invocation, origin, authoritati
12663
12737
  link = link.cause;
12664
12738
  }
12665
12739
  } else if (reportedByMachine(cause)) return;
12666
- const operationName = normalizeCapxulOperation(operation);
12740
+ const operationName = isCapxulOperation(operation) ? operation : normalizeCapxulOperation(readFailureOperation(cause) ?? operation);
12667
12741
  const kindName = normalizeErrorKind(errorKind(cause));
12668
12742
  const context = sanitizeObservationContext({
12669
12743
  ...invocation.context,
@@ -17763,7 +17837,7 @@ function paymentExecutionIntent(input) {
17763
17837
  value: decoded.success
17764
17838
  } : {
17765
17839
  ok: false,
17766
- error: invalidPaymentField(decoded.failure.issue)
17840
+ error: invalidPaymentField(decoded.failure.issue, "invalid personal payment input")
17767
17841
  };
17768
17842
  } catch {
17769
17843
  return {
@@ -17773,11 +17847,28 @@ function paymentExecutionIntent(input) {
17773
17847
  }
17774
17848
  }
17775
17849
  const formatIssue = SchemaIssue.makeFormatterStandardSchemaV1();
17776
- /** The first failing field and why, e.g. `amount.value`, as the backend's row decode names it (#2381). */
17777
- function invalidPaymentField(issue) {
17850
+ /** A key the schema allows only as absent (`currency?: never`). Effect reports it as an empty `AnyOf`. */
17851
+ const forbiddenKey = (ast) => SchemaAST.isUnion(ast) && ast.types.every((type) => SchemaAST.isNever(type) || SchemaAST.isUndefined(type));
17852
+ /** Whether the issue that the formatter reports first is a key the caller must not pass. */
17853
+ function unknownKey(issue) {
17854
+ switch (issue._tag) {
17855
+ case "Encoding":
17856
+ case "Filter":
17857
+ case "Pointer": return unknownKey(issue.issue);
17858
+ case "Composite": return unknownKey(issue.issues[0]);
17859
+ case "AnyOf": return issue.issues[0] === void 0 ? forbiddenKey(issue.ast) : unknownKey(issue.issues[0]);
17860
+ default: return issue._tag === "UnexpectedKey";
17861
+ }
17862
+ }
17863
+ /**
17864
+ * The first failing field and why, e.g. `amount.value`, as the backend's row decode names it (#2381).
17865
+ * `callerPath` maps the decoded path to the path the caller passed (#2400).
17866
+ */
17867
+ function invalidPaymentField(issue, fallbackReason, callerPath = (path) => path) {
17778
17868
  const first = formatIssue(issue).issues[0];
17779
- const field = first?.path?.map((segment) => String(typeof segment === "object" ? segment.key : segment)).join(".");
17780
- return Errors.invalidInput(field === void 0 || field.length === 0 ? "payment" : field, first?.message ?? "invalid personal payment input");
17869
+ const path = callerPath(first?.path?.map((segment) => String(typeof segment === "object" ? segment.key : segment)) ?? []);
17870
+ const reason = path.length > 0 && unknownKey(issue) ? `unknown field \`${path.at(-1)}\`` : first?.message;
17871
+ return Errors.invalidInput(path.length === 0 ? "payment" : path.join("."), reason ?? fallbackReason);
17781
17872
  }
17782
17873
  function normalizePaymentTiming(payment) {
17783
17874
  const { release: _release, ...rest } = payment;
@@ -18347,7 +18438,13 @@ const organizationPaymentIntentSchema = Schema.Struct({
18347
18438
  items: PrepareOrganizationPaymentExecutionInputSchema.fields.items,
18348
18439
  lineage: PrepareOrganizationPaymentExecutionInputSchema.fields.lineage
18349
18440
  });
18350
- function organizationPaymentIntent(orgId, input) {
18441
+ /** One Payment's decoded `items.0.amount.value` is the caller's `amount.value`. */
18442
+ const singleItemPath = (path) => path[0] === "items" && path[1] === "0" ? path.slice(2) : path;
18443
+ /**
18444
+ * Decode a batch. `single` says the caller passed one Payment that its call
18445
+ * site wrapped as `items: [item]`, so a refusal names the caller's own field.
18446
+ */
18447
+ function organizationPaymentIntent(orgId, input, single = false) {
18351
18448
  if (input.requestKey !== void 0) {
18352
18449
  if (Schema.decodeResult(PrepareOrganizationPaymentExecutionInputSchema.fields.requestKey)(input.requestKey)._tag === "Failure") return {
18353
18450
  ok: false,
@@ -18360,13 +18457,14 @@ function organizationPaymentIntent(orgId, input) {
18360
18457
  items: input.items,
18361
18458
  ...input.lineage === void 0 ? {} : { lineage: input.lineage }
18362
18459
  });
18363
- return decoded._tag === "Failure" ? {
18364
- ok: false,
18365
- error: Errors.invalidInput("payment", "invalid Organization Payment input")
18366
- } : {
18460
+ if (decoded._tag === "Success") return {
18367
18461
  ok: true,
18368
18462
  value: decoded.success
18369
18463
  };
18464
+ return {
18465
+ ok: false,
18466
+ error: invalidPaymentField(decoded.failure.issue, "invalid Organization Payment input", single ? singleItemPath : void 0)
18467
+ };
18370
18468
  }
18371
18469
  async function organizationPaymentRequest(scope, actor, intent, providedKey) {
18372
18470
  let requestKey;
@@ -18472,12 +18570,12 @@ function executionDependencies$1(input) {
18472
18570
  * Submit one Organization payment batch. Callers that repeat a request key join
18473
18571
  * the flight already in progress instead of preparing a second execution.
18474
18572
  */
18475
- async function executeOrganizationBatch(scope, input, signal, operation, controls, onPrepared) {
18573
+ async function executeOrganizationBatch(scope, input, signal, operation, controls, onPrepared, single = false) {
18476
18574
  if (signal?.aborted === true) return {
18477
18575
  ok: false,
18478
18576
  error: Errors.cancelled({ operation })
18479
18577
  };
18480
- const intent = organizationPaymentIntent(scope.orgId, input);
18578
+ const intent = organizationPaymentIntent(scope.orgId, input, single);
18481
18579
  if (!intent.ok) return intent;
18482
18580
  const execution = executionDependencies$1(scope.deps);
18483
18581
  if (execution === null) return {
@@ -18594,7 +18692,7 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
18594
18692
  requestKeyScope: deps.requestKeyScope ?? `client-${crypto.randomUUID()}`,
18595
18693
  flights: /* @__PURE__ */ new Map()
18596
18694
  };
18597
- const execute = (input, signal, operation = "organization-pay-batch", controls, onPrepared) => executeOrganizationBatch(scope, input, signal, operation, controls, onPrepared);
18695
+ const execute = (input, signal, operation = "organization-pay-batch", controls, onPrepared, single = false) => executeOrganizationBatch(scope, input, signal, operation, controls, onPrepared, single);
18598
18696
  /** One Owner-signed cancel or redirect, answering the one Payment it acted on (#2299). */
18599
18697
  const ownerLifecycle = (intent, controls, operation) => runCapxulEffect(Effect.gen(function* () {
18600
18698
  const captured = carryInvocationParentSpan(controls, yield* Effect.currentSpan.pipe(Effect.orDie));
@@ -18661,7 +18759,7 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
18661
18759
  ...providedRequestKey === void 0 ? {} : { requestKey: providedRequestKey },
18662
18760
  items: [item],
18663
18761
  ...lineage === void 0 ? {} : { lineage }
18664
- }, controls?.signal, "organization-pay", captured, options?.onPrepared);
18762
+ }, controls?.signal, "organization-pay", captured, options?.onPrepared, true);
18665
18763
  if (!result.ok) return result;
18666
18764
  const payment = result.value[0];
18667
18765
  return payment === void 0 ? {
@@ -19846,20 +19944,45 @@ async function checked(deps, signerAddress, prepared, expected, close) {
19846
19944
  };
19847
19945
  return close ? abandonPrepared(deps, evidence.executionId, "prepared_mismatch", refused) : refused;
19848
19946
  }
19849
- /** A retry, a request payment or a payroll run, rather than a new Payment. */
19850
- const isCommandApproval = (input) => "retry" in input || "request" in input || "payrollRun" in input;
19851
- /** Prepare a retry, a request payment or a payroll run for `signerAddress`, checked. */
19947
+ /** A retry, cancel or redirect, a request payment or a payroll run, rather than a new Payment. */
19948
+ const isCommandApproval = (input) => "retry" in input || "cancel" in input || "redirect" in input || "request" in input || "payrollRun" in input;
19949
+ /** The next step of an existing Payment the input names; a recipient that cannot be one is refused. */
19950
+ function lifecycleIntent(input) {
19951
+ if ("retry" in input) return {
19952
+ ok: true,
19953
+ value: {
19954
+ kind: "retry",
19955
+ paymentId: input.retry
19956
+ }
19957
+ };
19958
+ if ("cancel" in input) return {
19959
+ ok: true,
19960
+ value: {
19961
+ kind: "cancel",
19962
+ paymentId: input.cancel
19963
+ }
19964
+ };
19965
+ const recipient = normalizeTargetForBackend(input.to, "to");
19966
+ return recipient.ok ? {
19967
+ ok: true,
19968
+ value: {
19969
+ kind: "redirect",
19970
+ paymentId: input.redirect,
19971
+ recipient: recipient.value
19972
+ }
19973
+ } : recipient;
19974
+ }
19975
+ /** Prepare a retry, cancel, redirect, request payment or payroll run for `signerAddress`, checked. */
19852
19976
  function prepareVerifiedCommand(deps, input, signerAddress, signal) {
19853
- if ("retry" in input) return prepareVerifiedRetry(deps, input, signerAddress, signal);
19854
19977
  if ("request" in input) return prepareVerifiedRequestPayment(deps, input, signerAddress, signal);
19855
- return prepareVerifiedPayrollRun(deps, input, signerAddress, signal);
19856
- }
19857
- /** The retry of one Payment, prepared in the scope that paid it. */
19858
- async function prepareVerifiedRetry(deps, input, signerAddress, signal) {
19859
- const intent = {
19860
- kind: "retry",
19861
- paymentId: input.retry
19862
- };
19978
+ if ("payrollRun" in input) return prepareVerifiedPayrollRun(deps, input, signerAddress, signal);
19979
+ return prepareVerifiedLifecycle(deps, input, signerAddress, signal);
19980
+ }
19981
+ /** The next step of one Payment, prepared in the scope that paid it. */
19982
+ async function prepareVerifiedLifecycle(deps, input, signerAddress, signal) {
19983
+ const named = lifecycleIntent(input);
19984
+ if (!named.ok) return named;
19985
+ const intent = named.value;
19863
19986
  return checked(deps, signerAddress, await runIfActive(signal, CAPXUL_OPERATIONS.payments.prepareLifecycleExecution, () => callOperation(deps.convexCall, lifecycles.prepareScoped, {
19864
19987
  signerAddress,
19865
19988
  intent,
@@ -19928,7 +20051,7 @@ async function prepareVerifiedOrganizationPayment(deps, input, signerAddress, si
19928
20051
  items: [item],
19929
20052
  ...lineage === void 0 ? {} : { lineage },
19930
20053
  ...requestKey === void 0 ? {} : { requestKey }
19931
- });
20054
+ }, true);
19932
20055
  if (!intent.ok) return intent;
19933
20056
  const session = deps.actor?.authSession() ?? null;
19934
20057
  if (session === null || deps.chainId === void 0) return {
@@ -19986,6 +20109,16 @@ async function readApprovalPayments(deps, paymentIds, organizationId, signal) {
19986
20109
  }
19987
20110
  //#endregion
19988
20111
  //#region src/accounts/approvals.ts
20112
+ /** A Permission write or an invitation, rather than a Payment. */
20113
+ const isPermissionChange = (input) => "permission" in input || "invite" in input;
20114
+ /** Only a Permission change or an invitation moves no money: its own owner sends it. */
20115
+ const movesMoney = (approval) => approval.kind !== "permission_change" && approval.kind !== "invitation";
20116
+ /**
20117
+ * A wait ends once it is sent: a Permission change or an invitation, and a
20118
+ * cancel or redirect of a held Payment, whose Payment was sent long before
20119
+ * and so cannot say whether this step was (#2439).
20120
+ */
20121
+ const endsOnceSent = (approval) => !movesMoney(approval) || approval.kind === "payment_cancel" || approval.kind === "payment_redirect";
19989
20122
  function makeApprovalsMethods(deps) {
19990
20123
  const call = (name, row, args, signal) => runIfActive(signal, name, () => callOperation(deps.convexCall, row, args, { fresh: true }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
19991
20124
  const get = (approvalId) => call(approvals.get.name, approvals.get, { approvalId });
@@ -20026,6 +20159,10 @@ function makeApprovalsMethods(deps) {
20026
20159
  const prepare = async (input, options) => {
20027
20160
  const signal = options?.signal;
20028
20161
  if (isCommandApproval(input)) return openApproval(signal, (signerAddress) => prepareVerifiedCommand(deps, input, signerAddress, signal));
20162
+ if (isPermissionChange(input)) return openApproval(signal, async (signerAddress) => {
20163
+ const { prepareVerifiedPermissionChange } = await import("./permission-approvals-B4iv9bXz.mjs");
20164
+ return prepareVerifiedPermissionChange(deps, input, signerAddress, signal);
20165
+ });
20029
20166
  if ("organizationId" in input) return openApproval(signal, (signerAddress) => prepareVerifiedOrganizationPayment(deps, input, signerAddress, signal));
20030
20167
  const intent = paymentExecutionIntent(input);
20031
20168
  if (!intent.ok) return intent;
@@ -20092,10 +20229,23 @@ function makeApprovalsMethods(deps) {
20092
20229
  const submit = async (approvalId) => {
20093
20230
  const consumed = await call(approvals.consume.name, approvals.consume, { approvalId });
20094
20231
  if (!consumed.ok) return consumed;
20095
- const sent = await call(executions.submitCommand.name, executions.submitCommand, {
20096
- executionId: consumed.value.approval.operation.executionId,
20097
- signature: consumed.value.signature
20098
- });
20232
+ const { approval, signature } = consumed.value;
20233
+ const signed = {
20234
+ executionId: approval.operation.executionId,
20235
+ signature
20236
+ };
20237
+ if (!movesMoney(approval)) {
20238
+ const row = approval.kind === "invitation" ? configurations : commands;
20239
+ const sent = await call(row.submitExecution.name, row.submitExecution, signed);
20240
+ return sent.ok ? {
20241
+ ok: true,
20242
+ value: {
20243
+ approval,
20244
+ payments: []
20245
+ }
20246
+ } : sent;
20247
+ }
20248
+ const sent = await call(executions.submitCommand.name, executions.submitCommand, signed);
20099
20249
  if (!sent.ok) return sent;
20100
20250
  return {
20101
20251
  ok: true,
@@ -20118,6 +20268,20 @@ function makeApprovalsMethods(deps) {
20118
20268
  ok: true,
20119
20269
  value: null
20120
20270
  };
20271
+ if (endsOnceSent(approval)) {
20272
+ if (approval.state !== "approved" && approval.state !== "consumed") return {
20273
+ ok: true,
20274
+ value: {
20275
+ approval,
20276
+ payments: []
20277
+ }
20278
+ };
20279
+ const sent = await submit(approvalId);
20280
+ return sent.ok || !anotherSendInFlight(sent.error) ? sent : {
20281
+ ok: true,
20282
+ value: null
20283
+ };
20284
+ }
20121
20285
  const payments = await readApprovalPayments(deps, approval.operation.paymentIds, organizationId ?? (approval.actor.kind === "organization" ? approval.actor.orgId : void 0), signal);
20122
20286
  if (!payments.ok) return payments;
20123
20287
  if (unsent(approval, payments.value)) {
@@ -23047,4 +23211,4 @@ function executeIdentityProductObservation(telemetry, record, state) {
23047
23211
  return ignoreTransportFailure(() => invocationTelemetry.emit(mapped), "emit", mapped.name).pipe(Effect.andThen(ignoreTransportFailure(after, mapped.name === "auth_signed_out" ? "reset" : "identify", mapped.name)));
23048
23212
  }
23049
23213
  //#endregion
23050
- export { parseAssetAmount as $, hashPermissionReplacementPreview as $n, carryInvocationParentSpan as $r, isSettingUpLifecycle as $t, registerProductTelemetryInvocation as A, toEpochSeconds as Ai, onboardings as An, isEvmAddress as Ar, safe4337MultiSendUserOpCallData as At, makeOrganizationPaymentsMethods as B, isRecord as Bi, invitations as Bn, runPortEffect as Br, CAPXUL_SDK_EXPECTED_OUTCOME_EVENT as Bt, AccountReadPortTag as C, globalLocalStorage as Ci, EXCEPTION_EVENT_NAME as Cn, toRoleKey as Cr, SEND_SIGNATURE as Ct, convexCallErrorFromCapxul as D, parseCachedJwt as Di, normalizeCapxulOperation as Dn, toCurrencyCode as Dr, deriveCapxulSafeAddress as Dt, ConvexCallPortTag as E, parseAuthSession as Ei, isCapxulOperation as En, toAssetId as Er, TOKENS as Et, decodePayrollRunInput as F, Errors as Fi, PreparedPermissionExecutionSchema as Fn, reference as Fr, callOperation as Ft, makeActorRelationshipMethods as G, workspaces as Gn, awaitCapxulResult as Gr, withCapturedAttemptContext as Gt, makePaymentsMethods as H, AuthCacheError as Hi, roles as Hn, observationOnlyControls as Hr, observeFailedResult as Ht, toPayrollGroupId as I, CapxulError as Ii, PermissionCommandViewSchema as In, makeAuthMethods as Ir, asCapxulError as It, makeTargetsMethods as J, ORGANIZATION_SETUP_STATUSES as Jn, toCapxulResult as Jr, normalizeExceptionErrorKind as Jt, makeCheckoutMethods as K, OrganizationSetupSchema as Kn, defectAsCapxulError as Kr, EXCEPTION_MESSAGE as Kt, makeAccountMethods as L, isCapxulError as Li, PayrollGroupIdSchema as Ln, askIdentity as Lr, toPublicError$1 as Lt, makeApprovalsMethods as M, toEmail as Mi, commands as Mn, toChainId as Mr, BASE_SEPOLIA_CHAIN_ID as Mt, makePayrollMethods as N, toJwtToken as Ni, configurations as Nn, toWeiAmount as Nr, MULTI_SEND_CALL_ONLY as Nt, retryIdempotentRead as O, toDurationMs as Oi, OPERATIONS as On, toExactAssetAmount as Or, normalizeSafeSaltEmail as Ot, makeUnavailablePayrollMethods as P, toSessionToken as Pi, replacements as Pn, absurd as Pr, SAFE_SENTINEL_OWNERS as Pt, formatAssetAmount as Q, InvitationViewSchema as Qn, ActorFailure as Qr, version as Qt, emitDepositInitiated as R, FAILURE_MODES$1 as Ri, PayrollGroupInputSchema as Rn, publicIdentityFailure as Rr, failureDetail as Rt, valueIn as S, detectAuthCacheAdapter as Si, CLI_INVOCATION_KINDS as Sn, toPermissionId as Sr, SEND_BATCH_SIGNATURE as St, TelemetryPortTag as T, BrowserAuthCacheAdapter as Ti, CAPXUL_OPERATIONS as Tn, currencySymbolFor as Tr, CONFIGURED_MONEY_ASSETS as Tt, waitForPaymentSubmission as U, AuthCachePortTag as Ui, setups as Un, runCapxulEffect as Ur, observeSdkClient as Ut, makeOfframpMethods as V, readField as Vi, members as Vn, sessionFromActor as Vr, postHogFailureObservation as Vt, makeDestinationsMethods as W, treasuries as Wn, withVerifiedOrganizationScope as Wr, observationContextProps as Wt, assetAmountFromRaw as X, decodeChainCause as Xn, CAPXUL_ERROR_CODES as Xr, projectSdkException as Xt, subscribeFreshQuery as Y, CHAIN_UPSTREAMS as Yn, formatTraceparent as Yr, normalizeExceptionOperation as Yt, assetSymbolFor as Z, toOrgId as Zn, EXPECTED_OPERATION_OUTCOMES as Zr, safeExceptionLabel as Zt, accountFromAccountPositions as _, toAppId as _i, validateHandle as _n, PAYMENT_STATUSES as _r, ROLES_SET_ALLOWANCE_ABI as _t, paymentPhase as a, readClockNow as ai, openfortSignerNotReadyCode as an, roleKeyForPermission as ar, fingerprintPaymentIntent as at, MONEY_READ_RATES as b, AuthClientError as bi, CLI_CAPABILITIES as bn, toBudgetId as br, ROLE_MANAGEMENT_SIGNATURES as bt, makePaymentDocumentsMethods as c, observationRequestHeaders as ci, resolveFailureMode as cn, images as cr, resolveOrgPermissionIdentity as ct, SmartAccountPortTag as d, readInvocationObservation as di, toCountryCode as dn, isBytes32 as dr, MULTI_SEND_SELECTOR as dt, withInvocationParentSpan as ei, UNOBSERVABLE_SIGNER_STATUS as en, decodePermissionIntent as er, requireAsset as et, smartAccountErrorFromCapxul as f, sanitizeObservationContext as fi, toKycTier as fn, toExactHex as fr, OPERATOR as ft, ConvexAccountLayer as g, toAllowedOrigin as gi, toPartyId as gn, PAYMENT_DIRECTIONS as gr, ROLES_EXEC_TRANSACTION_WITH_ROLE_ABI as gt, makeAccountsMethods as h, isCredentialField as hi, toHandle as hn, toLowerHex as hr, ROLES_ASSIGN_ROLES_ABI as ht, inboxPhase as i, ClockPortTag as ii, isSignerNotReadySignal as in, ORG_BUDGET_ACTIONS as ir, canonicalJson as it, wireChainId as j, toAuthUserId as ji, authorities as jn, toAddress as jr, buildSafeMultiSendExecTransactionCall as jt, bindProductTelemetryInvocation as k, toEpochMs as ki, details as kn, EVM_ADDRESS_RE$1 as kr, safe4337ExecuteUserOpCallData as kt, makeSmartAccountMethods as l, attachInvocationObservation as li, makeCurrentUserMethods as ln, toAccountId as lr, CREATE_COMMITMENT_SIGNATURE as lt, PonderIndexerAdapter as m, redactUrlSecrets as mi, HANDLE_RE as mn, toLowerBytes32 as mr, PARAMETER_TYPE as mt, bootIdentityFlow as n, SystemClockLayer as ni, injectedWalletSigner as nn, CurrentPolicySchema as nr, isMoneyParseError as nt, requestPhase as o, BetterAuthNodeLayer as oi, recoverRawDigestSigner as on, diagnostics as or, moneySafeOpDigest as ot, makeHoldingsMethods as p, redactSecrets as pi, toTesterKind as pn, toLowerAddress as pr, OWNER_COMMITMENT_SIGNATURES as pt, isCheckoutSettlementConsumed as q, ORGANIZATION_SETUP_REASONS as qn, runIfActive as qr, SDK_VERSION as qt, makeMeMethods as r, ClockError as ri, isEcdsaSignatureHex as rn, MONTHLY_REFILL_PERIOD_SECONDS as rr, parseMoney as rt, makeActivityMethods as s, BetterAuthBrowserLayer as si, signerFailure as sn, AppIdSchema$1 as sr, ZODIAC_MODULE_PROXY_FACTORY as st, executeIdentityProductObservation as t, oauthBearerAuthClient as ti, causeChain as tn, keepRefillOnChange as tr, toRaw as tt, ConvexSmartAccountLayer as u, copyInvocationObservation as ui, makeClientRequestMethods as un, PaymentDocumentOptionsSchema as ur, MODULE_PROXY_FACTORY_ABI as ut, accountPositionsFromWire as v, toPublishableKey as vi, redactTelemetryEvent as vn, DurationMsSchema$1 as vr, ROLES_SET_TRANSACTION_UNWRAPPER_ABI as vt, accountReadErrorFromCapxul as w, InMemoryAuthCacheAdapter as wi, stampTelemetryEnvelope as wn, ChainIdSchema$1 as wr, CAPXUL_PAYMENTS_V2_ADDRESS as wt, valueActivitySummary as x, AuthClientPortTag as xi, CLI_COMMAND_NAMES as xn, toPermissionAssignmentId as xr, SAFE_ENABLE_MODULE_ABI as xt, positionPeg as y, authClientPortFromPromiseAdapter as yi, redactTelemetryProps as yn, EpochMsSchema$1 as yr, ROLES_SET_UP_ABI as yt, logDroppedEvent as z, isFailureMode as zi, FixedOfferDraftSchema as zn, runIdentityFacade as zr, failureEvidenceProps as zt };
23214
+ export { formatAssetAmount as $, InvitationViewSchema as $n, ActorFailure as $r, version as $t, registerProductTelemetryInvocation as A, toEpochMs as Ai, details as An, EVM_ADDRESS_RE$1 as Ar, safe4337ExecuteUserOpCallData as At, makeOrganizationPaymentsMethods as B, isFailureMode as Bi, FixedOfferDraftSchema as Bn, runIdentityFacade as Br, failureEvidenceProps as Bt, AccountReadPortTag as C, detectAuthCacheAdapter as Ci, CLI_INVOCATION_KINDS as Cn, toPermissionId as Cr, SEND_BATCH_SIGNATURE as Ct, convexCallErrorFromCapxul as D, parseAuthSession as Di, isCapxulOperation as Dn, toAssetId as Dr, TOKENS as Dt, ConvexCallPortTag as E, BrowserAuthCacheAdapter as Ei, CAPXUL_OPERATIONS as En, currencySymbolFor as Er, CONFIGURED_MONEY_ASSETS as Et, decodePayrollRunInput as F, toSessionToken as Fi, replacements as Fn, absurd as Fr, SAFE_SENTINEL_OWNERS as Ft, makeActorRelationshipMethods as G, treasuries as Gn, withVerifiedOrganizationScope as Gr, observationContextProps as Gt, makePaymentsMethods as H, readField as Hi, members as Hn, sessionFromActor as Hr, postHogFailureObservation as Ht, toPayrollGroupId as I, Errors as Ii, PreparedPermissionExecutionSchema as In, reference as Ir, callOperation as It, makeTargetsMethods as J, ORGANIZATION_SETUP_REASONS as Jn, runIfActive as Jr, SDK_VERSION as Jt, makeCheckoutMethods as K, workspaces as Kn, awaitCapxulResult as Kr, withCapturedAttemptContext as Kt, makeAccountMethods as L, CapxulError as Li, PermissionCommandViewSchema as Ln, makeAuthMethods as Lr, asCapxulError as Lt, makeApprovalsMethods as M, toAuthUserId as Mi, authorities as Mn, toAddress as Mr, buildSafeMultiSendExecTransactionCall as Mt, makePayrollMethods as N, toEmail as Ni, commands as Nn, toChainId as Nr, BASE_SEPOLIA_CHAIN_ID as Nt, retryIdempotentRead as O, parseCachedJwt as Oi, normalizeCapxulOperation as On, toCurrencyCode as Or, deriveCapxulSafeAddress as Ot, makeUnavailablePayrollMethods as P, toJwtToken as Pi, configurations as Pn, toWeiAmount as Pr, MULTI_SEND_CALL_ONLY as Pt, assetSymbolFor as Q, toOrgId as Qn, EXPECTED_OPERATION_OUTCOMES as Qr, safeExceptionLabel as Qt, emitDepositInitiated as R, isCapxulError as Ri, PayrollGroupIdSchema as Rn, askIdentity as Rr, toPublicError$1 as Rt, valueIn as S, AuthClientPortTag as Si, CLI_COMMAND_NAMES as Sn, toPermissionAssignmentId as Sr, SAFE_ENABLE_MODULE_ABI as St, TelemetryPortTag as T, InMemoryAuthCacheAdapter as Ti, stampTelemetryEnvelope as Tn, ChainIdSchema$1 as Tr, CAPXUL_PAYMENTS_V2_ADDRESS as Tt, waitForPaymentSubmission as U, AuthCacheError as Ui, roles as Un, observationOnlyControls as Ur, observeFailedResult as Ut, makeOfframpMethods as V, isRecord as Vi, invitations as Vn, runPortEffect as Vr, CAPXUL_SDK_EXPECTED_OUTCOME_EVENT as Vt, makeDestinationsMethods as W, AuthCachePortTag as Wi, setups as Wn, runCapxulEffect as Wr, observeSdkClient as Wt, abandonPrepared as X, CHAIN_UPSTREAMS as Xn, formatTraceparent as Xr, normalizeExceptionOperation as Xt, subscribeFreshQuery as Y, ORGANIZATION_SETUP_STATUSES as Yn, toCapxulResult as Yr, normalizeExceptionErrorKind as Yt, assetAmountFromRaw as Z, decodeChainCause as Zn, CAPXUL_ERROR_CODES as Zr, projectSdkException as Zt, accountFromAccountPositions as _, toAllowedOrigin as _i, toPartyId as _n, PAYMENT_DIRECTIONS as _r, ROLES_EXEC_TRANSACTION_WITH_ROLE_ABI as _t, paymentPhase as a, ClockPortTag as ai, isSignerNotReadySignal as an, ORG_BUDGET_ACTIONS as ar, canonicalJson as at, MONEY_READ_RATES as b, authClientPortFromPromiseAdapter as bi, redactTelemetryProps as bn, EpochMsSchema$1 as br, ROLES_SET_UP_ABI as bt, makePaymentDocumentsMethods as c, BetterAuthBrowserLayer as ci, signerFailure as cn, AppIdSchema$1 as cr, ZODIAC_MODULE_PROXY_FACTORY as ct, SmartAccountPortTag as d, copyInvocationObservation as di, makeClientRequestMethods as dn, PaymentDocumentOptionsSchema as dr, MODULE_PROXY_FACTORY_ABI as dt, carryInvocationParentSpan as ei, isSettingUpLifecycle as en, hashPermissionReplacementPreview as er, parseAssetAmount as et, smartAccountErrorFromCapxul as f, readInvocationObservation as fi, toCountryCode as fn, isBytes32 as fr, MULTI_SEND_SELECTOR as ft, ConvexAccountLayer as g, isCredentialField as gi, toHandle as gn, toLowerHex as gr, ROLES_ASSIGN_ROLES_ABI as gt, makeAccountsMethods as h, redactUrlSecrets as hi, HANDLE_RE as hn, toLowerBytes32 as hr, PARAMETER_TYPE as ht, inboxPhase as i, ClockError as ii, isEcdsaSignatureHex as in, MONTHLY_REFILL_PERIOD_SECONDS as ir, parseMoney as it, wireChainId as j, toEpochSeconds as ji, onboardings as jn, isEvmAddress as jr, safe4337MultiSendUserOpCallData as jt, bindProductTelemetryInvocation as k, toDurationMs as ki, OPERATIONS as kn, toExactAssetAmount as kr, normalizeSafeSaltEmail as kt, makeSmartAccountMethods as l, observationRequestHeaders as li, resolveFailureMode as ln, images as lr, resolveOrgPermissionIdentity as lt, PonderIndexerAdapter as m, redactSecrets as mi, toTesterKind as mn, toLowerAddress as mr, OWNER_COMMITMENT_SIGNATURES as mt, bootIdentityFlow as n, oauthBearerAuthClient as ni, causeChain as nn, keepRefillOnChange as nr, toRaw as nt, requestPhase as o, readClockNow as oi, openfortSignerNotReadyCode as on, roleKeyForPermission as or, fingerprintPaymentIntent as ot, makeHoldingsMethods as p, sanitizeObservationContext as pi, toKycTier as pn, toExactHex as pr, OPERATOR as pt, isCheckoutSettlementConsumed as q, OrganizationSetupSchema as qn, defectAsCapxulError as qr, EXCEPTION_MESSAGE as qt, makeMeMethods as r, SystemClockLayer as ri, injectedWalletSigner as rn, CurrentPolicySchema as rr, isMoneyParseError as rt, makeActivityMethods as s, BetterAuthNodeLayer as si, recoverRawDigestSigner as sn, diagnostics as sr, moneySafeOpDigest as st, executeIdentityProductObservation as t, withInvocationParentSpan as ti, UNOBSERVABLE_SIGNER_STATUS as tn, decodePermissionIntent as tr, requireAsset as tt, ConvexSmartAccountLayer as u, attachInvocationObservation as ui, makeCurrentUserMethods as un, toAccountId as ur, CREATE_COMMITMENT_SIGNATURE as ut, accountPositionsFromWire as v, toAppId as vi, validateHandle as vn, PAYMENT_STATUSES as vr, ROLES_SET_ALLOWANCE_ABI as vt, accountReadErrorFromCapxul as w, globalLocalStorage as wi, EXCEPTION_EVENT_NAME as wn, toRoleKey as wr, SEND_SIGNATURE as wt, valueActivitySummary as x, AuthClientError as xi, CLI_CAPABILITIES as xn, toBudgetId as xr, ROLE_MANAGEMENT_SIGNATURES as xt, positionPeg as y, toPublishableKey as yi, redactTelemetryEvent as yn, DurationMsSchema$1 as yr, ROLES_SET_TRANSACTION_UNWRAPPER_ABI as yt, logDroppedEvent as z, FAILURE_MODES$1 as zi, PayrollGroupInputSchema as zn, publicIdentityFailure as zr, failureDetail as zt };