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

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, SchemaParser } from "effect";
1
+ import { Cause, Clock, Context, Data, Deferred, Effect, Exit, Fiber, Layer, Option, Predicate, Queue, Ref, Result, Schema, 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";
@@ -858,7 +858,7 @@ const FIELD_RULES = {
858
858
  },
859
859
  anonymousId: {
860
860
  maxLength: 128,
861
- pattern: /^anon_[A-Za-z0-9-]+$/u
861
+ pattern: /^(?:anon_[A-Za-z0-9-]+|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/u
862
862
  },
863
863
  traceparent: {
864
864
  maxLength: 55,
@@ -4823,10 +4823,19 @@ const ApprovalNetworkSchema = Schema.Struct({
4823
4823
  name: Schema.String,
4824
4824
  explorerUrl: Schema.String
4825
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
+ })]);
4826
4834
  /** What the person reads before they sign. */
4827
4835
  const ApprovalSummarySchema = Schema.Struct({
4828
4836
  title: Schema.String,
4829
4837
  from: Schema.Struct({
4838
+ kind: Schema.Literals(["personal", "organization"]),
4830
4839
  label: Schema.String,
4831
4840
  address: AddressSchema$1
4832
4841
  }),
@@ -4848,6 +4857,7 @@ const ApprovalSchema = Schema.Struct({
4848
4857
  url: Schema.String,
4849
4858
  kind: Schema.Literals(APPROVAL_KINDS),
4850
4859
  state: Schema.Literals(APPROVAL_STATES),
4860
+ actor: ApprovalActorSchema,
4851
4861
  summary: ApprovalSummarySchema,
4852
4862
  operation: ApprovalOperationSchema,
4853
4863
  /** Who must sign: the owner key of the paying Safe. */
@@ -5515,6 +5525,28 @@ const probes = {
5515
5525
  })
5516
5526
  };
5517
5527
  //#endregion
5528
+ //#region ../protocol/src/evm/role-dsl.ts
5529
+ const ORG_BUDGET_ACTIONS = [
5530
+ "send",
5531
+ "sendBatch",
5532
+ "createCommitment"
5533
+ ];
5534
+ /**
5535
+ * How a capped Budget's allowance refills (#2298). `monthly` refills the
5536
+ * allowance to its cap every 30 days. Roles v2 counts fixed periods from the
5537
+ * moment the allowance is set; it has no calendar month. Absent means `none`:
5538
+ * the cap is one pot that spending drains for good.
5539
+ */
5540
+ const ORG_BUDGET_REFILLS = ["monthly", "none"];
5541
+ /** The fixed Roles v2 refill period of a `monthly` Budget: 30 days, in seconds. */
5542
+ const MONTHLY_REFILL_PERIOD_SECONDS = 30n * 24n * 60n * 60n;
5543
+ /** Derive the Zodiac substrate key for one durable Permission identity. */
5544
+ function roleKeyForPermission(permissionId) {
5545
+ const normalized = permissionId.trim();
5546
+ if (normalized.length === 0 || normalized !== permissionId) throw Errors.invalidInput("permissionId", "must be a non-empty canonical Permission ID");
5547
+ return keccak256(toBytes(`permission ${permissionId}`));
5548
+ }
5549
+ //#endregion
5518
5550
  //#region ../protocol/src/permissions/permission-schema.ts
5519
5551
  /**
5520
5552
  * One stored `setAllowance` call inside a command's expected authority set.
@@ -5553,12 +5585,19 @@ const BudgetScopeSchema = Schema.Struct({
5553
5585
  })]),
5554
5586
  actions: Schema.NonEmptyArray(Schema.Literals(["pay", "commitments"]))
5555
5587
  }).pipe(Schema.refine((scope) => new Set(scope.actions).size === scope.actions.length && (scope.recipients.type === "anyone" || scope.recipients.accounts.length >= 1 && scope.recipients.accounts.length <= 32 && new Set(scope.recipients.accounts).size === scope.recipients.accounts.length), { message: "Budget scope requires unique actions and one to 32 unique allowed Accounts" }));
5588
+ /**
5589
+ * How a capped Budget refills (#2298): `monthly` tops the cap back up every 30
5590
+ * days (a fixed Roles v2 period, not a calendar month); `none` never refills.
5591
+ * Absent means `none`, and writers store only `monthly`.
5592
+ */
5593
+ const BudgetRefillSchema = Schema.Literals(ORG_BUDGET_REFILLS);
5556
5594
  /** The accepted product policy stored with one Permission revision. */
5557
5595
  const CurrentPolicySchema = Schema.Union([Schema.Struct({
5558
5596
  type: Schema.Literal("budget"),
5559
5597
  asset: AssetIdSchema,
5560
5598
  limit: Schema.NullOr(Schema.String),
5561
- scope: BudgetScopeSchema
5599
+ scope: BudgetScopeSchema,
5600
+ refill: Schema.optional(BudgetRefillSchema)
5562
5601
  }), Schema.Struct({ type: Schema.Literal("managePeople") })]);
5563
5602
  const BudgetIntentSchema = CurrentPolicySchema.pipe(Schema.refine((value) => {
5564
5603
  if (value.type !== "budget") return false;
@@ -5623,7 +5662,8 @@ const ResolvedPermissionBudgetPolicySchema = Schema.Struct({
5623
5662
  "send",
5624
5663
  "sendBatch",
5625
5664
  "createCommitment"
5626
- ]))
5665
+ ])),
5666
+ refill: Schema.optional(BudgetRefillSchema)
5627
5667
  });
5628
5668
  const PermissionRecipientBindingSchema = Schema.Struct({
5629
5669
  accountId: AccountIdSchema$1,
@@ -5635,16 +5675,22 @@ const StoredPermissionIntentSchema = Schema.Union([Schema.Struct({
5635
5675
  type: Schema.Literal("budget"),
5636
5676
  asset: AssetIdSchema,
5637
5677
  limit: Schema.NullOr(AssetAmountSchema),
5638
- scope: Schema.optional(BudgetScopeSchema)
5678
+ scope: Schema.optional(BudgetScopeSchema),
5679
+ refill: Schema.optional(BudgetRefillSchema)
5639
5680
  }).pipe(Schema.refine((intent) => intent.limit === null || intent.limit.asset === intent.asset, { message: "Budget limit must use the Budget asset" })), Schema.Struct({ type: Schema.Literal("managePeople") })]);
5640
5681
  /** Writes state every granted right and use a finite positive AssetAmount cap. */
5641
5682
  const PermissionIntentSchema = Schema.Union([Schema.Struct({
5642
5683
  type: Schema.Literal("budget"),
5643
5684
  asset: AssetIdSchema,
5644
5685
  limit: AssetAmountSchema,
5645
- scope: BudgetScopeSchema
5686
+ scope: BudgetScopeSchema,
5687
+ refill: Schema.optional(BudgetRefillSchema)
5646
5688
  }).pipe(Schema.refine((intent) => intent.limit.asset === intent.asset && /[1-9]/u.test(intent.limit.value), { message: "Budget cap must be positive and use the Budget asset" })), Schema.Struct({ type: Schema.Literal("managePeople") })]);
5647
- /** Decode once and give set-like scope fields one stable command representation. */
5689
+ /**
5690
+ * Decode once and give set-like scope fields one stable command representation.
5691
+ * An explicit `refill: "none"` is kept: on a change it turns a refill off,
5692
+ * where a missing `refill` keeps the Budget's current one (`keepRefillOnChange`).
5693
+ */
5648
5694
  function decodePermissionIntent(input) {
5649
5695
  const intent = Schema.decodeUnknownSync(PermissionIntentSchema, { onExcessProperty: "error" })(input);
5650
5696
  if (intent.type === "managePeople") return intent;
@@ -5659,6 +5705,19 @@ function decodePermissionIntent(input) {
5659
5705
  }
5660
5706
  });
5661
5707
  }
5708
+ /**
5709
+ * A Budget change that leaves `refill` out keeps the Budget's current refill:
5710
+ * a change never turns a refill off by omission. An explicit `"none"` turns it
5711
+ * off. The backend plans, the SDK verifies and the CLI confirms the same
5712
+ * result. A create has no current refill, so a missing one means `none`.
5713
+ */
5714
+ function keepRefillOnChange(intent, before) {
5715
+ if (intent.type !== "budget" || intent.refill !== void 0 || before?.type !== "budget" || before.refill !== "monthly") return intent;
5716
+ return {
5717
+ ...intent,
5718
+ refill: before.refill
5719
+ };
5720
+ }
5662
5721
  //#endregion
5663
5722
  //#region ../protocol/src/permissions/replacement-schema.ts
