@capxul/sdk 4.20.0-beta.6 → 4.20.0-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { $ as toJwtToken, A as COUNTRY_CODE_RE, At as revertSummaryText, B as toAllowedOrigin, C as configuredMoneyAssetById, Ct as boundedResponseHeaders, D as BYTES32_RE, Dt as failureFingerprint, E as ASSET_ID_RE, Et as decodeChainCause, F as ZERO_BYTES32, G as toChainId, H as toAssetId, I as assetIdFor, J as toDurationMs, K as toCountryCode, M as EVM_ADDRESS_RE$1, Mt as isCredentialField, N as SUPPORTED_CURRENCY_CODES, Nt as redactSecrets, O as CLIENT_GRANT_ID_RE, Ot as isChainUpstream, P as WEI_RE, Pt as redactUrlSecrets, Q as toHandle, R as toAccountId, St as FAILURE_MODES$1, T as APP_ID_RE, Tt as chainEvidenceLabel, U as toAuthUserId, W as toBudgetId, X as toEpochMs, Y as toEmail, Z as toEpochSeconds, _ as normalizeBindingEmail, _t as CapxulError, at as toPermissionAssignmentId, b as CONFIGURED_MONEY_ASSETS, bt as isCapxulError, c as AuthCachePortTag, ct as toRoleKey, d as authClientPortFromPromiseAdapter, dt as toTxHash, et as toKycTier, f as AuthClientError, ft as toWeiAmount, g as orgRoleKeyForLabel, gt as CAPXUL_ERROR_CODES, h as ADMIN_ROLE_LABEL, ht as decodeConvexError, i as BrowserAuthCacheAdapter, it as toPayrollRunId, j as EMAIL_RE$1, jt as containsSensitiveMaterial, k as CLIENT_REQUEST_ID_RE, kt as isFailureMode, l as SystemClockLayer, lt as toSessionToken, mt as HANDLE_RE$1, nt as toPartyId, ot as toPermissionId, p as AuthClientPortTag, pt as validateHandle, q as toCurrencyCode, r as InMemoryAuthCacheAdapter, rt as toPayrollGroupId, st as toPublishableKey, tt as toOrgId, u as ClockPortTag, ut as toTesterKind, v as BASE_SEPOLIA_CHAIN_ID, vt as EXPECTED_OPERATION_OUTCOMES, w as ACCOUNT_ID_RE, wt as chainCauseProperties, x as SYNTHETIC_TEST_ASSET_FIXTURES, xt as CHAIN_UPSTREAMS, y as deriveCapxulSafeAddress, yt as Errors, z as toAddress } from "./OAuthBearerAuthClient-5ujCTtKE.mjs";
1
+ import { $ as toKycTier, A as EMAIL_RE$1, At as containsSensitiveMaterial, C as ACCOUNT_ID_RE, Ct as chainCauseProperties, D as CLIENT_GRANT_ID_RE, Dt as isChainUpstream, E as BYTES32_RE, Et as failureFingerprint, F as assetIdFor, G as toCountryCode, H as toAuthUserId, J as toEmail, K as toCurrencyCode, L as toAccountId, M as SUPPORTED_CURRENCY_CODES, Mt as redactSecrets, N as WEI_RE, Nt as redactUrlSecrets, O as CLIENT_REQUEST_ID_RE, Ot as isFailureMode, P as ZERO_BYTES32, Q as toJwtToken, R as toAddress, S as configuredMoneyAssetById, St as boundedResponseHeaders, T as ASSET_ID_RE, Tt as decodeChainCause, U as toBudgetId, V as toAssetId, W as toChainId, X as toEpochSeconds, Y as toEpochMs, Z as toHandle, _ as BASE_SEPOLIA_CHAIN_ID, _t as EXPECTED_OPERATION_OUTCOMES, at as toPermissionId, b as SYNTHETIC_TEST_ASSET_FIXTURES, bt as CHAIN_UPSTREAMS, c as AuthCachePortTag, ct as toSessionToken, d as authClientPortFromPromiseAdapter, dt as toWeiAmount, et as toOrgId, f as AuthClientError, ft as validateHandle, g as normalizeBindingEmail, gt as CapxulError, h as ADMIN_ROLE_LABEL, ht as CAPXUL_ERROR_CODES, i as BrowserAuthCacheAdapter, it as toPermissionAssignmentId, j as EVM_ADDRESS_RE$1, jt as isCredentialField, k as COUNTRY_CODE_RE, kt as revertSummaryText, l as SystemClockLayer, lt as toTesterKind, mt as decodeConvexError, nt as toPayrollGroupId, ot as toPublishableKey, p as AuthClientPortTag, pt as HANDLE_RE$1, q as toDurationMs, r as InMemoryAuthCacheAdapter, rt as toPayrollRunId, st as toRoleKey, tt as toPartyId, u as ClockPortTag, ut as toTxHash, v as deriveCapxulSafeAddress, vt as Errors, w as APP_ID_RE, wt as chainEvidenceLabel, xt as FAILURE_MODES$1, y as CONFIGURED_MONEY_ASSETS, yt as isCapxulError, z as toAllowedOrigin } from "./OAuthBearerAuthClient-DdKYPHE0.mjs";
2
2
  import { formatUnits, keccak256, recoverAddress, stringToHex, toBytes } from "viem";
3
3
  import { Cause, Clock, Context, Data, Deferred, Duration, Effect, Exit, Fiber, FiberSet, Layer, Logger, Metric, Option, Queue, Ref, References, Result, Schedule, Schema, SchemaGetter, SchemaIssue, SchemaParser, Scope, Stream, Tracer } from "effect";
4
4
  import { getFunctionName, makeFunctionReference } from "convex/server";
@@ -937,10 +937,12 @@ const CAPXUL_OPERATIONS = {
937
937
  prepareOrganizationPaymentExecution: "moneyExecution.prepareOrganizationPaymentExecution",
938
938
  preparePaymentExecution: "moneyExecution.preparePaymentExecution",
939
939
  preparePaymentLifecycleExecution: "moneyExecution.preparePaymentLifecycleExecution",
940
+ prepareInvitationConfiguration: "moneyExecution.prepareInvitationConfiguration",
940
941
  preparePermissionExecution: "moneyExecution.preparePermissionExecution",
941
942
  recoverSubmissionClaims: "moneyExecution.recoverSubmissionClaims",
942
943
  submit: "moneyExecution.submit",
943
944
  submitPaymentCommandExecution: "moneyExecution.submitPaymentCommandExecution",
945
+ submitInvitationConfigurationExecution: "moneyExecution.submitInvitationConfigurationExecution",
944
946
  submitPaymentExecution: "moneyExecution.submitPaymentExecution",
945
947
  submitPermissionExecution: "moneyExecution.submitPermissionExecution"
946
948
  },
@@ -962,20 +964,52 @@ const CAPXUL_OPERATIONS = {
962
964
  completePerson: "onboarding.completePerson"
963
965
  },
