@capxul/sdk 4.20.0-beta.6 → 4.20.0-beta.8
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.
- package/dist/{OAuthBearerAuthClient-B7Nbepmu.d.mts → OAuthBearerAuthClient-DOPDDSPs.d.mts} +3 -1
- package/dist/{OAuthBearerAuthClient-5ujCTtKE.mjs → OAuthBearerAuthClient-DdKYPHE0.mjs} +23 -9
- package/dist/index.d.mts +42 -11
- package/dist/index.mjs +3 -3
- package/dist/node/index.d.mts +1 -1
- package/dist/node/index.mjs +1 -1
- package/dist/{production-pLe7MsUo.d.mts → production-CDJHj_pg.d.mts} +553 -49
- package/dist/{production-B4NzzuUb.mjs → production-DI1pfsy1.mjs} +746 -122
- package/dist/testing/index.d.mts +2 -2
- package/dist/testing/index.mjs +2 -2
- package/package.json +4 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
@@ -5856,6 +6219,18 @@ function withInvocationParentSpan(effect, controls) {
|
|
|
5856
6219
|
const parent = controls?.[INVOCATION_PARENT_SPAN];
|
|
5857
6220
|
return parent === void 0 ? effect : effect.pipe(Effect.withParentSpan(parent));
|
|
5858
6221
|
}
|
|
6222
|
+
/**
|
|
6223
|
+
* The input field a refused request named.
|
|
6224
|
+
*
|
|
6225
|
+
* The surfaces that call the port directly already carry `details.field` for an
|
|
6226
|
+
* `INVALID_INPUT` refusal. The actor keeps that one allowlisted detail instead of
|
|
6227
|
+
* dropping it, so a caller sees the same refusal either way.
|
|
6228
|
+
*/
|
|
6229
|
+
const refusedInputField = (failure) => {
|
|
6230
|
+
if (failure.code !== "INVALID_INPUT") return void 0;
|
|
6231
|
+
const field = failure.error?.details?.field;
|
|
6232
|
+
return typeof field === "string" && field.length > 0 ? { field } : void 0;
|
|
6233
|
+
};
|
|
5859
6234
|
var ActorFailure = class extends Error {
|
|
5860
6235
|
reason;
|
|
5861
6236
|
machine;
|
|
@@ -6021,7 +6396,7 @@ const boot = (spec, options = {}) => Effect.gen(function* () {
|
|
|
6021
6396
|
const event = { _tag: env.origin.event };
|
|
6022
6397
|
const failedState = exit.failure === timeoutFailure || exit.failure === cancelledFailure ? yield* recoverFailure(state, env.origin, exit.failure) : state;
|
|
6023
6398
|
yield* emit(nonApplied(failedState, event, exit.failure.code, outcome, env, exit.failure));
|
|
6024
|
-
const details = exit.failure === timeoutFailure ? { reason: "timeout" } :
|
|
6399
|
+
const details = exit.failure === timeoutFailure ? { reason: "timeout" } : refusedInputField(exit.failure);
|
|
6025
6400
|
yield* failReply(held.reply, makeFailure(failedState, event, exit.failure.code, details, exit.failure.error ?? exit.failure));
|
|
6026
6401
|
return;
|
|
6027
6402
|
}
|
|
@@ -7148,11 +7523,13 @@ const financialOpsContract = {
|
|
|
7148
7523
|
//#region src/contract/money-execution.ts
|
|
7149
7524
|
const moneyExecutionContract = {
|
|
7150
7525
|
abandonPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].abandonPaymentExecution),
|
|
7526
|
+
prepareInvitationConfiguration: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].prepareInvitationConfiguration),
|
|
7151
7527
|
preparePermissionExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].preparePermissionExecution),
|
|
7152
7528
|
preparePaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].preparePaymentExecution),
|
|
7153
7529
|
prepareOrganizationPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/paymentCommandActions"].prepareOrganizationPaymentExecution),
|
|
7154
7530
|
preparePaymentLifecycleExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/paymentCommandActions"].preparePaymentLifecycleExecution),
|
|
7155
7531
|
submitPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].submitPaymentExecution),
|
|
7532
|
+
submitInvitationConfigurationExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].submitInvitationConfigurationExecution),
|
|
7156
7533
|
submitPermissionExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].submitPermissionExecution),
|
|
7157
7534
|
submitPaymentCommandExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/paymentCommandActions"].submitPaymentCommandExecution)
|
|
7158
7535
|
};
|
|
@@ -7733,7 +8110,7 @@ function subscribeActivity(deps, actor, controls, onChange) {
|
|
|
7733
8110
|
}
|
|
7734
8111
|
//#endregion
|
|
7735
8112
|
//#region package.json
|
|
7736
|
-
var version = "4.20.0-beta.
|
|
8113
|
+
var version = "4.20.0-beta.8";
|
|
7737
8114
|
//#endregion
|
|
7738
8115
|
//#region src/telemetry/exception-projection.ts
|
|
7739
8116
|
/** Fixed fallback for failures that have no safe message. */
|
|
@@ -8569,7 +8946,7 @@ function isMoneyTelemetryDebugEnabled() {
|
|
|
8569
8946
|
}
|
|
8570
8947
|
//#endregion
|
|
8571
8948
|
//#region src/surface/payment-command-execution.ts
|
|
8572
|
-
function isAborted$
|
|
8949
|
+
function isAborted$3(signal) {
|
|
8573
8950
|
return signal?.aborted === true;
|
|
8574
8951
|
}
|
|
8575
8952
|
function canonicalJson(value) {
|
|
@@ -8595,7 +8972,7 @@ async function abandonPrepared$1(deps, executionId, closePayment, reason, result
|
|
|
8595
8972
|
return result;
|
|
8596
8973
|
}
|
|
8597
8974
|
async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnExit, onPreparedClosed, signal, controls) {
|
|
8598
|
-
if (isAborted$
|
|
8975
|
+
if (isAborted$3(signal)) return {
|
|
8599
8976
|
ok: false,
|
|
8600
8977
|
error: Errors.cancelled({ operation: "payments" })
|
|
8601
8978
|
};
|
|
@@ -8624,7 +9001,7 @@ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnE
|
|
|
8624
9001
|
ok: false,
|
|
8625
9002
|
error: Errors.invalidInput("payment", "prepared authority mismatch")
|
|
8626
9003
|
}, onPreparedClosed, controls);
|
|
8627
|
-
if (isAborted$
|
|
9004
|
+
if (isAborted$3(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
|
|
8628
9005
|
ok: false,
|
|
8629
9006
|
error: Errors.cancelled({ operation: "payments" })
|
|
8630
9007
|
}, onPreparedClosed, controls);
|
|
@@ -8650,7 +9027,7 @@ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnE
|
|
|
8650
9027
|
error: signerFailure(deps.signer.source, "signUserOpHash", cause)
|
|
8651
9028
|
}, onPreparedClosed, controls);
|
|
8652
9029
|
}
|
|
8653
|
-
if (isAborted$
|
|
9030
|
+
if (isAborted$3(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
|
|
8654
9031
|
ok: false,
|
|
8655
9032
|
error: Errors.cancelled({ operation: "payments" })
|
|
8656
9033
|
}, onPreparedClosed, controls);
|
|
@@ -8685,7 +9062,7 @@ function cancelled(operation) {
|
|
|
8685
9062
|
error: Errors.cancelled({ operation })
|
|
8686
9063
|
};
|
|
8687
9064
|
}
|
|
8688
|
-
function isAborted$
|
|
9065
|
+
function isAborted$2(signal) {
|
|
8689
9066
|
return signal?.aborted === true;
|
|
8690
9067
|
}
|
|
8691
9068
|
async function signerCall(source, operation, run) {
|
|
@@ -8711,7 +9088,7 @@ async function abandonPrepared(deps, executionId, reason, result, onPreparedClos
|
|
|
8711
9088
|
return result;
|
|
8712
9089
|
}
|
|
8713
9090
|
async function executePersonalPayment(deps, payment, signal, requestKey, onPreparedClosed) {
|
|
8714
|
-
if (isAborted$
|
|
9091
|
+
if (isAborted$2(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
|
|
8715
9092
|
if (deps.signer === void 0) return mismatch("signer", "payments.pay requires a configured CapxulSigner");
|
|
8716
9093
|
const session = deps.actor.authSession();
|
|
8717
9094
|
if (session === null) return {
|
|
@@ -8739,10 +9116,10 @@ async function executePersonalPayment(deps, payment, signal, requestKey, onPrepa
|
|
|
8739
9116
|
executionId: prepared.value.executionId,
|
|
8740
9117
|
recipient: prepared.value.recipientObservation
|
|
8741
9118
|
});
|
|
8742
|
-
if (isAborted$
|
|
9119
|
+
if (isAborted$2(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
|
|
8743
9120
|
const signature = await signerCall(deps.signer.source, "signUserOpHash", () => deps.signer.signUserOpHash(prepared.value.digest));
|
|
8744
9121
|
if (!signature.ok) return abandonPrepared(deps, prepared.value.executionId, "signer_rejected", signature, onPreparedClosed);
|
|
8745
|
-
if (isAborted$
|
|
9122
|
+
if (isAborted$2(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
|
|
8746
9123
|
return runIfActive(void 0, CAPXUL_OPERATIONS.payments.submitExecution, () => deps.convexCall.action(deps.functions.submitPaymentExecution, { input: {
|
|
8747
9124
|
executionId: prepared.value.executionId,
|
|
8748
9125
|
signature: signature.value
|
|
@@ -11314,6 +11691,7 @@ function mapBetterAuthError(operation, body) {
|
|
|
11314
11691
|
const code = typeof errBody.code === "string" ? errBody.code : "";
|
|
11315
11692
|
if (code === "OTP_EXPIRED") return Errors.otpExpired();
|
|
11316
11693
|
if (code === "INVALID_OTP") return Errors.invalidInput("otp", errBody.message ?? "invalid OTP");
|
|
11694
|
+
if (code === "TOO_MANY_ATTEMPTS") return Errors.rateLimited({ resource: "better-auth/verifyOtp" });
|
|
11317
11695
|
if (code === "VALIDATION_ERROR" || code === "INVALID_EMAIL") return Errors.invalidInput("email", errBody.message ?? "invalid email");
|
|
11318
11696
|
}
|
|
11319
11697
|
return Errors.providerError("better-auth", operation, new Error(String(body)));
|
|
@@ -11931,6 +12309,10 @@ var BetterAuthNodeAdapter = class {
|
|
|
11931
12309
|
ok: false,
|
|
11932
12310
|
error: Errors.invalidInput("otp", errBody.message ?? "invalid OTP")
|
|
11933
12311
|
};
|
|
12312
|
+
if (errBody.code === "TOO_MANY_ATTEMPTS") return {
|
|
12313
|
+
ok: false,
|
|
12314
|
+
error: Errors.rateLimited({ resource: "better-auth/verifyOtp" })
|
|
12315
|
+
};
|
|
11934
12316
|
}
|
|
11935
12317
|
}
|
|
11936
12318
|
return {
|
|
@@ -12490,6 +12872,12 @@ const stderrConvexLogger = {
|
|
|
12490
12872
|
error: writeConvexDiagnostic,
|
|
12491
12873
|
logVerbose: () => void 0
|
|
12492
12874
|
};
|
|
12875
|
+
const silentConvexLogger = {
|
|
12876
|
+
log: () => void 0,
|
|
12877
|
+
warn: () => void 0,
|
|
12878
|
+
error: () => void 0,
|
|
12879
|
+
logVerbose: () => void 0
|
|
12880
|
+
};
|
|
12493
12881
|
/** Exact floor-first allowlist; every additional handler must migrate its validator first. */
|
|
12494
12882
|
const OBSERVED_CONVEX_ACTIONS = /* @__PURE__ */ new Set([
|
|
12495
12883
|
"system:healthObserved",
|
|
@@ -12561,7 +12949,9 @@ const OBSERVED_CONVEX_MUTATIONS = /* @__PURE__ */ new Set([
|
|
|
12561
12949
|
"smartAccount/mutations:provision",
|
|
12562
12950
|
"org/lifecycle:startOrResume",
|
|
12563
12951
|
"org/lifecycle:recordFailure",
|
|
12564
|
-
"org/lifecycle:retry"
|
|
12952
|
+
"org/lifecycle:retry",
|
|
12953
|
+
"org/mutations:invite",
|
|
12954
|
+
"org/mutations:accept"
|
|
12565
12955
|
]);
|
|
12566
12956
|
var ConvexCallAdapter = class {
|
|
12567
12957
|
#client;
|
|
@@ -12576,7 +12966,7 @@ var ConvexCallAdapter = class {
|
|
|
12576
12966
|
const webSocketConstructor = this.#connectionMonitor.observedWebSocketConstructor();
|
|
12577
12967
|
this.#client = deps.client ?? new ConvexClient(deps.convexUrl, {
|
|
12578
12968
|
...webSocketConstructor === void 0 ? {} : { webSocketConstructor },
|
|
12579
|
-
|
|
12969
|
+
logger: deps.localDiagnostics === true ? stderrConvexLogger : silentConvexLogger
|
|
12580
12970
|
});
|
|
12581
12971
|
this.#tokenProvider = deps.tokenProvider;
|
|
12582
12972
|
this.#applicationId = deps.applicationId;
|
|
@@ -13234,10 +13624,7 @@ const DEFAULT_FUNCTIONS$1 = {
|
|
|
13234
13624
|
listAll: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].listAll),
|
|
13235
13625
|
listRoles: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].listRolesByOrgId),
|
|
13236
13626
|
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)
|
|
13627
|
+
readTreasury: makeFunctionReference(CAPXUL_FUNCTIONS["org/actions"].readTreasury)
|
|
13241
13628
|
};
|
|
13242
13629
|
/**
|
|
13243
13630
|
* Standard production Organization read adapter. It intentionally has no
|
|
@@ -13273,22 +13660,6 @@ var ConvexOrganizationAdapter = class {
|
|
|
13273
13660
|
pendingMembers(input) {
|
|
13274
13661
|
return this.listMembers(input).pipe(Effect.map((members) => members.filter((member) => member.status === "pending" || member.status === "pending_safe" || member.status === "pending_grant")));
|
|
13275
13662
|
}
|
|
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
13663
|
#readTreasuryWire(input) {
|
|
13293
13664
|
const orgId = String(input.orgId);
|
|
13294
13665
|
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 +13704,12 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
13333
13704
|
#fns;
|
|
13334
13705
|
constructor(input) {
|
|
13335
13706
|
this.#convex = input.convex;
|
|
13336
|
-
this.#signer = input.signer;
|
|
13707
|
+
this.#signer = input.signer ?? null;
|
|
13337
13708
|
this.#chainId = input.chainId;
|
|
13338
13709
|
this.#fns = input.functions ?? DEFAULT_FUNCTIONS;
|
|
13339
13710
|
}
|
|
13340
13711
|
async startOrResume(input) {
|
|
13712
|
+
if (this.#signer === null) return fail$1(Errors.capabilityUnavailable("signer", "startOrResume"));
|
|
13341
13713
|
const result = await runCall("startOrResume", this.#convex.mutation(this.#fns.startOrResume, copyInvocationObservation(input, {
|
|
13342
13714
|
...input,
|
|
13343
13715
|
chainId: this.#chainId
|
|
@@ -13365,7 +13737,9 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
13365
13737
|
async authorizeAndSubmitBootstrap(input) {
|
|
13366
13738
|
const cancelled = cancellation(input.signal);
|
|
13367
13739
|
if (cancelled !== void 0) return cancelled;
|
|
13368
|
-
const
|
|
13740
|
+
const signer = this.#signer;
|
|
13741
|
+
if (signer === null) return fail$1(Errors.capabilityUnavailable("signer", "authorizeAndSubmitBootstrap"));
|
|
13742
|
+
const signerAddress = await signerResult(signer.source, "getAddress", () => signer.getAddress());
|
|
13369
13743
|
if (!signerAddress.ok) return signerAddress;
|
|
13370
13744
|
const prepared = await runCall("prepareBootstrap", this.#convex.action(this.#fns.prepareBootstrap, copyInvocationObservation(input, {
|
|
13371
13745
|
orgId: input.orgId,
|
|
@@ -13377,7 +13751,7 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
13377
13751
|
if (!authority.ok) return authority;
|
|
13378
13752
|
const cancelledAfterPrepare = cancellation(input.signal);
|
|
13379
13753
|
if (cancelledAfterPrepare !== void 0) return cancelledAfterPrepare;
|
|
13380
|
-
const signature = await signerResult(
|
|
13754
|
+
const signature = await signerResult(signer.source, "signUserOpHash", () => signer.signUserOpHash(prepared.value.digest));
|
|
13381
13755
|
if (!signature.ok) return signature;
|
|
13382
13756
|
const cancelledAfterSign = cancellation(input.signal);
|
|
13383
13757
|
if (cancelledAfterSign !== void 0) return cancelledAfterSign;
|
|
@@ -13433,7 +13807,8 @@ var ConvexOrganizationSetupAdapter = class {
|
|
|
13433
13807
|
...input.observationContext === void 0 ? {} : { observationContext: input.observationContext }
|
|
13434
13808
|
});
|
|
13435
13809
|
if (!current.ok) return current;
|
|
13436
|
-
if (current.value.status === "failed" && current.value.retryable &&
|
|
13810
|
+
if (current.value.status === "failed" && current.value.retryable && current.value.at === "awaitingFounderAuthorization") {
|
|
13811
|
+
if (this.#signer === null) return fail$1(Errors.capabilityUnavailable("signer", "retry"));
|
|
13437
13812
|
const reset = resetSignerSession(this.#signer);
|
|
13438
13813
|
if (!reset.ok) return reset;
|
|
13439
13814
|
}
|
|
@@ -15481,6 +15856,271 @@ function makeOrgMeMethod(deps, orgId) {
|
|
|
15481
15856
|
};
|
|
15482
15857
|
}
|
|
15483
15858
|
//#endregion
|
|
15859
|
+
//#region src/contract/invitations.ts
|
|
15860
|
+
const invitationContract = {
|
|
15861
|
+
preview: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].previewInvite),
|
|
15862
|
+
listMine: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].listMyInvitations),
|
|
15863
|
+
listScoped: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].listInvitations),
|
|
15864
|
+
get: makeFunctionReference(CAPXUL_FUNCTIONS["org/queries"].getInvitation),
|
|
15865
|
+
invite: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].invite),
|
|
15866
|
+
accept: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].accept),
|
|
15867
|
+
decline: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].decline),
|
|
15868
|
+
cancel: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].cancel),
|
|
15869
|
+
resend: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].resend),
|
|
15870
|
+
retry: makeFunctionReference(CAPXUL_FUNCTIONS["org/mutations"].retry)
|
|
15871
|
+
};
|
|
15872
|
+
//#endregion
|
|
15873
|
+
//#region src/surface/invitations.ts
|
|
15874
|
+
/**
|
|
15875
|
+
* The one refusal a scoped invitation result that names another Organization
|
|
15876
|
+
* receives, whether it was read or returned by the authoring write.
|
|
15877
|
+
*/
|
|
15878
|
+
function scopeRefusal(orgId) {
|
|
15879
|
+
return Errors.invalidInput("orgId", `The invitation result does not belong to Organization ${JSON.stringify(orgId)}.`);
|
|
15880
|
+
}
|
|
15881
|
+
/**
|
|
15882
|
+
* A scoped invitation result belongs to the Organization it was read under.
|
|
15883
|
+
*
|
|
15884
|
+
* One owner holds the refusal copy and the verified-scope span: a single view
|
|
15885
|
+
* reports whether it names the scope, and a page — which names no Organization
|
|
15886
|
+
* of its own — reports whether every row does. A result that does not belong is
|
|
15887
|
+
* refused here rather than handed to a consumer, so a future route change
|
|
15888
|
+
* cannot turn into a silent cross-Organization read on a caller that trusted
|
|
15889
|
+
* the scope it passed. A successful scoped read also marks the verifying
|
|
15890
|
+
* Organization on the owning span, exactly as `org.me` does — the caller's
|
|
15891
|
+
* scope hint is not authority, the completed scoped read is.
|
|
15892
|
+
*/
|
|
15893
|
+
function verifyScope(orgId, value, belongsToScope) {
|
|
15894
|
+
if (!belongsToScope(value)) return Effect.fail(scopeRefusal(orgId));
|
|
15895
|
+
return Effect.annotateCurrentSpan({
|
|
15896
|
+
verified_organization_id: orgId,
|
|
15897
|
+
scope_kind: "organization"
|
|
15898
|
+
}).pipe(Effect.as(value));
|
|
15899
|
+
}
|
|
15900
|
+
/** One view names its own Organization. */
|
|
15901
|
+
const namesScope = (orgId) => (value) => String(value.orgId) === orgId;
|
|
15902
|
+
/** A page names no Organization of its own, so every row must name the scope. */
|
|
15903
|
+
const rowsNameScope = (orgId) => (page) => page.items.every((item) => String(item.orgId) === orgId);
|
|
15904
|
+
const ops = CAPXUL_OPERATIONS.org.invitations;
|
|
15905
|
+
/** Truth for a caller-owned signal, without narrowing its type. */
|
|
15906
|
+
function isAborted$1(signal) {
|
|
15907
|
+
return signal?.aborted === true;
|
|
15908
|
+
}
|
|
15909
|
+
/**
|
|
15910
|
+
* One observed operation around one Convex hop, exactly like `org.me`. The
|
|
15911
|
+
* call-start invocation snapshot rides the arguments, so the backend continues
|
|
15912
|
+
* the attempt this call started rather than resolving a new one.
|
|
15913
|
+
*/
|
|
15914
|
+
function observed$1(deps, operation, options, args, call, check) {
|
|
15915
|
+
const controls = deps.invocationControls?.(options) ?? options;
|
|
15916
|
+
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);
|
|
15917
|
+
}
|
|
15918
|
+
/**
|
|
15919
|
+
* The Admin's preview stays a read: it reaches the preview query and nothing
|
|
15920
|
+
* else. It reads current policies and live assignments, so the operator sees
|
|
15921
|
+
* what the offered authority is now, not a frozen copy.
|
|
15922
|
+
*/
|
|
15923
|
+
function makeOrgInvitationMethods(deps, orgId) {
|
|
15924
|
+
const scopeCheck = (value) => verifyScope(orgId, value, namesScope(orgId));
|
|
15925
|
+
return {
|
|
15926
|
+
preview: (input, options) => observed$1(deps, ops.preview, options, {
|
|
15927
|
+
orgId,
|
|
15928
|
+
request: input
|
|
15929
|
+
}, (args) => deps.convexCall.query(invitationContract.preview, args), scopeCheck),
|
|
15930
|
+
invite: makeInviteMethod(deps, orgId),
|
|
15931
|
+
accept: (input, options) => observed$1(deps, ops.accept, options, {
|
|
15932
|
+
orgId,
|
|
15933
|
+
invitationId: input.invitationId,
|
|
15934
|
+
expectedOfferDigest: input.expectedOfferDigest
|
|
15935
|
+
}, (args) => deps.convexCall.mutation(invitationContract.accept, args), scopeCheck),
|
|
15936
|
+
list: (input, options) => observed$1(deps, ops.listScoped, options, {
|
|
15937
|
+
orgId,
|
|
15938
|
+
...pageArgs(input)
|
|
15939
|
+
}, (args) => deps.convexCall.query(invitationContract.listScoped, args), (page) => verifyScope(orgId, page, rowsNameScope(orgId))),
|
|
15940
|
+
get: (input, options) => observed$1(deps, ops.get, options, {
|
|
15941
|
+
orgId,
|
|
15942
|
+
invitationId: input.invitationId
|
|
15943
|
+
}, (args) => deps.convexCall.query(invitationContract.get, args), scopeCheck),
|
|
15944
|
+
decline: (input, options) => observed$1(deps, ops.decline, options, {
|
|
15945
|
+
orgId,
|
|
15946
|
+
invitationId: input.invitationId
|
|
15947
|
+
}, (args) => deps.convexCall.mutation(invitationContract.decline, args), scopeCheck),
|
|
15948
|
+
cancel: (input, options) => observed$1(deps, ops.cancel, options, {
|
|
15949
|
+
orgId,
|
|
15950
|
+
invitationId: input.invitationId
|
|
15951
|
+
}, (args) => deps.convexCall.mutation(invitationContract.cancel, args), scopeCheck),
|
|
15952
|
+
resend: (input, options) => observed$1(deps, ops.resend, options, {
|
|
15953
|
+
orgId,
|
|
15954
|
+
invitationId: input.invitationId
|
|
15955
|
+
}, (args) => deps.convexCall.mutation(invitationContract.resend, args), scopeCheck),
|
|
15956
|
+
retry: (input, options) => observed$1(deps, ops.retry, options, {
|
|
15957
|
+
orgId,
|
|
15958
|
+
invitationId: input.invitationId
|
|
15959
|
+
}, (args) => deps.convexCall.mutation(invitationContract.retry, args), scopeCheck)
|
|
15960
|
+
};
|
|
15961
|
+
}
|
|
15962
|
+
/**
|
|
15963
|
+
* The authoring write, including its configuration hop.
|
|
15964
|
+
*
|
|
15965
|
+
* The mutation persists the invitation and its configure command before any
|
|
15966
|
+
* signature exists. The write then drives the existing human configuration
|
|
15967
|
+
* owner exactly as the Permission and payment surfaces drive theirs: prepare
|
|
15968
|
+
* the stored command for this Account's Safe, check the prepared authority
|
|
15969
|
+
* against the request, deliver the durable identity to the caller, sign the
|
|
15970
|
+
* returned digest, and submit it. The backend keeps the only authorization
|
|
15971
|
+
* rule (`prepareInvitationConfigurationIntentInTx` /
|
|
15972
|
+
* `submitInvitationConfigurationExecution`); this edge adds no second one.
|
|
15973
|
+
*
|
|
15974
|
+
* Cancellation owns the whole compound: an abort before the digest is signed
|
|
15975
|
+
* stops the write and forwards no signature, and an already-signed submission
|
|
15976
|
+
* completes.
|
|
15977
|
+
*/
|
|
15978
|
+
async function executeInvite(deps, orgId, input, signal, controls, verifiedOrganization, onPrepared) {
|
|
15979
|
+
if (isAborted$1(signal)) return {
|
|
15980
|
+
ok: false,
|
|
15981
|
+
error: Errors.cancelled({ operation: ops.authorize })
|
|
15982
|
+
};
|
|
15983
|
+
if (deps.actor === void 0 || deps.chainId === void 0 || deps.signer === void 0) return {
|
|
15984
|
+
ok: false,
|
|
15985
|
+
error: Errors.notImplemented("invitations", "executionComposition")
|
|
15986
|
+
};
|
|
15987
|
+
const session = deps.actor.authSession();
|
|
15988
|
+
if (session === null) return {
|
|
15989
|
+
ok: false,
|
|
15990
|
+
error: Errors.notAuthenticated()
|
|
15991
|
+
};
|
|
15992
|
+
const authored = await runIfActive(signal, ops.authorize, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.mutation(invitationContract.invite, copyInvocationObservation(controls, {
|
|
15993
|
+
orgId,
|
|
15994
|
+
request: input
|
|
15995
|
+
}))), controls), deps.runPromise);
|
|
15996
|
+
if (!authored.ok) return authored;
|
|
15997
|
+
const view = authored.value;
|
|
15998
|
+
if (String(view.orgId) !== orgId) return {
|
|
15999
|
+
ok: false,
|
|
16000
|
+
error: scopeRefusal(orgId)
|
|
16001
|
+
};
|
|
16002
|
+
if (view.phase !== "authorizing") return {
|
|
16003
|
+
ok: true,
|
|
16004
|
+
value: view
|
|
16005
|
+
};
|
|
16006
|
+
if (view.commandId === null) return {
|
|
16007
|
+
ok: false,
|
|
16008
|
+
error: Errors.invalidInput("invitationId", "The invitation does not name its configuration command.")
|
|
16009
|
+
};
|
|
16010
|
+
const commandId = view.commandId;
|
|
16011
|
+
let signerAddress;
|
|
16012
|
+
try {
|
|
16013
|
+
signerAddress = await deps.signer.getAddress();
|
|
16014
|
+
} catch (cause) {
|
|
16015
|
+
return {
|
|
16016
|
+
ok: false,
|
|
16017
|
+
error: signerFailure(deps.signer.source, "getAddress", cause)
|
|
16018
|
+
};
|
|
16019
|
+
}
|
|
16020
|
+
const prepared = await runIfActive(signal, ops.prepareConfiguration, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.action(moneyExecutionContract.prepareInvitationConfiguration, copyInvocationObservation(controls, { input: {
|
|
16021
|
+
commandId,
|
|
16022
|
+
signerAddress
|
|
16023
|
+
} }))), controls), deps.runPromise);
|
|
16024
|
+
if (!prepared.ok) return prepared;
|
|
16025
|
+
const expectedSafe = deriveCapxulSafeAddress({ email: session.email });
|
|
16026
|
+
if (!preparedAuthorityMatches({
|
|
16027
|
+
prepared: prepared.value,
|
|
16028
|
+
chainId: deps.chainId,
|
|
16029
|
+
signerAddress,
|
|
16030
|
+
expectedSafe,
|
|
16031
|
+
commandId,
|
|
16032
|
+
invitationId: view.id,
|
|
16033
|
+
orgId
|
|
16034
|
+
})) return {
|
|
16035
|
+
ok: false,
|
|
16036
|
+
error: Errors.invalidInput("invitation", "prepared authority mismatch")
|
|
16037
|
+
};
|
|
16038
|
+
verifiedOrganization(prepared.value.orgId);
|
|
16039
|
+
if (isAborted$1(signal)) return {
|
|
16040
|
+
ok: false,
|
|
16041
|
+
error: Errors.cancelled({ operation: ops.authorize })
|
|
16042
|
+
};
|
|
16043
|
+
if (onPrepared !== void 0) try {
|
|
16044
|
+
await onPrepared({
|
|
16045
|
+
invitationId: prepared.value.invitationId,
|
|
16046
|
+
commandId: prepared.value.commandId
|
|
16047
|
+
});
|
|
16048
|
+
} catch (cause) {
|
|
16049
|
+
return {
|
|
16050
|
+
ok: false,
|
|
16051
|
+
error: cause instanceof CapxulError ? cause : Errors.unknown(cause)
|
|
16052
|
+
};
|
|
16053
|
+
}
|
|
16054
|
+
if (isAborted$1(signal)) return {
|
|
16055
|
+
ok: false,
|
|
16056
|
+
error: Errors.cancelled({ operation: ops.authorize })
|
|
16057
|
+
};
|
|
16058
|
+
let signature;
|
|
16059
|
+
try {
|
|
16060
|
+
signature = await deps.signer.signUserOpHash(prepared.value.digest);
|
|
16061
|
+
} catch (cause) {
|
|
16062
|
+
return {
|
|
16063
|
+
ok: false,
|
|
16064
|
+
error: signerFailure(deps.signer.source, "signUserOpHash", cause)
|
|
16065
|
+
};
|
|
16066
|
+
}
|
|
16067
|
+
if (isAborted$1(signal)) return {
|
|
16068
|
+
ok: false,
|
|
16069
|
+
error: Errors.cancelled({ operation: ops.authorize })
|
|
16070
|
+
};
|
|
16071
|
+
const submitted = await runIfActive(void 0, ops.submitConfiguration, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.action(moneyExecutionContract.submitInvitationConfigurationExecution, copyInvocationObservation(controls, { input: {
|
|
16072
|
+
executionId: prepared.value.executionId,
|
|
16073
|
+
signature
|
|
16074
|
+
} }))), controls), deps.runPromise);
|
|
16075
|
+
if (!submitted.ok) return submitted;
|
|
16076
|
+
return {
|
|
16077
|
+
ok: true,
|
|
16078
|
+
value: view
|
|
16079
|
+
};
|
|
16080
|
+
}
|
|
16081
|
+
/**
|
|
16082
|
+
* The prepared authority must be exactly the one this write asked for: the same
|
|
16083
|
+
* chain, the caller's signer, this Account's Safe, and the exact command and
|
|
16084
|
+
* invitation the authoring view named.
|
|
16085
|
+
*/
|
|
16086
|
+
function preparedAuthorityMatches(input) {
|
|
16087
|
+
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;
|
|
16088
|
+
}
|
|
16089
|
+
function makeInviteMethod(deps, orgId) {
|
|
16090
|
+
return (input, options) => {
|
|
16091
|
+
const { onPrepared, ...supplied } = options ?? {};
|
|
16092
|
+
const controls = deps.invocationControls?.(supplied) ?? supplied;
|
|
16093
|
+
let verifiedOrganizationId;
|
|
16094
|
+
return runCapxulEffect(Effect.gen(function* () {
|
|
16095
|
+
if (controls?.signal?.aborted === true) return yield* Effect.fail(Errors.cancelled({ operation: ops.authorize }));
|
|
16096
|
+
const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
|
|
16097
|
+
const captured = carryInvocationParentSpan(controls, parent);
|
|
16098
|
+
const result = yield* Effect.tryPromise({
|
|
16099
|
+
try: () => executeInvite(deps, orgId, input, controls?.signal, captured, (id) => {
|
|
16100
|
+
verifiedOrganizationId = id;
|
|
16101
|
+
}, onPrepared),
|
|
16102
|
+
catch: (cause) => cause instanceof CapxulError ? cause : Errors.unknown(cause)
|
|
16103
|
+
});
|
|
16104
|
+
return yield* result.ok ? Effect.succeed(result.value) : Effect.fail(result.error);
|
|
16105
|
+
}).pipe(Effect.ensuring(Effect.suspend(() => verifiedOrganizationId === void 0 ? Effect.void : Effect.annotateCurrentSpan({
|
|
16106
|
+
verified_organization_id: verifiedOrganizationId,
|
|
16107
|
+
scope_kind: "organization"
|
|
16108
|
+
})).pipe(Effect.catchCause(() => Effect.void)))), observationOnlyControls(controls), ops.authorize, deps.runPromise);
|
|
16109
|
+
};
|
|
16110
|
+
}
|
|
16111
|
+
/** Drop the page fields the caller did not supply; a bounded page sends only its bounds. */
|
|
16112
|
+
function pageArgs(input) {
|
|
16113
|
+
if (input === void 0) return {};
|
|
16114
|
+
return {
|
|
16115
|
+
...input.cursor === void 0 ? {} : { cursor: input.cursor },
|
|
16116
|
+
...input.limit === void 0 ? {} : { limit: input.limit },
|
|
16117
|
+
...input.phases === void 0 ? {} : { phases: input.phases }
|
|
16118
|
+
};
|
|
16119
|
+
}
|
|
16120
|
+
function makeOwnInvitationsMethod(deps) {
|
|
16121
|
+
return (input, options) => observed$1(deps, ops.list, options, pageArgs(input), (args) => deps.convexCall.query(invitationContract.listMine, args));
|
|
16122
|
+
}
|
|
16123
|
+
//#endregion
|
|
15484
16124
|
//#region src/contract/permission.ts
|
|
15485
16125
|
const permissionContract = { read: makeFunctionReference(CAPXUL_FUNCTIONS["permission/queries"].read) };
|
|
15486
16126
|
//#endregion
|
|
@@ -16168,20 +16808,6 @@ function hermeticOrgView(input) {
|
|
|
16168
16808
|
observedAt: 0
|
|
16169
16809
|
};
|
|
16170
16810
|
}
|
|
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
16811
|
function createOrgProgram(input) {
|
|
16186
16812
|
return Effect.gen(function* () {
|
|
16187
16813
|
const deps = yield* OrgDepsTag;
|
|
@@ -16282,35 +16908,6 @@ function listMembersProgram(orgId) {
|
|
|
16282
16908
|
return [];
|
|
16283
16909
|
});
|
|
16284
16910
|
}
|
|
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
16911
|
function listOrgsProgram() {
|
|
16315
16912
|
return Effect.gen(function* () {
|
|
16316
16913
|
const deps = yield* OrgDepsTag;
|
|
@@ -16416,6 +17013,20 @@ function observedRunnerDeps(deps) {
|
|
|
16416
17013
|
...deps.invocationControls === void 0 ? {} : { invocationControls: deps.invocationControls }
|
|
16417
17014
|
};
|
|
16418
17015
|
}
|
|
17016
|
+
/**
|
|
17017
|
+
* The invitation edge needs the call seam, the observed-runner pair, and — for
|
|
17018
|
+
* the authoring write's configuration hop — the same execution composition the
|
|
17019
|
+
* Permission, payment, and payroll bundles receive.
|
|
17020
|
+
*/
|
|
17021
|
+
function invitationMethodsDeps(deps, convexCall) {
|
|
17022
|
+
return {
|
|
17023
|
+
convexCall,
|
|
17024
|
+
...observedRunnerDeps(deps),
|
|
17025
|
+
...deps.actor === void 0 ? {} : { actor: deps.actor },
|
|
17026
|
+
...deps.chainId === void 0 ? {} : { chainId: Number(deps.chainId) },
|
|
17027
|
+
...deps.signer === void 0 ? {} : { signer: deps.signer }
|
|
17028
|
+
};
|
|
17029
|
+
}
|
|
16419
17030
|
function makeOrgMethods(deps) {
|
|
16420
17031
|
const orgDeps = {
|
|
16421
17032
|
...deps.orgPort === void 0 ? {} : { orgPort: deps.orgPort },
|
|
@@ -16447,13 +17058,10 @@ function makeOrgMethods(deps) {
|
|
|
16447
17058
|
});
|
|
16448
17059
|
return toCapxulResult(createOrgProgram(input), layer);
|
|
16449
17060
|
},
|
|
16450
|
-
orgs: Object.assign((options) => listOrganizations(deps.invocationControls?.(options) ?? options), {
|
|
16451
|
-
|
|
16452
|
-
|
|
16453
|
-
|
|
16454
|
-
});
|
|
16455
|
-
return toCapxulResult(detectAndAcceptPendingInvitationsProgram(), layer);
|
|
16456
|
-
} }),
|
|
17061
|
+
orgs: Object.assign((options) => listOrganizations(deps.invocationControls?.(options) ?? options), { invitations: deps.convexCall === void 0 ? () => Promise.resolve({
|
|
17062
|
+
ok: false,
|
|
17063
|
+
error: Errors.notImplemented("invitations", "listOwn")
|
|
17064
|
+
}) : makeOwnInvitationsMethod(invitationMethodsDeps(deps, deps.convexCall)) }),
|
|
16457
17065
|
org(orgId) {
|
|
16458
17066
|
const convexCall = deps.convexCall;
|
|
16459
17067
|
return {
|
|
@@ -16561,17 +17169,7 @@ function makeOrgMethods(deps) {
|
|
|
16561
17169
|
});
|
|
16562
17170
|
return toCapxulResult(listRolesProgram(orgId), layer);
|
|
16563
17171
|
},
|
|
16564
|
-
|
|
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
|
-
},
|
|
17172
|
+
invitations: convexCall === void 0 ? makeNotImplementedInvitationMethods() : makeOrgInvitationMethods(invitationMethodsDeps(deps, convexCall), String(orgId)),
|
|
16575
17173
|
auditLog(_options) {
|
|
16576
17174
|
if (_options?.signal?.aborted) return Promise.resolve({
|
|
16577
17175
|
ok: false,
|
|
@@ -16634,6 +17232,28 @@ const orgMeUnavailable = () => Promise.resolve({
|
|
|
16634
17232
|
ok: false,
|
|
16635
17233
|
error: Errors.notImplemented("org", "me")
|
|
16636
17234
|
});
|
|
17235
|
+
/**
|
|
17236
|
+
* The closed invitation surface for a client with no backend seam. It reports
|
|
17237
|
+
* `NOT_IMPLEMENTED` for every method rather than an empty list or a fabricated
|
|
17238
|
+
* view: an absent composition root is not an absent invitation.
|
|
17239
|
+
*/
|
|
17240
|
+
function makeNotImplementedInvitationMethods() {
|
|
17241
|
+
return {
|
|
17242
|
+
preview: invitationExecutionUnavailable,
|
|
17243
|
+
invite: invitationExecutionUnavailable,
|
|
17244
|
+
accept: invitationExecutionUnavailable,
|
|
17245
|
+
list: invitationExecutionUnavailable,
|
|
17246
|
+
get: invitationExecutionUnavailable,
|
|
17247
|
+
decline: invitationExecutionUnavailable,
|
|
17248
|
+
cancel: invitationExecutionUnavailable,
|
|
17249
|
+
resend: invitationExecutionUnavailable,
|
|
17250
|
+
retry: invitationExecutionUnavailable
|
|
17251
|
+
};
|
|
17252
|
+
}
|
|
17253
|
+
const invitationExecutionUnavailable = () => Promise.resolve({
|
|
17254
|
+
ok: false,
|
|
17255
|
+
error: Errors.notImplemented("invitations", "executionComposition")
|
|
17256
|
+
});
|
|
16637
17257
|
const permissionExecutionUnavailable = () => Promise.resolve({
|
|
16638
17258
|
ok: false,
|
|
16639
17259
|
error: Errors.notImplemented("permissions", "executionComposition")
|
|
@@ -17025,7 +17645,6 @@ function assembleCapxulClient(input) {
|
|
|
17025
17645
|
};
|
|
17026
17646
|
if (input.signal !== void 0) input.signal.addEventListener("abort", () => void stopActor(), { once: true });
|
|
17027
17647
|
const selectedOrgPort = input.orgPort ?? input.orgDeploymentPort;
|
|
17028
|
-
let detectPendingOrgInvitations;
|
|
17029
17648
|
let kickProvisioning;
|
|
17030
17649
|
const financialOps = makeFinancialOpsMethods({
|
|
17031
17650
|
runPromise: effectRunner.runPromise,
|
|
@@ -17074,7 +17693,6 @@ function assembleCapxulClient(input) {
|
|
|
17074
17693
|
if (browserSigner.statusStore?.status() === "unknown" && typeof browserSigner.ensureWalletReady === "function") browserSigner.ensureWalletReady().catch(() => {});
|
|
17075
17694
|
}
|
|
17076
17695
|
if (accountSetup === "explicit") return;
|
|
17077
|
-
await detectPendingOrgInvitations?.();
|
|
17078
17696
|
kickProvisioning?.();
|
|
17079
17697
|
}
|
|
17080
17698
|
});
|
|
@@ -17142,9 +17760,6 @@ function assembleCapxulClient(input) {
|
|
|
17142
17760
|
...input.signer === void 0 ? {} : { signer: input.signer },
|
|
17143
17761
|
...input.organizationSetup === void 0 ? {} : { organizationSetup: input.organizationSetup }
|
|
17144
17762
|
});
|
|
17145
|
-
if (selectedOrgPort !== void 0) detectPendingOrgInvitations = async () => {
|
|
17146
|
-
await orgMethods.orgs.detectAndAcceptPendingInvitations();
|
|
17147
|
-
};
|
|
17148
17763
|
const currentUser = makeCurrentUserMethods({
|
|
17149
17764
|
me: financialOps.me,
|
|
17150
17765
|
accounts,
|
|
@@ -18036,7 +18651,7 @@ function productionAuthCacheLayer(input) {
|
|
|
18036
18651
|
function productionConvexCallLayer(input, refreshConvexAuthRef) {
|
|
18037
18652
|
return Layer.unwrap(Effect.map(AuthClientPortTag, (authClient) => ConvexCallLayer({
|
|
18038
18653
|
convexUrl: input.runtimeUrls.convexUrl,
|
|
18039
|
-
|
|
18654
|
+
localDiagnostics: input.localDiagnostics,
|
|
18040
18655
|
...input.applicationId === void 0 ? {} : { applicationId: input.applicationId },
|
|
18041
18656
|
...input.observation === void 0 ? {} : { observation: input.observation },
|
|
18042
18657
|
...input.convexClient === void 0 ? {} : { client: input.convexClient },
|
|
@@ -18075,6 +18690,7 @@ function resolveProductionObservability(input) {
|
|
|
18075
18690
|
};
|
|
18076
18691
|
}
|
|
18077
18692
|
async function createProductionAdapters(input) {
|
|
18693
|
+
const localDiagnostics = productionLocalDiagnostics(input);
|
|
18078
18694
|
const { observation, telemetry, invocationObservation, invocationTelemetry } = resolveProductionObservability(input);
|
|
18079
18695
|
const resolvedInput = resolveInput(input);
|
|
18080
18696
|
if (!resolvedInput.ok) return resolvedInput;
|
|
@@ -18145,6 +18761,7 @@ async function createProductionAdapters(input) {
|
|
|
18145
18761
|
const portsLayer = mergeProductionAdapterLayers(makeProductionAdapterLayerEntries({
|
|
18146
18762
|
bootstrap,
|
|
18147
18763
|
runtime: resolvedInput.value.runtime,
|
|
18764
|
+
localDiagnostics,
|
|
18148
18765
|
...resolvedInput.value.origin === void 0 ? {} : { origin: resolvedInput.value.origin },
|
|
18149
18766
|
runtimeUrls: runtimeUrls.value,
|
|
18150
18767
|
chainId: bootstrapResult.value.chainId,
|
|
@@ -18159,7 +18776,7 @@ async function createProductionAdapters(input) {
|
|
|
18159
18776
|
...input.signal === void 0 ? {} : { signal: input.signal },
|
|
18160
18777
|
...input.resetSignerSession === void 0 ? {} : { resetSignerSession: input.resetSignerSession }
|
|
18161
18778
|
}));
|
|
18162
|
-
const applicationLayer = Layer.merge(portsLayer, optionalEngineeringTelemetryLayer(bootstrapResult.value.engineeringTelemetry, resolvedInput.value.runtime, hostEngineeringPolicy(input.observability))).pipe(Layer.provideMerge(resolvedInput.value.runtime
|
|
18779
|
+
const applicationLayer = Layer.merge(portsLayer, optionalEngineeringTelemetryLayer(bootstrapResult.value.engineeringTelemetry, resolvedInput.value.runtime, hostEngineeringPolicy(input.observability))).pipe(Layer.provideMerge(localDiagnosticsLayer(localDiagnostics, resolvedInput.value.runtime)));
|
|
18163
18780
|
const context = await Effect.runPromise(Layer.buildWithScope(applicationLayer, scope));
|
|
18164
18781
|
const collected = await Effect.runPromise(collectProductionFlowPorts.pipe(Effect.provide(context)));
|
|
18165
18782
|
const indexerUrl = input.indexerUrl ?? bootstrapResult.value.indexerUrl;
|
|
@@ -18223,6 +18840,13 @@ function optionalEngineeringTelemetryLayer(policy, runtime, hostPolicy) {
|
|
|
18223
18840
|
return Layer.empty;
|
|
18224
18841
|
}
|
|
18225
18842
|
}
|
|
18843
|
+
function localDiagnosticsLayer(enabled, runtime) {
|
|
18844
|
+
if (!enabled) return Logger.layer([]);
|
|
18845
|
+
return runtime === "node" ? Layer.succeed(Logger.LogToStderr, true) : Layer.empty;
|
|
18846
|
+
}
|
|
18847
|
+
function productionLocalDiagnostics(input) {
|
|
18848
|
+
return input.localDiagnostics !== false;
|
|
18849
|
+
}
|
|
18226
18850
|
function refreshConvexAuthOnSession(authClient, refresh) {
|
|
18227
18851
|
return {
|
|
18228
18852
|
...authClient,
|
|
@@ -18287,7 +18911,7 @@ async function createCapxulClientWithSignerControls(input, controls) {
|
|
|
18287
18911
|
runtime,
|
|
18288
18912
|
authBaseUrl: resolvedAuthBaseUrl,
|
|
18289
18913
|
createBrowserSigner: createOpenfortBrowserSignerFromBootstrap,
|
|
18290
|
-
diagnostic: new EffectLogDiagnosticAdapter(adapters.value.context, new ConsoleDiagnosticAdapter()),
|
|
18914
|
+
diagnostic: new EffectLogDiagnosticAdapter(adapters.value.context, productionLocalDiagnostics(input) ? new ConsoleDiagnosticAdapter() : void 0),
|
|
18291
18915
|
signer: input.signer,
|
|
18292
18916
|
factory: input.openfortSignerFactory,
|
|
18293
18917
|
finalSign: controls.signUserOpHash,
|
|
@@ -18316,11 +18940,11 @@ async function createCapxulClientWithSignerControls(input, controls) {
|
|
|
18316
18940
|
accountSetup: input.accountSetup,
|
|
18317
18941
|
...signer === void 0 ? {} : { signer },
|
|
18318
18942
|
orgPort: Context.get(adapters.value.context, OrgPortTag),
|
|
18319
|
-
|
|
18943
|
+
organizationSetup: new ConvexOrganizationSetupAdapter({
|
|
18320
18944
|
convex: adapters.value.ports.convexCall,
|
|
18321
|
-
signer,
|
|
18945
|
+
...signer === void 0 ? {} : { signer },
|
|
18322
18946
|
chainId: adapters.value.bootstrap.chainId
|
|
18323
|
-
})
|
|
18947
|
+
}),
|
|
18324
18948
|
...input.signal === void 0 ? {} : { signal: input.signal },
|
|
18325
18949
|
...input.otpTtlMs === void 0 ? {} : { otpTtlMs: input.otpTtlMs },
|
|
18326
18950
|
invokeTimeoutMs: input.invokeTimeoutMs ?? 3e4,
|