5664
5723
  const InvitationPhaseSchema = Schema.Literals([
@@ -5863,7 +5922,7 @@ const InviteGrantsSchema = Schema.Array(Schema.Union([
5863
5922
  Schema.Struct({
5864
5923
  type: Schema.Literal("new_budget"),
5865
5924
  label: Schema.String.pipe(Schema.refine((value) => value.trim().length >= 1 && value.trim().length <= 128)),
5866
- intent: BudgetIntentSchema
5925
+ intent: BudgetIntentSchema.pipe(Schema.refine((intent) => intent.refill !== "monthly", { message: "An invitation's new Budget cannot refill; change it once granted" }))
5867
5926
  })
5868
5927
  ])).pipe(Schema.refine((grants) => {
5869
5928
  if (grants.length < 1 || grants.length > 16) return false;
@@ -8954,7 +9013,9 @@ const PEOPLE_OPERATIONS = {
8954
9013
  emitSafeConfirmed: "accounts.safes.emitSafeConfirmed",
8955
9014
  readSafe: "accounts.safes.readSafe",
8956
9015
  recordDeployment: "accounts.safes.recordDeployment"
8957
- }
9016
+ },
9017
+ /** The home's requests to pay and Payments to retry, read in one query. */
9018
+ summaries: { loadNeedsYou: "accounts.summaries.loadNeedsYou" }
8958
9019
  },
8959
9020
  /** The host observer's names for `client.approvals.*`. */
8960
9021
  approvals: {
@@ -9135,7 +9196,11 @@ const ORGANIZATION_OPERATIONS = {
9135
9196
  seedNativeReadiness: "operator.fixtures.seedNativeReadiness",
9136
9197
  seedPrerequisites: "operator.fixtures.seedPrerequisites"
9137
9198
  },
9138
- identities: { purgeByEmail: "operator.identities.purgeByEmail" }
9199
+ identities: {
9200
+ purgeByEmail: "operator.identities.purgeByEmail",
9201
+ /** One Account and every row that refers to it, unless it has Payments or an Organization tie. */
9202
+ purgeAccount: "operator.identities.purgeAccount"
9203
+ }
9139
9204
  },
9140
9205
  /** Organizations' internal functions; its public rows join from `OPERATIONS`. */
9141
9206
  organizations: {
@@ -9209,7 +9274,9 @@ emitSaved: "activity.annotations.emitSaved" },
9209
9274
  pay: "organizationPayments.pay",
9210
9275
  payBatch: "organizationPayments.payBatch",
9211
9276
  prepareExecution: "organizationPayments.prepareExecution",
9212
- retry: "organizationPayments.retry"
9277
+ retry: "organizationPayments.retry",
9278
+ cancel: "organizationPayments.cancel",
9279
+ redirect: "organizationPayments.redirect"
9213
9280
  },
9214
9281
  /**
9215
9282
  * Payments' internal functions and the client's own method names; its public
@@ -9231,7 +9298,9 @@ emitSaved: "activity.annotations.emitSaved" },
9231
9298
  loadContext: "payments.commands.loadContext",
9232
9299
  loadExecutionContext: "payments.commands.loadExecutionContext",
9233
9300
  /** The capped Budget a prepared Organization command spends from, before its allowance is read on chain. */
9234
- loadBudgetAllowance: "payments.commands.loadBudgetAllowance"
9301
+ loadBudgetAllowance: "payments.commands.loadBudgetAllowance",
9302
+ /** What a new Payment command would spend and from which Safe, read before it is born. */
9303
+ loadBirthFunding: "payments.commands.loadBirthFunding"
9235
9304
  },
9236
9305
  lifecycles: { prepareIntent: "payments.lifecycles.prepareIntent" },
9237
9306
  /** The stored UserOperation of every money command: Payment, Permission and configuration. */
@@ -9385,7 +9454,11 @@ const PLATFORM_OPERATIONS = {
9385
9454
  recordUse: "applications.bootstraps.recordUse",
9386
9455
  resolve: "applications.bootstraps.resolve"
9387
9456
  },
9388
- keys: { issue: "applications.keys.issue" },
9457
+ keys: {
9458
+ issue: "applications.keys.issue",
9459
+ /** Operator-only: revoke one key by its id, whoever owns it. */
9460
+ revokeById: "applications.keys.revokeById"
9461
+ },
9389
9462
  quickstarts: {
9390
9463
  claim: "applications.quickstarts.claim",
9391
9464
  mint: "applications.quickstarts.mint"
@@ -9586,6 +9659,13 @@ const OptionalReasonCode = Schema.optional(Schema.Literals(CAPXUL_ERROR_CODES));
9586
9659
  * no catalog schema validates it.
9587
9660
  */
9588
9661
  const EXCEPTION_EVENT_NAME = "$exception";
9662
+ /**
9663
+ * The SDK's twin of `capxul_backend_expected_outcome`: an expected outcome the
9664
+ * SDK's failure projection captures through the host's PostHog client. Like
9665
+ * the backend's, its properties are the error evidence, so no catalog schema
9666
+ * validates it.
9667
+ */
9668
+ const SDK_EXPECTED_OUTCOME_EVENT_NAME = "capxul_sdk_expected_outcome";
9589
9669
  const PII = Schema.String.pipe(Schema.brand("PII"));
9590
9670
  /**
9591
9671
  * The canonical envelope (ADR-0020 A4): snake_case ONLY. `capxul_env` and
@@ -9685,6 +9765,42 @@ const UiStepProps = {
9685
9765
  organization_id: OptionalOrgId,
9686
9766
  reason_code: OptionalReasonCode
9687
9767
  };
9768
+ /**
9769
+ * A journey's variants (`JOURNEYS`): the way a person came into a journey, or
9770
+ * the way they took through it. A variant is a property of the journey's step
9771
+ * events, never a journey of its own, so each journey funnel breaks down by
9772
+ * it. A step event takes only the variants that a journey contract names on
9773
+ * it, picked one by one; the analytics plan test checks both directions.
9774
+ * `pay_path` and `funding_source` have no carrier until their Phase 2 events.
9775
+ * `payment_*` events already carry `recipient_is_capxul_account`, and
9776
+ * `invoice_issued` carries `issuer_scope_kind`; neither is repeated here.
9777
+ */
9778
+ const JourneyVariantProps = {
9779
+ /** How a person came to Get started: by themselves, an invite, money that waited, or an invoice. */
9780
+ entry_path: Schema.optional(Schema.Literals([
9781
+ "signup",
9782
+ "invite",
9783
+ "claim",
9784
+ "invoice"
9785
+ ])),
9786
+ /** Where the person acted. `agent` is an AI agent driving the CLI. */
9787
+ surface: Schema.optional(Schema.Literals([
9788
+ "web",
9789
+ "cli",
9790
+ "agent"
9791
+ ])),
9792
+ /** Who pays: a person from their own account, or an Organization from a Budget. */
9793
+ payer_kind: Schema.optional(Schema.Literals(["person", "organization"])),
9794
+ /** How a request was paid: from the payer's inbox, or by its link at checkout. */
9795
+ pay_path: Schema.optional(Schema.Literals(["inbox", "link"])),
9796
+ /** Where an account's first money came from. `bank` is the planned on-ramp. */
9797
+ funding_source: Schema.optional(Schema.Literals([
9798
+ "deposit",
9799
+ "payment",
9800
+ "claim",
9801
+ "bank"
9802
+ ]))
9803
+ };
9688
9804
  //#endregion
9689
9805
  //#region ../observability/src/events/money.ts
9690
9806
  /**
@@ -9774,6 +9890,8 @@ const PaymentInitiatedProps = Schema.Struct({
9774
9890
  execution_id: OptionalString,
9775
9891
  payment_lifecycle_id: OptionalString,
9776
9892
  ...TelemetryEnvelopeProps,
9893
+ payer_kind: JourneyVariantProps.payer_kind,
9894
+ surface: JourneyVariantProps.surface,
9777
9895
  ...RecipientTelemetryProps,
9778
9896
  kind: Schema.String,
9779
9897
  payment_id: Schema.String
@@ -9789,6 +9907,8 @@ const PaymentLifecycleProps = {
9789
9907
  const PaymentSettledL2Props = Schema.Struct({
9790
9908
  ...PaymentLifecycleProps,
9791
9909
  ...TelemetryEnvelopeProps,
9910
+ payer_kind: JourneyVariantProps.payer_kind,
9911
+ surface: JourneyVariantProps.surface,
9792
9912
  ...RecipientTelemetryProps,
9793
9913
  kind: Schema.String,
9794
9914
  chain_id: Schema.Finite,
@@ -9996,6 +10116,7 @@ const OrganizationCreationStartedProps = Schema.Struct({
9996
10116
  });
9997
10117
  const OrganizationCreationReadyProps = Schema.Struct({
9998
10118
  ...TelemetryEnvelopeProps,
10119
+ surface: JourneyVariantProps.surface,
9999
10120
  $insert_id: Schema.String,
10000
10121
  organization_id: OrgIdTelemetrySchema,
10001
10122
  attempt_number: AttemptNumberSchema,
@@ -10020,45 +10141,6 @@ const OrganizationCreationFailedProps = Schema.Struct({
10020
10141
  ...ORGANIZATION_SETUP_REASONS
10021
10142
  ]))
10022
10143
  });
10023
- const OrgCreateStartedProps = Schema.Struct({
10024
- ...TelemetryEnvelopeProps,
10025
- org_id: OptionalOrgId,
10026
- email_domain: OptionalString,
10027
- template: OptionalString
10028
- });
10029
- const OrgSafeCreatedProps = Schema.Struct({
10030
- ...TelemetryEnvelopeProps,
10031
- org_id: OptionalOrgId,
10032
- chainId: OptionalChainId,
10033
- safe_address: OptionalAddress
10034
- });
10035
- const OrgSafeConfirmedProps = Schema.Struct({
10036
- ...TelemetryEnvelopeProps,
10037
- org_id: OptionalOrgId,
10038
- chainId: OptionalChainId,
10039
- safe_address: OptionalAddress,
10040
- durationMs: OptionalDurationMs
10041
- });
10042
- const OrgRolesSeededProps = Schema.Struct({
10043
- ...TelemetryEnvelopeProps,
10044
- org_id: OptionalOrgId,
10045
- chainId: OptionalChainId,
10046
- role: OptionalString,
10047
- txHash: OptionalTxHash
10048
- });
10049
- const OrgCreatedProps = Schema.Struct({
10050
- ...TelemetryEnvelopeProps,
10051
- org_id: OptionalOrgId,
10052
- chainId: OptionalChainId,
10053
- safe_address: OptionalAddress,
10054
- durationMs: OptionalDurationMs
10055
- });
10056
- const OrgCreateFailedProps = Schema.Struct({
10057
- ...TelemetryEnvelopeProps,
10058
- ...ChainCauseTelemetryProps,
10059
- org_id: OptionalOrgId,
10060
- reason: OptionalString
10061
- });
10062
10144
  const OrgInviteSentProps = Schema.Struct({
10063
10145
  ...TelemetryEnvelopeProps,
10064
10146
  org_id: OptionalOrgId,
@@ -10103,30 +10185,6 @@ Schema.Struct({
10103
10185
  name: Schema.Literal("organization_creation_failed"),
10104
10186
  props: OrganizationCreationFailedProps
10105
10187
  });
10106
- Schema.Struct({
10107
- name: Schema.Literal("org_create_started"),
10108
- props: OrgCreateStartedProps
10109
- });
10110
- Schema.Struct({
10111
- name: Schema.Literal("org_safe_created"),
10112
- props: OrgSafeCreatedProps
10113
- });
10114
- Schema.Struct({
10115
- name: Schema.Literal("org_safe_confirmed"),
10116
- props: OrgSafeConfirmedProps
10117
- });
10118
- Schema.Struct({
10119
- name: Schema.Literal("org_roles_seeded"),
10120
- props: OrgRolesSeededProps
10121
- });
10122
- Schema.Struct({
10123
- name: Schema.Literal("org_created"),
10124
- props: OrgCreatedProps
10125
- });
10126
- Schema.Struct({
10127
- name: Schema.Literal("org_create_failed"),
10128
- props: OrgCreateFailedProps
10129
- });
10130
10188
  Schema.Struct({
10131
10189
  name: Schema.Literal("org_invite_sent"),
10132
10190
  props: OrgInviteSentProps
@@ -11000,10 +11058,14 @@ const BootstrapFailedProps = Schema.Struct({
11000
11058
  });
11001
11059
  const MemberActivationStartedProps = Schema.Struct({
11002
11060
  ...TelemetryEnvelopeProps,
11061
+ entry_path: JourneyVariantProps.entry_path,
11062
+ surface: JourneyVariantProps.surface,
11003
11063
  $insert_id: Schema.String
11004
11064
  });
11005
11065
  const MemberActivationReadyProps = Schema.Struct({
11006
11066
  ...TelemetryEnvelopeProps,
11067
+ entry_path: JourneyVariantProps.entry_path,
11068
+ surface: JourneyVariantProps.surface,
11007
11069
  $insert_id: Schema.String,
11008
11070
  duration_ms: DurationMsSchema
11009
11071
  });
@@ -12549,7 +12611,7 @@ function mapAccountLifecycle(input) {
12549
12611
  }
12550
12612
  //#endregion
12551
12613
  //#region package.json
12552
- var version = "4.20.0-beta.26";
12614
+ var version = "4.20.0-beta.28";
12553
12615
  //#endregion
12554
12616
  //#region src/observability/telemetry/exception-projection.ts
12555
12617
  /** Fixed fallback for failures that have no safe message. */
@@ -12987,7 +13049,7 @@ const REVERT_SELECTOR_RE = /^0x(?:[0-9a-fA-F]{8})?$/u;
12987
13049
  //#region src/observability/posthog-failure.ts
12988
13050
  /** The expected-outcome codes, read as plain strings so a free-form kind can be looked up. */
12989
13051
  /** Stable PostHog event used for typed failures that are expected product outcomes. */
12990
- const CAPXUL_SDK_EXPECTED_OUTCOME_EVENT = "capxul_sdk_expected_outcome";
13052
+ const CAPXUL_SDK_EXPECTED_OUTCOME_EVENT = SDK_EXPECTED_OUTCOME_EVENT_NAME;
12991
13053
  /**
12992
13054
  * Adapt the host's already-initialized PostHog-like client. This function does
12993
13055
  * not import, initialize, configure, or own PostHog.
@@ -15670,6 +15732,12 @@ function paymentsV2Signature(name) {
15670
15732
  const SEND_SIGNATURE = paymentsV2Signature("send");
15671
15733
  const SEND_BATCH_SIGNATURE = paymentsV2Signature("sendBatch");
15672
15734
  const CREATE_COMMITMENT_SIGNATURE = paymentsV2Signature("createCommitment");
15735
+ /**
15736
+ * #2299 ruling C: only an Owner cancels or redirects an Organization-funded
15737
+ * commitment, so these two sit in the Owner role's scope, never a Budget's.
15738
+ * The contract admits only the commitment's creator, the Organization Safe.
15739
+ */
15740
+ const OWNER_COMMITMENT_SIGNATURES = [paymentsV2Signature("cancel"), paymentsV2Signature("redirect")];
15673
15741
  //#endregion
15674
15742
  //#region ../protocol/src/evm/organization-payments.ts
15675
15743
  /** Zodiac ModuleProxyFactory on Base Sepolia. */
@@ -15906,24 +15974,18 @@ function encodePreparedPaymentCallData(command) {
15906
15974
  }));