964
966
  org: {
965
- acceptInvitations: "org.acceptInvitations",
966
967
  account: { get: "org.account.get" },
967
- activateMember: "org.activateMember",
968
968
  auditLog: "org.auditLog",
969
969
  confirmBootstrap: "org.confirmBootstrap",
970
970
  createOrg: "org.createOrg",
971
971
  create: "org.create",
972
- detectAndAcceptPendingInvitations: "org.detectAndAcceptPendingInvitations",
972
+ /**
973
+ * §11: the consent mutation reports `org_invite_accepted` through its own
974
+ * scheduled emitter. It is named for the emit, not the acceptance, because
975
+ * the interactive acceptance itself owns `org.invitations.accept`.
976
+ */
977
+ emitInviteAccepted: "org.emitInviteAccepted",
973
978
  emitInviteProgressed: "org.emitInviteProgressed",
974
979
  expireInvitations: "org.expireInvitations",
975
980
  getLifecycle: "org.getLifecycle",
976
981
  getProofReceipt: "org.getProofReceipt",
977
982
  invite: "org.invite",
978
- inviteMember: "org.inviteMember",
983
+ /** D8 invitation lifecycle: preview, own list, read, and the four transitions. */
984
+ invitations: {
985
+ /** The exact grantee's consent commit (§8): one accepted digest, once. */
986
+ accept: "org.invitations.accept",
987
+ /**
988
+ * The authoring write. It is named `authorize`, not `invite`, because the
989
+ * backend already uses `org.invitations.invite` as a refusal label and
990
+ * `lint:telemetry-spine` refuses a label that collides with an operation.
991
+ */
992
+ authorize: "org.invitations.authorize",
993
+ cancel: "org.invitations.cancel",
994
+ decline: "org.invitations.decline",
995
+ get: "org.invitations.get",
996
+ list: "org.invitations.list",
997
+ /**
998
+ * The Admin-scoped Organization list. It is named `listScoped`, not
999
+ * `list`, because the own-offer list already owns `org.invitations.list`.
1000
+ */
1001
+ listScoped: "org.invitations.listScoped",
1002
+ /**
1003
+ * The authoring write's inner hops: the SDK drives the backend's existing
1004
+ * prepare/submit pair, and these names label the two Convex calls. The
1005
+ * owning `capxul_sdk_operation` record stays `org.invitations.authorize`.
1006
+ */
1007
+ prepareConfiguration: "org.invitations.prepareConfiguration",
1008
+ preview: "org.invitations.preview",
1009
+ resend: "org.invitations.resend",
1010
+ retry: "org.invitations.retry",
1011
+ submitConfiguration: "org.invitations.submitConfiguration"
1012
+ },
979
1013
  list: "org.list",
980
1014
  load: "org.load",
981
1015
  me: "org.me",
@@ -1034,7 +1068,6 @@ const CAPXUL_OPERATIONS = {
1034
1068
  },
1035
1069
  recordFailure: "org.recordFailure",
1036
1070
  recordProgress: "org.recordProgress",
1037
- resendInviteToken: "org.resendInviteToken",
1038
1071
  resumeBootstrapSubmission: "org.resumeBootstrapSubmission",
1039
1072
  retry: "org.retry",
1040
1073
  retrySetup: "org.retrySetup",
@@ -1051,7 +1084,6 @@ const CAPXUL_OPERATIONS = {
1051
1084
  retry: "organizationPayments.retry"
1052
1085
  },
1053
1086
  organizationSetup: { getProofReceipt: "organizationSetup.getProofReceipt" },
1054
- organizations: { detectAndAcceptPendingInvitations: "orgs.detectAndAcceptPendingInvitations" },
1055
1087
  payments: {
1056
1088
  cancel: "payments.cancel",
1057
1089
  claim: "payments.claim",
@@ -1089,6 +1121,7 @@ const CAPXUL_OPERATIONS = {
1089
1121
  terms: "payroll.terms"
1090
1122
  },
1091
1123
  permission: {
1124
+ verifyInvitationConfiguration: "permission.verifyInvitationConfiguration",
1092
1125
  command: "permission.command",
1093
1126
  retryVerification: "permission.retryVerification",
1094
1127
  verify: "permission.verify",
@@ -1646,6 +1679,11 @@ const OrgCreateFailedProps = Schema.Struct({
1646
1679
  const OrgInviteSentProps = Schema.Struct({
1647
1680
  ...TelemetryEnvelopeProps,
1648
1681
  org_id: OptionalOrgId,
1682
+ invitation_id: OptionalString,
1683
+ generation: OptionalString,
1684
+ command_id: OptionalString,
1685
+ subject_party_id: OptionalString,
1686
+ persisted_at: OptionalEpochMs,
1649
1687
  email_domain: OptionalString,
1650
1688
  role: OptionalString,
1651
1689
  status: OptionalString
@@ -1653,6 +1691,11 @@ const OrgInviteSentProps = Schema.Struct({
1653
1691
  const OrgInviteAcceptedProps = Schema.Struct({
1654
1692
  ...TelemetryEnvelopeProps,
1655
1693
  org_id: OptionalOrgId,
1694
+ invitation_id: OptionalString,
1695
+ accepted_at: OptionalEpochMs,
1696
+ generation: OptionalString,
1697
+ command_id: OptionalString,
1698
+ subject_party_id: OptionalString,
1656
1699
  role: OptionalString,
1657
1700
  status: OptionalString
1658
1701
  });
@@ -1660,6 +1703,7 @@ const OrgInviteExpiredProps = Schema.Struct({
1660
1703
  ...TelemetryEnvelopeProps,
1661
1704
  org_id: OptionalOrgId,
1662
1705
  email_domain: OptionalString,
1706
+ invitation_id: OptionalString,
1663
1707
  reason: OptionalString,
1664
1708
  role: OptionalString,
1665
1709
  status: OptionalString
@@ -1812,9 +1856,24 @@ const PermissionMirrorVerificationProps = Schema.Struct({
1812
1856
  "applied",
1813
1857
  "replayed",
1814
1858
  "conflicting_replay",
1815
- "revision_mismatch"
1859
+ "revision_mismatch",
1860
+ "cleanup_required",
1861
+ "not_applied",
1862
+ "application_failure",
1863
+ "mismatch",
1864
+ "refused"
1816
1865
  ])),
1866
+ command_kind: Schema.optional(Schema.Literals(["invitation_configuration", "invitation_eoa"])),
1817
1867
  command_id: OptionalString,
1868
+ invitation_id: OptionalString,
1869
+ generation: OptionalString,
1870
+ purpose: Schema.optional(Schema.Literals([
1871
+ "configure",
1872
+ "grant",
1873
+ "disable",
1874
+ "compensate"
1875
+ ])),
1876
+ $insert_id: OptionalString,
1818
1877
  /**
1819
1878
  * #1961 R03. The authorized stored row names the Permission it changed; the
1820
1879
  * verified receipt names the chain facts that prove it. Every field is
@@ -2201,6 +2260,13 @@ const CLI_COMMAND_NAMES = [
2201
2260
  "auth.profile",
2202
2261
  "auth.status",
2203
2262
  "auth.logout",
2263
+ "contact",
2264
+ "contact.list",
2265
+ "contact.get",
2266
+ "contact.add",
2267
+ "contact.label",
2268
+ "contact.hide",
2269
+ "contact.unhide",
2204
2270
  "org",
2205
2271
  CAPXUL_OPERATIONS.org.list,
2206
2272
  "org.use",
@@ -2209,6 +2275,24 @@ const CLI_COMMAND_NAMES = [
2209
2275
  CAPXUL_OPERATIONS.org.members,
2210
2276
  "org.member",
2211
2277
  "org.member.get",
2278
+ "org.member.invite",
2279
+ "org.contact",
2280
+ "org.contact.list",
2281
+ "org.contact.get",
2282
+ "org.contact.add",
2283
+ "org.contact.label",
2284
+ "org.contact.hide",
2285
+ "org.contact.unhide",
2286
+ CAPXUL_OPERATIONS.org.invite,
2287
+ "org.invite.list",
2288
+ "org.invite.get",
2289
+ "org.invite.wait",
2290
+ "org.invite.review",
2291
+ "org.invite.accept",
2292
+ "org.invite.decline",
2293
+ "org.invite.cancel",
2294
+ "org.invite.resend",
2295
+ "org.invite.retry",
2212
2296
  "org.wait",
2213
2297
  CAPXUL_OPERATIONS.org.create,
2214
2298
  CAPXUL_OPERATIONS.org.retry,
@@ -2219,7 +2303,8 @@ const CLI_CAPABILITIES = [
2219
2303
  "diagnostics",
2220
2304
  "collection",
2221
2305
  "authentication",
2222
- "organization"
2306
+ "organization",
2307
+ "contacts"
2223
2308
  ];
2224
2309
  const CLI_INVOCATION_KINDS = [
2225
2310
  "command",
@@ -2461,6 +2546,7 @@ Schema.Struct({
2461
2546
  ...TelemetryEnvelopeProps,
2462
2547
  organization_id: OrgIdTelemetrySchema,
2463
2548
  progress: Schema.Literals([
2549
+ "configuration_authorized",
2464
2550
  "account_ready",
2465
2551
  "permission_applied",
2466
2552
  "membership_activated",
@@ -2468,6 +2554,9 @@ Schema.Struct({
2468
2554
  ]),
2469
2555
  /** The invited Party. The initiating actor stays on the envelope's identity. */
2470
2556
  member_party_id: Schema.String,
2557
+ invitation_id: Schema.optional(Schema.String),
2558
+ generation: Schema.optional(Schema.String),
2559
+ command_id: Schema.optional(Schema.String),
2471
2560
  occurred_at: Schema.Number
2472
2561
  })
2473
2562
  });
@@ -3027,8 +3116,10 @@ const CAPXUL_FUNCTIONS = {
3027
3116
  "movement/annotations": { overlay: "movement/annotations:overlay" },
3028
3117
  "moneyExecution/actions": {
3029
3118
  abandonPaymentExecution: "moneyExecution/actions:abandonPaymentExecution",
3119
+ prepareInvitationConfiguration: "moneyExecution/actions:prepareInvitationConfiguration",
3030
3120
  preparePermissionExecution: "moneyExecution/actions:preparePermissionExecution",
3031
3121
  preparePaymentExecution: "moneyExecution/actions:preparePaymentExecution",
3122
+ submitInvitationConfigurationExecution: "moneyExecution/actions:submitInvitationConfigurationExecution",
3032
3123
  submitPermissionExecution: "moneyExecution/actions:submitPermissionExecution",
3033
3124
  submitPaymentExecution: "moneyExecution/actions:submitPaymentExecution"
3034
3125
  },
@@ -3045,8 +3136,6 @@ const CAPXUL_FUNCTIONS = {
3045
3136
  },
3046
3137
  "org/actions": {
3047
3138
  confirmBootstrap: "org/actions:confirmBootstrap",
3048
- detectAndAcceptPendingInvitations: "org/actions:detectAndAcceptPendingInvitations",
3049
- inviteMember: "org/actions:inviteMember",
3050
3139
  prepareBootstrap: "org/actions:prepareBootstrap",
3051
3140
  prepareFounderAccount: "org/actions:prepareFounderAccount",
3052
3141
  readTreasury: "org/actions:readTreasury",
@@ -3077,16 +3166,25 @@ const CAPXUL_FUNCTIONS = {
3077
3166
  startOrResume: "org/lifecycle:startOrResume"
3078
3167
  },
3079
3168
  "org/mutations": {
3169
+ accept: "org/mutations:accept",
3170
+ cancel: "org/mutations:cancel",
3080
3171
  createOrg: "org/mutations:createOrg",
3081
- resendInviteToken: "org/mutations:resendInviteToken"
3172
+ decline: "org/mutations:decline",
3173
+ invite: "org/mutations:invite",
3174
+ resend: "org/mutations:resend",
3175
+ retry: "org/mutations:retry"
3082
3176
  },
3083
3177
  "org/queries": {
3178
+ getInvitation: "org/queries:getInvitation",
3084
3179
  listAll: "org/queries:listAll",
3180
+ listInvitations: "org/queries:listInvitations",
3085
3181
  listMembersByOrgId: "org/queries:listMembersByOrgId",
3086
3182
  listMine: "org/queries:listMine",
3183
+ listMyInvitations: "org/queries:listMyInvitations",
3087
3184
  listRolesByOrgId: "org/queries:listRolesByOrgId",
3088
3185
  loadByOrgId: "org/queries:loadByOrgId",
3089
- me: "org/queries:me"
3186
+ me: "org/queries:me",
3187
+ previewInvite: "org/queries:previewInvite"
3090
3188
  },
3091
3189
  "smartAccount/actions": {
3092
3190
  claim: "smartAccount/actions:claim",
@@ -4046,6 +4144,94 @@ const EventRefSchema = Schema.Struct({
4046
4144
  topic0: Bytes32Schema,
4047
4145
  dataHash: Bytes32Schema
4048
4146
  });
4147
+ const InvitationEoaReceiptSchema = Schema.Struct({
4148
+ kind: Schema.Literal("invitation_eoa"),
4149
+ chainId: BaseSepoliaChainIdSchema,
4150
+ transactionHash: TxHashSchema,
4151
+ blockNumber: BlockNumberSchema,
4152
+ blockHash: Bytes32Schema,
4153
+ sender: AddressSchema,
4154
+ nonce: Schema.String.pipe(Schema.refine((value) => /^(0|[1-9][0-9]*)$/.test(value)))
4155
+ });
4156
+ const PermissionReceiptRefSchema = Schema.Union([Schema.Struct({
4157
+ kind: Schema.Literal("user_operation"),
4158
+ ...ReceiptRefSchema.fields
4159
+ }), InvitationEoaReceiptSchema]);
4160
+ const PermissionEventRefSchema = Schema.Struct({
4161
+ receipt: PermissionReceiptRefSchema,
4162
+ emitter: AddressSchema,
4163
+ transactionIndex: LogIndexSchema,
4164
+ logIndex: LogIndexSchema,
4165
+ topic0: Bytes32Schema,
4166
+ dataHash: Bytes32Schema
4167
+ });
4168
+ Schema.Union([
4169
+ Schema.Struct({
4170
+ status: Schema.Literal("pending"),
4171
+ reason: Schema.Literal("receipt_missing")
4172
+ }),
4173
+ Schema.Struct({
4174
+ status: Schema.Literal("provider_failure"),
4175
+ retryable: Schema.Literal(true)
4176
+ }),
4177
+ Schema.Struct({
4178
+ status: Schema.Literal("mismatch"),
4179
+ code: Schema.Literals([
4180
+ "wrong_chain",
4181
+ "wrong_sender",
4182
+ "wrong_transaction",
4183
+ "failed_transaction",
4184
+ "non_canonical_block",
4185
+ "wrong_contract_identity",
4186
+ "missing_event",
4187
+ "extra_authority_event",
4188
+ "wrong_fact_tuple",
4189
+ "wrong_state",
4190
+ "conflicting_replay"
4191
+ ]),
4192
+ attemptTransactionHash: Schema.optional(TxHashSchema),
4193
+ receipt: Schema.optional(InvitationEoaReceiptSchema)
4194
+ }),
4195
+ Schema.Struct({
4196
+ status: Schema.Literal("verified"),
4197
+ commandId: PaymentCommandIdSchema,
4198
+ receipt: InvitationEoaReceiptSchema,
4199
+ events: Schema.Array(PermissionEventRefSchema),
4200
+ factsHash: Bytes32Schema
4201
+ })
4202
+ ]);
4203
+ /**
4204
+ * One stored `setAllowance` call inside a command's expected authority set.
4205
+ *
4206
+ * The pinned Roles module emits `SetAllowance` as *post-state*, not as the call
4207
+ * arguments: `maxRefill = 0` becomes `type(uint128).max`, and `timestamp = 0`
4208
+ * becomes the receipt block's timestamp. A hash over the call arguments can
4209
+ * therefore never match that receipt. `index` names the entry in
4210
+ * `expectedAuthorityEvents` the call produced, and `data` is the call's own
4211
+ * calldata, so the verifier can rebuild the one hash the module actually emits.
4212
+ * The rule is pinned by `test:invitation-conformance`.
4213
+ */
4214
+ const AllowanceExpectationSchema = Schema.Struct({
4215
+ index: nonNegativeInteger("index"),
4216
+ data: Schema.String.pipe(Schema.refine((value) => /^0x[0-9a-fA-F]+$/u.test(value), { message: "data must be 0x-prefixed hex" }))
4217
+ });
4218
+ Schema.Struct({
4219
+ commandId: PaymentCommandIdSchema,
4220
+ userOpHash: Bytes32Schema,
4221
+ generationHash: Bytes32Schema,
4222
+ chainId: BaseSepoliaChainIdSchema,
4223
+ organizationSafe: SafeAddressSchema,
4224
+ rolesModule: ModuleAddressSchema,
4225
+ userOpSenderSafe: SafeAddressSchema,
4226
+ expectedAuthorityEvents: Schema.Array(Bytes32Schema),
4227
+ /**
4228
+ * Absent means "no normalization": every expected hash is compared as stored.
4229
+ * A command whose set contains `setAllowance` then refuses (`wrong_fact_tuple`)
4230
+ * rather than passing on a weakened proof, so an incomplete caller fails
4231
+ * closed.
4232
+ */
4233
+ allowanceExpectations: Schema.optional(Schema.Array(AllowanceExpectationSchema))
4234
+ });
4049
4235
  const PermissionOperationSchema = Schema.Literals([
4050
4236
  "create",
4051
4237
  "change",
@@ -4089,7 +4275,9 @@ const StoredPermissionCommandSchema = Schema.Struct({
4089
4275
  });
4090
4276
  Schema.Struct({
4091
4277
  command: StoredPermissionCommandSchema,
4092
- userOpHash: Bytes32Schema
4278
+ userOpHash: Bytes32Schema,
4279
+ /** The stored `setAllowance` calls of this command's own expectation. */
4280
+ allowanceExpectations: Schema.optional(Schema.Array(AllowanceExpectationSchema))
4093
4281
  });
4094
4282
  Schema.Union([
4095
4283
  Schema.Struct({
@@ -4933,6 +5121,27 @@ Schema.Struct({
4933
5121
  digest: Bytes32Schema,
4934
5122
  value: PermissionResourceSchema
4935
5123
  });
5124
+ Schema.Struct({
5125
+ commandId: PaymentCommandIdSchema,
5126
+ signerAddress: AddressSchema
5127
+ });
5128
+ Schema.Struct({
5129
+ executionId: MoneyExecutionIdSchema,
5130
+ commandId: PaymentCommandIdSchema,
5131
+ orgId: nonEmpty("orgId"),
5132
+ invitationId: nonEmpty("invitationId"),
5133
+ generationHash: Bytes32Schema,
5134
+ chainId: BaseSepoliaChainIdSchema,
5135
+ signerAddress: AddressSchema,
5136
+ userOpSenderSafe: SafeAddressSchema,
5137
+ digest: Bytes32Schema
5138
+ });
5139
+ Schema.Struct({
5140
+ status: Schema.Literal("submitted"),
5141
+ executionId: MoneyExecutionIdSchema,
5142
+ commandId: PaymentCommandIdSchema,
5143
+ userOpHash: Bytes32Schema
5144
+ });
4936
5145
  Schema.Struct({
4937
5146
  status: Schema.Literal("submitted"),
4938
5147
  executionId: MoneyExecutionIdSchema,
@@ -5506,6 +5715,160 @@ const CurrentPolicySchema = Schema.Union([Schema.Struct({
5506
5715
  actions: Schema.NonEmptyArray(Schema.Literals(["pay", "commitments"]))
5507
5716
  })
5508
5717
  }), Schema.Struct({ type: Schema.Literal("managePeople") })]);
5718
+ const BudgetIntentSchema = CurrentPolicySchema.pipe(Schema.refine((value) => {
5719
+ if (value.type !== "budget") return false;
5720
+ const { actions, recipients } = value.scope;
5721
+ if (new Set(actions).size !== actions.length) return false;
5722
+ return recipients.type === "anyone" || recipients.accounts.length >= 1 && recipients.accounts.length <= 32 && new Set(recipients.accounts).size === recipients.accounts.length;
5723
+ }));
5724
+ const InvitationIdSchema = Schema.NonEmptyString;
5725
+ const InvitationTargetSchema = Schema.Struct({ invitationId: InvitationIdSchema });
5726
+ Schema.Struct({
5727
+ ...InvitationTargetSchema.fields,
5728
+ expectedOfferDigest: Bytes32Schema
5729
+ });
5730
+ /** The requested grantee of one invitation. */
5731
+ const GranteeRefSchema = Schema.Union([Schema.Struct({
5732
+ type: Schema.Literal("email"),
5733
+ email: Schema.NonEmptyString
5734
+ }), Schema.Struct({
5735
+ type: Schema.Literal("account"),
5736
+ accountId: AccountIdSchema
5737
+ })]);
5738
+ Schema.Struct({
5739
+ requestKey: Schema.String.pipe(Schema.refine((value) => /^[\x20-\x7e]{1,128}$/.test(value))),
5740
+ to: GranteeRefSchema,
5741
+ grants: Schema.Array(Schema.Union([
5742
+ Schema.Struct({
5743
+ type: Schema.Literal("budget"),
5744
+ budgetId: PermissionIdSchema
5745
+ }),
5746
+ Schema.Struct({
5747
+ type: Schema.Literal("managePeople"),
5748
+ permissionId: PermissionIdSchema
5749
+ }),
5750
+ Schema.Struct({
5751
+ type: Schema.Literal("new_budget"),
5752
+ label: Schema.String.pipe(Schema.refine((value) => value.trim().length >= 1 && value.trim().length <= 128)),
5753
+ intent: BudgetIntentSchema
5754
+ })
5755
+ ]))
5756
+ }).pipe(Schema.refine((value) => {
5757
+ if (value.grants.length < 1 || value.grants.length > 16) return false;
5758
+ const existing = value.grants.flatMap((grant) => grant.type === "new_budget" ? [] : [grant.type === "budget" ? grant.budgetId : grant.permissionId]);
5759
+ return new Set(existing).size === existing.length && value.grants.filter((grant) => grant.type === "new_budget").length <= 4;
5760
+ }));
5761
+ const InvitationPhaseSchema = Schema.Literals([
5762
+ "authorizing",
5763
+ "pending",
5764
+ "pending_grant",
5765
+ "active",
5766
+ "revoking",
5767
+ "declined",
5768
+ "cancelled",
5769
+ "expired",
5770
+ "revoked"
5771
+ ]);
5772
+ const EndingReasonSchema = Schema.Literals([
5773
+ "declined",
5774
+ "cancelled",
5775
+ "expired",
5776
+ "revoked"
5777
+ ]);
5778
+ const OfferedAuthoritySchema = Schema.Union([Schema.Struct({
5779
+ type: Schema.Literal("budget"),
5780
+ budgetId: Schema.NonEmptyString.pipe(Schema.refine((value) => value.length > 0)),
5781
+ label: Schema.String,
5782
+ policy: BudgetIntentSchema,
5783
+ policyDigest: Bytes32Schema
5784
+ }), Schema.Struct({
5785
+ type: Schema.Literal("managePeople"),
5786
+ permissionId: PermissionIdSchema,
5787
+ label: Schema.String
5788
+ })]);
5789
+ const NewBudgetOfferSchema = Schema.Struct({
5790
+ type: Schema.Literal("new_budget"),
5791
+ label: Schema.String,
5792
+ policy: BudgetIntentSchema,
5793
+ policyDigest: Bytes32Schema
5794
+ });
5795
+ const PreviewGranteeSchema = Schema.Struct({
5796
+ partyId: Schema.NullOr(PartyIdSchema),
5797
+ accountId: Schema.NullOr(AccountIdSchema),
5798
+ safeAddress: AddressSchema,
5799
+ accountReady: Schema.NullOr(Schema.Boolean)
5800
+ });
5801
+ Schema.Struct({
5802
+ orgId: Schema.NonEmptyString.pipe(Schema.refine((value) => value.length > 0)),
5803
+ grantee: PreviewGranteeSchema,
5804
+ grants: Schema.Array(Schema.Union([OfferedAuthoritySchema, NewBudgetOfferSchema])),
5805
+ existingAssignments: Schema.Array(PermissionAssignmentIdSchema),
5806
+ includesManagement: Schema.Boolean,
5807
+ observedAt: EpochMsSchema
5808
+ });
5809
+ Schema.Struct({
5810
+ cursor: Schema.optional(Schema.NonEmptyString),
5811
+ limit: Schema.optional(Schema.Number.pipe(Schema.refine((value) => Number.isSafeInteger(value) && value >= 1 && value <= 100))),
5812
+ phases: Schema.optional(Schema.Array(InvitationPhaseSchema).pipe(Schema.refine((value) => new Set(value).size === value.length)))
5813
+ });
5814
+ const InvitationRecoverySchema = Schema.Struct({
5815
+ actor: Schema.Literals([
5816
+ "system",
5817
+ "invitee",
5818
+ "admin"
5819
+ ]),
5820
+ action: Schema.Literals([
5821
+ "wait",
5822
+ "retry",
5823
+ "review_offer",
5824
+ "reauthorize"
5825
+ ]),
5826
+ reason: Schema.Literals([
5827
+ "configuration_pending",
5828
+ "grant_pending",
5829
+ "provider_unavailable",
5830
+ "policy_changed",
5831
+ "cleanup_pending",
5832
+ "signer_unavailable"
5833
+ ])
5834
+ });
5835
+ const InvitationViewSchema = Schema.Struct({
5836
+ id: InvitationIdSchema,
5837
+ orgId: Schema.NonEmptyString.pipe(Schema.refine((value) => value.length > 0)),
5838
+ organizationName: Schema.String,
5839
+ grantee: Schema.Struct({
5840
+ partyId: PartyIdSchema,
5841
+ accountId: Schema.NullOr(AccountIdSchema),
5842
+ safeAddress: AddressSchema,
5843
+ accountReady: Schema.NullOr(Schema.Boolean)
5844
+ }),
5845
+ phase: InvitationPhaseSchema,
5846
+ grants: Schema.Array(Schema.Union([Schema.Struct({
5847
+ type: Schema.Literal("budget"),
5848
+ budgetId: Schema.NonEmptyString.pipe(Schema.refine((value) => value.length > 0))
5849
+ }), Schema.Struct({
5850
+ type: Schema.Literal("managePeople"),
5851
+ permissionId: PermissionIdSchema
5852
+ })])),
5853
+ offers: Schema.Array(OfferedAuthoritySchema),
5854
+ recovery: Schema.NullOr(InvitationRecoverySchema),
5855
+ offerDigest: Bytes32Schema,
5856
+ authorizedAt: Schema.NullOr(EpochMsSchema),
5857
+ acceptedAt: Schema.NullOr(EpochMsSchema),
5858
+ expiresAt: Schema.NullOr(EpochMsSchema),
5859
+ commandId: Schema.NullOr(PaymentCommandIdSchema),
5860
+ endingReason: Schema.NullOr(EndingReasonSchema),
5861
+ delivery: Schema.Literals([
5862
+ "not_confirmed",
5863
+ "sent",
5864
+ "failed"
5865
+ ])
5866
+ });
5867
+ Schema.Struct({
5868
+ items: Schema.Array(InvitationViewSchema),
5869
+ nextCursor: Schema.NullOr(Schema.NonEmptyString),
5870
+ observedAt: EpochMsSchema
5871
+ });
5509
5872
  const ActiveBudgetSchema = Schema.Struct({
5510
5873
  id: PermissionIdSchema,
5511
5874
  label: Schema.String,
@@ -7148,11 +7511,13 @@ const financialOpsContract = {
7148
7511
  //#region src/contract/money-execution.ts
7149
7512
  const moneyExecutionContract = {
7150
7513
  abandonPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].abandonPaymentExecution),
7514
+ prepareInvitationConfiguration: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].prepareInvitationConfiguration),
7151
7515
  preparePermissionExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].preparePermissionExecution),
7152
7516
  preparePaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].preparePaymentExecution),
7153
7517
  prepareOrganizationPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/paymentCommandActions"].prepareOrganizationPaymentExecution),
7154
7518
  preparePaymentLifecycleExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/paymentCommandActions"].preparePaymentLifecycleExecution),
7155
7519
  submitPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].submitPaymentExecution),
7520
+ submitInvitationConfigurationExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].submitInvitationConfigurationExecution),
7156
7521
  submitPermissionExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].submitPermissionExecution),
7157
7522
  submitPaymentCommandExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/paymentCommandActions"].submitPaymentCommandExecution)
7158
7523
  };
@@ -7733,7 +8098,7 @@ function subscribeActivity(deps, actor, controls, onChange) {
7733
8098
  }
7734
8099
  //#endregion
7735
8100
  //#region package.json
7736
- var version = "4.20.0-beta.6";
8101
+ var version = "4.20.0-beta.7";
7737
8102
  //#endregion
7738
8103
  //#region src/telemetry/exception-projection.ts
7739
8104
  /** Fixed fallback for failures that have no safe message. */
@@ -8569,7 +8934,7 @@ function isMoneyTelemetryDebugEnabled() {
8569
8934
  }
8570
8935
  //#endregion
8571
8936
  //#region src/surface/payment-command-execution.ts
8572
- function isAborted$2(signal) {
8937
+ function isAborted$3(signal) {
8573
8938
  return signal?.aborted === true;
8574
8939
  }
8575
8940
  function canonicalJson(value) {
@@ -8595,7 +8960,7 @@ async function abandonPrepared$1(deps, executionId, closePayment, reason, result
8595
8960
  return result;
8596
8961
  }
8597
8962
  async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnExit, onPreparedClosed, signal, controls) {
8598
- if (isAborted$2(signal)) return {
8963
+ if (isAborted$3(signal)) return {
8599
8964
  ok: false,
8600
8965
  error: Errors.cancelled({ operation: "payments" })
8601
8966
  };
@@ -8624,7 +8989,7 @@ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnE
8624
8989
  ok: false,
8625
8990
  error: Errors.invalidInput("payment", "prepared authority mismatch")
8626
8991
  }, onPreparedClosed, controls);
8627
- if (isAborted$2(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
8992
+ if (isAborted$3(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
8628
8993
  ok: false,
8629
8994
  error: Errors.cancelled({ operation: "payments" })
8630
8995
  }, onPreparedClosed, controls);
@@ -8650,7 +9015,7 @@ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnE
8650
9015
  error: signerFailure(deps.signer.source, "signUserOpHash", cause)
8651
9016
  }, onPreparedClosed, controls);
8652
9017
  }
8653
- if (isAborted$2(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
9018
+ if (isAborted$3(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
8654
9019
  ok: false,
8655
9020
  error: Errors.cancelled({ operation: "payments" })
8656
9021
  }, onPreparedClosed, controls);
@@ -8685,7 +9050,7 @@ function cancelled(operation) {
8685
9050
  error: Errors.cancelled({ operation })
8686
9051
  };
8687
9052
  }
8688
- function isAborted$1(signal) {
9053
+ function isAborted$2(signal) {
8689
9054
  return signal?.aborted === true;
8690
9055
  }
8691
9056
  async function signerCall(source, operation, run) {
@@ -8711,7 +9076,7 @@ async function abandonPrepared(deps, executionId, reason, result, onPreparedClos
8711
9076
  return result;
8712
9077
  }
8713
9078
  async function executePersonalPayment(deps, payment, signal, requestKey, onPreparedClosed) {
8714
- if (isAborted$1(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
9079
+ if (isAborted$2(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
8715
9080
  if (deps.signer === void 0) return mismatch("signer", "payments.pay requires a configured CapxulSigner");
8716
9081
  const session = deps.actor.authSession();
8717
9082
  if (session === null) return {
@@ -8739,10 +9104,10 @@ async function executePersonalPayment(deps, payment, signal, requestKey, onPrepa
8739
9104
  executionId: prepared.value.executionId,
8740
9105
  recipient: prepared.value.recipientObservation
8741
9106
  });
8742
- if (isAborted$1(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
9107
+ if (isAborted$2(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
8743
9108
  const signature = await signerCall(deps.signer.source, "signUserOpHash", () => deps.signer.signUserOpHash(prepared.value.digest));
8744
9109
  if (!signature.ok) return abandonPrepared(deps, prepared.value.executionId, "signer_rejected", signature, onPreparedClosed);
8745
- if (isAborted$1(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
9110
+ if (isAborted$2(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
8746
9111
  return runIfActive(void 0, CAPXUL_OPERATIONS.payments.submitExecution, () => deps.convexCall.action(deps.functions.submitPaymentExecution, { input: {
8747
9112
  executionId: prepared.value.executionId,
8748
9113
  signature: signature.value
@@ -12561,7 +12926,9 @@ const OBSERVED_CONVEX_MUTATIONS = /* @__PURE__ */ new Set([
12561
12926
  "smartAccount/mutations:provision",
12562
12927
  "org/lifecycle:startOrResume",
12563
12928
  "org/lifecycle:recordFailure",
12564
- "org/lifecycle:retry"
12929
+ "org/lifecycle:retry",
12930
+ "org/mutations:invite",
12931
+ "org/mutations:accept"
12565
12932
  ]);
12566
12933
  var ConvexCallAdapter = class {
12567
12934
  #client;
@@ -13234,10 +13601,7 @@ const DEFAULT_FUNCTIONS$1 = {
13234
13601
  listAll: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].listAll),
13235
13602
  listRoles: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].listRolesByOrgId),
13236
13603
  listMembers: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].listMembersByOrgId),
13237
- readTreasury: makeFunctionReference(CAPXUL_FUNCTIONS["org/actions"].readTreasury),
13238
- inviteMember: makeFunctionReference(CAPXUL_FUNCTIONS["org/actions"].inviteMember),
13239
- resendInvite: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].resendInviteToken),
13240
- detectInvitations: makeFunctionReference(CAPXUL_FUNCTIONS["org/actions"].detectAndAcceptPendingInvitations)
13604
+ readTreasury: makeFunctionReference(CAPXUL_FUNCTIONS["org/actions"].readTreasury)
13241
13605
  };
13242
13606
  /**
13243
13607
  * Standard production Organization read adapter. It intentionally has no
@@ -13273,22 +13637,6 @@ var ConvexOrganizationAdapter = class {
13273
13637
  pendingMembers(input) {
13274
13638
  return this.listMembers(input).pipe(Effect.map((members) => members.filter((member) => member.status === "pending" || member.status === "pending_safe" || member.status === "pending_grant")));
13275
13639
  }
13276
- inviteMember(input) {
13277
- return this.#convex.action(this.#fns.inviteMember, copyInvocationObservation(input, {
13278
- orgId: input.orgId,
13279
- email: input.input.email,
13280
- role: input.input.role
13281
- })).pipe(Effect.mapError((error) => orgErrorFromCapxul("inviteMember", error.publicError, error)), Effect.map(brandOrgMember), Effect.catchDefect((cause) => Effect.fail(toOrgError("inviteMember", cause))));
13282
- }
13283
- resendInviteToken(input) {
13284
- return this.#convex.mutation(this.#fns.resendInvite, {
13285
- orgId: input.orgId,
13286
- email: input.email
13287
- }).pipe(Effect.mapError((error) => orgErrorFromCapxul("resendInviteToken", error.publicError, error)), Effect.map(brandOrgMember), Effect.catchDefect((cause) => Effect.fail(toOrgError("resendInviteToken", cause))));
13288
- }
13289
- detectAndAcceptPendingInvitations(_input) {
13290
- return this.#convex.action(this.#fns.detectInvitations, {}).pipe(Effect.mapError((error) => orgErrorFromCapxul("detectAndAcceptPendingInvitations", error.publicError, error)), Effect.map((result) => ({ matched: result.matched.map(toOrgId) })), Effect.catchDefect((cause) => Effect.fail(toOrgError("detectAndAcceptPendingInvitations", cause))));
13291
- }
13292
13640
  #readTreasuryWire(input) {
13293
13641
  const orgId = String(input.orgId);
13294
13642
  return retryIdempotentRead(this.#convex.action(this.#fns.readTreasury, copyInvocationObservation(input, { orgId })), CAPXUL_OPERATIONS.org.treasury, this.#telemetry, input).pipe(Effect.mapError((error) => orgErrorFromCapxul("readTreasury", error.publicError, error)), Effect.map((wire) => {
@@ -13333,11 +13681,12 @@ var ConvexOrganizationSetupAdapter = class {
13333
13681
  #fns;
13334
13682
  constructor(input) {
13335
13683
  this.#convex = input.convex;
13336
- this.#signer = input.signer;
13684
+ this.#signer = input.signer ?? null;
13337
13685
  this.#chainId = input.chainId;
13338
13686
  this.#fns = input.functions ?? DEFAULT_FUNCTIONS;
13339
13687
  }
13340
13688
  async startOrResume(input) {
13689
+ if (this.#signer === null) return fail$1(Errors.capabilityUnavailable("signer", "startOrResume"));
13341
13690
  const result = await runCall("startOrResume", this.#convex.mutation(this.#fns.startOrResume, copyInvocationObservation(input, {
13342
13691
  ...input,
13343
13692
  chainId: this.#chainId
@@ -13365,7 +13714,9 @@ var ConvexOrganizationSetupAdapter = class {
13365
13714
  async authorizeAndSubmitBootstrap(input) {
13366
13715
  const cancelled = cancellation(input.signal);
13367
13716
  if (cancelled !== void 0) return cancelled;
13368
- const signerAddress = await signerResult(this.#signer.source, "getAddress", () => this.#signer.getAddress());
13717
+ const signer = this.#signer;
13718
+ if (signer === null) return fail$1(Errors.capabilityUnavailable("signer", "authorizeAndSubmitBootstrap"));
13719
+ const signerAddress = await signerResult(signer.source, "getAddress", () => signer.getAddress());
13369
13720
  if (!signerAddress.ok) return signerAddress;
13370
13721
  const prepared = await runCall("prepareBootstrap", this.#convex.action(this.#fns.prepareBootstrap, copyInvocationObservation(input, {
13371
13722
  orgId: input.orgId,
@@ -13377,7 +13728,7 @@ var ConvexOrganizationSetupAdapter = class {
13377
13728
  if (!authority.ok) return authority;
13378
13729
  const cancelledAfterPrepare = cancellation(input.signal);
13379
13730
  if (cancelledAfterPrepare !== void 0) return cancelledAfterPrepare;
13380
- const signature = await signerResult(this.#signer.source, "signUserOpHash", () => this.#signer.signUserOpHash(prepared.value.digest));
13731
+ const signature = await signerResult(signer.source, "signUserOpHash", () => signer.signUserOpHash(prepared.value.digest));
13381
13732
  if (!signature.ok) return signature;
13382
13733
  const cancelledAfterSign = cancellation(input.signal);
13383
13734
  if (cancelledAfterSign !== void 0) return cancelledAfterSign;
@@ -13433,7 +13784,8 @@ var ConvexOrganizationSetupAdapter = class {
13433
13784
  ...input.observationContext === void 0 ? {} : { observationContext: input.observationContext }
13434
13785
  });
13435
13786
  if (!current.ok) return current;
13436
- if (current.value.status === "failed" && current.value.retryable && (current.value.at === "awaitingFounderAuthorization" || current.value.at === "submittingBootstrap")) {
13787
+ if (current.value.status === "failed" && current.value.retryable && current.value.at === "awaitingFounderAuthorization") {
13788
+ if (this.#signer === null) return fail$1(Errors.capabilityUnavailable("signer", "retry"));
13437
13789
  const reset = resetSignerSession(this.#signer);
13438
13790
  if (!reset.ok) return reset;
13439
13791
  }
@@ -15481,6 +15833,271 @@ function makeOrgMeMethod(deps, orgId) {
15481
15833
  };
15482
15834
  }
15483
15835
  //#endregion
15836
+ //#region src/contract/invitations.ts
15837
+ const invitationContract = {
15838
+ preview: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].previewInvite),
15839
+ listMine: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].listMyInvitations),
15840
+ listScoped: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].listInvitations),
15841
+ get: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].getInvitation),
15842
+ invite: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].invite),
15843
+ accept: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].accept),
15844
+ decline: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].decline),
15845
+ cancel: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].cancel),
15846
+ resend: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].resend),
15847
+ retry: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].retry)
15848
+ };
15849
+ //#endregion
15850
+ //#region src/surface/invitations.ts
15851
+ /**
15852
+ * The one refusal a scoped invitation result that names another Organization
15853
+ * receives, whether it was read or returned by the authoring write.
15854
+ */
15855
+ function scopeRefusal(orgId) {
15856
+ return Errors.invalidInput("orgId", `The invitation result does not belong to Organization ${JSON.stringify(orgId)}.`);
15857
+ }
15858
+ /**
15859
+ * A scoped invitation result belongs to the Organization it was read under.
15860
+ *
15861
+ * One owner holds the refusal copy and the verified-scope span: a single view
15862
+ * reports whether it names the scope, and a page — which names no Organization
15863
+ * of its own — reports whether every row does. A result that does not belong is
15864
+ * refused here rather than handed to a consumer, so a future route change
15865
+ * cannot turn into a silent cross-Organization read on a caller that trusted
15866
+ * the scope it passed. A successful scoped read also marks the verifying
15867
+ * Organization on the owning span, exactly as `org.me` does — the caller's
15868
+ * scope hint is not authority, the completed scoped read is.
15869
+ */
15870
+ function verifyScope(orgId, value, belongsToScope) {
15871
+ if (!belongsToScope(value)) return Effect.fail(scopeRefusal(orgId));
15872
+ return Effect.annotateCurrentSpan({
15873
+ verified_organization_id: orgId,
15874
+ scope_kind: "organization"
15875
+ }).pipe(Effect.as(value));
15876
+ }
15877
+ /** One view names its own Organization. */
15878
+ const namesScope = (orgId) => (value) => String(value.orgId) === orgId;
15879
+ /** A page names no Organization of its own, so every row must name the scope. */
15880
+ const rowsNameScope = (orgId) => (page) => page.items.every((item) => String(item.orgId) === orgId);
15881
+ const ops = CAPXUL_OPERATIONS.org.invitations;
15882
+ /** Truth for a caller-owned signal, without narrowing its type. */
15883
+ function isAborted$1(signal) {
15884
+ return signal?.aborted === true;
15885
+ }
15886
+ /**
15887
+ * One observed operation around one Convex hop, exactly like `org.me`. The
15888
+ * call-start invocation snapshot rides the arguments, so the backend continues
15889
+ * the attempt this call started rather than resolving a new one.
15890
+ */
15891
+ function observed$1(deps, operation, options, args, call, check) {
15892
+ const controls = deps.invocationControls?.(options) ?? options;
15893
+ return runCapxulEffect(call(copyInvocationObservation(controls, args)).pipe(Effect.mapError((failure) => failure.publicError), Effect.flatMap((value) => check === void 0 ? Effect.succeed(value) : check(value))), controls, operation, deps.runPromise);
15894
+ }
15895
+ /**
15896
+ * The Admin's preview stays a read: it reaches the preview query and nothing
15897
+ * else. It reads current policies and live assignments, so the operator sees
15898
+ * what the offered authority is now, not a frozen copy.
15899
+ */
15900
+ function makeOrgInvitationMethods(deps, orgId) {
15901
+ const scopeCheck = (value) => verifyScope(orgId, value, namesScope(orgId));
15902
+ return {
15903
+ preview: (input, options) => observed$1(deps, ops.preview, options, {
15904
+ orgId,
15905
+ request: input
15906
+ }, (args) => deps.convexCall.query(invitationContract.preview, args), scopeCheck),
15907
+ invite: makeInviteMethod(deps, orgId),
15908
+ accept: (input, options) => observed$1(deps, ops.accept, options, {
15909
+ orgId,
15910
+ invitationId: input.invitationId,
15911
+ expectedOfferDigest: input.expectedOfferDigest
15912
+ }, (args) => deps.convexCall.mutation(invitationContract.accept, args), scopeCheck),
15913
+ list: (input, options) => observed$1(deps, ops.listScoped, options, {
15914
+ orgId,
15915
+ ...pageArgs(input)
15916
+ }, (args) => deps.convexCall.query(invitationContract.listScoped, args), (page) => verifyScope(orgId, page, rowsNameScope(orgId))),
15917
+ get: (input, options) => observed$1(deps, ops.get, options, {
15918
+ orgId,
15919
+ invitationId: input.invitationId
15920
+ }, (args) => deps.convexCall.query(invitationContract.get, args), scopeCheck),
15921
+ decline: (input, options) => observed$1(deps, ops.decline, options, {
15922
+ orgId,
15923
+ invitationId: input.invitationId
15924
+ }, (args) => deps.convexCall.mutation(invitationContract.decline, args), scopeCheck),
15925
+ cancel: (input, options) => observed$1(deps, ops.cancel, options, {
15926
+ orgId,
15927
+ invitationId: input.invitationId
15928
+ }, (args) => deps.convexCall.mutation(invitationContract.cancel, args), scopeCheck),
15929
+ resend: (input, options) => observed$1(deps, ops.resend, options, {
15930
+ orgId,
15931
+ invitationId: input.invitationId
15932
+ }, (args) => deps.convexCall.mutation(invitationContract.resend, args), scopeCheck),
15933
+ retry: (input, options) => observed$1(deps, ops.retry, options, {
15934
+ orgId,
15935
+ invitationId: input.invitationId
15936
+ }, (args) => deps.convexCall.mutation(invitationContract.retry, args), scopeCheck)
15937
+ };
15938
+ }
15939
+ /**
15940
+ * The authoring write, including its configuration hop.
15941
+ *
15942
+ * The mutation persists the invitation and its configure command before any
15943
+ * signature exists. The write then drives the existing human configuration
15944
+ * owner exactly as the Permission and payment surfaces drive theirs: prepare
15945
+ * the stored command for this Account's Safe, check the prepared authority
15946
+ * against the request, deliver the durable identity to the caller, sign the
15947
+ * returned digest, and submit it. The backend keeps the only authorization
15948
+ * rule (`prepareInvitationConfigurationIntentInTx` /
15949
+ * `submitInvitationConfigurationExecution`); this edge adds no second one.
15950
+ *
15951
+ * Cancellation owns the whole compound: an abort before the digest is signed
15952
+ * stops the write and forwards no signature, and an already-signed submission
15953
+ * completes.
15954
+ */
15955
+ async function executeInvite(deps, orgId, input, signal, controls, verifiedOrganization, onPrepared) {
15956
+ if (isAborted$1(signal)) return {
15957
+ ok: false,
15958
+ error: Errors.cancelled({ operation: ops.authorize })
15959
+ };
15960
+ if (deps.actor === void 0 || deps.chainId === void 0 || deps.signer === void 0) return {
15961
+ ok: false,
15962
+ error: Errors.notImplemented("invitations", "executionComposition")
15963
+ };
15964
+ const session = deps.actor.authSession();
15965
+ if (session === null) return {
15966
+ ok: false,
15967
+ error: Errors.notAuthenticated()
15968
+ };
15969
+ const authored = await runIfActive(signal, ops.authorize, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.mutation(invitationContract.invite, copyInvocationObservation(controls, {
15970
+ orgId,
15971
+ request: input
15972
+ }))), controls), deps.runPromise);
15973
+ if (!authored.ok) return authored;
15974
+ const view = authored.value;
15975
+ if (String(view.orgId) !== orgId) return {
15976
+ ok: false,
15977
+ error: scopeRefusal(orgId)
15978
+ };
15979
+ if (view.phase !== "authorizing") return {
15980
+ ok: true,
15981
+ value: view
15982
+ };
15983
+ if (view.commandId === null) return {
15984
+ ok: false,
15985
+ error: Errors.invalidInput("invitationId", "The invitation does not name its configuration command.")
15986
+ };
15987
+ const commandId = view.commandId;
15988
+ let signerAddress;
15989
+ try {
15990
+ signerAddress = await deps.signer.getAddress();
15991
+ } catch (cause) {
15992
+ return {
15993
+ ok: false,
15994
+ error: signerFailure(deps.signer.source, "getAddress", cause)
15995
+ };
15996
+ }
15997
+ const prepared = await runIfActive(signal, ops.prepareConfiguration, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.action(moneyExecutionContract.prepareInvitationConfiguration, copyInvocationObservation(controls, { input: {
15998
+ commandId,
15999
+ signerAddress
16000
+ } }))), controls), deps.runPromise);
16001
+ if (!prepared.ok) return prepared;
16002
+ const expectedSafe = deriveCapxulSafeAddress({ email: session.email });
16003
+ if (!preparedAuthorityMatches({
16004
+ prepared: prepared.value,
16005
+ chainId: deps.chainId,
16006
+ signerAddress,
16007
+ expectedSafe,
16008
+ commandId,
16009
+ invitationId: view.id,
16010
+ orgId
16011
+ })) return {
16012
+ ok: false,
16013
+ error: Errors.invalidInput("invitation", "prepared authority mismatch")
16014
+ };
16015
+ verifiedOrganization(prepared.value.orgId);
16016
+ if (isAborted$1(signal)) return {
16017
+ ok: false,
16018
+ error: Errors.cancelled({ operation: ops.authorize })
16019
+ };
16020
+ if (onPrepared !== void 0) try {
16021
+ await onPrepared({
16022
+ invitationId: prepared.value.invitationId,
16023
+ commandId: prepared.value.commandId
16024
+ });
16025
+ } catch (cause) {
16026
+ return {
16027
+ ok: false,
16028
+ error: cause instanceof CapxulError ? cause : Errors.unknown(cause)
16029
+ };
16030
+ }
16031
+ if (isAborted$1(signal)) return {
16032
+ ok: false,
16033
+ error: Errors.cancelled({ operation: ops.authorize })
16034
+ };
16035
+ let signature;
16036
+ try {
16037
+ signature = await deps.signer.signUserOpHash(prepared.value.digest);
16038
+ } catch (cause) {
16039
+ return {
16040
+ ok: false,
16041
+ error: signerFailure(deps.signer.source, "signUserOpHash", cause)
16042
+ };
16043
+ }
16044
+ if (isAborted$1(signal)) return {
16045
+ ok: false,
16046
+ error: Errors.cancelled({ operation: ops.authorize })
16047
+ };
16048
+ const submitted = await runIfActive(void 0, ops.submitConfiguration, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.action(moneyExecutionContract.submitInvitationConfigurationExecution, copyInvocationObservation(controls, { input: {
16049
+ executionId: prepared.value.executionId,
16050
+ signature
16051
+ } }))), controls), deps.runPromise);
16052
+ if (!submitted.ok) return submitted;
16053
+ return {
16054
+ ok: true,
16055
+ value: view
16056
+ };
16057
+ }
16058
+ /**
16059
+ * The prepared authority must be exactly the one this write asked for: the same
16060
+ * chain, the caller's signer, this Account's Safe, and the exact command and
16061
+ * invitation the authoring view named.
16062
+ */
16063
+ function preparedAuthorityMatches(input) {
16064
+ return input.prepared.chainId === input.chainId && input.prepared.signerAddress.toLowerCase() === input.signerAddress.toLowerCase() && input.prepared.userOpSenderSafe.toLowerCase() === input.expectedSafe.toLowerCase() && input.prepared.commandId === input.commandId && input.prepared.invitationId === input.invitationId && input.prepared.orgId === input.orgId;
16065
+ }
16066
+ function makeInviteMethod(deps, orgId) {
16067
+ return (input, options) => {
16068
+ const { onPrepared, ...supplied } = options ?? {};
16069
+ const controls = deps.invocationControls?.(supplied) ?? supplied;
16070
+ let verifiedOrganizationId;
16071
+ return runCapxulEffect(Effect.gen(function* () {
16072
+ if (controls?.signal?.aborted === true) return yield* Effect.fail(Errors.cancelled({ operation: ops.authorize }));
16073
+ const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
16074
+ const captured = carryInvocationParentSpan(controls, parent);
16075
+ const result = yield* Effect.tryPromise({
16076
+ try: () => executeInvite(deps, orgId, input, controls?.signal, captured, (id) => {
16077
+ verifiedOrganizationId = id;
16078
+ }, onPrepared),
16079
+ catch: (cause) => cause instanceof CapxulError ? cause : Errors.unknown(cause)
16080
+ });
16081
+ return yield* result.ok ? Effect.succeed(result.value) : Effect.fail(result.error);
16082
+ }).pipe(Effect.ensuring(Effect.suspend(() => verifiedOrganizationId === void 0 ? Effect.void : Effect.annotateCurrentSpan({
16083
+ verified_organization_id: verifiedOrganizationId,
16084
+ scope_kind: "organization"
16085
+ })).pipe(Effect.catchCause(() => Effect.void)))), observationOnlyControls(controls), ops.authorize, deps.runPromise);
16086
+ };
16087
+ }
16088
+ /** Drop the page fields the caller did not supply; a bounded page sends only its bounds. */
16089
+ function pageArgs(input) {
16090
+ if (input === void 0) return {};
16091
+ return {
16092
+ ...input.cursor === void 0 ? {} : { cursor: input.cursor },
16093
+ ...input.limit === void 0 ? {} : { limit: input.limit },
16094
+ ...input.phases === void 0 ? {} : { phases: input.phases }
16095
+ };
16096
+ }
16097
+ function makeOwnInvitationsMethod(deps) {
16098
+ return (input, options) => observed$1(deps, ops.list, options, pageArgs(input), (args) => deps.convexCall.query(invitationContract.listMine, args));
16099
+ }
16100
+ //#endregion
15484
16101
  //#region src/contract/permission.ts
15485
16102
  const permissionContract = { read: makeFunctionReference(CAPXUL_FUNCTIONS["permission/queries"].read) };
15486
16103
  //#endregion
@@ -16168,20 +16785,6 @@ function hermeticOrgView(input) {
16168
16785
  observedAt: 0
16169
16786
  };
16170
16787
  }
16171
- function hermeticMember(input) {
16172
- return {
16173
- orgId: input.orgId,
16174
- accountId: null,
16175
- email: toEmail(input.email),
16176
- name: null,
16177
- personalSafeAddress: input.personalSafeAddress ?? null,
16178
- role: input.role,
16179
- roleKey: toRoleKey(orgRoleKeyForLabel(input.role)),
16180
- status: input.status,
16181
- grantTxHash: input.grantTxHash ?? null,
16182
- revokeTxHash: input.revokeTxHash ?? null
16183
- };
16184
- }
16185
16788
  function createOrgProgram(input) {
16186
16789
  return Effect.gen(function* () {
16187
16790
  const deps = yield* OrgDepsTag;
@@ -16282,35 +16885,6 @@ function listMembersProgram(orgId) {
16282
16885
  return [];
16283
16886
  });
16284
16887
  }
16285
- /**
16286
- * R06 (#1964): the SDK no longer emits `org_invite_sent`. The backend action
16287
- * that writes the invitation is its ONE producer, so a hermetic call — which
16288
- * writes nothing — can no longer report an invitation that never happened, and
16289
- * a live call is counted once instead of twice. The captured attempt rides the
16290
- * port input, so the durable event carries the correlation this call ran under.
16291
- */
16292
- function inviteMemberProgram(orgId, input) {
16293
- return Effect.gen(function* () {
16294
- const deps = yield* OrgDepsTag;
16295
- if (deps.orgPort === void 0) return hermeticMember({
16296
- orgId,
16297
- email: input.email,
16298
- role: input.role,
16299
- status: "pending"
16300
- });
16301
- return yield* deps.orgPort.inviteMember(copyInvocationObservation(deps.invocationSource, {
16302
- orgId,
16303
- input
16304
- })).pipe(Effect.mapError((error) => error.publicError));
16305
- });
16306
- }
16307
- function detectAndAcceptPendingInvitationsProgram() {
16308
- return Effect.gen(function* () {
16309
- const deps = yield* OrgDepsTag;
16310
- if (deps.orgPort !== void 0) return yield* deps.orgPort.detectAndAcceptPendingInvitations({}).pipe(Effect.mapError((error) => error.publicError));
16311
- return { matched: [] };
16312
- });
16313
- }
16314
16888
  function listOrgsProgram() {
16315
16889
  return Effect.gen(function* () {
16316
16890
  const deps = yield* OrgDepsTag;
@@ -16416,6 +16990,20 @@ function observedRunnerDeps(deps) {
16416
16990
  ...deps.invocationControls === void 0 ? {} : { invocationControls: deps.invocationControls }
16417
16991
  };
16418
16992
  }
16993
+ /**
16994
+ * The invitation edge needs the call seam, the observed-runner pair, and — for
16995
+ * the authoring write's configuration hop — the same execution composition the
16996
+ * Permission, payment, and payroll bundles receive.
16997
+ */
16998
+ function invitationMethodsDeps(deps, convexCall) {
16999
+ return {
17000
+ convexCall,
17001
+ ...observedRunnerDeps(deps),
17002
+ ...deps.actor === void 0 ? {} : { actor: deps.actor },
17003
+ ...deps.chainId === void 0 ? {} : { chainId: Number(deps.chainId) },
17004
+ ...deps.signer === void 0 ? {} : { signer: deps.signer }
17005
+ };
17006
+ }
16419
17007
  function makeOrgMethods(deps) {
16420
17008
  const orgDeps = {
16421
17009
  ...deps.orgPort === void 0 ? {} : { orgPort: deps.orgPort },
@@ -16447,13 +17035,10 @@ function makeOrgMethods(deps) {
16447
17035
  });
16448
17036
  return toCapxulResult(createOrgProgram(input), layer);
16449
17037
  },
16450
- orgs: Object.assign((options) => listOrganizations(deps.invocationControls?.(options) ?? options), { detectAndAcceptPendingInvitations(options) {
16451
- if (options?.signal?.aborted) return Promise.resolve({
16452
- ok: false,
16453
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.organizations.detectAndAcceptPendingInvitations })
16454
- });
16455
- return toCapxulResult(detectAndAcceptPendingInvitationsProgram(), layer);
16456
- } }),
17038
+ orgs: Object.assign((options) => listOrganizations(deps.invocationControls?.(options) ?? options), { invitations: deps.convexCall === void 0 ? () => Promise.resolve({
17039
+ ok: false,
17040
+ error: Errors.notImplemented("invitations", "listOwn")
17041
+ }) : makeOwnInvitationsMethod(invitationMethodsDeps(deps, deps.convexCall)) }),
16457
17042
  org(orgId) {
16458
17043
  const convexCall = deps.convexCall;
16459
17044
  return {
@@ -16561,17 +17146,7 @@ function makeOrgMethods(deps) {
16561
17146
  });
16562
17147
  return toCapxulResult(listRolesProgram(orgId), layer);
16563
17148
  },
16564
- invite(_input, _options) {
16565
- const controls = deps.invocationControls?.(_options) ?? _options;
16566
- if (controls?.signal?.aborted) return Promise.resolve({
16567
- ok: false,
16568
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.org.invite })
16569
- });
16570
- return runCapxulEffect(inviteMemberProgram(orgId, _input).pipe(Effect.provide(orgDepsLayer({
16571
- ...orgDeps,
16572
- ...controls === void 0 ? {} : { invocationSource: controls }
16573
- }))), controls, CAPXUL_OPERATIONS.org.invite, deps.runPromise);
16574
- },
17149
+ invitations: convexCall === void 0 ? makeNotImplementedInvitationMethods() : makeOrgInvitationMethods(invitationMethodsDeps(deps, convexCall), String(orgId)),
16575
17150
  auditLog(_options) {
16576
17151
  if (_options?.signal?.aborted) return Promise.resolve({
16577
17152
  ok: false,
@@ -16634,6 +17209,28 @@ const orgMeUnavailable = () => Promise.resolve({
16634
17209
  ok: false,
16635
17210
  error: Errors.notImplemented("org", "me")
16636
17211
  });
17212
+ /**
17213
+ * The closed invitation surface for a client with no backend seam. It reports
17214
+ * `NOT_IMPLEMENTED` for every method rather than an empty list or a fabricated
17215
+ * view: an absent composition root is not an absent invitation.
17216
+ */
17217
+ function makeNotImplementedInvitationMethods() {
17218
+ return {
17219
+ preview: invitationExecutionUnavailable,
17220
+ invite: invitationExecutionUnavailable,
17221
+ accept: invitationExecutionUnavailable,
17222
+ list: invitationExecutionUnavailable,
17223
+ get: invitationExecutionUnavailable,
17224
+ decline: invitationExecutionUnavailable,
17225
+ cancel: invitationExecutionUnavailable,
17226
+ resend: invitationExecutionUnavailable,
17227
+ retry: invitationExecutionUnavailable
17228
+ };
17229
+ }
17230
+ const invitationExecutionUnavailable = () => Promise.resolve({
17231
+ ok: false,
17232
+ error: Errors.notImplemented("invitations", "executionComposition")
17233
+ });
16637
17234
  const permissionExecutionUnavailable = () => Promise.resolve({
16638
17235
  ok: false,
16639
17236
  error: Errors.notImplemented("permissions", "executionComposition")
@@ -17025,7 +17622,6 @@ function assembleCapxulClient(input) {
17025
17622
  };
17026
17623
  if (input.signal !== void 0) input.signal.addEventListener("abort", () => void stopActor(), { once: true });
17027
17624
  const selectedOrgPort = input.orgPort ?? input.orgDeploymentPort;
17028
- let detectPendingOrgInvitations;
17029
17625
  let kickProvisioning;
17030
17626
  const financialOps = makeFinancialOpsMethods({
17031
17627
  runPromise: effectRunner.runPromise,
@@ -17074,7 +17670,6 @@ function assembleCapxulClient(input) {
17074
17670
  if (browserSigner.statusStore?.status() === "unknown" && typeof browserSigner.ensureWalletReady === "function") browserSigner.ensureWalletReady().catch(() => {});
17075
17671
  }
17076
17672
  if (accountSetup === "explicit") return;
17077
- await detectPendingOrgInvitations?.();
17078
17673
  kickProvisioning?.();
17079
17674
  }
17080
17675
  });
@@ -17142,9 +17737,6 @@ function assembleCapxulClient(input) {
17142
17737
  ...input.signer === void 0 ? {} : { signer: input.signer },
17143
17738
  ...input.organizationSetup === void 0 ? {} : { organizationSetup: input.organizationSetup }
17144
17739
  });
17145
- if (selectedOrgPort !== void 0) detectPendingOrgInvitations = async () => {
17146
- await orgMethods.orgs.detectAndAcceptPendingInvitations();
17147
- };
17148
17740
  const currentUser = makeCurrentUserMethods({
17149
17741
  me: financialOps.me,
17150
17742
  accounts,
@@ -18316,11 +18908,11 @@ async function createCapxulClientWithSignerControls(input, controls) {
18316
18908
  accountSetup: input.accountSetup,
18317
18909
  ...signer === void 0 ? {} : { signer },
18318
18910
  orgPort: Context.get(adapters.value.context, OrgPortTag),
18319
- ...signer === void 0 ? {} : { organizationSetup: new ConvexOrganizationSetupAdapter({
18911
+ organizationSetup: new ConvexOrganizationSetupAdapter({
18320
18912
  convex: adapters.value.ports.convexCall,
18321
- signer,
18913
+ ...signer === void 0 ? {} : { signer },
18322
18914
  chainId: adapters.value.bootstrap.chainId
18323
- }) },
18915
+ }),
18324
18916
  ...input.signal === void 0 ? {} : { signal: input.signal },
18325
18917
  ...input.otpTtlMs === void 0 ? {} : { otpTtlMs: input.otpTtlMs },
18326
18918
  invokeTimeoutMs: input.invokeTimeoutMs ?? 3e4,