15907
15975
  }
15908
15976
  const [item] = command.items;
15909
- if (command.executionRoute.kind !== "direct" || command.items.length !== 1 || item === void 0 || isBirth(item)) throw Errors.invalidInput("items", "Commitment lifecycle requires one direct execution");
15910
- return safe4337ExecuteUserOpCallData({
15977
+ const route = command.executionRoute;
15978
+ if (command.items.length !== 1 || item === void 0 || isBirth(item) || route.kind !== "direct" && item.operation === "claim_commitment") throw Errors.invalidInput("items", "Commitment lifecycle requires one lone execution");
15979
+ const call = {
15911
15980
  to: command.contractAddress,
15981
+ value: 0n,
15912
15982
  data: lifecycleData(item)
15913
- });
15914
- }
15915
- //#endregion
15916
- //#region ../protocol/src/evm/role-dsl.ts
15917
- const ORG_BUDGET_ACTIONS = [
15918
- "send",
15919
- "sendBatch",
15920
- "createCommitment"
15921
- ];
15922
- /** Derive the Zodiac substrate key for one durable Permission identity. */
15923
- function roleKeyForPermission(permissionId) {
15924
- const normalized = permissionId.trim();
15925
- if (normalized.length === 0 || normalized !== permissionId) throw Errors.invalidInput("permissionId", "must be a non-empty canonical Permission ID");
15926
- return keccak256(toBytes(`permission ${permissionId}`));
15983
+ };
15984
+ return route.kind === "direct" ? safe4337ExecuteUserOpCallData(call) : buildOrgRoleSpendPersonalCallData(buildOrgRoleMultiCall({
15985
+ rolesModuleAddress: route.rolesModule,
15986
+ roleKey: route.roleKey,
15987
+ calls: [call]
15988
+ }));
15927
15989
  }
15928
15990
  //#endregion
15929
15991
  //#region src/payments/operation-verification.ts
@@ -15952,6 +16014,16 @@ function moneySafeOpDigest(operation, chainId) {
15952
16014
  userOp: safe4337UserOperation(operation)
15953
16015
  });
15954
16016
  }
16017
+ /**
16018
+ * An Organization-funded cancel or redirect runs through the Owner role
16019
+ * (#2299), which no Budget names. Its role key cannot widen what the signer
16020
+ * may do: the Roles module admits only a role the signer's Safe holds, and the
16021
+ * contract admits only the commitment's creator.
16022
+ */
16023
+ function isOwnerLifecycle(command) {
16024
+ const [item] = command.items;
16025
+ return command.items.length === 1 && (item?.operation === "cancel_commitment" || item?.operation === "redirect_commitment");
16026
+ }
15955
16027
  /** Verify every actual Money signing target against configured trust anchors. */
15956
16028
  function verifiesMoneyOperation(evidence, expectedSafe, chainId, permissionId) {
15957
16029
  try {
@@ -15962,7 +16034,7 @@ function verifiesMoneyOperation(evidence, expectedSafe, chainId, permissionId) {
15962
16034
  const route = command.executionRoute;
15963
16035
  if (route.kind === "direct") {
15964
16036
  if (permissionId !== void 0 || command.senderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return false;
15965
- } else if (permissionId === void 0 || route.roleKey.toLowerCase() !== roleKeyForPermission(permissionId).toLowerCase() || command.senderSafe.toLowerCase() !== route.organizationSafe.toLowerCase()) return false;
16037
+ } else if ((permissionId === void 0 ? !isOwnerLifecycle(command) : route.roleKey.toLowerCase() !== roleKeyForPermission(permissionId).toLowerCase()) || command.senderSafe.toLowerCase() !== route.organizationSafe.toLowerCase()) return false;
15966
16038
  if (operation.callData.toLowerCase() !== encodePreparedPaymentCallData(command).toLowerCase()) return false;
15967
16039
  const digest = moneySafeOpDigest(operation, chainId);
15968
16040
  return evidence.digest.toLowerCase() === digest.toLowerCase() && evidence.executionId === `money_execution_${digest.slice(2).toLowerCase()}`;
@@ -16750,6 +16822,15 @@ function subscribeFreshQuery(deps, args, listener, operation, projection, option
16750
16822
  }
16751
16823
  //#endregion
16752
16824
  //#region src/payments/lifecycle-execution.ts
16825
+ /**
16826
+ * The prepared command is this lifecycle intent; a retry also names the
16827
+ * original birth command of the scope it was asked for. A claim, and an
16828
+ * Account's own cancel or redirect, runs directly from the signer's Safe; an
16829
+ * Organization's cancel or redirect runs through its Owner role (#2299).
16830
+ */
16831
+ 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 : evidence.preparedCommand?.executionRoute.kind === (intent.kind === "claim" || expectedOrganizationId === void 0 ? "direct" : "zodiac_role"));
16832
+ /** The prepared command pays exactly the request the payer confirmed. */
16833
+ const requestPaymentCheck = (confirmation) => async (request) => "kind" in request && request.kind === "payment_request" && canonicalJson(request.confirmation) === canonicalJson(confirmation);
16753
16834
  function executePaymentLifecycle(deps, intent, signal, controls, expectedOrganizationId, onPrepared) {
16754
16835
  return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.payments.prepareLifecycleExecution, () => withInvocationParentSpan(Effect.suspend(() => callOperation(deps.convexCall, lifecycles.prepareScoped, copyInvocationObservation(controls, {
16755
16836
  signerAddress,
@@ -16758,13 +16839,13 @@ function executePaymentLifecycle(deps, intent, signal, controls, expectedOrganiz
16758
16839
  kind: "organization",
16759
16840
  orgId: expectedOrganizationId
16760
16841
  }
16761
- })).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);
16842
+ })).pipe(Effect.mapError((publicError) => ({ publicError })))), controls), deps.runPromise), lifecycleCommandCheck(intent, expectedOrganizationId), false, void 0, signal, controls, onPrepared);
16762
16843
  }
16763
16844
  function executeRequestPayment(deps, confirmation, controls, onPrepared) {
16764
16845
  return executePrepared(deps, (signerAddress) => runIfActive(controls?.signal, commands$1.prepareRequest.name, () => withInvocationParentSpan(Effect.suspend(() => callOperation(deps.convexCall, commands$1.prepareRequest, copyInvocationObservation(controls, {
16765
16846
  confirmation,
16766
16847
  signerAddress
16767
- })).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);
16848
+ })).pipe(Effect.mapError((publicError) => ({ publicError })))), controls), deps.runPromise), requestPaymentCheck(confirmation), false, void 0, controls?.signal, controls, onPrepared);
16768
16849
  }
16769
16850
  function executeOrganizationPayment(deps, input, signal, onPreparedClosed, controls, onPrepared) {
16770
16851
  return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.organizationPayments.prepareExecution, () => withInvocationParentSpan(Effect.suspend(() => callOperation(deps.convexCall, commands$1.prepareOrganization, copyInvocationObservation(controls, {
@@ -17668,17 +17749,21 @@ function paymentExecutionIntent(input) {
17668
17749
  const to = normalizeTargetForBackend(input.to, "to");
17669
17750
  if (!to.ok) return to;
17670
17751
  try {
17671
- return {
17752
+ const decoded = Schema.decodeResult(PaymentExecutionIntentSchema, { onExcessProperty: "error" })({
17753
+ to: to.value,
17754
+ amount: input.amount,
17755
+ ...input.externalAddressAcknowledged === void 0 ? {} : { externalAddressAcknowledged: input.externalAddressAcknowledged },
17756
+ ...input.paymentType === void 0 ? {} : { paymentType: input.paymentType },
17757
+ ...input.document === void 0 ? {} : { document: input.document },
17758
+ ...input.supportingReceipts === void 0 ? {} : { supportingReceipts: input.supportingReceipts },
17759
+ ...input.timing === void 0 ? {} : { timing: input.timing }
17760
+ });
17761
+ return Result.isSuccess(decoded) ? {
17672
17762
  ok: true,
17673
- value: Schema.decodeSync(PaymentExecutionIntentSchema, { onExcessProperty: "error" })({
17674
- to: to.value,
17675
- amount: input.amount,
17676
- ...input.externalAddressAcknowledged === void 0 ? {} : { externalAddressAcknowledged: input.externalAddressAcknowledged },
17677
- ...input.paymentType === void 0 ? {} : { paymentType: input.paymentType },
17678
- ...input.document === void 0 ? {} : { document: input.document },
17679
- ...input.supportingReceipts === void 0 ? {} : { supportingReceipts: input.supportingReceipts },
17680
- ...input.timing === void 0 ? {} : { timing: input.timing }
17681
- })
17763
+ value: decoded.success
17764
+ } : {
17765
+ ok: false,
17766
+ error: invalidPaymentField(decoded.failure.issue)
17682
17767
  };
17683
17768
  } catch {
17684
17769
  return {
@@ -17687,6 +17772,13 @@ function paymentExecutionIntent(input) {
17687
17772
  };
17688
17773
  }
17689
17774
  }
17775
+ 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) {
17778
+ 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");
17781
+ }
17690
17782
  function normalizePaymentTiming(payment) {
17691
17783
  const { release: _release, ...rest } = payment;
17692
17784
  return {
@@ -18366,7 +18458,7 @@ function makeOrganizationPaymentReadMethods(deps, orgId) {
18366
18458
  }
18367
18459
  //#endregion
18368
18460
  //#region src/payments/organization-flights.ts
18369
- function executionDependencies(input) {
18461
+ function executionDependencies$1(input) {
18370
18462
  return input.actor === void 0 || input.chainId === void 0 || input.signer === void 0 ? null : {
18371
18463
  actor: input.actor,
18372
18464
  chainId: input.chainId,
@@ -18387,7 +18479,7 @@ async function executeOrganizationBatch(scope, input, signal, operation, control
18387
18479
  };
18388
18480
  const intent = organizationPaymentIntent(scope.orgId, input);
18389
18481
  if (!intent.ok) return intent;
18390
- const execution = executionDependencies(scope.deps);
18482
+ const execution = executionDependencies$1(scope.deps);
18391
18483
  if (execution === null) return {
18392
18484
  ok: false,
18393
18485
  error: Errors.notImplemented("organizationPayments", "executionComposition")
@@ -18503,6 +18595,27 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
18503
18595
  flights: /* @__PURE__ */ new Map()
18504
18596
  };
18505
18597
  const execute = (input, signal, operation = "organization-pay-batch", controls, onPrepared) => executeOrganizationBatch(scope, input, signal, operation, controls, onPrepared);
18598
+ /** One Owner-signed cancel or redirect, answering the one Payment it acted on (#2299). */
18599
+ const ownerLifecycle = (intent, controls, operation) => runCapxulEffect(Effect.gen(function* () {
18600
+ const captured = carryInvocationParentSpan(controls, yield* Effect.currentSpan.pipe(Effect.orDie));
18601
+ return yield* awaitCapxulResult(async () => {
18602
+ const execution = executionDependencies$1(deps);
18603
+ if (execution === null) return {
18604
+ ok: false,
18605
+ error: Errors.notImplemented("organizationPayments", "executionComposition")
18606
+ };
18607
+ const result = await executePaymentLifecycle(execution, intent, controls?.signal, captured, orgId);
18608
+ if (!result.ok) return result;
18609
+ const [payment, ...rest] = result.value.payments;
18610
+ return payment === void 0 || rest.length !== 0 ? {
18611
+ ok: false,
18612
+ error: Errors.unknown()
18613
+ } : {
18614
+ ok: true,
18615
+ value: normalizePaymentTiming(payment)
18616
+ };
18617
+ });
18618
+ }), observationOnlyControls(controls), operation, deps.runPromise);
18506
18619
  return {
18507
18620
  ...makeOrganizationPaymentReadMethods(deps, orgId),
18508
18621
  retry: (paymentId, options) => {
@@ -18511,7 +18624,7 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
18511
18624
  const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
18512
18625
  const captured = carryInvocationParentSpan(controls, parent);
18513
18626
  return yield* awaitCapxulResult(async () => {
18514
- const execution = executionDependencies(deps);
18627
+ const execution = executionDependencies$1(deps);
18515
18628
  if (execution === null) return {
18516
18629
  ok: false,
18517
18630
  error: Errors.notImplemented("organizationPayments", "executionComposition")
@@ -18561,6 +18674,19 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
18561
18674
  });
18562
18675
  }), observationOnlyControls(controls), CAPXUL_OPERATIONS.organizationPayments.pay, deps.runPromise);
18563
18676
  },
18677
+ cancel: (paymentId, options) => ownerLifecycle({
18678
+ kind: "cancel",
18679
+ paymentId
18680
+ }, deps.invocationControls?.(options) ?? options, CAPXUL_OPERATIONS.organizationPayments.cancel),
18681
+ redirect: (input, options) => {
18682
+ const controls = deps.invocationControls?.(options) ?? options;
18683
+ const recipient = normalizeTargetForBackend(input.to, "to");
18684
+ return recipient.ok ? ownerLifecycle({
18685
+ kind: "redirect",
18686
+ paymentId: input.paymentId,
18687
+ recipient: recipient.value
18688
+ }, controls, CAPXUL_OPERATIONS.organizationPayments.redirect) : runCapxulEffect(Effect.fail(recipient.error), observationOnlyControls(controls), CAPXUL_OPERATIONS.organizationPayments.redirect, deps.runPromise);
18689
+ },
18564
18690
  payBatch: (input, options) => {
18565
18691
  const controls = deps.invocationControls?.(options) ?? options;
18566
18692
  return runCapxulEffect(Effect.gen(function* () {
@@ -19275,6 +19401,524 @@ function sleep(ms, signal) {
19275
19401
  });
19276
19402
  }
19277
19403
  //#endregion
19404
+ //#region ../protocol/src/payroll/model.ts
19405
+ function toPayrollRunId(raw) {
19406
+ return toNonEmptyStringBrand(raw, "payrollRunId", (value) => isNonEmptyString(value));
19407
+ }
19408
+ function toPayrollGroupId(raw) {
19409
+ return toNonEmptyStringBrand(raw, "payrollGroupId", (value) => isNonEmptyString(value));
19410
+ }
19411
+ //#endregion
19412
+ //#region src/payroll/run-checks.ts
19413
+ /** Match the caller's compensation to the committed V3 Payslip. */
19414
+ function payslipIdentityMatches(message, item, index, runId, period) {
19415
+ return message.runId === runId && message.itemIndex === index && message.employeeRef === item.partyId && message.periodStart === period.start && message.periodEnd === period.end && message.adjustmentsHash === hashAdjustmentsV3(item.adjustments);
19416
+ }
19417
+ function payslipAmountMatches(message, item) {
19418
+ const exact = toExactAssetAmount(item.amount, CONFIGURED_MONEY_ASSETS);
19419
+ 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;
19420
+ }
19421
+ function isRunItem(prepared, item, evidence, index, runId, period) {
19422
+ if (prepared === void 0) return false;
19423
+ const bundle = evidence.preparedCommand?.documentBundles?.[index];
19424
+ const preparedItem = evidence.preparedCommand?.items[index];
19425
+ const payslip = bundle?.envelope;
19426
+ if (bundle === void 0 || payslip?.primaryType !== "Payslip") return false;
19427
+ 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;
19428
+ }
19429
+ /**
19430
+ * The batch the backend derived from a payroll intent must be the batch this
19431
+ * caller asked for, checked before the digest is signed.
19432
+ *
19433
+ * The payslip envelope on each item is server-built and carries the run row's
19434
+ * own `issuedAt`, so the batch cannot be fingerprinted against a local copy
19435
+ * (`matchesIntent` is unavailable here). What CAN be verified is every field
19436
+ * the caller supplied — the org, the Budget, the request key, and per item the
19437
+ * recipient, the amount and the payslip figures — plus the lineage binding the
19438
+ * batch to the run just written. A prepared command that pays a different
19439
+ * person, a different amount, from a different Budget, or under a different
19440
+ * run never reaches the signer.
19441
+ */
19442
+ function isRunBatch(input) {
19443
+ 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)));
19444
+ }
19445
+ /**
19446
+ * The batch is `isRunBatch` for the run the backend just wrote, and that run
19447
+ * is the period the caller asked for: the payslip's `period` is a
19448
+ * server-formatted label, so the stored run is where the caller's own two
19449
+ * numbers are checkable.
19450
+ */
19451
+ function isAuthorizedRunBatch(input, run) {
19452
+ return (request, evidence) => run === void 0 || run.periodStart !== input.period.start || run.periodEnd !== input.period.end ? Promise.resolve(false) : isRunBatch({
19453
+ ...input,
19454
+ runId: run.id
19455
+ })(request, evidence);
19456
+ }
19457
+ /** A decoded detail is the run asked for, whole: its scope, membership and quantities agree. */
19458
+ function checkPayrollRunDetail(value, orgId, runId) {
19459
+ if (value === null) return {
19460
+ ok: true,
19461
+ value: null
19462
+ };
19463
+ 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 {
19464
+ ok: false,
19465
+ error: Errors.invalidInput("run", "Payroll run scope or membership does not match")
19466
+ };
19467
+ try {
19468
+ const total = toExactAssetAmount(value.run.total, CONFIGURED_MONEY_ASSETS);
19469
+ let rawTotal = 0n;
19470
+ for (const item of value.items) {
19471
+ const amount = toExactAssetAmount(item.amount, CONFIGURED_MONEY_ASSETS);
19472
+ const payment = toExactAssetAmount(item.payment.amount, CONFIGURED_MONEY_ASSETS);
19473
+ if (amount.minorUnits !== payment.minorUnits) return {
19474
+ ok: false,
19475
+ error: Errors.invalidInput("run", "Payroll item quantity does not match its Payment")
19476
+ };
19477
+ rawTotal += BigInt(amount.minorUnits);
19478
+ }
19479
+ if (rawTotal !== BigInt(total.minorUnits)) return {
19480
+ ok: false,
19481
+ error: Errors.invalidInput("run", "Payroll run total does not match its items")
19482
+ };
19483
+ } catch {
19484
+ return {
19485
+ ok: false,
19486
+ error: Errors.invalidInput("run", "Payroll run quantities are invalid")
19487
+ };
19488
+ }
19489
+ return {
19490
+ ok: true,
19491
+ value
19492
+ };
19493
+ }
19494
+ //#endregion
19495
+ //#region src/payroll/run-decoding.ts
19496
+ function toPayrollRun(wire) {
19497
+ return {
19498
+ id: toPayrollRunId(wire.id),
19499
+ status: wire.status,
19500
+ periodStart: wire.periodStart,
19501
+ periodEnd: wire.periodEnd,
19502
+ total: wire.total,
19503
+ recipientCount: wire.recipientCount
19504
+ };
19505
+ }
19506
+ function toPayrollRuns(wire) {
19507
+ return {
19508
+ ...mapPage(wire, toPayrollRun),
19509
+ settledThisMonth: wire.settledThisMonth
19510
+ };
19511
+ }
19512
+ function toPayrollGroup(wire) {
19513
+ return {
19514
+ id: toPayrollGroupId(wire.id),
19515
+ name: wire.name,
19516
+ tone: wire.tone,
19517
+ members: wire.members.map((member) => ({
19518
+ partyId: member.partyId,
19519
+ amount: member.amount,
19520
+ currency: member.currency
19521
+ }))
19522
+ };
19523
+ }
19524
+ function validateRunItems(input) {
19525
+ for (const [index, item] of input.items.entries()) {
19526
+ if (Schema.decodeResult(PayrollRunItemInputSchema, { onExcessProperty: "error" })(item)._tag === "Failure") return Errors.invalidInput(`items.${index}`, "invalid Payroll item");
19527
+ try {
19528
+ const exact = toExactAssetAmount(item.amount, CONFIGURED_MONEY_ASSETS);
19529
+ const net = BigInt(item.net);
19530
+ const gross = BigInt(item.gross);
19531
+ const adjustments = item.adjustments.reduce((sum, row) => sum + BigInt(row.amount), 0n);
19532
+ if (item.amount.asset !== input.asset || item.net !== exact.minorUnits || gross + adjustments !== net) return Errors.invalidInput(`items.${index}`, "invalid Payroll units");
19533
+ } catch {
19534
+ return Errors.invalidInput(`items.${index}`, "invalid Payroll units");
19535
+ }
19536
+ }
19537
+ return null;
19538
+ }
19539
+ const RunInputSchema = Schema.Struct({
19540
+ permissionId: AuthorizePayrollRunExecutionInputSchema.fields.permissionId,
19541
+ asset: AuthorizePayrollRunExecutionInputSchema.fields.asset,
19542
+ period: AuthorizePayrollRunExecutionInputSchema.fields.period,
19543
+ items: AuthorizePayrollRunExecutionInputSchema.fields.items,
19544
+ requestKey: Schema.optional(AuthorizePayrollRunExecutionInputSchema.fields.requestKey)
19545
+ });
19546
+ /** Decode caller input before session or signer work. Keep routing outside the input. */
19547
+ function decodePayrollRunInput(value) {
19548
+ try {
19549
+ const decoded = Schema.decodeUnknownSync(RunInputSchema, { onExcessProperty: "error" })(value);
19550
+ const input = {
19551
+ permissionId: decoded.permissionId,
19552
+ asset: decoded.asset,
19553
+ period: decoded.period,
19554
+ ...decoded.requestKey === void 0 ? {} : { requestKey: decoded.requestKey },
19555
+ items: decoded.items.map((item) => ({
19556
+ amount: item.amount,
19557
+ gross: item.gross,
19558
+ net: item.net,
19559
+ adjustments: item.adjustments,
19560
+ partyId: toPartyId(item.partyId),
19561
+ to: item.to.kind === "party" ? {
19562
+ kind: "party",
19563
+ partyId: toPartyId(item.to.partyId)
19564
+ } : item.to.kind === "address" ? {
19565
+ kind: "address",
19566
+ address: toAddress(item.to.address)
19567
+ } : item.to
19568
+ }))
19569
+ };
19570
+ if (input.items.length === 0 || input.period.start > input.period.end) throw Errors.invalidInput("input", "Payroll requires items and an ordered period");
19571
+ const error = validateRunItems(input);
19572
+ if (error !== null) throw error;
19573
+ return input;
19574
+ } catch (cause) {
19575
+ throw cause instanceof CapxulError ? cause : Errors.invalidInput("input", "Invalid Payroll input");
19576
+ }
19577
+ }
19578
+ /** Read only the exact backend prepare receipt, never an arbitrary signer failure. */
19579
+ function payrollResolution(error, requestKey) {
19580
+ const details = error.details;
19581
+ if (error.code !== "WRONG_STATE" || details?.method !== runs.authorize.name || details.requestKey !== requestKey || typeof details.commandId !== "string" || typeof details.runId !== "string") return void 0;
19582
+ return details.payrollResolution === "failed" || details.payrollResolution === "settled" ? details.payrollResolution : void 0;
19583
+ }
19584
+ function validatePayrollRunLookup(orgId, runId) {
19585
+ return !Schema.is(PayrollRunIdSchema)(runId) || orgId.length === 0 ? {
19586
+ ok: false,
19587
+ error: Errors.invalidInput("runId", "Organization and run ID must be valid")
19588
+ } : {
19589
+ ok: true,
19590
+ value: void 0
19591
+ };
19592
+ }
19593
+ /** Strict saved detail decoder shared by the read and fresh stream. */
19594
+ function decodePayrollRunDetail(raw, orgId, runId) {
19595
+ const decoded = Schema.decodeUnknownResult(Schema.NullOr(PayrollRunDetailSchema), { onExcessProperty: "error" })(raw);
19596
+ if (decoded._tag === "Failure") return {
19597
+ ok: false,
19598
+ error: Errors.invalidInput("run", "Invalid Payroll run detail")
19599
+ };
19600
+ return checkPayrollRunDetail(decoded.success, orgId, runId);
19601
+ }
19602
+ //#endregion
19603
+ //#region src/payroll/run-subscription.ts
19604
+ function detailValue(result) {
19605
+ if (!result.ok) throw result.error;
19606
+ return result.value;
19607
+ }
19608
+ function subscribePayrollRun(deps, orgId, runId, listener, options) {
19609
+ const operation = CAPXUL_OPERATIONS.org.payroll.subscribeRun;
19610
+ const valid = deps.validate(orgId, runId);
19611
+ if (!valid.ok) return runCapxulEffect(Effect.fail(valid.error), observationOnlyControls(deps.invocationControls?.(options) ?? options), operation, deps.runPromise);
19612
+ const decode = (raw) => detailValue(deps.decode(raw, orgId, runId));
19613
+ return subscribeFreshQuery(deps, {
19614
+ orgId,
19615
+ runId
19616
+ }, listener, operation, {
19617
+ decode,
19618
+ validateCached: (raw) => {
19619
+ decode(raw);
19620
+ },
19621
+ invalidValue: (cause) => isCapxulError(cause) ? cause : Errors.invalidInput("run", "Invalid Payroll run detail"),
19622
+ invalidScope: () => Errors.invalidInput("run", "Payroll run subscription scope does not match"),
19623
+ lostValue: () => Errors.invalidInput("run", "Payroll run is no longer readable"),
19624
+ unavailable: () => Errors.notImplemented("payroll", "subscribeRun")
19625
+ }, options);
19626
+ }
19627
+ //#endregion
19628
+ //#region src/payroll/run-authorization.ts
19629
+ /**
19630
+ * Authorize one payroll run: a stable request key, the prepared batch checked
19631
+ * against the run the caller asked for, the signature, and the submission.
19632
+ */
19633
+ async function authorizePayrollRun(scope, input, controls, onRequestKey, onResolved) {
19634
+ const { deps, orgId, requestKeyScope } = scope;
19635
+ const signal = controls?.signal;
19636
+ const execution = executionDependencies(deps);
19637
+ if (execution === null) return {
19638
+ ok: false,
19639
+ error: Errors.notImplemented("payroll", "executionComposition")
19640
+ };
19641
+ try {
19642
+ input = decodePayrollRunInput(input);
19643
+ } catch (cause) {
19644
+ return {
19645
+ ok: false,
19646
+ error: asCapxulError(cause)
19647
+ };
19648
+ }
19649
+ const { requestKey: provided, ...canonicalInput } = input;
19650
+ const actorId = onRequestKey === void 0 ? void 0 : execution.actor.authSession()?.authUserId;
19651
+ if (onRequestKey !== void 0 && actorId === void 0) return {
19652
+ ok: false,
19653
+ error: Errors.notAuthenticated()
19654
+ };
19655
+ const requestKey = await paymentRequestKeyLifecycle(`${requestKeyScope}:${AUTHORIZE_RUN}`, onRequestKey === void 0 ? {
19656
+ orgId,
19657
+ input
19658
+ } : {
19659
+ actorId,
19660
+ orgId,
19661
+ input: canonicalInput
19662
+ }, provided, onRequestKey === void 0 ? void 0 : { manageProvidedKey: true });
19663
+ try {
19664
+ await onRequestKey?.(requestKey.key);
19665
+ if (onRequestKey !== void 0 && execution.actor.authSession()?.authUserId !== actorId) {
19666
+ await requestKey.finish(false).catch(() => void 0);
19667
+ return {
19668
+ ok: false,
19669
+ error: Errors.notAuthenticated()
19670
+ };
19671
+ }
19672
+ } catch (cause) {
19673
+ await requestKey.finish(false).catch(() => void 0);
19674
+ return {
19675
+ ok: false,
19676
+ error: asCapxulError(cause)
19677
+ };
19678
+ }
19679
+ let authorized;
19680
+ let acceptedReplay;
19681
+ let preparedClosed = false;
19682
+ let terminalReplay;
19683
+ const submitted = await executePrepared(execution, async (signerAddress) => {
19684
+ const prepared = await runIfActive(signal, AUTHORIZE_RUN, () => withInvocationParentSpan(Effect.suspend(() => callOperation(deps.convexCall, runs.authorize, copyInvocationObservation(controls, {
19685
+ orgId,
19686
+ permissionId: input.permissionId,
19687
+ asset: input.asset,
19688
+ requestKey: requestKey.key,
19689
+ signerAddress,
19690
+ period: input.period,
19691
+ items: input.items
19692
+ }))).pipe(Effect.mapError((publicError) => ({ publicError }))), controls), deps.runPromise);
19693
+ if (!prepared.ok) {
19694
+ terminalReplay = payrollResolution(prepared.error, requestKey.key);
19695
+ return prepared;
19696
+ }
19697
+ authorized = prepared.value.run;
19698
+ acceptedReplay = prepared.value.replay.kind === "accepted" ? prepared.value.replay.submission : void 0;
19699
+ return {
19700
+ ok: true,
19701
+ value: prepared.value.execution
19702
+ };
19703
+ }, (request, evidence) => isAuthorizedRunBatch({
19704
+ orgId,
19705
+ permissionId: input.permissionId,
19706
+ requestKey: requestKey.key,
19707
+ asset: input.asset,
19708
+ period: input.period,
19709
+ items: input.items
19710
+ }, authorized)(request, evidence), true, () => preparedClosed = true, signal, controls, void 0, () => acceptedReplay);
19711
+ const resolution = preparedClosed ? "failed" : terminalReplay;
19712
+ if (resolution !== void 0) try {
19713
+ await onResolved?.(resolution);
19714
+ } catch {}
19715
+ try {
19716
+ await requestKey.finish(submitted.ok || resolution !== void 0);
19717
+ } catch {}
19718
+ if (!submitted.ok) return submitted;
19719
+ return authorized === void 0 ? {
19720
+ ok: false,
19721
+ error: Errors.unknown()
19722
+ } : {
19723
+ ok: true,
19724
+ value: toPayrollRun(authorized)
19725
+ };
19726
+ }
19727
+ const AUTHORIZE_RUN = runs.authorize.name;
19728
+ function executionDependencies(deps) {
19729
+ return deps.actor === void 0 || deps.chainId === void 0 || deps.signer === void 0 ? null : {
19730
+ actor: deps.actor,
19731
+ chainId: deps.chainId,
19732
+ convexCall: deps.convexCall,
19733
+ runPromise: deps.runPromise,
19734
+ signer: deps.signer,
19735
+ ...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
19736
+ };
19737
+ }
19738
+ //#endregion
19739
+ //#region src/payroll/runs.ts
19740
+ function makePayrollMethods(deps, orgId) {
19741
+ const requestKeyScope = deps.requestKeyScope ?? `client-${crypto.randomUUID()}`;
19742
+ /** One observed call of one payroll row, its reply projected inside the call, under the row's name. */
19743
+ const call = (row, args, options, project) => {
19744
+ const controls = deps.invocationControls?.(options) ?? options;
19745
+ return runPortEffect(callOperation(deps.convexCall, row, copyInvocationObservation(controls, args)).pipe(Effect.map(project), Effect.mapError((publicError) => ({ publicError }))), controls, row.name, deps.runPromise);
19746
+ };
19747
+ return {
19748
+ subscribeRun: (runId, listener, options) => subscribePayrollRun({
19749
+ actor: deps.actor,
19750
+ convexCall: deps.convexCall,
19751
+ query: reference(runs.get),
19752
+ runPromise: deps.runPromise,
19753
+ invocationControls: deps.invocationControls,
19754
+ decode: decodePayrollRunDetail,
19755
+ validate: validatePayrollRunLookup
19756
+ }, orgId, runId, listener, options),
19757
+ getRun: (runId, options) => {
19758
+ const controls = deps.invocationControls?.(options) ?? options;
19759
+ const lifetime = deps.actor?.authLifetime();
19760
+ const operation = runs.get.name;
19761
+ return runCapxulEffect(Effect.gen(function* () {
19762
+ const lookup = validatePayrollRunLookup(orgId, runId);
19763
+ if (!lookup.ok) return yield* Effect.fail(lookup.error);
19764
+ if (lifetime === void 0 || lifetime.authUserId === null || deps.actor === void 0) return yield* Effect.fail(Errors.notAuthenticated());
19765
+ const current = () => deps.actor?.matchesAuthLifetime(lifetime, lifetime.authUserId) === true;
19766
+ if (!current()) return yield* Effect.fail(Errors.notAuthenticated());
19767
+ const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
19768
+ const captured = carryInvocationParentSpan(controls, parent);
19769
+ const run = yield* awaitCapxulResult(() => runIfActive(controls?.signal, operation, () => withInvocationParentSpan(Effect.suspend(() => callOperation(deps.convexCall, runs.get, copyInvocationObservation(captured, {
19770
+ orgId,
19771
+ runId
19772
+ }))).pipe(Effect.mapError((publicError) => ({ publicError }))), captured), deps.runPromise));
19773
+ if (!current()) return yield* Effect.fail(Errors.cancelled({ operation }));
19774
+ const checked = checkPayrollRunDetail(run, orgId, runId);
19775
+ return yield* checked.ok ? Effect.succeed(checked.value) : Effect.fail(checked.error);
19776
+ }), observationOnlyControls(controls), operation, deps.runPromise);
19777
+ },
19778
+ runs: (options) => call(runs.list, { orgId }, options, toPayrollRuns),
19779
+ authorizeRun: (input, options) => {
19780
+ const controls = deps.invocationControls?.(options) ?? options;
19781
+ return runCapxulEffect(Effect.gen(function* () {
19782
+ if (controls?.signal?.aborted === true) return yield* Effect.fail(Errors.cancelled({ operation: AUTHORIZE_RUN }));
19783
+ const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
19784
+ return yield* awaitCapxulResult(() => authorizePayrollRun({
19785
+ deps,
19786
+ orgId,
19787
+ requestKeyScope
19788
+ }, input, carryInvocationParentSpan(controls, parent), options?.onRequestKey, options?.onResolved));
19789
+ }), observationOnlyControls(controls), AUTHORIZE_RUN, deps.runPromise);
19790
+ },
19791
+ terms: (options) => call(terms.list, { orgId }, options, (rates) => rates),
19792
+ groups: {
19793
+ list: (options) => call(groups.list, { orgId }, options, (saved) => mapPage(saved, toPayrollGroup)),
19794
+ save: (input, options) => call(groups.save, {
19795
+ orgId,
19796
+ ...input.id === void 0 ? {} : { id: String(input.id) },
19797
+ name: input.name,
19798
+ tone: input.tone,
19799
+ members: input.members
19800
+ }, options, toPayrollGroup),
19801
+ remove: (id, options) => call(groups.remove, {
19802
+ orgId,
19803
+ id
19804
+ }, options, () => void 0)
19805
+ }
19806
+ };
19807
+ }
19808
+ const payrollUnavailable = () => Promise.resolve({
19809
+ ok: false,
19810
+ error: Errors.notImplemented("payroll", "executionComposition")
19811
+ });
19812
+ /** The bundle an unconfigured client exposes — every verb refuses, none throws. */
19813
+ function makeUnavailablePayrollMethods() {
19814
+ return {
19815
+ getRun: payrollUnavailable,
19816
+ subscribeRun: payrollUnavailable,
19817
+ runs: payrollUnavailable,
19818
+ authorizeRun: payrollUnavailable,
19819
+ terms: payrollUnavailable,
19820
+ groups: {
19821
+ list: payrollUnavailable,
19822
+ save: payrollUnavailable,
19823
+ remove: payrollUnavailable
19824
+ }
19825
+ };
19826
+ }
19827
+ //#endregion
19828
+ //#region src/accounts/command-approvals.ts
19829
+ /**
19830
+ * Keep a prepared command only when it is the one asked for and its operation
19831
+ * is the person's own. A mismatch is closed unsent when `close`, as the signed
19832
+ * path closes a new Payment; a retry or a request keeps its Payment open.
19833
+ */
19834
+ async function checked(deps, signerAddress, prepared, expected, close) {
19835
+ if (!prepared.ok) return prepared;
19836
+ const session = deps.actor?.authSession() ?? null;
19837
+ if (session === null || deps.chainId === void 0) return {
19838
+ ok: false,
19839
+ error: Errors.notAuthenticated()
19840
+ };
19841
+ const evidence = prepared.value;
19842
+ if (await expected(evidence.request, evidence) && await verifiedPreparedCommand(evidence, session.email, signerAddress, deps.chainId)) return prepared;
19843
+ const refused = {
19844
+ ok: false,
19845
+ error: Errors.invalidInput("execution", "prepared command mismatch")
19846
+ };
19847
+ return close ? abandonPrepared(deps, evidence.executionId, "prepared_mismatch", refused) : refused;
19848
+ }
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. */
19852
+ function prepareVerifiedCommand(deps, input, signerAddress, signal) {
19853
+ if ("retry" in input) return prepareVerifiedRetry(deps, input, signerAddress, signal);
19854
+ 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
+ };
19863
+ return checked(deps, signerAddress, await runIfActive(signal, CAPXUL_OPERATIONS.payments.prepareLifecycleExecution, () => callOperation(deps.convexCall, lifecycles.prepareScoped, {
19864
+ signerAddress,
19865
+ intent,
19866
+ expectedScope: input.organizationId === void 0 ? { kind: "account" } : {
19867
+ kind: "organization",
19868
+ orgId: input.organizationId
19869
+ }
19870
+ }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise), lifecycleCommandCheck(intent, input.organizationId), false);
19871
+ }
19872
+ /** The Payment of one request, exactly as the request froze it. */
19873
+ async function prepareVerifiedRequestPayment(deps, input, signerAddress, signal) {
19874
+ const decoded = Schema.decodeResult(RequestPaymentConfirmationSchema, { onExcessProperty: "error" })(input.request);
19875
+ if (decoded._tag === "Failure") return {
19876
+ ok: false,
19877
+ error: Errors.invalidInput("confirmation", "invalid request confirmation")
19878
+ };
19879
+ const confirmation = decoded.success;
19880
+ return checked(deps, signerAddress, await runIfActive(signal, commands$1.prepareRequest.name, () => callOperation(deps.convexCall, commands$1.prepareRequest, {
19881
+ confirmation,
19882
+ signerAddress
19883
+ }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise), requestPaymentCheck(confirmation), false);
19884
+ }
19885
+ /** One payroll run: the run the backend writes and the batch that pays it, checked together. */
19886
+ async function prepareVerifiedPayrollRun(deps, input, signerAddress, signal) {
19887
+ let run;
19888
+ try {
19889
+ run = decodePayrollRunInput(input.payrollRun);
19890
+ } catch (cause) {
19891
+ return {
19892
+ ok: false,
19893
+ error: asCapxulError(cause)
19894
+ };
19895
+ }
19896
+ const orgId = input.organizationId;
19897
+ const requestKey = run.requestKey ?? `payroll_${crypto.randomUUID()}`;
19898
+ const { permissionId, asset, period, items } = run;
19899
+ const authorized = await runIfActive(signal, runs.authorize.name, () => callOperation(deps.convexCall, runs.authorize, {
19900
+ orgId,
19901
+ permissionId,
19902
+ asset,
19903
+ requestKey,
19904
+ signerAddress,
19905
+ period,
19906
+ items
19907
+ }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
19908
+ if (!authorized.ok) return authorized;
19909
+ return checked(deps, signerAddress, {
19910
+ ok: true,
19911
+ value: authorized.value.execution
19912
+ }, isAuthorizedRunBatch({
19913
+ orgId,
19914
+ permissionId,
19915
+ requestKey,
19916
+ asset,
19917
+ period,
19918
+ items
19919
+ }, authorized.value.run), authorized.value.replay.kind !== "accepted");
19920
+ }
19921
+ //#endregion
19278
19922
  //#region src/accounts/organization-approvals.ts
19279
19923
  /** The Organization Payment prepared for `signerAddress` and checked, before any approval. */
19280
19924
  async function prepareVerifiedOrganizationPayment(deps, input, signerAddress, signal) {
@@ -19381,6 +20025,7 @@ function makeApprovalsMethods(deps) {
19381
20025
  };
19382
20026
  const prepare = async (input, options) => {
19383
20027
  const signal = options?.signal;
20028
+ if (isCommandApproval(input)) return openApproval(signal, (signerAddress) => prepareVerifiedCommand(deps, input, signerAddress, signal));
19384
20029
  if ("organizationId" in input) return openApproval(signal, (signerAddress) => prepareVerifiedOrganizationPayment(deps, input, signerAddress, signal));
19385
20030
  const intent = paymentExecutionIntent(input);
19386
20031
  if (!intent.ok) return intent;
@@ -19473,7 +20118,7 @@ function makeApprovalsMethods(deps) {
19473
20118
  ok: true,
19474
20119
  value: null
19475
20120
  };
19476
- const payments = await readApprovalPayments(deps, approval.operation.paymentIds, organizationId, signal);
20121
+ const payments = await readApprovalPayments(deps, approval.operation.paymentIds, organizationId ?? (approval.actor.kind === "organization" ? approval.actor.orgId : void 0), signal);
19477
20122
  if (!payments.ok) return payments;
19478
20123
  if (unsent(approval, payments.value)) {
19479
20124
  const sent = await submit(approvalId);
@@ -22402,4 +23047,4 @@ function executeIdentityProductObservation(telemetry, record, state) {
22402
23047
  return ignoreTransportFailure(() => invocationTelemetry.emit(mapped), "emit", mapped.name).pipe(Effect.andThen(ignoreTransportFailure(after, mapped.name === "auth_signed_out" ? "reset" : "identify", mapped.name)));
22403
23048
  }
22404
23049
  //#endregion
22405
- export { toRaw as $, workspaces as $n, formatTraceparent as $r, version as $t, registerProductTelemetryInvocation as A, parseAuthSession as Ai, details as An, toAssetId as Ar, safe4337MultiSendUserOpCallData as At, paymentRequestKeyLifecycle as B, toNonEmptyStringBrand as Bi, terms as Bn, makeAuthMethods as Br, failureEvidenceProps as Bt, AccountReadPortTag as C, authClientPortFromPromiseAdapter as Ci, CLI_INVOCATION_KINDS as Cn, EpochMsSchema$1 as Cr, CAPXUL_PAYMENTS_V2_ADDRESS as Ct, convexCallErrorFromCapxul as D, globalLocalStorage as Di, isCapxulOperation as Dn, toRoleKey as Dr, deriveCapxulSafeAddress as Dt, ConvexCallPortTag as E, detectAuthCacheAdapter as Ei, CAPXUL_OPERATIONS as En, toPermissionId as Er, TOKENS as Et, logDroppedEvent as F, toAuthUserId as Fi, replacements as Fn, toAddress as Fr, callOperation as Ft, makeTargetsMethods as G, isFailureMode as Gi, PayrollRunIdSchema as Gn, sessionFromActor as Gr, observationContextProps as Gt, makeActorRelationshipMethods as H, CapxulError as Hi, PayrollGroupIdSchema as Hn, publicIdentityFailure as Hr, postHogFailureObservation as Ht, makeOrganizationPaymentsMethods as I, toEmail as Ii, PreparedPermissionExecutionSchema as In, toChainId as Ir, asCapxulError as It, assetAmountFromRaw as J, AuthCacheError as Ji, invitations as Jn, withVerifiedOrganizationScope as Jr, SDK_VERSION as Jt, subscribeFreshQuery as K, isRecord as Ki, PayrollRunItemInputSchema as Kn, observationOnlyControls as Kr, withCapturedAttemptContext as Kt, makeOfframpMethods as L, toJwtToken as Li, PermissionCommandViewSchema as Ln, toWeiAmount as Lr, mapPage as Lt, makeApprovalsMethods as M, toDurationMs as Mi, authorities as Mn, toExactAssetAmount as Mr, BASE_SEPOLIA_CHAIN_ID as Mt, makeAccountMethods as N, toEpochMs as Ni, commands as Nn, EVM_ADDRESS_RE$1 as Nr, MULTI_SEND_CALL_ONLY as Nt, retryIdempotentRead as O, InMemoryAuthCacheAdapter as Oi, normalizeCapxulOperation as On, ChainIdSchema$1 as Or, normalizeSafeSaltEmail as Ot, emitDepositInitiated as P, toEpochSeconds as Pi, configurations as Pn, isEvmAddress as Pr, SAFE_SENTINEL_OWNERS as Pt, requireAsset as Q, treasuries as Qn, toCapxulResult as Qr, safeExceptionLabel as Qt, makePaymentsMethods as R, toSessionToken as Ri, groups as Rn, absurd as Rr, toPublicError$1 as Rt, valueIn as S, toPublishableKey as Si, CLI_COMMAND_NAMES as Sn, DurationMsSchema$1 as Sr, SEND_SIGNATURE as St, TelemetryPortTag as T, AuthClientPortTag as Ti, stampTelemetryEnvelope as Tn, toPermissionAssignmentId as Tr, CONFIGURED_MONEY_ASSETS as Tt, makeCheckoutMethods as U, isCapxulError as Ui, PayrollGroupInputSchema as Un, runIdentityFacade as Ur, observeFailedResult as Ut, makeDestinationsMethods as V, Errors as Vi, AuthorizePayrollRunExecutionInputSchema as Vn, askIdentity as Vr, CAPXUL_SDK_EXPECTED_OUTCOME_EVENT as Vt, isCheckoutSettlementConsumed as W, FAILURE_MODES$1 as Wi, PayrollRunDetailSchema as Wn, runPortEffect as Wr, observeSdkClient as Wt, formatAssetAmount as X, roles as Xn, defectAsCapxulError as Xr, normalizeExceptionOperation as Xt, assetSymbolFor as Y, AuthCachePortTag as Yi, members as Yn, awaitCapxulResult as Yr, normalizeExceptionErrorKind as Yt, parseAssetAmount as Z, setups as Zn, runIfActive as Zr, projectSdkException as Zt, accountFromAccountPositions as _, redactSecrets as _i, toPartyId as _n, toLowerAddress as _r, ROLES_SET_TRANSACTION_UNWRAPPER_ABI as _t, paymentPhase as a, oauthBearerAuthClient as ai, isSignerNotReadySignal as an, toOrgId as ar, ORG_BUDGET_ACTIONS as at, MONEY_READ_RATES as b, toAllowedOrigin as bi, redactTelemetryProps as bn, PAYMENT_DIRECTIONS as br, SAFE_ENABLE_MODULE_ABI as bt, makePaymentDocumentsMethods as c, ClockPortTag as ci, signerFailure as cn, decodePermissionIntent as cr, resolveOrgPermissionIdentity as ct, SmartAccountPortTag as d, BetterAuthBrowserLayer as di, makeClientRequestMethods as dn, AppIdSchema$1 as dr, MULTI_SEND_SELECTOR as dt, CAPXUL_ERROR_CODES as ei, isSettingUpLifecycle as en, OrganizationSetupSchema as er, isMoneyParseError as et, smartAccountErrorFromCapxul as f, observationRequestHeaders as fi, toCountryCode as fn, images as fr, OPERATOR as ft, ConvexAccountLayer as g, sanitizeObservationContext as gi, toHandle as gn, toExactHex as gr, ROLES_SET_ALLOWANCE_ABI as gt, makeAccountsMethods as h, readInvocationObservation as hi, HANDLE_RE as hn, isBytes32 as hr, ROLES_EXEC_TRANSACTION_WITH_ROLE_ABI as ht, inboxPhase as i, withInvocationParentSpan as ii, isEcdsaSignatureHex as in, decodeChainCause as ir, moneySafeOpDigest as it, wireChainId as j, parseCachedJwt as ji, onboardings as jn, toCurrencyCode as jr, buildSafeMultiSendExecTransactionCall as jt, bindProductTelemetryInvocation as k, BrowserAuthCacheAdapter as ki, OPERATIONS as kn, currencySymbolFor as kr, safe4337ExecuteUserOpCallData as kt, makeSmartAccountMethods as l, readClockNow as li, resolveFailureMode as ln, CurrentPolicySchema as lr, CREATE_COMMITMENT_SIGNATURE as lt, PonderIndexerAdapter as m, copyInvocationObservation as mi, toTesterKind as mn, PaymentDocumentOptionsSchema as mr, ROLES_ASSIGN_ROLES_ABI as mt, bootIdentityFlow as n, ActorFailure as ni, causeChain as nn, ORGANIZATION_SETUP_STATUSES as nr, canonicalJson as nt, requestPhase as o, SystemClockLayer as oi, openfortSignerNotReadyCode as on, InvitationViewSchema as or, roleKeyForPermission as ot, makeHoldingsMethods as p, attachInvocationObservation as pi, toKycTier as pn, toAccountId as pr, PARAMETER_TYPE as pt, executePrepared as q, readField as qi, FixedOfferDraftSchema as qn, runCapxulEffect as qr, EXCEPTION_MESSAGE as qt, makeMeMethods as r, carryInvocationParentSpan as ri, injectedWalletSigner as rn, CHAIN_UPSTREAMS as rr, fingerprintPaymentIntent as rt, makeActivityMethods as s, ClockError as si, recoverRawDigestSigner as sn, hashPermissionReplacementPreview as sr, ZODIAC_MODULE_PROXY_FACTORY as st, executeIdentityProductObservation as t, EXPECTED_OPERATION_OUTCOMES as ti, UNOBSERVABLE_SIGNER_STATUS as tn, ORGANIZATION_SETUP_REASONS as tr, parseMoney as tt, ConvexSmartAccountLayer as u, BetterAuthNodeLayer as ui, makeCurrentUserMethods as un, diagnostics as ur, MODULE_PROXY_FACTORY_ABI as ut, accountPositionsFromWire as v, redactUrlSecrets as vi, validateHandle as vn, toLowerBytes32 as vr, ROLES_SET_UP_ABI as vt, accountReadErrorFromCapxul as w, AuthClientError as wi, EXCEPTION_EVENT_NAME as wn, toBudgetId as wr, hashAdjustmentsV3 as wt, valueActivitySummary as x, toAppId as xi, CLI_CAPABILITIES as xn, PAYMENT_STATUSES as xr, SEND_BATCH_SIGNATURE as xt, positionPeg as y, isCredentialField as yi, redactTelemetryEvent as yn, toLowerHex as yr, ROLE_MANAGEMENT_SIGNATURES as yt, waitForPaymentSubmission as z, isNonEmptyString as zi, runs as zn, reference as zr, failureDetail as zt };
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 };