@capxul/mcp 3.2.0 → 4.0.1

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.
Files changed (3) hide show
  1. package/README.md +51 -14
  2. package/dist/main.mjs +1506 -569
  3. package/package.json +6 -3
package/dist/main.mjs CHANGED
@@ -3,11 +3,12 @@ import { a as __require, i as __exportAll, o as __toESM, r as __commonJSMin } fr
3
3
  import { a as aexists, c as clean, d as toBytes$2, f as u32, i as abytes, l as createHasher, n as sha256$2, o as anumber, r as Hash, s as aoutput, t as secp256k1, u as swap32IfBE } from "./secp256k1-oe2FO-K6.mjs";
4
4
  import { t as require_lib } from "./lib-vbuHK0v7.mjs";
5
5
  import { serveStdio } from "@modelcontextprotocol/server/stdio";
6
+ import { PostHog } from "posthog-node";
6
7
  import { createHash } from "node:crypto";
7
8
  import { createServer } from "node:http";
8
9
  import { localhostHostValidation, localhostOriginValidation, toNodeHandler } from "@modelcontextprotocol/node";
9
10
  import { z } from "zod";
10
- import { Cause, Context, Data, Deferred, Duration, Effect, Exit, Fiber, Layer, Queue, Ref, Result, Schedule, Schema, SchemaGetter, SchemaIssue, SchemaParser, Scope, Tracer } from "effect";
11
+ import { Cause, Clock, Context, Data, Deferred, Duration, Effect, Exit, Fiber, Layer, Queue, Ref, Result, Schedule, Schema, SchemaGetter, SchemaIssue, SchemaParser, Scope, Tracer } from "effect";
11
12
  import { FetchHttpClient, Headers, HttpClient } from "effect/unstable/http";
12
13
  import { OtlpExporter, OtlpLogger, OtlpSerialization, OtlpTracer } from "effect/unstable/observability";
13
14
  import { resolve } from "path";
@@ -21,6 +22,7 @@ import { EventEmitter } from "events";
21
22
  import http2 from "http2";
22
23
  import zlib from "zlib";
23
24
  import { McpServer, createMcpHandler } from "@modelcontextprotocol/server";
25
+ import { instrument } from "@posthog/mcp";
24
26
  //#region ../../packages/errors/src/secret-material.ts
25
27
  const SENSITIVE_MATERIAL_PATTERNS = [
26
28
  /(?:^|[^a-fA-F0-9])(?<!0[xX])[a-fA-F0-9]{64}(?:$|[^a-fA-F0-9])/u,
@@ -549,6 +551,31 @@ function decodeConvexError(err) {
549
551
  return null;
550
552
  }
551
553
  //#endregion
554
+ //#region ../../packages/errors/src/index.ts
555
+ /** Canonical handle syntax shared by validation and branded constructors. */
556
+ const HANDLE_RE$1 = /^[a-z0-9_-]{3,30}$/;
557
+ //#endregion
558
+ //#region ../../packages/config/src/handle.ts
559
+ const RESERVED_HANDLES = /* @__PURE__ */ new Set([
560
+ "admin",
561
+ "api",
562
+ "capxul",
563
+ "help",
564
+ "root",
565
+ "support",
566
+ "system",
567
+ "www"
568
+ ]);
569
+ function normalizeHandle(raw) {
570
+ return raw.trim().toLowerCase().replace(/^@/, "");
571
+ }
572
+ function validateHandle(raw) {
573
+ const handle = normalizeHandle(raw);
574
+ if (!HANDLE_RE$1.test(handle)) throw Errors.invalidInput("handle", "must be 3-30 characters of a-z, 0-9, underscore, or hyphen");
575
+ if (RESERVED_HANDLES.has(handle)) throw Errors.invalidInput("handle", "handle is reserved");
576
+ return handle;
577
+ }
578
+ //#endregion
552
579
  //#region ../../packages/config/src/tokens.ts
553
580
  /** `TestUSDC` ("USDX") — Base Sepolia, 6 decimals, open `mint`. (Canon §1.) */
554
581
  const USDX_ADDRESS_BASE_SEPOLIA = "0xf09fcbb6df9f8f918e58f9c8ab15a76ade862b77";
@@ -3390,6 +3417,19 @@ function readResourceEnvConfig(port, env = process.env) {
3390
3417
  function readHost(env = process.env) {
3391
3418
  return env.CAPXUL_MCP_HOST?.trim() || "127.0.0.1";
3392
3419
  }
3420
+ /** MCP Analytics stays disabled until the process has a PostHog project token. */
3421
+ function readMcpAnalyticsEnvConfig(env = process.env) {
3422
+ const projectToken = env.POSTHOG_PROJECT_TOKEN?.trim();
3423
+ if (projectToken === void 0 || projectToken.length === 0) return void 0;
3424
+ return {
3425
+ projectToken,
3426
+ host: env.POSTHOG_HOST?.trim() || "https://us.i.posthog.com",
3427
+ environment: mcpAnalyticsEnvironment(env.CAPXUL_ENV?.trim() || env.APP_ENV?.trim())
3428
+ };
3429
+ }
3430
+ function mcpAnalyticsEnvironment(value) {
3431
+ return value === "development" || value === "staging" || value === "production" || value === "test" ? value : "unknown";
3432
+ }
3393
3433
  /** Stdio only: the bearer every request in the process is treated as carrying. */
3394
3434
  function readStdioAccessToken(env = process.env) {
3395
3435
  const token = env.CAPXUL_MCP_ACCESS_TOKEN?.trim();
@@ -3882,6 +3922,10 @@ function toPartyId(raw) {
3882
3922
  if (typeof raw !== "string" || !PARTY_ID_RE$1.test(raw)) throw Errors.invalidInput("partyId", invalidValueReason("must be party_ plus an alphanumeric id", raw));
3883
3923
  return raw;
3884
3924
  }
3925
+ function toHandle(raw) {
3926
+ if (typeof raw !== "string" || !HANDLE_RE$1.test(raw)) throw Errors.invalidInput("handle", invalidValueReason("must be 3-30 characters of a-z, 0-9, underscore, or hyphen", raw));
3927
+ return raw;
3928
+ }
3885
3929
  function toBudgetId(raw) {
3886
3930
  return toNonEmptyStringBrand(raw, "budgetId");
3887
3931
  }
@@ -3930,6 +3974,10 @@ function toCurrencyCode(raw) {
3930
3974
  if (typeof raw !== "string" || !SUPPORTED_CURRENCY_CODES.includes(raw)) throw Errors.invalidInput("currencyCode", invalidValueReason("unsupported currency", raw));
3931
3975
  return raw;
3932
3976
  }
3977
+ function toTesterKind(raw) {
3978
+ if (raw !== "human" && raw !== "e2e" && raw !== "agent") throw Errors.invalidInput("testerKind", "must be human, e2e, or agent");
3979
+ return raw;
3980
+ }
3933
3981
  function toKycTier(raw) {
3934
3982
  if (typeof raw !== "number" || !Number.isInteger(raw) || raw < 0 || raw > 3) throw Errors.invalidInput("kycTier", invalidValueReason("must be an integer in [0, 3]", raw));
3935
3983
  return raw;
@@ -4062,7 +4110,6 @@ const CAPXUL_OPERATIONS = {
4062
4110
  current: "holdings.current",
4063
4111
  primary: "holdings.primary"
4064
4112
  },
4065
- handles: { resolve: "handles.resolve" },
4066
4113
  identity: {
4067
4114
  accountAt: "identity.AccountAt",
4068
4115
  accountClaimed: "identity.AccountClaimed",
@@ -4077,6 +4124,7 @@ const CAPXUL_OPERATIONS = {
4077
4124
  createOrganization: "identity.CreateOrganization",
4078
4125
  ensureAccount: "identity.EnsureAccount",
4079
4126
  leaveOrganization: "identity.LeaveOrganization",
4127
+ loadByAuthUserId: "identity.loadByAuthUserId",
4080
4128
  loadCurrent: "identity.loadCurrent",
4081
4129
  orgAt: "identity.OrgAt",
4082
4130
  orgFailed: "identity.OrgFailed",
@@ -4098,7 +4146,7 @@ const CAPXUL_OPERATIONS = {
4098
4146
  signOut: "identity.SignOut",
4099
4147
  signOutFailed: "identity.SignOutFailed",
4100
4148
  update: "identity.update",
4101
- usernameAvailable: "identity.usernameAvailable",
4149
+ handleAvailable: "identity.handleAvailable",
4102
4150
  verified: "identity.Verified",
4103
4151
  verifyFailed: "identity.VerifyFailed",
4104
4152
  verifyOtp: "identity.VerifyOtp"
@@ -4114,10 +4162,12 @@ const CAPXUL_OPERATIONS = {
4114
4162
  get: "me.get"
4115
4163
  },
4116
4164
  moneyExecution: {
4165
+ abandonPaymentExecution: "moneyExecution.abandonPaymentExecution",
4117
4166
  prepareOrganizationPaymentExecution: "moneyExecution.prepareOrganizationPaymentExecution",
4118
4167
  preparePaymentExecution: "moneyExecution.preparePaymentExecution",
4119
4168
  preparePaymentLifecycleExecution: "moneyExecution.preparePaymentLifecycleExecution",
4120
4169
  preparePermissionExecution: "moneyExecution.preparePermissionExecution",
4170
+ recoverSubmissionClaims: "moneyExecution.recoverSubmissionClaims",
4121
4171
  submit: "moneyExecution.submit",
4122
4172
  submitPaymentCommandExecution: "moneyExecution.submitPaymentCommandExecution",
4123
4173
  submitPaymentExecution: "moneyExecution.submitPaymentExecution",
@@ -4136,9 +4186,14 @@ const CAPXUL_OPERATIONS = {
4136
4186
  quote: "offramp.quote",
4137
4187
  status: "offramp.status"
4138
4188
  },
4139
- onboarding: { completePerson: "onboarding.completePerson" },
4189
+ onboarding: {
4190
+ completeOrganization: "onboarding.completeOrganization",
4191
+ completePerson: "onboarding.completePerson"
4192
+ },
4140
4193
  org: {
4194
+ acceptInvitations: "org.acceptInvitations",
4141
4195
  account: { get: "org.account.get" },
4196
+ activateMember: "org.activateMember",
4142
4197
  auditLog: "org.auditLog",
4143
4198
  confirmBootstrap: "org.confirmBootstrap",
4144
4199
  createOrg: "org.createOrg",
@@ -4149,6 +4204,7 @@ const CAPXUL_OPERATIONS = {
4149
4204
  getProofReceipt: "org.getProofReceipt",
4150
4205
  invite: "org.invite",
4151
4206
  inviteMember: "org.inviteMember",
4207
+ list: "org.list",
4152
4208
  load: "org.load",
4153
4209
  me: "org.me",
4154
4210
  members: "org.members",
@@ -4219,7 +4275,8 @@ const CAPXUL_OPERATIONS = {
4219
4275
  organizationPayments: {
4220
4276
  pay: "organizationPayments.pay",
4221
4277
  payBatch: "organizationPayments.payBatch",
4222
- prepareExecution: "organizationPayments.prepareExecution"
4278
+ prepareExecution: "organizationPayments.prepareExecution",
4279
+ retry: "organizationPayments.retry"
4223
4280
  },
4224
4281
  organizationSetup: { getProofReceipt: "organizationSetup.getProofReceipt" },
4225
4282
  organizations: { detectAndAcceptPendingInvitations: "orgs.detectAndAcceptPendingInvitations" },
@@ -4234,6 +4291,7 @@ const CAPXUL_OPERATIONS = {
4234
4291
  prepareExecution: "payments.prepareExecution",
4235
4292
  prepareLifecycleExecution: "payments.prepareLifecycleExecution",
4236
4293
  redirect: "payments.redirect",
4294
+ retry: "payments.retry",
4237
4295
  submitCommandExecution: "payments.submitCommandExecution",
4238
4296
  submitExecution: "payments.submitExecution"
4239
4297
  },
@@ -4241,11 +4299,7 @@ const CAPXUL_OPERATIONS = {
4241
4299
  render: "paymentDocuments.render",
4242
4300
  verify: "paymentDocuments.verify"
4243
4301
  },
4244
- payees: {
4245
- create: "payees.create",
4246
- get: "payees.get",
4247
- resolve: "payees.resolve"
4248
- },
4302
+ recipient: { resolve: "recipient.resolve" },
4249
4303
  payroll: {
4250
4304
  authorizeRun: "payroll.authorizeRun",
4251
4305
  groups: {
@@ -4319,6 +4373,7 @@ const CAPXUL_OPERATIONS = {
4319
4373
  smartAccount: {
4320
4374
  claim: "smartAccount.claim",
4321
4375
  confirmDeployment: "smartAccount.confirmDeployment",
4376
+ loadByAuthUserId: "smartAccount.loadByAuthUserId",
4322
4377
  loadCurrent: "smartAccount.loadCurrent",
4323
4378
  provision: "smartAccount.provision"
4324
4379
  },
@@ -4327,12 +4382,6 @@ const CAPXUL_OPERATIONS = {
4327
4382
  ping: "system.ping",
4328
4383
  runtimeChain: "system.runtimeChain"
4329
4384
  },
4330
- targets: { resolve: {
4331
- email: "targets.resolve.email",
4332
- handle: "targets.resolve.handle",
4333
- organization: "targets.resolve.organization",
4334
- payee: "targets.resolve.payee"
4335
- } },
4336
4385
  testUsdc: { mint: "TestUSDC.mint" },
4337
4386
  _internal: {
4338
4387
  accounts: { fund: "_internal.accounts.fund" },
@@ -4745,32 +4794,116 @@ const OrgInviteExpiredProps = Schema.Struct({
4745
4794
  role: OptionalString,
4746
4795
  status: OptionalString
4747
4796
  });
4797
+ const RecipientLocatorKindSchema = Schema.Literals([
4798
+ "handle",
4799
+ "email",
4800
+ "address",
4801
+ "party"
4802
+ ]);
4803
+ const RecipientResolutionStatusSchema = Schema.Literals([
4804
+ "known_party",
4805
+ "new_email",
4806
+ "external_address"
4807
+ ]);
4808
+ const RecipientPartyKindSchema = Schema.Literals([
4809
+ "person",
4810
+ "organization",
4811
+ "unresolved"
4812
+ ]);
4813
+ const RecipientTelemetryProps = {
4814
+ recipient_locator_kind: Schema.optional(RecipientLocatorKindSchema),
4815
+ recipient_resolution_status: Schema.optional(RecipientResolutionStatusSchema),
4816
+ recipient_party_id: OptionalString,
4817
+ recipient_party_kind: Schema.optional(RecipientPartyKindSchema),
4818
+ recipient_is_capxul_account: Schema.optional(Schema.Boolean),
4819
+ recipient_handle: OptionalString,
4820
+ recipient_address: OptionalAddress,
4821
+ external_address_acknowledged: Schema.optional(Schema.Boolean)
4822
+ };
4748
4823
  const PaymentInitiatedProps = Schema.Struct({
4824
+ command_id: OptionalString,
4825
+ execution_id: OptionalString,
4826
+ payment_lifecycle_id: OptionalString,
4749
4827
  ...TelemetryEnvelopeProps,
4828
+ ...RecipientTelemetryProps,
4750
4829
  kind: Schema.String,
4751
4830
  payment_id: Schema.String
4752
4831
  });
4832
+ const PaymentLifecycleProps = {
4833
+ payment_state: OptionalString,
4834
+ execution_state: OptionalString,
4835
+ occurred_at: Schema.optional(Schema.Number),
4836
+ causal_sequence: Schema.optional(Schema.Number),
4837
+ sponsorship_valid_until: Schema.optional(Schema.Number),
4838
+ terminal_event_id: OptionalString
4839
+ };
4753
4840
  const PaymentSettledL2Props = Schema.Struct({
4841
+ ...PaymentLifecycleProps,
4754
4842
  ...TelemetryEnvelopeProps,
4843
+ ...RecipientTelemetryProps,
4755
4844
  kind: Schema.String,
4756
4845
  chain_id: Schema.Number,
4757
- settlement_id: Schema.String
4846
+ settlement_id: Schema.String,
4847
+ payment_id: OptionalString,
4848
+ payment_ids: OptionalString,
4849
+ command_id: OptionalString,
4850
+ payment_lifecycle_id: OptionalString,
4851
+ execution_id: OptionalString,
4852
+ user_op_hash: OptionalString,
4853
+ transaction_hash: OptionalString
4758
4854
  });
4759
4855
  const PaymentFailedL2Props = Schema.Struct({
4856
+ ...PaymentLifecycleProps,
4760
4857
  ...TelemetryEnvelopeProps,
4761
4858
  ...ChainCauseTelemetryProps,
4859
+ ...RecipientTelemetryProps,
4762
4860
  kind: Schema.String,
4763
4861
  payment_id: Schema.String,
4764
- reason_code: Schema.String
4862
+ payment_ids: OptionalString,
4863
+ reason_code: Schema.String,
4864
+ command_id: OptionalString,
4865
+ payment_lifecycle_id: OptionalString,
4866
+ execution_id: OptionalString,
4867
+ user_op_hash: OptionalString
4765
4868
  });
4766
4869
  const PaymentVerificationRetryProps = Schema.Struct({
4870
+ ...PaymentLifecycleProps,
4767
4871
  ...TelemetryEnvelopeProps,
4872
+ ...RecipientTelemetryProps,
4768
4873
  command_id: Schema.String,
4874
+ payment_lifecycle_id: Schema.String,
4769
4875
  attempt: Schema.Number,
4770
4876
  reason_code: Schema.String,
4771
4877
  chain_id: Schema.Number,
4772
4878
  delay_ms: DurationMsSchema$1,
4773
- outcome: Schema.Literals(["scheduled", "unresolved"])
4879
+ outcome: Schema.Literals(["scheduled", "unresolved"]),
4880
+ payment_id: OptionalString,
4881
+ payment_ids: OptionalString,
4882
+ execution_id: OptionalString,
4883
+ user_op_hash: OptionalString
4884
+ });
4885
+ const PaymentLifecycleTransitionProps = Schema.Struct({
4886
+ ...TelemetryEnvelopeProps,
4887
+ ...RecipientTelemetryProps,
4888
+ payment_id: Schema.String,
4889
+ payment_lifecycle_id: Schema.String,
4890
+ command_id: Schema.String,
4891
+ payment_state: Schema.String,
4892
+ occurred_at: Schema.Number,
4893
+ causal_sequence: Schema.Number,
4894
+ execution_id: OptionalString,
4895
+ execution_state: OptionalString,
4896
+ user_op_hash: OptionalString,
4897
+ sponsorship_valid_until: Schema.optional(Schema.Number),
4898
+ reason_code: OptionalString
4899
+ });
4900
+ const QuickPayExternalAddressAcknowledgedProps = Schema.Struct({
4901
+ ...TelemetryEnvelopeProps,
4902
+ recipient_locator_kind: Schema.Literal("address"),
4903
+ recipient_resolution_status: Schema.Literal("external_address"),
4904
+ recipient_address: AddressSchema$1,
4905
+ external_address_acknowledged: Schema.Literal(true),
4906
+ organization_id: OptionalOrgId
4774
4907
  });
4775
4908
  const DepositInitiatedProps = Schema.Struct({ ...TelemetryEnvelopeProps });
4776
4909
  const DepositSettledProps = Schema.Struct({
@@ -4978,6 +5111,14 @@ Schema.Struct({
4978
5111
  name: Schema.Literal("payment_verification_retry"),
4979
5112
  props: PaymentVerificationRetryProps
4980
5113
  });
5114
+ Schema.Struct({
5115
+ name: Schema.Literal("payment_lifecycle_transition"),
5116
+ props: PaymentLifecycleTransitionProps
5117
+ });
5118
+ Schema.Struct({
5119
+ name: Schema.Literal("quick_pay_external_address_acknowledged"),
5120
+ props: QuickPayExternalAddressAcknowledgedProps
5121
+ });
4981
5122
  Schema.Struct({
4982
5123
  name: Schema.Literal("deposit_initiated"),
4983
5124
  props: DepositInitiatedProps
@@ -5320,16 +5461,13 @@ const CAPXUL_FUNCTIONS = {
5320
5461
  list: "financialOps/destinations:list",
5321
5462
  remove: "financialOps/destinations:remove"
5322
5463
  },
5323
- "financialOps/mutations": { createPayee: "financialOps/mutations:createPayee" },
5324
5464
  "financialOps/queries": {
5325
5465
  depositInstructions: "financialOps/queries:depositInstructions",
5326
- getPayee: "financialOps/queries:getPayee",
5327
5466
  getPayment: "financialOps/queries:getPayment",
5328
5467
  listPayments: "financialOps/queries:listPayments",
5329
5468
  me: "financialOps/queries:me",
5330
5469
  renderStoredDocument: "financialOps/queries:renderStoredDocument",
5331
- resolveHandle: "financialOps/queries:resolveHandle",
5332
- resolvePayee: "financialOps/queries:resolvePayee",
5470
+ resolveRecipient: "financialOps/queries:resolveRecipient",
5333
5471
  verifyPaymentDocument: "financialOps/queries:verifyPaymentDocument"
5334
5472
  },
5335
5473
  "financialOps/requestsInbox": {
@@ -5348,7 +5486,7 @@ const CAPXUL_FUNCTIONS = {
5348
5486
  },
5349
5487
  "identity/queries": {
5350
5488
  loadByAuthUserId: "identity/queries:loadByAuthUserId",
5351
- usernameAvailable: "identity/queries:usernameAvailable"
5489
+ handleAvailable: "identity/queries:handleAvailable"
5352
5490
  },
5353
5491
  "holdings/actions": { current: "holdings/actions:current" },
5354
5492
  "movement/activity": {
@@ -5358,6 +5496,7 @@ const CAPXUL_FUNCTIONS = {
5358
5496
  summary: "movement/activity:summary"
5359
5497
  },
5360
5498
  "moneyExecution/actions": {
5499
+ abandonPaymentExecution: "moneyExecution/actions:abandonPaymentExecution",
5361
5500
  preparePermissionExecution: "moneyExecution/actions:preparePermissionExecution",
5362
5501
  preparePaymentExecution: "moneyExecution/actions:preparePaymentExecution",
5363
5502
  submitPermissionExecution: "moneyExecution/actions:submitPermissionExecution",
@@ -5435,6 +5574,7 @@ const CAPXUL_FUNCTIONS = {
5435
5574
  const PAYMENT_STATUSES = [
5436
5575
  "pending",
5437
5576
  "settling",
5577
+ "unresolved",
5438
5578
  "scheduled",
5439
5579
  "streaming",
5440
5580
  "pending_claim",
@@ -5442,6 +5582,30 @@ const PAYMENT_STATUSES = [
5442
5582
  "cancelled",
5443
5583
  "failed"
5444
5584
  ];
5585
+ /** The lifecycle of one signed Payment execution attempt. */
5586
+ const PAYMENT_EXECUTION_STATUS = {
5587
+ PENDING: "pending",
5588
+ INCLUDED: "included",
5589
+ DROPPED: "dropped",
5590
+ REPLACED: "replaced",
5591
+ EXPIRED: "expired",
5592
+ UNRESOLVED: "unresolved",
5593
+ SUPERSEDED: "superseded",
5594
+ FAILED: "failed",
5595
+ SETTLED: "settled"
5596
+ };
5597
+ const PAYMENT_EXECUTION_STATUSES = [
5598
+ PAYMENT_EXECUTION_STATUS.PENDING,
5599
+ PAYMENT_EXECUTION_STATUS.INCLUDED,
5600
+ PAYMENT_EXECUTION_STATUS.DROPPED,
5601
+ PAYMENT_EXECUTION_STATUS.REPLACED,
5602
+ PAYMENT_EXECUTION_STATUS.EXPIRED,
5603
+ PAYMENT_EXECUTION_STATUS.UNRESOLVED,
5604
+ PAYMENT_EXECUTION_STATUS.SUPERSEDED,
5605
+ PAYMENT_EXECUTION_STATUS.FAILED,
5606
+ PAYMENT_EXECUTION_STATUS.SETTLED
5607
+ ];
5608
+ PAYMENT_EXECUTION_STATUS.DROPPED, PAYMENT_EXECUTION_STATUS.REPLACED, PAYMENT_EXECUTION_STATUS.EXPIRED, PAYMENT_EXECUTION_STATUS.SUPERSEDED;
5445
5609
  /** The payment direction relative to the current actor. */
5446
5610
  const PAYMENT_DIRECTIONS = [
5447
5611
  "in",
@@ -5477,22 +5641,16 @@ const EVM_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
5477
5641
  */
5478
5642
  const PAYMENT_DOCUMENT_VERIFYING_CONTRACT = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
5479
5643
  const PAYMENT_ID_RE = /^payment_[0-9A-Za-z]+$/;
5480
- const PAYEE_ID_RE = /^payee_[0-9A-Za-z]+$/;
5481
5644
  const ORG_ID_RE = /^org_[0-9A-Za-z]+$/;
5482
- const USER_ID_RE = /^user_[0-9A-Za-z]+$/;
5483
5645
  const PARTY_ID_RE = /^party_[0-9A-Za-z]+$/;
5484
- const HANDLE_RE = /^@?[a-z0-9][a-z0-9-]{2,31}$/;
5485
- const ORG_HANDLE_RE = /^[a-z0-9][a-z0-9-]{2,31}$/;
5646
+ const HANDLE_RE = /^@?[a-z0-9_-]{3,30}$/;
5486
5647
  const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
5487
5648
  const MinorUnitStringSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => MINOR_UNIT_STRING_RE.test(value), { message: "must be a non-negative integer minor-unit string" })));
5488
5649
  const PaymentIdSchema$1 = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => PAYMENT_ID_RE.test(value), { message: "must be payment_ plus an alphanumeric id" })));
5489
- const PayeeIdSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => PAYEE_ID_RE.test(value), { message: "must be payee_ plus an alphanumeric id" })));
5490
5650
  const OrgIdSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => ORG_ID_RE.test(value), { message: "must be org_ plus an alphanumeric id" })));
5491
- const UserIdSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => USER_ID_RE.test(value), { message: "must be user_ plus an alphanumeric id" })));
5492
5651
  const PartyIdSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => PARTY_ID_RE.test(value), { message: "must be party_ plus an alphanumeric id" })));
5493
5652
  const DecimalStringSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => DECIMAL_STRING_RE.test(value), { message: "must be a non-negative decimal string" })));
5494
5653
  const HandleValueSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => !EVM_ADDRESS_RE.test(value) && HANDLE_RE.test(value), { message: "must be a handle; raw addresses are not accepted" })));
5495
- const OrgHandleValueSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => !EVM_ADDRESS_RE.test(value) && ORG_HANDLE_RE.test(value), { message: "must be an org handle; raw addresses are not accepted" })));
5496
5654
  const EmailValueSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => !EVM_ADDRESS_RE.test(value) && EMAIL_RE.test(value), { message: "must be an email; raw addresses are not accepted" })));
5497
5655
  const Uint8Schema$1 = Schema.Number.pipe(Schema.check(Schema.makeFilter((value) => Number.isSafeInteger(value) && value >= 0 && value <= 255, { message: "must be a uint8" })));
5498
5656
  const Uint64Schema = Schema.Number.pipe(Schema.check(Schema.makeFilter((value) => Number.isSafeInteger(value) && value >= 0, { message: "must be a non-negative safe integer" })));
@@ -5612,42 +5770,39 @@ const WithdrawalDocumentEnvelope = Schema.Struct({
5612
5770
  primaryType: Schema.Literal("Withdrawal"),
5613
5771
  message: WithdrawalDocument
5614
5772
  });
5615
- Schema.Union([AttachablePaymentDocumentEnvelope, WithdrawalDocumentEnvelope]);
5616
- Schema.Struct({
5617
- payeeId: PayeeIdSchema,
5618
- label: Schema.String,
5619
- trustState: Schema.Literals([
5620
- "unverified",
5621
- "trusted",
5622
- "blocked"
5623
- ]),
5624
- destinationKind: Schema.Literals([
5625
- "handle",
5626
- "email",
5627
- "saved-payee",
5628
- "org"
5629
- ])
5630
- });
5631
- const PaymentRecipient = Schema.Struct({
5632
- kind: Schema.Literals([
5633
- "handle",
5634
- "email",
5635
- "payee",
5636
- "capxulUserId",
5637
- "me",
5638
- "org",
5639
- "party",
5640
- "external_address"
5641
- ]),
5642
- label: Schema.String,
5643
- payeeId: Schema.optional(PayeeIdSchema)
5644
- });
5773
+ const PaymentDocumentEnvelope = Schema.Union([AttachablePaymentDocumentEnvelope, WithdrawalDocumentEnvelope]);
5774
+ const ENVELOPE_PRIMARY_TYPE_TO_KIND = {
5775
+ Memo: "memo",
5776
+ Invoice: "invoice",
5777
+ Payslip: "payslip",
5778
+ Receipt: "receipt",
5779
+ Withdrawal: "withdrawal"
5780
+ };
5781
+ /**
5782
+ * Derive the wire `paymentType` an UNKNOWN document envelope classifies to
5783
+ * (payment-document-spec.md D11: memo/withdrawal → unspecified, invoice →
5784
+ * invoice, payslip → payroll, receipt → reimbursement), or `undefined` if the
5785
+ * envelope is absent / malformed — the same tolerance as
5786
+ * `tryHashPaymentDocument`. Callers holding an untyped envelope (e.g. the MCP
5787
+ * org spend port, #712) use this so the type they record agrees with the type
5788
+ * the backend re-derives from the same document.
5789
+ */
5790
+ function paymentTypeForDocumentEnvelope(envelope) {
5791
+ if (envelope === void 0 || envelope === null) return void 0;
5792
+ const decoded = SchemaParser.decodeUnknownResult(PaymentDocumentEnvelope)(envelope);
5793
+ if (decoded._tag === "Failure") return void 0;
5794
+ return paymentTypeForDocumentKind(ENVELOPE_PRIMARY_TYPE_TO_KIND[decoded.success.primaryType]);
5795
+ }
5796
+ const PaymentRecipient = Schema.Union([Schema.Struct({
5797
+ kind: Schema.Literal("party"),
5798
+ partyId: PartyIdSchema,
5799
+ label: Schema.String
5800
+ }), Schema.Struct({
5801
+ kind: Schema.Literal("external_address"),
5802
+ label: Schema.String
5803
+ })]);
5645
5804
  /**
5646
- * A raw external EVM address for the B3 withdraw lane — the cash-out
5647
- * destination. This is the ONE schema that ACCEPTS a bare 0x (the withdraw
5648
- * mutation args use it), as opposed to `PaymentRecipientRefSchema` which
5649
- * REJECTS bare addresses to protect the pay lane. The full address never
5650
- * crosses the model wire; it lives on the kind:4 Withdrawal document only.
5805
+ * A raw external EVM address for a payment or withdrawal destination.
5651
5806
  */
5652
5807
  const ExternalAddressSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => EVM_ADDRESS_RE.test(value), { message: "must be a 0x EVM address (40 hex chars)" })));
5653
5808
  const PaymentTiming = Schema.Union([
@@ -5673,16 +5828,8 @@ const PaymentRef = Schema.Union([
5673
5828
  email: EmailValueSchema
5674
5829
  }),
5675
5830
  Schema.Struct({
5676
- kind: Schema.Literal("orgHandle"),
5677
- orgHandle: OrgHandleValueSchema
5678
- }),
5679
- Schema.Struct({
5680
- kind: Schema.Literal("capxulUserId"),
5681
- capxulUserId: UserIdSchema
5682
- }),
5683
- Schema.Struct({
5684
- kind: Schema.Literal("payeeId"),
5685
- payeeId: PayeeIdSchema
5831
+ kind: Schema.Literal("address"),
5832
+ address: ExternalAddressSchema
5686
5833
  }),
5687
5834
  Schema.Struct({
5688
5835
  kind: Schema.Literal("party"),
@@ -5705,6 +5852,10 @@ const Payment = Schema.Struct({
5705
5852
  timing: PaymentTiming,
5706
5853
  released: FinancialOpsMoney,
5707
5854
  availableToClaim: FinancialOpsMoney,
5855
+ execution: Schema.optional(Schema.Struct({
5856
+ status: Schema.Literals(PAYMENT_EXECUTION_STATUSES),
5857
+ retryRequired: Schema.Boolean
5858
+ })),
5708
5859
  createdAt: EpochMsSchema,
5709
5860
  updatedAt: EpochMsSchema
5710
5861
  }).pipe(Schema.check(Schema.makeFilter((payment) => payment.documents.every((document) => paymentTypeForDocumentKind(document.kind) === payment.paymentType), { message: "document kind must map to paymentType" })));
@@ -5849,11 +6000,21 @@ const MovementIdentitySchema = Schema.Struct({
5849
6000
  txHash: TxHashSchema,
5850
6001
  logIndex: LogIndexSchema
5851
6002
  });
5852
- const MovementCanonicalStateSchema = Schema.Literals([
6003
+ const MovementCanonicalStateInputSchema = Schema.Literals([
5853
6004
  "observed",
6005
+ "included",
5854
6006
  "finalized",
5855
6007
  "removed"
5856
6008
  ]);
6009
+ const MovementCanonicalStateOutputSchema = Schema.Literals([
6010
+ "observed",
6011
+ "included",
6012
+ "removed"
6013
+ ]);
6014
+ const MovementCanonicalStateSchema = MovementCanonicalStateInputSchema.pipe(Schema.decodeTo(MovementCanonicalStateOutputSchema, {
6015
+ decode: SchemaGetter.transform((state) => state === "finalized" ? "included" : state),
6016
+ encode: SchemaGetter.transform((state) => state)
6017
+ }));
5857
6018
  const MovementSchema = Schema.Struct({
5858
6019
  ...MovementIdentitySchema.fields,
5859
6020
  movementId: MovementIdSchema,
@@ -6204,7 +6365,7 @@ Schema.Struct({
6204
6365
  transfers: Schema.Array(TransferEvidenceSchema),
6205
6366
  requestCount: nonNegativeInteger("requestCount")
6206
6367
  });
6207
- const FinalizedMoneyEvidenceCommonSchema = Schema.Struct({
6368
+ const VerifiedMoneyEvidenceCommonSchema = Schema.Struct({
6208
6369
  chainId: BaseSepoliaChainIdSchema,
6209
6370
  contractAddress: AddressSchema,
6210
6371
  userOpHash: Bytes32Schema,
@@ -6214,8 +6375,8 @@ const FinalizedMoneyEvidenceCommonSchema = Schema.Struct({
6214
6375
  blockTimestamp: Uint48Schema,
6215
6376
  eventLogIndex: LogIndexSchema
6216
6377
  });
6217
- const FinalizedPaymentEvidenceSchema = Schema.Struct({
6218
- ...FinalizedMoneyEvidenceCommonSchema.fields,
6378
+ const VerifiedPaymentEvidenceSchema = Schema.Struct({
6379
+ ...VerifiedMoneyEvidenceCommonSchema.fields,
6219
6380
  operation: Schema.Literal("send"),
6220
6381
  settlementId: SettlementIdSchema,
6221
6382
  purposeKind: PaymentPurposeKindSchema,
@@ -6227,8 +6388,8 @@ const FinalizedPaymentEvidenceSchema = Schema.Struct({
6227
6388
  destination: AddressSchema,
6228
6389
  rawAmount: WeiAmountSchema
6229
6390
  });
6230
- const FinalizedCommitmentCreationEvidenceSchema = Schema.Struct({
6231
- ...FinalizedMoneyEvidenceCommonSchema.fields,
6391
+ const VerifiedCommitmentCreationEvidenceSchema = Schema.Struct({
6392
+ ...VerifiedMoneyEvidenceCommonSchema.fields,
6232
6393
  operation: Schema.Literal("create_commitment"),
6233
6394
  commitmentId: Uint256StringSchema,
6234
6395
  settlementId: SettlementIdSchema,
@@ -6244,8 +6405,8 @@ const FinalizedCommitmentCreationEvidenceSchema = Schema.Struct({
6244
6405
  documentHash: NonzeroDocumentHashSchema,
6245
6406
  transferLogIndex: LogIndexSchema
6246
6407
  });
6247
- const FinalizedCommitmentClaimEvidenceSchema = Schema.Struct({
6248
- ...FinalizedMoneyEvidenceCommonSchema.fields,
6408
+ const VerifiedCommitmentClaimEvidenceSchema = Schema.Struct({
6409
+ ...VerifiedMoneyEvidenceCommonSchema.fields,
6249
6410
  operation: Schema.Literal("claim_commitment"),
6250
6411
  commitmentId: Uint256StringSchema,
6251
6412
  settlementId: SettlementIdSchema,
@@ -6258,8 +6419,8 @@ const FinalizedCommitmentClaimEvidenceSchema = Schema.Struct({
6258
6419
  documentHash: NonzeroDocumentHashSchema,
6259
6420
  transferLogIndex: LogIndexSchema
6260
6421
  });
6261
- const FinalizedCommitmentCancelEvidenceSchema = Schema.Struct({
6262
- ...FinalizedMoneyEvidenceCommonSchema.fields,
6422
+ const VerifiedCommitmentCancelEvidenceSchema = Schema.Struct({
6423
+ ...VerifiedMoneyEvidenceCommonSchema.fields,
6263
6424
  operation: Schema.Literal("cancel_commitment"),
6264
6425
  commitmentId: Uint256StringSchema,
6265
6426
  settlementId: SettlementIdSchema,
@@ -6273,8 +6434,8 @@ const FinalizedCommitmentCancelEvidenceSchema = Schema.Struct({
6273
6434
  documentHash: NonzeroDocumentHashSchema,
6274
6435
  transfer: Schema.NullOr(TransferEvidenceSchema)
6275
6436
  });
6276
- const FinalizedCommitmentRedirectEvidenceSchema = Schema.Struct({
6277
- ...FinalizedMoneyEvidenceCommonSchema.fields,
6437
+ const VerifiedCommitmentRedirectEvidenceSchema = Schema.Struct({
6438
+ ...VerifiedMoneyEvidenceCommonSchema.fields,
6278
6439
  operation: Schema.Literal("redirect_commitment"),
6279
6440
  commitmentId: Uint256StringSchema,
6280
6441
  settlementId: SettlementIdSchema,
@@ -6285,12 +6446,12 @@ const FinalizedCommitmentRedirectEvidenceSchema = Schema.Struct({
6285
6446
  documentHash: NonzeroDocumentHashSchema,
6286
6447
  transfer: Schema.Null
6287
6448
  });
6288
- const FinalizedMoneyEvidenceSchema = Schema.Union([
6289
- FinalizedPaymentEvidenceSchema,
6290
- FinalizedCommitmentCreationEvidenceSchema,
6291
- FinalizedCommitmentClaimEvidenceSchema,
6292
- FinalizedCommitmentCancelEvidenceSchema,
6293
- FinalizedCommitmentRedirectEvidenceSchema
6449
+ const VerifiedMoneyEvidenceSchema = Schema.Union([
6450
+ VerifiedPaymentEvidenceSchema,
6451
+ VerifiedCommitmentCreationEvidenceSchema,
6452
+ VerifiedCommitmentClaimEvidenceSchema,
6453
+ VerifiedCommitmentCancelEvidenceSchema,
6454
+ VerifiedCommitmentRedirectEvidenceSchema
6294
6455
  ]);
6295
6456
  Schema.Union([
6296
6457
  Schema.Struct({
@@ -6300,7 +6461,7 @@ Schema.Union([
6300
6461
  }),
6301
6462
  Schema.Struct({
6302
6463
  status: Schema.Literal("verified"),
6303
- evidence: FinalizedMoneyEvidenceSchema
6464
+ evidence: VerifiedMoneyEvidenceSchema
6304
6465
  }),
6305
6466
  Schema.Struct({
6306
6467
  status: Schema.Literal("mismatch"),
@@ -6312,7 +6473,7 @@ Schema.Union([
6312
6473
  retryable: Schema.Literal(true)
6313
6474
  })
6314
6475
  ]);
6315
- const FinalizedAttributedInboundMovementSchema = Schema.Struct({
6476
+ const VerifiedAttributedInboundMovementSchema = Schema.Struct({
6316
6477
  movement: MovementSchema,
6317
6478
  attribution: MovementAttributionSchema
6318
6479
  });
@@ -6338,6 +6499,25 @@ const ProtocolBirthInputSchema = Schema.Struct({
6338
6499
  release: ReleaseTermsSchema,
6339
6500
  lineage: Schema.optional(PaymentCommandLineageSchema)
6340
6501
  }).pipe(Schema.refine((birth) => hasActorBoundPermission(birth.actor, birth.actor.kind === "organization" ? birth.actor.orgId : void 0, birth.permissionId), { message: "Organization Payment and Payout births require permissionId; personal births forbid it" }));
6502
+ const ApplyVerifiedEvidenceCommandSchema = Schema.Struct({
6503
+ kind: Schema.Literal("apply_verified_evidence"),
6504
+ paymentId: PaymentIdSchema,
6505
+ evidence: VerifiedMoneyEvidenceSchema
6506
+ });
6507
+ const ApplyFinalizedEvidenceCommandSchema = Schema.Struct({
6508
+ kind: Schema.Literal("apply_finalized_evidence"),
6509
+ paymentId: PaymentIdSchema,
6510
+ evidence: VerifiedMoneyEvidenceSchema
6511
+ }).pipe(Schema.decodeTo(ApplyVerifiedEvidenceCommandSchema, {
6512
+ decode: SchemaGetter.transform((value) => ({
6513
+ ...value,
6514
+ kind: "apply_verified_evidence"
6515
+ })),
6516
+ encode: SchemaGetter.transform((value) => ({
6517
+ ...value,
6518
+ kind: "apply_finalized_evidence"
6519
+ }))
6520
+ }));
6341
6521
  Schema.Union([
6342
6522
  Schema.Struct({
6343
6523
  kind: Schema.Literal("birth"),
@@ -6345,7 +6525,7 @@ Schema.Union([
6345
6525
  }),
6346
6526
  Schema.Struct({
6347
6527
  kind: Schema.Literal("birth_deposit"),
6348
- movement: FinalizedAttributedInboundMovementSchema
6528
+ movement: VerifiedAttributedInboundMovementSchema
6349
6529
  }),
6350
6530
  Schema.Struct({
6351
6531
  kind: Schema.Literal("rollback_deposit"),
@@ -6357,11 +6537,8 @@ Schema.Union([
6357
6537
  paymentIds: Schema.Array(PaymentIdSchema),
6358
6538
  userOpHash: Bytes32Schema
6359
6539
  }),
6360
- Schema.Struct({
6361
- kind: Schema.Literal("apply_finalized_evidence"),
6362
- paymentId: PaymentIdSchema,
6363
- evidence: FinalizedMoneyEvidenceSchema
6364
- }),
6540
+ ApplyVerifiedEvidenceCommandSchema,
6541
+ ApplyFinalizedEvidenceCommandSchema,
6365
6542
  Schema.Struct({
6366
6543
  kind: Schema.Literal("transition"),
6367
6544
  paymentId: PaymentIdSchema,
@@ -6503,6 +6680,7 @@ const MoneyExecutionIdSchema = Schema.String.pipe(Schema.refine((value) => /^mon
6503
6680
  const OwnerSignatureSchema = Schema.String.pipe(Schema.refine((value) => /^0x[0-9a-fA-F]{130}$/u.test(value), { message: "signature must be a 65-byte 0x value" }));
6504
6681
  const PaymentExecutionIntentSchema = Schema.Struct({
6505
6682
  to: PaymentRef,
6683
+ externalAddressAcknowledged: Schema.optional(Schema.Literal(true)),
6506
6684
  amount: FinancialOpsMoney,
6507
6685
  paymentType: Schema.optional(Schema.Literals([
6508
6686
  "unspecified",
@@ -6519,7 +6697,31 @@ Schema.Struct({
6519
6697
  signerAddress: AddressSchema,
6520
6698
  payment: PaymentExecutionIntentSchema
6521
6699
  });
6700
+ const RecipientObservationSchema = Schema.Struct({
6701
+ recipient_locator_kind: Schema.Literals([
6702
+ "handle",
6703
+ "email",
6704
+ "party",
6705
+ "address"
6706
+ ]),
6707
+ recipient_resolution_status: Schema.Literals([
6708
+ "known_party",
6709
+ "new_email",
6710
+ "external_address"
6711
+ ]),
6712
+ recipient_is_capxul_account: Schema.Boolean,
6713
+ recipient_party_id: Schema.optional(Schema.String),
6714
+ recipient_party_kind: Schema.optional(Schema.Literals([
6715
+ "person",
6716
+ "organization",
6717
+ "unresolved"
6718
+ ])),
6719
+ recipient_handle: Schema.optional(Schema.String),
6720
+ recipient_address: AddressSchema,
6721
+ external_address_acknowledged: Schema.Boolean
6722
+ });
6522
6723
  Schema.Struct({
6724
+ recipientObservation: RecipientObservationSchema,
6523
6725
  executionId: MoneyExecutionIdSchema,
6524
6726
  commandId: PaymentCommandIdSchema,
6525
6727
  paymentId: PaymentIdSchema,
@@ -6536,6 +6738,14 @@ Schema.Struct({
6536
6738
  executionId: MoneyExecutionIdSchema,
6537
6739
  signature: OwnerSignatureSchema
6538
6740
  });
6741
+ Schema.Struct({
6742
+ executionId: MoneyExecutionIdSchema,
6743
+ reason: Schema.Literals([
6744
+ "signer_rejected",
6745
+ "cancelled",
6746
+ "prepared_mismatch"
6747
+ ])
6748
+ });
6539
6749
  Schema.Struct({
6540
6750
  executionId: MoneyExecutionIdSchema,
6541
6751
  commandId: PaymentCommandIdSchema,
@@ -6549,6 +6759,10 @@ Schema.Struct({
6549
6759
  payments: Schema.Array(Payment)
6550
6760
  });
6551
6761
  const PaymentLifecycleExecutionIntentSchema = Schema.Union([
6762
+ Schema.Struct({
6763
+ kind: Schema.Literal("retry"),
6764
+ paymentId: PaymentIdSchema
6765
+ }),
6552
6766
  Schema.Struct({
6553
6767
  kind: Schema.Literal("claim"),
6554
6768
  paymentId: PaymentIdSchema
@@ -6569,6 +6783,7 @@ Schema.Struct({
6569
6783
  });
6570
6784
  const OrganizationPaymentExecutionItemSchema = Schema.Struct({
6571
6785
  to: PaymentRef,
6786
+ externalAddressAcknowledged: Schema.optional(Schema.Literal(true)),
6572
6787
  amount: FinancialOpsMoney,
6573
6788
  paymentType: Schema.optional(Schema.Literals([
6574
6789
  "unspecified",
@@ -6587,6 +6802,8 @@ Schema.Struct({
6587
6802
  lineage: Schema.optional(PaymentCommandLineageSchema)
6588
6803
  });
6589
6804
  const PreparedPaymentCommandExecutionSchema = Schema.Struct({
6805
+ recipientObservations: Schema.Array(RecipientObservationSchema),
6806
+ emitPaymentInitiated: Schema.Boolean,
6590
6807
  executionId: MoneyExecutionIdSchema,
6591
6808
  commandId: PaymentCommandIdSchema,
6592
6809
  paymentIds: Schema.Array(PaymentIdSchema),
@@ -6622,7 +6839,8 @@ const PermissionCommandSchema = Schema.Union([
6622
6839
  operation: Schema.Literal("assign"),
6623
6840
  requestKey: nonEmpty("requestKey"),
6624
6841
  permissionId: PermissionIdSchema,
6625
- accountId: nonEmpty("accountId")
6842
+ accountId: nonEmpty("accountId"),
6843
+ expectedMemberEmail: Schema.optional(nonEmpty("expectedMemberEmail"))
6626
6844
  }),
6627
6845
  Schema.Struct({
6628
6846
  operation: Schema.Literal("revoke"),
@@ -6877,9 +7095,10 @@ const INVOCATION_OBSERVATION = Symbol("capxul.invocation-observation");
6877
7095
  const FAILURE_INVOCATION_SNAPSHOT = Symbol("capxul.failure-invocation-snapshot");
6878
7096
  /** @internal Attach one immutable, non-wire invocation snapshot to an SDK-owned object. */
6879
7097
  function attachInvocationObservation(target, source) {
6880
- const snapshot = Object.freeze(source.context === void 0 ? { active: source.active } : {
7098
+ const snapshot = Object.freeze({
6881
7099
  active: source.active,
6882
- context: Object.freeze({ ...source.context })
7100
+ ...source.actorId === void 0 ? {} : { actorId: source.actorId },
7101
+ ...source.context === void 0 ? {} : { context: Object.freeze({ ...source.context }) }
6883
7102
  });
6884
7103
  Object.defineProperty(target, INVOCATION_OBSERVATION, {
6885
7104
  configurable: false,
@@ -6909,6 +7128,12 @@ function markFailureInvocationSnapshot(failure, snapshot) {
6909
7128
  });
6910
7129
  return failure;
6911
7130
  }
7131
+ /** @internal Read the call-start delivery decision; undefined means a direct adapter call. */
7132
+ function readFailureInvocationSnapshot(failure) {
7133
+ if (typeof failure !== "object" || failure === null) return void 0;
7134
+ const snapshot = failure[FAILURE_INVOCATION_SNAPSHOT];
7135
+ return typeof snapshot === "object" && snapshot !== null && "active" in snapshot ? snapshot : void 0;
7136
+ }
6912
7137
  //#endregion
6913
7138
  //#region ../../packages/sdk/src/surface/_shared/provisioning-telemetry.ts
6914
7139
  async function emitProvisioningTelemetry(telemetry, smartAccount) {
@@ -9526,10 +9751,10 @@ const logIdentityTransition = (record) => (record.outcome === "applied" ? Effect
9526
9751
  //#region ../../packages/sdk/src/domain/machine/shell.ts
9527
9752
  const INVOCATION_PARENT_SPAN = Symbol("@capxul/sdk/identity-invocation-parent-span");
9528
9753
  function carryInvocationParentSpan(controls, parent) {
9529
- return {
9754
+ return copyInvocationObservation(controls, {
9530
9755
  ...controls,
9531
9756
  [INVOCATION_PARENT_SPAN]: parent
9532
- };
9757
+ });
9533
9758
  }
9534
9759
  function withInvocationParentSpan(effect, controls) {
9535
9760
  const parent = controls?.[INVOCATION_PARENT_SPAN];
@@ -9880,13 +10105,13 @@ async function toCapxulResult(program, layer) {
9880
10105
  * with `{ publicError }` rather than a bare `CapxulError`, so the wrapper is
9881
10106
  * unwrapped here — once — instead of at every call site.
9882
10107
  */
9883
- async function runIfActive(signal, operation, effect, runPromise = Effect.runPromise) {
9884
- if (signal?.aborted === true) return {
10108
+ async function runIfActive(signal, operation, effect, runPromise = Effect.runPromise, observe) {
10109
+ if (signal?.aborted === true && observe === void 0) return {
9885
10110
  ok: false,
9886
10111
  error: Errors.cancelled({ operation })
9887
10112
  };
9888
- const program = effect().pipe(Effect.mapError((error) => error.publicError));
9889
- return runProgram(signal === void 0 ? program : Effect.raceFirst(program, Effect.callback((resume) => {
10113
+ const program = signal?.aborted === true ? Effect.fail(Errors.cancelled({ operation })) : Effect.suspend(effect).pipe(Effect.mapError((error) => error.publicError));
10114
+ const controlled = signal === void 0 ? program : Effect.raceFirst(program, Effect.callback((resume) => {
9890
10115
  if (signal.aborted) {
9891
10116
  resume(Effect.fail(Errors.cancelled({ operation })));
9892
10117
  return Effect.void;
@@ -9894,7 +10119,8 @@ async function runIfActive(signal, operation, effect, runPromise = Effect.runPro
9894
10119
  const onAbort = () => resume(Effect.fail(Errors.cancelled({ operation })));
9895
10120
  signal.addEventListener("abort", onAbort, { once: true });
9896
10121
  return Effect.sync(() => signal.removeEventListener("abort", onAbort));
9897
- })), runPromise);
10122
+ }));
10123
+ return runProgram(observe === void 0 ? controlled : observe(controlled), runPromise);
9898
10124
  }
9899
10125
  //#endregion
9900
10126
  //#region ../../packages/sdk/src/surface/_shared/effect-actor-bridge.ts
@@ -9945,22 +10171,52 @@ async function runPortEffect(effect, controls, operation = CAPXUL_OPERATIONS.run
9945
10171
  orElse: () => Effect.fail({ publicError: Errors.providerTimeout("sdk", operation, timeoutMs) })
9946
10172
  }))).pipe(Effect.mapError((failure) => failure.publicError)), controls, operation, runPromise);
9947
10173
  }
10174
+ /** Keep observation metadata while the compound operation owns cancellation. */
10175
+ function observationOnlyControls(controls) {
10176
+ const { signal: _signal, timeoutMs: _timeoutMs, deadlineMs: _deadlineMs, ...observation } = controls ?? {};
10177
+ return copyInvocationObservation(controls, observation);
10178
+ }
9948
10179
  /** Observe a public Effect that already uses the canonical CapxulError channel. */
9949
10180
  async function runCapxulEffect(effect, controls, operation = CAPXUL_OPERATIONS.runtime.port, runPromise = Effect.runPromise) {
9950
10181
  const invocation = readInvocationObservation(controls);
9951
- const correlationId = safeEngineeringIdentifier(controls?.correlation_id ?? invocation?.context?.correlationId);
9952
- const observed = effect.pipe(Effect.tap(() => Effect.annotateCurrentSpan({ outcome: "succeeded" })), Effect.tapError((error) => {
9953
- const mode = error.mode ?? error.details?.failure_mode;
9954
- return Effect.annotateCurrentSpan({
9955
- outcome: portFailureOutcome(error.code),
9956
- failure_code: error.code,
9957
- ...typeof mode === "string" ? { mode } : {}
9958
- });
9959
- }), Effect.tapDefect(() => Effect.annotateCurrentSpan({
9960
- outcome: "failed",
9961
- failure_code: "UNKNOWN"
9962
- })), Effect.withSpan(`identity.port.${operation}`), Effect.annotateSpans(correlationId === void 0 ? {} : { correlation_id: correlationId }));
9963
- return runIfActive(controls?.signal, operation, () => withInvocationParentSpan(observed, controls).pipe(Effect.mapError((publicError) => ({ publicError }))), runPromise);
10182
+ const correlationId = safeEngineeringIdentifier(invocation?.context?.correlationId ?? controls?.correlation_id);
10183
+ const context = invocation?.active === false ? void 0 : sanitizeObservationContext(invocation?.context);
10184
+ const fields = {
10185
+ operation,
10186
+ ...correlationId === void 0 ? {} : { correlation_id: correlationId },
10187
+ ...context?.sessionId === void 0 ? {} : {
10188
+ session_id: context.sessionId,
10189
+ sessionId: context.sessionId
10190
+ },
10191
+ ...context?.journeyId === void 0 ? {} : { journey_id: context.journeyId },
10192
+ ...context?.release === void 0 ? {} : { release: context.release },
10193
+ ...context?.application === void 0 ? {} : { application: context.application },
10194
+ ...safeEngineeringIdentifier(invocation?.actorId) === void 0 ? {} : {
10195
+ actor_id: invocation.actorId,
10196
+ actor_kind: "authenticated",
10197
+ posthogDistinctId: invocation.actorId
10198
+ }
10199
+ };
10200
+ const result = await runIfActive(controls?.signal, operation, () => effect.pipe(Effect.mapError((publicError) => ({ publicError }))), runPromise, (program) => withInvocationParentSpan(Effect.gen(function* () {
10201
+ const startedAt = yield* Clock.currentTimeMillis;
10202
+ const exit = yield* Effect.exit(program.pipe(Effect.catchDefect((cause) => Effect.fail(Errors.unknown(cause)))));
10203
+ const duration_ms = (yield* Clock.currentTimeMillis) - startedAt;
10204
+ const error = Exit.isFailure(exit) ? Cause.squash(exit.cause) : void 0;
10205
+ const failure = error instanceof CapxulError ? error : void 0;
10206
+ const outcome = Exit.isSuccess(exit) ? "succeeded" : failure?.code === "CANCELLED" ? "cancelled" : failure !== void 0 && EXPECTED_OPERATION_OUTCOMES.has(failure.code) ? "refused" : "failed";
10207
+ const completion = {
10208
+ ...fields,
10209
+ duration_ms,
10210
+ outcome,
10211
+ ...failure === void 0 ? {} : { failure_code: failure.code },
10212
+ ...typeof failure?.mode === "string" ? { mode: failure.mode } : {},
10213
+ ...failure?.mode === void 0 && typeof failure?.details?.failure_mode === "string" ? { mode: failure.details.failure_mode } : {}
10214
+ };
10215
+ yield* Effect.annotateCurrentSpan(completion).pipe(Effect.catchCause(() => Effect.void));
10216
+ yield* (outcome === "failed" ? Effect.logError("capxul_sdk_operation") : Effect.logInfo("capxul_sdk_operation")).pipe(Effect.annotateLogs(completion), Effect.catchCause(() => Effect.void));
10217
+ return yield* Exit.isSuccess(exit) ? Effect.succeed(exit.value) : Effect.failCause(exit.cause);
10218
+ }).pipe(Effect.withSpan(operation)), controls));
10219
+ return !result.ok && invocation !== void 0 ? markFailureInvocationSnapshot(result, invocation) : result;
9964
10220
  }
9965
10221
  /** Map machine-internal failure state onto the public SDK error vocabulary. */
9966
10222
  function publicIdentityFailure(failure) {
@@ -10519,76 +10775,110 @@ function makeActorRelationshipMethods(deps) {
10519
10775
  const fns = actorScopeContract;
10520
10776
  return {
10521
10777
  addressBook: {
10522
- list: (input, options) => mapOk$1(CAPXUL_OPERATIONS.addressBook.list, awaitableConvex(options?.signal, CAPXUL_OPERATIONS.addressBook.list, () => convexCall.query(fns.addressBookList, {
10523
- actor,
10524
- ...input?.includeHidden === void 0 ? {} : { includeHidden: input.includeHidden }
10525
- })), (entries) => entries.map(mapAddressBookEntry)),
10526
- get: (entryId, options) => mapOk$1(CAPXUL_OPERATIONS.addressBook.get, awaitableConvex(options?.signal, CAPXUL_OPERATIONS.addressBook.get, () => convexCall.query(fns.addressBookGet, {
10527
- actor,
10528
- partyId: entryId
10529
- })), (entry) => entry === null ? null : mapAddressBookEntry(entry)),
10530
- add: async (input, options) => {
10778
+ list: (input, options) => {
10779
+ const controls = deps.invocationControls?.(options) ?? options;
10780
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.addressBook.list, Effect.suspend(() => convexCall.query(fns.addressBookList, copyInvocationObservation(controls, {
10781
+ actor,
10782
+ ...input?.includeHidden === void 0 ? {} : { includeHidden: input.includeHidden }
10783
+ }))), (entries) => entries.map(mapAddressBookEntry)), controls, CAPXUL_OPERATIONS.addressBook.list, deps.runPromise);
10784
+ },
10785
+ get: (entryId, options) => {
10786
+ const controls = deps.invocationControls?.(options) ?? options;
10787
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.addressBook.get, Effect.suspend(() => convexCall.query(fns.addressBookGet, copyInvocationObservation(controls, {
10788
+ actor,
10789
+ partyId: entryId
10790
+ }))), (entry) => entry === null ? null : mapAddressBookEntry(entry)), controls, CAPXUL_OPERATIONS.addressBook.get, deps.runPromise);
10791
+ },
10792
+ add: (input, options) => {
10793
+ const controls = deps.invocationControls?.(options) ?? options;
10531
10794
  const ref = normalizeRefForBackend$1(input.ref, "ref");
10532
- if (!ref.ok) return ref;
10533
- return mapOk$1(CAPXUL_OPERATIONS.addressBook.add, await awaitableConvex(options?.signal, CAPXUL_OPERATIONS.addressBook.add, () => convexCall.mutation(fns.addressBookAdd, {
10795
+ if (!ref.ok) return runCapxulEffect(Effect.fail(ref.error), controls, CAPXUL_OPERATIONS.addressBook.add, deps.runPromise);
10796
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.addressBook.add, Effect.suspend(() => convexCall.mutation(fns.addressBookAdd, copyInvocationObservation(controls, {
10534
10797
  actor,
10535
10798
  ref: ref.value,
10536
10799
  ...input.label === void 0 ? {} : { label: input.label }
10537
- })), mapAddressBookEntry);
10800
+ }))), mapAddressBookEntry), controls, CAPXUL_OPERATIONS.addressBook.add, deps.runPromise);
10801
+ },
10802
+ hide: (entryId, options) => {
10803
+ const controls = deps.invocationControls?.(options) ?? options;
10804
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.addressBook.hide, Effect.suspend(() => convexCall.mutation(fns.addressBookHide, copyInvocationObservation(controls, {
10805
+ actor,
10806
+ partyId: entryId
10807
+ }))), mapAddressBookEntry), controls, CAPXUL_OPERATIONS.addressBook.hide, deps.runPromise);
10808
+ },
10809
+ unhide: (entryId, options) => {
10810
+ const controls = deps.invocationControls?.(options) ?? options;
10811
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.addressBook.unhide, Effect.suspend(() => convexCall.mutation(fns.addressBookUnhide, copyInvocationObservation(controls, {
10812
+ actor,
10813
+ partyId: entryId
10814
+ }))), mapAddressBookEntry), controls, CAPXUL_OPERATIONS.addressBook.unhide, deps.runPromise);
10538
10815
  },
10539
- hide: (entryId, options) => mapOk$1(CAPXUL_OPERATIONS.addressBook.hide, awaitableConvex(options?.signal, CAPXUL_OPERATIONS.addressBook.hide, () => convexCall.mutation(fns.addressBookHide, {
10540
- actor,
10541
- partyId: entryId
10542
- })), mapAddressBookEntry),
10543
- unhide: (entryId, options) => mapOk$1(CAPXUL_OPERATIONS.addressBook.unhide, awaitableConvex(options?.signal, CAPXUL_OPERATIONS.addressBook.unhide, () => convexCall.mutation(fns.addressBookUnhide, {
10544
- actor,
10545
- partyId: entryId
10546
- })), mapAddressBookEntry),
10547
- label: (input, options) => mapOk$1(CAPXUL_OPERATIONS.addressBook.label, awaitableConvex(options?.signal, CAPXUL_OPERATIONS.addressBook.label, () => convexCall.mutation(fns.addressBookLabel, {
10548
- actor,
10549
- partyId: input.entryId,
10550
- label: input.label
10551
- })), mapAddressBookEntry)
10816
+ label: (input, options) => {
10817
+ const controls = deps.invocationControls?.(options) ?? options;
10818
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.addressBook.label, Effect.suspend(() => convexCall.mutation(fns.addressBookLabel, copyInvocationObservation(controls, {
10819
+ actor,
10820
+ partyId: input.entryId,
10821
+ label: input.label
10822
+ }))), mapAddressBookEntry), controls, CAPXUL_OPERATIONS.addressBook.label, deps.runPromise);
10823
+ }
10552
10824
  },
10553
10825
  requests: {
10554
- issue: async (input, options) => {
10826
+ issue: (input, options) => {
10827
+ const controls = deps.invocationControls?.(options) ?? options;
10555
10828
  const payer = normalizeRefForBackend$1(input.payer, "payer");
10556
- if (!payer.ok) return payer;
10557
- return mapOk$1(CAPXUL_OPERATIONS.requests.issue, await awaitableConvex(options?.signal, CAPXUL_OPERATIONS.requests.issue, () => convexCall.mutation(fns.requestsIssue, {
10829
+ if (!payer.ok) return runCapxulEffect(Effect.fail(payer.error), controls, CAPXUL_OPERATIONS.requests.issue, deps.runPromise);
10830
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.requests.issue, Effect.suspend(() => convexCall.mutation(fns.requestsIssue, copyInvocationObservation(controls, {
10558
10831
  actor,
10559
10832
  payer: payer.value,
10560
10833
  amount: input.amount,
10561
10834
  reference: input.reference,
10562
10835
  ...input.memo === void 0 ? {} : { memo: input.memo },
10563
10836
  ...input.expiresAt === void 0 ? {} : { expiresAt: input.expiresAt }
10564
- })), (request) => mapActorRequest(request, input.payer));
10837
+ }))), (request) => mapActorRequest(request, input.payer)), controls, CAPXUL_OPERATIONS.requests.issue, deps.runPromise);
10838
+ },
10839
+ list: (options) => {
10840
+ const controls = deps.invocationControls?.(options) ?? options;
10841
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.requests.list, Effect.suspend(() => convexCall.query(fns.requestsList, copyInvocationObservation(controls, { actor }))), (requests) => requests.map((request) => mapActorRequest(request))), controls, CAPXUL_OPERATIONS.requests.list, deps.runPromise);
10842
+ },
10843
+ get: (requestId, options) => {
10844
+ const controls = deps.invocationControls?.(options) ?? options;
10845
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.requests.get, Effect.suspend(() => convexCall.query(fns.requestsGet, copyInvocationObservation(controls, {
10846
+ actor,
10847
+ paymentRequestId: requestId
10848
+ }))), (request) => request === null ? null : mapActorRequest(request)), controls, CAPXUL_OPERATIONS.requests.get, deps.runPromise);
10565
10849
  },
10566
- list: (options) => mapOk$1(CAPXUL_OPERATIONS.requests.list, awaitableConvex(options?.signal, CAPXUL_OPERATIONS.requests.list, () => convexCall.query(fns.requestsList, { actor })), (requests) => requests.map((request) => mapActorRequest(request))),
10567
- get: (requestId, options) => mapOk$1(CAPXUL_OPERATIONS.requests.get, awaitableConvex(options?.signal, CAPXUL_OPERATIONS.requests.get, () => convexCall.query(fns.requestsGet, {
10568
- actor,
10569
- paymentRequestId: requestId
10570
- })), (request) => request === null ? null : mapActorRequest(request)),
10571
- cancel: (requestId, options) => mapOk$1(CAPXUL_OPERATIONS.requests.cancel, awaitableConvex(options?.signal, CAPXUL_OPERATIONS.requests.cancel, () => convexCall.mutation(fns.requestsCancel, {
10572
- actor,
10573
- paymentRequestId: requestId
10574
- })), (request) => mapActorRequest(request))
10850
+ cancel: (requestId, options) => {
10851
+ const controls = deps.invocationControls?.(options) ?? options;
10852
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.requests.cancel, Effect.suspend(() => convexCall.mutation(fns.requestsCancel, copyInvocationObservation(controls, {
10853
+ actor,
10854
+ paymentRequestId: requestId
10855
+ }))), (request) => mapActorRequest(request)), controls, CAPXUL_OPERATIONS.requests.cancel, deps.runPromise);
10856
+ }
10575
10857
  },
10576
10858
  inbox: {
10577
- list: (options) => mapOk$1(CAPXUL_OPERATIONS.inbox.list, awaitableConvex(options?.signal, CAPXUL_OPERATIONS.inbox.list, () => convexCall.query(fns.inboxList, { actor })), (items) => items.map(mapInboxItem)),
10578
- approve: async (input, options) => {
10579
- const result = await awaitableConvex(options?.signal, CAPXUL_OPERATIONS.inbox.approve, () => convexCall.mutation(fns.inboxApprove, {
10859
+ list: (options) => {
10860
+ const controls = deps.invocationControls?.(options) ?? options;
10861
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.inbox.list, Effect.suspend(() => convexCall.query(fns.inboxList, copyInvocationObservation(controls, { actor }))), (items) => items.map(mapInboxItem)), controls, CAPXUL_OPERATIONS.inbox.list, deps.runPromise);
10862
+ },
10863
+ approve: (input, options) => {
10864
+ const controls = deps.invocationControls?.(options) ?? options;
10865
+ return runPortEffect(Effect.suspend(() => convexCall.mutation(fns.inboxApprove, copyInvocationObservation(controls, {
10580
10866
  actor,
10581
10867
  paymentRequestId: input.requestId,
10582
10868
  ...input.timing === void 0 ? {} : { timing: input.timing },
10583
10869
  ...input.permissionId === void 0 ? {} : { permissionId: input.permissionId }
10584
- }));
10585
- if (!result.ok) return result;
10586
- return mapApprovedInboxPayment(result.value, input);
10870
+ }))).pipe(Effect.flatMap((prepared) => {
10871
+ const result = mapApprovedInboxPayment(prepared, input);
10872
+ return result.ok ? Effect.succeed(result.value) : Effect.fail({ publicError: result.error });
10873
+ })), controls, CAPXUL_OPERATIONS.inbox.approve, deps.runPromise);
10587
10874
  },
10588
- decline: (requestId, options) => mapOk$1(CAPXUL_OPERATIONS.inbox.decline, awaitableConvex(options?.signal, CAPXUL_OPERATIONS.inbox.decline, () => convexCall.mutation(fns.inboxDecline, {
10589
- actor,
10590
- paymentRequestId: requestId
10591
- })), mapInboxItem)
10875
+ decline: (requestId, options) => {
10876
+ const controls = deps.invocationControls?.(options) ?? options;
10877
+ return runPortEffect(mapReply(CAPXUL_OPERATIONS.inbox.decline, Effect.suspend(() => convexCall.mutation(fns.inboxDecline, copyInvocationObservation(controls, {
10878
+ actor,
10879
+ paymentRequestId: requestId
10880
+ }))), mapInboxItem), controls, CAPXUL_OPERATIONS.inbox.decline, deps.runPromise);
10881
+ }
10592
10882
  },
10593
10883
  profile: {
10594
10884
  get: (options) => {
@@ -10665,22 +10955,12 @@ function missingConvexCall(operation) {
10665
10955
  * promise and the caller's `if (!result.ok)` never runs (ADR-0023: errors are
10666
10956
  * values, and a code crosses the seam).
10667
10957
  */
10668
- async function mapOk$1(operation, resultOrPromise, f) {
10669
- const result = await resultOrPromise;
10670
- if (!result.ok) return result;
10671
- try {
10672
- return {
10673
- ok: true,
10674
- value: f(result.value)
10675
- };
10676
- } catch (cause) {
10677
- return {
10678
- ok: false,
10679
- error: cause instanceof CapxulError ? cause : Errors.providerError("convex", operation, cause)
10680
- };
10681
- }
10958
+ function mapReply(operation, program, project) {
10959
+ return program.pipe(Effect.flatMap((value) => Effect.try({
10960
+ try: () => project(value),
10961
+ catch: (cause) => ({ publicError: cause instanceof CapxulError ? cause : Errors.providerError("convex", operation, cause) })
10962
+ })));
10682
10963
  }
10683
- const awaitableConvex = runIfActive;
10684
10964
  const ADDRESS_BOOK_RELATIONSHIPS = [
10685
10965
  "paid",
10686
10966
  "paidBy",
@@ -10806,25 +11086,11 @@ function normalizeRefForBackend$1(ref, field) {
10806
11086
  email: nonEmptyRefValue$1(ref.email, "email")
10807
11087
  }
10808
11088
  };
10809
- case "orgHandle": return {
10810
- ok: true,
10811
- value: {
10812
- kind: "orgHandle",
10813
- orgHandle: nonEmptyRefValue$1(ref.orgHandle, "orgHandle")
10814
- }
10815
- };
10816
- case "capxulUserId": return {
10817
- ok: true,
10818
- value: {
10819
- kind: "capxulUserId",
10820
- capxulUserId: nonEmptyRefValue$1(ref.capxulUserId, "capxulUserId")
10821
- }
10822
- };
10823
- case "payeeId": return {
11089
+ case "address": return {
10824
11090
  ok: true,
10825
11091
  value: {
10826
- kind: "payeeId",
10827
- payeeId: nonEmptyRefValue$1(ref.payeeId, "payeeId")
11092
+ kind: "address",
11093
+ address: toAddress(ref.address)
10828
11094
  }
10829
11095
  };
10830
11096
  case "party": return {
@@ -11062,6 +11328,8 @@ function makeAccountMethods(deps) {
11062
11328
  return {
11063
11329
  methods: {
11064
11330
  ...makeActorRelationshipMethods({
11331
+ ...deps.runPromise === void 0 ? {} : { runPromise: deps.runPromise },
11332
+ ...deps.invocationControls === void 0 ? {} : { invocationControls: deps.invocationControls },
11065
11333
  actor: { kind: "account" },
11066
11334
  ...deps.convexCall === void 0 ? {} : { convexCall: deps.convexCall },
11067
11335
  ...deps.profileMethods === void 0 ? {} : { accountProfileMethods: deps.profileMethods }
@@ -11088,10 +11356,7 @@ function makeAccountMethods(deps) {
11088
11356
  const financialOpsContract = {
11089
11357
  me: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].me),
11090
11358
  depositInstructions: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].depositInstructions),
11091
- resolveHandle: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].resolveHandle),
11092
- createPayee: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/mutations"].createPayee),
11093
- getPayee: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].getPayee),
11094
- resolvePayee: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].resolvePayee),
11359
+ resolveRecipient: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].resolveRecipient),
11095
11360
  addDestination: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/destinations"].add),
11096
11361
  listDestinations: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/destinations"].list),
11097
11362
  removeDestination: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/destinations"].remove),
@@ -11107,6 +11372,7 @@ const financialOpsContract = {
11107
11372
  //#endregion
11108
11373
  //#region ../../packages/sdk/src/contract/money-execution.ts
11109
11374
  const moneyExecutionContract = {
11375
+ abandonPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].abandonPaymentExecution),
11110
11376
  preparePermissionExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].preparePermissionExecution),
11111
11377
  preparePaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].preparePaymentExecution),
11112
11378
  prepareOrganizationPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/paymentCommandActions"].prepareOrganizationPaymentExecution),
@@ -11117,7 +11383,7 @@ const moneyExecutionContract = {
11117
11383
  };
11118
11384
  //#endregion
11119
11385
  //#region ../../packages/sdk/package.json
11120
- var version$1 = "3.2.0";
11386
+ var version$1 = "4.0.1";
11121
11387
  //#endregion
11122
11388
  //#region ../../packages/sdk/src/telemetry/exception-projection.ts
11123
11389
  /** Fixed fallback for failures that have no safe message. */
@@ -11196,7 +11462,8 @@ function observeSdkClient(client, adapter, snapshot) {
11196
11462
  };
11197
11463
  const processOutput = (output, path, invocation) => {
11198
11464
  if (isFailedResult(output)) {
11199
- report(adapter, "operation", path.join("."), output.error, invocation);
11465
+ const captured = readFailureInvocationSnapshot(output);
11466
+ report(adapter, "operation", path.join("."), output.error, captured ?? invocation, void 0, captured !== void 0);
11200
11467
  return output;
11201
11468
  }
11202
11469
  if (isCapxulResult(output)) return output;
@@ -11228,7 +11495,7 @@ function reportedByMachine(cause) {
11228
11495
  }
11229
11496
  return false;
11230
11497
  }
11231
- function report(adapter, kind, operation, cause, invocation, origin) {
11498
+ function report(adapter, kind, operation, cause, invocation, origin, authoritativeSnapshot = false) {
11232
11499
  if (origin === "machine") {
11233
11500
  let link = cause;
11234
11501
  for (let depth = 0; depth < 8 && typeof link === "object" && link !== null; depth++) {
@@ -11240,7 +11507,7 @@ function report(adapter, kind, operation, cause, invocation, origin) {
11240
11507
  const kindName = normalizeErrorKind(errorKind$1(cause));
11241
11508
  const context = sanitizeObservationContext({
11242
11509
  ...invocation.context,
11243
- ...isCapxulError(cause) && cause.correlationId !== void 0 ? { correlationId: cause.correlationId } : {}
11510
+ ...!authoritativeSnapshot && isCapxulError(cause) && cause.correlationId !== void 0 ? { correlationId: cause.correlationId } : {}
11244
11511
  });
11245
11512
  const detail = failureDetail(cause);
11246
11513
  const evidence = failureEvidence(cause);
@@ -11254,6 +11521,7 @@ function report(adapter, kind, operation, cause, invocation, origin) {
11254
11521
  ...evidence
11255
11522
  }, {
11256
11523
  active: invocation.active,
11524
+ ...invocation.actorId === void 0 ? {} : { actorId: invocation.actorId },
11257
11525
  ...context === void 0 ? {} : { context }
11258
11526
  });
11259
11527
  try {
@@ -11633,7 +11901,11 @@ function emitPaymentInitiated(telemetry, input) {
11633
11901
  name: "payment_initiated",
11634
11902
  props: {
11635
11903
  kind: input.kind,
11636
- payment_id: input.paymentId
11904
+ payment_id: input.paymentId,
11905
+ payment_lifecycle_id: `payment_lifecycle_${input.paymentId}`,
11906
+ ...input.commandId === void 0 ? {} : { command_id: input.commandId },
11907
+ ...input.executionId === void 0 ? {} : { execution_id: input.executionId },
11908
+ ...input.recipient
11637
11909
  }
11638
11910
  });
11639
11911
  }
@@ -11665,7 +11937,17 @@ async function fingerprintPaymentIntent(intent) {
11665
11937
  function matchesIntent(expected) {
11666
11938
  return async (request) => await fingerprintPaymentIntent(request) === await fingerprintPaymentIntent(expected);
11667
11939
  }
11668
- async function executePrepared(deps, prepare, isExpectedRequest, signal) {
11940
+ async function abandonPrepared$1(deps, executionId, closePayment, reason, result, onPreparedClosed, controls) {
11941
+ if (!closePayment) return result;
11942
+ const abandoned = await runIfActive(void 0, CAPXUL_OPERATIONS.moneyExecution.abandonPaymentExecution, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.action(deps.functions.abandonPaymentExecution, copyInvocationObservation(controls, { input: {
11943
+ executionId,
11944
+ reason
11945
+ } }))), controls), deps.runPromise);
11946
+ if (!abandoned.ok) return abandoned;
11947
+ if (abandoned.value) onPreparedClosed?.();
11948
+ return result;
11949
+ }
11950
+ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnExit, onPreparedClosed, signal, controls) {
11669
11951
  if (isAborted$2(signal)) return {
11670
11952
  ok: false,
11671
11953
  error: Errors.cancelled({ operation: "payments" })
@@ -11686,48 +11968,61 @@ async function executePrepared(deps, prepare, isExpectedRequest, signal) {
11686
11968
  }
11687
11969
  const prepared = await prepare(signerAddress);
11688
11970
  if (!prepared.ok) return prepared;
11689
- if (!await isExpectedRequest(prepared.value.request)) return {
11971
+ if (!await isExpectedRequest(prepared.value.request)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "prepared_mismatch", {
11690
11972
  ok: false,
11691
11973
  error: Errors.invalidInput("payment", "prepared command mismatch")
11692
- };
11974
+ }, onPreparedClosed, controls);
11693
11975
  const expectedSafe = deriveCapxulSafeAddress({ email: session.email });
11694
- if (prepared.value.chainId !== deps.chainId || prepared.value.signerAddress.toLowerCase() !== signerAddress.toLowerCase() || prepared.value.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return {
11976
+ if (prepared.value.chainId !== deps.chainId || prepared.value.signerAddress.toLowerCase() !== signerAddress.toLowerCase() || prepared.value.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "prepared_mismatch", {
11695
11977
  ok: false,
11696
11978
  error: Errors.invalidInput("payment", "prepared authority mismatch")
11697
- };
11698
- if (isAborted$2(signal)) return {
11979
+ }, onPreparedClosed, controls);
11980
+ if (isAborted$2(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
11699
11981
  ok: false,
11700
11982
  error: Errors.cancelled({ operation: "payments" })
11701
- };
11983
+ }, onPreparedClosed, controls);
11984
+ if (prepared.value.emitPaymentInitiated && "items" in prepared.value.request) for (const [index, item] of prepared.value.request.items.entries()) {
11985
+ const paymentId = prepared.value.paymentIds[index];
11986
+ const recipient = prepared.value.recipientObservations[index];
11987
+ if (paymentId === void 0 || recipient === void 0) continue;
11988
+ const paymentType = paymentTypeForDocumentEnvelope(item.document) ?? item.paymentType ?? "unspecified";
11989
+ await emitPaymentInitiated(deps.telemetry, {
11990
+ commandId: prepared.value.commandId,
11991
+ executionId: prepared.value.executionId,
11992
+ paymentId,
11993
+ kind: paymentType === "unspecified" ? "quick_pay" : paymentType,
11994
+ recipient
11995
+ });
11996
+ }
11702
11997
  let signature;
11703
11998
  try {
11704
11999
  signature = await deps.signer.signUserOpHash(prepared.value.digest);
11705
12000
  } catch (cause) {
11706
- return {
12001
+ return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "signer_rejected", {
11707
12002
  ok: false,
11708
12003
  error: signerFailure(deps.signer.source, "signUserOpHash", cause)
11709
- };
12004
+ }, onPreparedClosed, controls);
11710
12005
  }
11711
- if (isAborted$2(signal)) return {
12006
+ if (isAborted$2(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
11712
12007
  ok: false,
11713
12008
  error: Errors.cancelled({ operation: "payments" })
11714
- };
11715
- return runIfActive(void 0, CAPXUL_OPERATIONS.payments.submitCommandExecution, () => deps.convexCall.action(deps.functions.submitPaymentCommandExecution, { input: {
12009
+ }, onPreparedClosed, controls);
12010
+ return runIfActive(void 0, CAPXUL_OPERATIONS.payments.submitCommandExecution, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.action(deps.functions.submitPaymentCommandExecution, copyInvocationObservation(controls, { input: {
11716
12011
  executionId: prepared.value.executionId,
11717
12012
  signature
11718
- } }));
12013
+ } }))), controls), deps.runPromise);
11719
12014
  }
11720
- function executePaymentLifecycle(deps, intent, signal) {
11721
- return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.payments.prepareLifecycleExecution, () => deps.convexCall.action(deps.functions.preparePaymentLifecycleExecution, { input: {
12015
+ function executePaymentLifecycle(deps, intent, signal, controls) {
12016
+ return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.payments.prepareLifecycleExecution, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.action(deps.functions.preparePaymentLifecycleExecution, copyInvocationObservation(controls, { input: {
11722
12017
  signerAddress,
11723
12018
  intent
11724
- } })), matchesIntent(intent), signal);
12019
+ } }))), controls), deps.runPromise), matchesIntent(intent), false, void 0, signal, controls);
11725
12020
  }
11726
- function executeOrganizationPayment(deps, input, signal) {
11727
- return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.organizationPayments.prepareExecution, () => deps.convexCall.action(deps.functions.prepareOrganizationPaymentExecution, { input: {
12021
+ function executeOrganizationPayment(deps, input, signal, onPreparedClosed, controls) {
12022
+ return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.organizationPayments.prepareExecution, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.action(deps.functions.prepareOrganizationPaymentExecution, copyInvocationObservation(controls, { input: {
11728
12023
  ...input,
11729
12024
  signerAddress
11730
- } })), matchesIntent(input), signal);
12025
+ } }))), controls), deps.runPromise), matchesIntent(input), true, onPreparedClosed, signal, controls);
11731
12026
  }
11732
12027
  //#endregion
11733
12028
  //#region ../../packages/sdk/src/surface/payment-execution.ts
@@ -11759,7 +12054,16 @@ async function signerCall(source, operation, run) {
11759
12054
  };
11760
12055
  }
11761
12056
  }
11762
- async function executePersonalPayment(deps, payment, signal, requestKey) {
12057
+ async function abandonPrepared(deps, executionId, reason, result, onPreparedClosed) {
12058
+ const abandoned = await runIfActive(void 0, CAPXUL_OPERATIONS.moneyExecution.abandonPaymentExecution, () => deps.convexCall.action(deps.functions.abandonPaymentExecution, { input: {
12059
+ executionId,
12060
+ reason
12061
+ } }));
12062
+ if (!abandoned.ok) return abandoned;
12063
+ if (abandoned.value) onPreparedClosed?.();
12064
+ return result;
12065
+ }
12066
+ async function executePersonalPayment(deps, payment, signal, requestKey, onPreparedClosed) {
11763
12067
  if (isAborted$1(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
11764
12068
  if (deps.signer === void 0) return mismatch("signer", "payments.pay requires a configured CapxulSigner");
11765
12069
  const session = deps.actor.authSession();
@@ -11777,18 +12081,21 @@ async function executePersonalPayment(deps, payment, signal, requestKey) {
11777
12081
  payment
11778
12082
  } }));
11779
12083
  if (!prepared.ok) return prepared;
11780
- if (prepared.value.requestKey !== resolvedRequestKey || canonicalJson(prepared.value.payment) !== canonicalJson(payment)) return mismatch("payment", "prepared Payment execution uses another request");
11781
- if (prepared.value.chainId !== deps.chainId) return mismatch("chainId", "prepared Payment execution uses another chain");
11782
- if (prepared.value.signerAddress.toLowerCase() !== signerAddress.value.toLowerCase()) return mismatch("signerAddress", "prepared Payment execution uses another signer");
11783
- if (prepared.value.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return mismatch("userOpSenderSafe", "prepared Payment execution uses another Account Safe");
12084
+ if (prepared.value.requestKey !== resolvedRequestKey || canonicalJson(prepared.value.payment) !== canonicalJson(payment)) return abandonPrepared(deps, prepared.value.executionId, "prepared_mismatch", mismatch("payment", "prepared Payment execution uses another request"), onPreparedClosed);
12085
+ if (prepared.value.chainId !== deps.chainId) return abandonPrepared(deps, prepared.value.executionId, "prepared_mismatch", mismatch("chainId", "prepared Payment execution uses another chain"), onPreparedClosed);
12086
+ if (prepared.value.signerAddress.toLowerCase() !== signerAddress.value.toLowerCase()) return abandonPrepared(deps, prepared.value.executionId, "prepared_mismatch", mismatch("signerAddress", "prepared Payment execution uses another signer"), onPreparedClosed);
12087
+ if (prepared.value.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return abandonPrepared(deps, prepared.value.executionId, "prepared_mismatch", mismatch("userOpSenderSafe", "prepared Payment execution uses another Account Safe"), onPreparedClosed);
11784
12088
  if (prepared.value.emitPaymentInitiated) await emitPaymentInitiated(deps.telemetry, {
11785
12089
  kind: prepared.value.purposeKind,
11786
- paymentId: prepared.value.paymentId
12090
+ paymentId: prepared.value.paymentId,
12091
+ commandId: prepared.value.commandId,
12092
+ executionId: prepared.value.executionId,
12093
+ recipient: prepared.value.recipientObservation
11787
12094
  });
11788
- if (isAborted$1(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
12095
+ if (isAborted$1(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
11789
12096
  const signature = await signerCall(deps.signer.source, "signUserOpHash", () => deps.signer.signUserOpHash(prepared.value.digest));
11790
- if (!signature.ok) return signature;
11791
- if (isAborted$1(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
12097
+ if (!signature.ok) return abandonPrepared(deps, prepared.value.executionId, "signer_rejected", signature, onPreparedClosed);
12098
+ if (isAborted$1(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
11792
12099
  return runIfActive(void 0, CAPXUL_OPERATIONS.payments.submitExecution, () => deps.convexCall.action(deps.functions.submitPaymentExecution, { input: {
11793
12100
  executionId: prepared.value.executionId,
11794
12101
  signature: signature.value
@@ -12016,6 +12323,30 @@ async function waitForPaymentSubmission(submission, signal, operation, onCancel
12016
12323
  });
12017
12324
  });
12018
12325
  }
12326
+ function normalizeActivityDetail(detail) {
12327
+ if (detail === null) return null;
12328
+ if (detail.kind === "payment") {
12329
+ if (detail.evidence === null) return detail;
12330
+ return {
12331
+ ...detail,
12332
+ evidence: {
12333
+ ...detail.evidence,
12334
+ inclusion: "included",
12335
+ verification: "verified",
12336
+ finality: "finalized"
12337
+ }
12338
+ };
12339
+ }
12340
+ return {
12341
+ ...detail,
12342
+ evidence: {
12343
+ ...detail.evidence,
12344
+ inclusion: "included",
12345
+ verification: "verified",
12346
+ canonicalState: "finalized"
12347
+ }
12348
+ };
12349
+ }
12019
12350
  function paymentExecutionIntent(input) {
12020
12351
  if (actorReferenceToBackend(input.actor)?.kind === "org") return {
12021
12352
  ok: false,
@@ -12028,6 +12359,7 @@ function paymentExecutionIntent(input) {
12028
12359
  value: {
12029
12360
  to: to.value,
12030
12361
  amount: input.amount,
12362
+ ...input.externalAddressAcknowledged === void 0 ? {} : { externalAddressAcknowledged: input.externalAddressAcknowledged },
12031
12363
  ...input.paymentType === void 0 ? {} : { paymentType: input.paymentType },
12032
12364
  ...input.document === void 0 ? {} : { document: input.document },
12033
12365
  ...input.timing === void 0 ? {} : { timing: input.timing },
@@ -12065,6 +12397,7 @@ function makeFinancialOpsMethods(deps) {
12065
12397
  let flight = inFlightPersonalPayments.get(sharedKey);
12066
12398
  if (flight === void 0) {
12067
12399
  const controller = new AbortController();
12400
+ const requestState = { resolved: false };
12068
12401
  const submission = executePersonalPayment({
12069
12402
  actor: deps.actor,
12070
12403
  chainId: deps.chainId,
@@ -12072,10 +12405,11 @@ function makeFinancialOpsMethods(deps) {
12072
12405
  functions: executionFns,
12073
12406
  ...deps.signer === void 0 ? {} : { signer: deps.signer },
12074
12407
  ...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
12075
- }, payment.value, controller.signal, requestKey.key);
12408
+ }, payment.value, controller.signal, requestKey.key, () => requestState.resolved = true);
12076
12409
  flight = {
12077
12410
  controller,
12078
12411
  promise: submission,
12412
+ requestState,
12079
12413
  waiters: 0,
12080
12414
  settled: false
12081
12415
  };
@@ -12113,7 +12447,7 @@ function makeFinancialOpsMethods(deps) {
12113
12447
  }
12114
12448
  release(false);
12115
12449
  try {
12116
- await requestKey.finish(submitted.ok);
12450
+ await requestKey.finish(submitted.ok || flight.requestState.resolved);
12117
12451
  } catch {}
12118
12452
  return mapOk(submitted, (value) => normalizePaymentTiming(value.payment));
12119
12453
  };
@@ -12127,87 +12461,61 @@ function makeFinancialOpsMethods(deps) {
12127
12461
  chainId: deps.chainId,
12128
12462
  convexCall: deps.convexCall,
12129
12463
  functions: executionFns,
12130
- signer: deps.signer
12131
- }
12132
- };
12133
- const runLifecycle = async (intent, signal) => {
12134
- const execution = lifecycleDependencies();
12135
- if (!execution.ok) return execution;
12136
- try {
12137
- const submitted = await executePaymentLifecycle(execution.value, intent, signal);
12138
- if (!submitted.ok) return submitted;
12139
- const payments = submitted.value.payments;
12140
- const payment = payments[0];
12141
- if (payment === void 0 || payments.length !== 1) return {
12142
- ok: false,
12143
- error: Errors.unknown()
12144
- };
12145
- return {
12146
- ok: true,
12147
- value: normalizePaymentTiming(payment)
12148
- };
12149
- } catch (cause) {
12150
- return {
12151
- ok: false,
12152
- error: cause instanceof CapxulError ? cause : Errors.unknown(cause)
12153
- };
12464
+ signer: deps.signer,
12465
+ ...deps.runPromise === void 0 ? {} : { runPromise: deps.runPromise }
12154
12466
  }
12155
12467
  };
12468
+ const runLifecycle = (intent, controls, operation) => runCapxulEffect(Effect.gen(function* () {
12469
+ const captured = carryInvocationParentSpan(controls, yield* Effect.currentSpan.pipe(Effect.orDie));
12470
+ const result = yield* Effect.tryPromise({
12471
+ try: async () => {
12472
+ const execution = lifecycleDependencies();
12473
+ if (!execution.ok) return execution;
12474
+ const submitted = await executePaymentLifecycle(execution.value, intent, controls?.signal, captured);
12475
+ if (!submitted.ok) return submitted;
12476
+ const payments = submitted.value.payments;
12477
+ const payment = payments[0];
12478
+ if (payment === void 0 || payments.length !== 1) return {
12479
+ ok: false,
12480
+ error: Errors.unknown()
12481
+ };
12482
+ return {
12483
+ ok: true,
12484
+ value: normalizePaymentTiming(payment)
12485
+ };
12486
+ },
12487
+ catch: (cause) => cause instanceof CapxulError ? cause : Errors.unknown(cause)
12488
+ });
12489
+ return yield* result.ok ? Effect.succeed(result.value) : Effect.fail(result.error);
12490
+ }), observationOnlyControls(controls), operation, deps.runPromise);
12491
+ const retryPayment = (paymentId, controls) => runCapxulEffect(Effect.gen(function* () {
12492
+ const captured = carryInvocationParentSpan(controls, yield* Effect.currentSpan.pipe(Effect.orDie));
12493
+ const result = yield* Effect.tryPromise({
12494
+ try: async () => {
12495
+ const execution = lifecycleDependencies();
12496
+ if (!execution.ok) return execution;
12497
+ const submitted = await executePaymentLifecycle(execution.value, {
12498
+ kind: "retry",
12499
+ paymentId
12500
+ }, controls?.signal, captured);
12501
+ return submitted.ok ? {
12502
+ ok: true,
12503
+ value: submitted.value.payments.map((payment) => normalizePaymentTiming(payment))
12504
+ } : submitted;
12505
+ },
12506
+ catch: (cause) => cause instanceof CapxulError ? cause : Errors.unknown(cause)
12507
+ });
12508
+ return yield* result.ok ? Effect.succeed(result.value) : Effect.fail(result.error);
12509
+ }), observationOnlyControls(controls), CAPXUL_OPERATIONS.payments.retry, deps.runPromise);
12156
12510
  return {
12157
12511
  me: {
12158
12512
  get: (options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.me.get, () => deps.convexCall.query(fns.me, {})),
12159
12513
  depositInstructions: (options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.me.depositInstructions, () => deps.convexCall.query(fns.depositInstructions, {}).pipe(Effect.tap(() => Effect.promise(() => emitDepositInitiated(deps.telemetry)))))
12160
12514
  },
12161
- handles: { resolve: (handle, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.handles.resolve, () => deps.convexCall.query(fns.resolveHandle, { handle })) },
12162
- payees: {
12163
- create: (input, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payees.create, () => deps.convexCall.mutation(fns.createPayee, {
12164
- label: input.label,
12165
- recipient: input.recipient,
12166
- ...input.handle === void 0 ? {} : { handle: input.handle }
12167
- })),
12168
- get: (payeeId, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payees.get, () => deps.convexCall.query(fns.getPayee, { payeeId })),
12169
- resolve: (recipient, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payees.resolve, () => deps.convexCall.query(fns.resolvePayee, { recipient }))
12170
- },
12171
12515
  targets: { resolve: async (reference, options) => {
12172
- switch (reference.kind) {
12173
- case "handle": return mapOk(await runIfActive(options?.signal, CAPXUL_OPERATIONS.targets.resolve.handle, () => deps.convexCall.query(fns.resolveHandle, { handle: reference.handle })), (target) => resolvedTargetFromResolution(reference, target));
12174
- case "email": return mapOk(await runIfActive(options?.signal, CAPXUL_OPERATIONS.targets.resolve.email, () => deps.convexCall.query(fns.resolvePayee, { recipient: reference.email })), (target) => resolvedTargetFromResolution(reference, target));
12175
- case "organization": {
12176
- const resolved = await runIfActive(options?.signal, CAPXUL_OPERATIONS.targets.resolve.organization, () => deps.convexCall.query(fns.resolveHandle, { handle: reference.handle }));
12177
- if (!resolved.ok) return {
12178
- ok: false,
12179
- error: resolved.error
12180
- };
12181
- if (resolved.value.kind !== "org") return {
12182
- ok: false,
12183
- error: Errors.invalidInput("reference", "organization handle could not be resolved")
12184
- };
12185
- return {
12186
- ok: true,
12187
- value: resolvedTargetFromResolution(reference, resolved.value)
12188
- };
12189
- }
12190
- case "payee": {
12191
- const payee = await runIfActive(options?.signal, CAPXUL_OPERATIONS.targets.resolve.payee, () => deps.convexCall.query(fns.getPayee, { payeeId: reference.id }));
12192
- if (!payee.ok) return {
12193
- ok: false,
12194
- error: payee.error
12195
- };
12196
- if (payee.value === null) return {
12197
- ok: false,
12198
- error: Errors.invalidInput("reference", "payee not found")
12199
- };
12200
- return {
12201
- ok: true,
12202
- value: resolvedTargetFromPayee(reference, payee.value)
12203
- };
12204
- }
12205
- case "party":
12206
- case "destination": return Promise.resolve({
12207
- ok: false,
12208
- error: Errors.notImplemented("targets", `resolve.${reference.kind}`)
12209
- });
12210
- }
12516
+ const recipient = normalizeTargetForBackend(reference, "reference");
12517
+ if (!recipient.ok) return recipient;
12518
+ return mapOk(await runIfActive(options?.signal, CAPXUL_OPERATIONS.recipient.resolve, () => deps.convexCall.query(fns.resolveRecipient, { recipient: recipient.value })), resolvedTargetFromResolution);
12211
12519
  } },
12212
12520
  destinations: {
12213
12521
  add: async (input, options) => {
@@ -12250,57 +12558,64 @@ function makeFinancialOpsMethods(deps) {
12250
12558
  },
12251
12559
  payments: {
12252
12560
  pay,
12561
+ retry: (paymentId, options) => retryPayment(paymentId, deps.invocationControls?.(options) ?? options),
12253
12562
  createCommitment: (input, options) => pay(input, options),
12254
12563
  claim: (paymentId, options) => runLifecycle({
12255
12564
  kind: "claim",
12256
12565
  paymentId
12257
- }, options?.signal),
12566
+ }, deps.invocationControls?.(options) ?? options, CAPXUL_OPERATIONS.payments.claim),
12258
12567
  list: async (options) => mapOk(await runIfActive(options?.signal, CAPXUL_OPERATIONS.payments.list, () => deps.convexCall.query(fns.listPayments, {})), (payments) => payments.map(normalizePaymentTiming)),
12259
12568
  get: async (paymentId, options) => mapOk(await runIfActive(options?.signal, CAPXUL_OPERATIONS.payments.get, () => deps.convexCall.query(fns.getPayment, { paymentId })), (payment) => payment === null ? null : normalizePaymentTiming(payment)),
12260
12569
  cancel: (paymentId, options) => runLifecycle({
12261
12570
  kind: "cancel",
12262
12571
  paymentId
12263
- }, options?.signal),
12572
+ }, deps.invocationControls?.(options) ?? options, CAPXUL_OPERATIONS.payments.cancel),
12264
12573
  redirect: async (input, options) => {
12574
+ const controls = deps.invocationControls?.(options) ?? options;
12265
12575
  const recipient = normalizeTargetForBackend(input.to, "to");
12266
- if (!recipient.ok) return recipient;
12576
+ if (!recipient.ok) return runCapxulEffect(Effect.fail(recipient.error), observationOnlyControls(controls), CAPXUL_OPERATIONS.payments.redirect, deps.runPromise);
12267
12577
  return runLifecycle({
12268
12578
  kind: "redirect",
12269
12579
  paymentId: input.paymentId,
12270
12580
  recipient: recipient.value
12271
- }, options?.signal);
12581
+ }, controls, CAPXUL_OPERATIONS.payments.redirect);
12272
12582
  }
12273
12583
  },
12274
12584
  activity: {
12275
- list: (params, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.activity.list, () => deps.convexCall.query(fns.activityList, { input: {
12276
- ...activityActorField(params?.actor),
12277
- ...params?.cursor === void 0 ? {} : { cursor: params.cursor },
12278
- ...params?.limit === void 0 ? {} : { limit: params.limit },
12279
- ...params?.range === void 0 ? {} : { range: params.range },
12280
- ...params?.filter === void 0 ? {} : { filter: params.filter }
12281
- } })),
12282
- summary: (params, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.activity.summary, () => deps.convexCall.query(fns.activitySummary, { input: {
12283
- ...activityActorField(params?.actor),
12284
- ...params?.window === void 0 ? {} : { window: params.window }
12285
- } })),
12585
+ list: (params, options) => {
12586
+ const controls = deps.invocationControls?.(options) ?? options;
12587
+ return runPortEffect(Effect.suspend(() => deps.convexCall.query(fns.activityList, copyInvocationObservation(controls, { input: {
12588
+ ...activityActorField(params?.actor),
12589
+ ...params?.cursor === void 0 ? {} : { cursor: params.cursor },
12590
+ ...params?.limit === void 0 ? {} : { limit: params.limit },
12591
+ ...params?.range === void 0 ? {} : { range: params.range },
12592
+ ...params?.filter === void 0 ? {} : { filter: params.filter }
12593
+ } }))), controls, CAPXUL_OPERATIONS.activity.list, deps.runPromise);
12594
+ },
12595
+ summary: (params, options) => {
12596
+ const controls = deps.invocationControls?.(options) ?? options;
12597
+ return runPortEffect(Effect.suspend(() => deps.convexCall.query(fns.activitySummary, copyInvocationObservation(controls, { input: {
12598
+ ...activityActorField(params?.actor),
12599
+ ...params?.window === void 0 ? {} : { window: params.window }
12600
+ } }))), controls, CAPXUL_OPERATIONS.activity.summary, deps.runPromise);
12601
+ },
12286
12602
  get: (reference, options) => {
12603
+ const controls = deps.invocationControls?.(options) ?? options;
12287
12604
  const actor = actorReferenceToBackend(options?.actor);
12288
- return runIfActive(options?.signal, CAPXUL_OPERATIONS.activity.get, () => deps.convexCall.query(fns.activityGet, {
12605
+ return runPortEffect(Effect.suspend(() => deps.convexCall.query(fns.activityGet, copyInvocationObservation(controls, {
12289
12606
  input: {
12290
12607
  kind: reference.kind,
12291
12608
  id: reference.id,
12292
12609
  ...reference.kind === "payment" ? activityActorField(reference.actor) : {}
12293
12610
  },
12294
12611
  ...actor === void 0 ? {} : { actor }
12295
- }));
12612
+ }))).pipe(Effect.map(normalizeActivityDetail)), controls, CAPXUL_OPERATIONS.activity.get, deps.runPromise);
12296
12613
  },
12297
12614
  annotate: (input, options) => {
12298
- if (input.actor !== void 0 && input.reference.kind === "payment" && input.reference.actor !== void 0 && !sameActor(input.actor, input.reference.actor)) return Promise.resolve({
12299
- ok: false,
12300
- error: Errors.invalidInput("reference.actor", "must match the annotation actor")
12301
- });
12615
+ const controls = deps.invocationControls?.(options) ?? options;
12616
+ if (input.actor !== void 0 && input.reference.kind === "payment" && input.reference.actor !== void 0 && !sameActor(input.actor, input.reference.actor)) return runCapxulEffect(Effect.fail(Errors.invalidInput("reference.actor", "must match the annotation actor")), controls, CAPXUL_OPERATIONS.activity.annotate, deps.runPromise);
12302
12617
  const referenceActor = input.reference.kind === "payment" ? activityActorField(input.reference.actor).actor : void 0;
12303
- return runIfActive(options?.signal, CAPXUL_OPERATIONS.activity.annotate, () => deps.convexCall.mutation(fns.activityAnnotate, { input: {
12618
+ return runPortEffect(Effect.suspend(() => deps.convexCall.mutation(fns.activityAnnotate, copyInvocationObservation(controls, { input: {
12304
12619
  ...activityActorField(input.actor),
12305
12620
  reference: input.reference.kind === "payment" && referenceActor !== void 0 ? {
12306
12621
  kind: "payment",
@@ -12313,7 +12628,7 @@ function makeFinancialOpsMethods(deps) {
12313
12628
  ...input.counterpartyLabel === void 0 ? {} : { counterpartyLabel: input.counterpartyLabel },
12314
12629
  ...input.accountingCategory === void 0 ? {} : { accountingCategory: input.accountingCategory },
12315
12630
  ...input.memo === void 0 ? {} : { memo: input.memo }
12316
- } }));
12631
+ } }))), controls, CAPXUL_OPERATIONS.activity.annotate, deps.runPromise);
12317
12632
  }
12318
12633
  },
12319
12634
  offramp: {
@@ -12339,8 +12654,14 @@ function makeFinancialOpsMethods(deps) {
12339
12654
  }
12340
12655
  },
12341
12656
  paymentDocuments: {
12342
- verify: (documentHash, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.paymentDocuments.verify, () => deps.convexCall.query(fns.verifyPaymentDocument, { documentHash })),
12343
- render: (documentHash, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.paymentDocuments.render, () => deps.convexCall.query(fns.renderStoredDocument, { documentHash }))
12657
+ verify: (documentHash, options) => {
12658
+ const controls = deps.invocationControls?.(options) ?? options;
12659
+ return runPortEffect(Effect.suspend(() => deps.convexCall.query(fns.verifyPaymentDocument, copyInvocationObservation(controls, { documentHash }))), controls, CAPXUL_OPERATIONS.paymentDocuments.verify, deps.runPromise);
12660
+ },
12661
+ render: (documentHash, options) => {
12662
+ const controls = deps.invocationControls?.(options) ?? options;
12663
+ return runPortEffect(Effect.suspend(() => deps.convexCall.query(fns.renderStoredDocument, copyInvocationObservation(controls, { documentHash }))), controls, CAPXUL_OPERATIONS.paymentDocuments.render, deps.runPromise);
12664
+ }
12344
12665
  }
12345
12666
  };
12346
12667
  }
@@ -12379,18 +12700,11 @@ function refFromTargetReference(reference, field) {
12379
12700
  email: reference.email
12380
12701
  }
12381
12702
  };
12382
- case "organization": return {
12383
- ok: true,
12384
- value: {
12385
- kind: "orgHandle",
12386
- orgHandle: reference.handle
12387
- }
12388
- };
12389
- case "payee": return {
12703
+ case "address": return {
12390
12704
  ok: true,
12391
12705
  value: {
12392
- kind: "payeeId",
12393
- payeeId: reference.id
12706
+ kind: "address",
12707
+ address: reference.address
12394
12708
  }
12395
12709
  };
12396
12710
  case "party": return {
@@ -12400,10 +12714,6 @@ function refFromTargetReference(reference, field) {
12400
12714
  partyId: reference.partyId
12401
12715
  }
12402
12716
  };
12403
- case "destination": return {
12404
- ok: false,
12405
- error: Errors.notImplemented("targets", "reference.destination")
12406
- };
12407
12717
  default: return {
12408
12718
  ok: false,
12409
12719
  error: Errors.invalidInput(field, "target must be a known TargetReference variant")
@@ -12458,39 +12768,28 @@ function targetReferenceFromBackendRef(ref) {
12458
12768
  kind: "email",
12459
12769
  email: ref.email
12460
12770
  };
12461
- case "orgHandle": return {
12462
- kind: "organization",
12463
- handle: ref.orgHandle
12464
- };
12465
- case "payeeId": return {
12466
- kind: "payee",
12467
- id: ref.payeeId
12771
+ case "address": return {
12772
+ kind: "address",
12773
+ address: ref.address
12468
12774
  };
12469
12775
  case "party": return {
12470
12776
  kind: "party",
12471
12777
  partyId: ref.partyId
12472
12778
  };
12473
- case "capxulUserId": throw Errors.notImplemented("targets", "reference.capxulUserId");
12474
12779
  }
12475
12780
  }
12476
- function resolvedTargetFromResolution(reference, resolution) {
12477
- const kind = resolution.kind === "org" ? "organization" : resolution.kind === "payee" ? "payee" : "person";
12781
+ function resolvedTargetFromResolution(resolution) {
12782
+ const kind = resolution.status === "known_party" ? resolution.partyKind === "org" ? "organization" : "person" : resolution.status === "external_address" ? "external_address" : "unresolved";
12478
12783
  return {
12479
- reference,
12784
+ reference: targetReferenceFromBackendRef(resolution.recipient),
12480
12785
  label: resolution.label,
12786
+ status: resolution.status,
12481
12787
  kind,
12482
- capabilities: {
12483
- canPay: true,
12484
- canRequest: true,
12485
- canPayout: false
12486
- }
12487
- };
12488
- }
12489
- function resolvedTargetFromPayee(reference, payee) {
12490
- return {
12491
- reference,
12492
- label: payee.label,
12493
- kind: "payee",
12788
+ safeAddress: toAddress(resolution.safeAddress),
12789
+ isCapxulAccount: resolution.isCapxulAccount,
12790
+ ...resolution.partyId === void 0 ? {} : { partyId: toPartyId(resolution.partyId) },
12791
+ ...resolution.handle === void 0 ? {} : { handle: resolution.handle },
12792
+ ...resolution.requiresAcknowledgement === void 0 ? {} : { requiresAcknowledgement: resolution.requiresAcknowledgement },
12494
12793
  capabilities: {
12495
12794
  canPay: true,
12496
12795
  canRequest: true,
@@ -12548,10 +12847,6 @@ function destinationFromBackend(destination) {
12548
12847
  };
12549
12848
  }
12550
12849
  function normalizeDestinationRefForBackend(ref, field) {
12551
- if (typeof ref === "object" && ref !== null && "kind" in ref && ref.kind === "capxulUserId") return {
12552
- ok: false,
12553
- error: Errors.notImplemented("targets", "reference.capxulUserId")
12554
- };
12555
12850
  return normalizeRefForBackend(ref, field);
12556
12851
  }
12557
12852
  function normalizeRefForBackend(ref, field) {
@@ -12579,25 +12874,11 @@ function normalizeRefForBackend(ref, field) {
12579
12874
  email: nonEmptyRefValue(ref.email, "email")
12580
12875
  }
12581
12876
  };
12582
- case "orgHandle": return {
12877
+ case "address": return {
12583
12878
  ok: true,
12584
12879
  value: {
12585
- kind: "orgHandle",
12586
- orgHandle: nonEmptyRefValue(ref.orgHandle, "orgHandle")
12587
- }
12588
- };
12589
- case "capxulUserId": return {
12590
- ok: true,
12591
- value: {
12592
- kind: "capxulUserId",
12593
- capxulUserId: nonEmptyRefValue(ref.capxulUserId, "capxulUserId")
12594
- }
12595
- };
12596
- case "payeeId": return {
12597
- ok: true,
12598
- value: {
12599
- kind: "payeeId",
12600
- payeeId: nonEmptyRefValue(ref.payeeId, "payeeId")
12880
+ kind: "address",
12881
+ address: toAddress(ref.address)
12601
12882
  }
12602
12883
  };
12603
12884
  case "party": return {
@@ -17177,6 +17458,7 @@ function makeConnectionId() {
17177
17458
  //#region ../../packages/sdk/src/adapters/convex-call/ConvexCallAdapter.ts
17178
17459
  /** Exact floor-first allowlist; every additional handler must migrate its validator first. */
17179
17460
  const OBSERVED_CONVEX_ACTIONS = /* @__PURE__ */ new Set([
17461
+ "payroll/actions:authorizeRun",
17180
17462
  "account/actions:readBalance",
17181
17463
  "holdings/actions:current",
17182
17464
  "smartAccount/actions:claim",
@@ -17185,14 +17467,45 @@ const OBSERVED_CONVEX_ACTIONS = /* @__PURE__ */ new Set([
17185
17467
  "org/actions:submitBootstrap",
17186
17468
  "org/actions:resumeBootstrapSubmission",
17187
17469
  "org/actions:confirmBootstrap",
17188
- "org/actions:readTreasury"
17470
+ "org/actions:readTreasury",
17471
+ "moneyExecution/actions:preparePaymentExecution",
17472
+ "moneyExecution/actions:abandonPaymentExecution",
17473
+ "moneyExecution/actions:submitPaymentExecution",
17474
+ "moneyExecution/paymentCommandActions:preparePaymentLifecycleExecution",
17475
+ "moneyExecution/paymentCommandActions:prepareOrganizationPaymentExecution",
17476
+ "moneyExecution/paymentCommandActions:submitPaymentCommandExecution"
17189
17477
  ]);
17190
17478
  const OBSERVED_CONVEX_QUERIES = /* @__PURE__ */ new Set([
17479
+ "movement/activity:list",
17480
+ "movement/activity:summary",
17481
+ "movement/activity:get",
17482
+ "financialOps/queries:verifyPaymentDocument",
17483
+ "financialOps/queries:renderStoredDocument",
17484
+ "financialOps/addressBook:list",
17485
+ "financialOps/addressBook:get",
17486
+ "financialOps/requestsInbox:list",
17487
+ "financialOps/requestsInbox:get",
17488
+ "financialOps/requestsInbox:inboxList",
17489
+ "payroll/queries:runs",
17490
+ "payroll/queries:groups",
17491
+ "payroll/queries:terms",
17492
+ "financialOps/queries:resolveRecipient",
17191
17493
  "identity/queries:loadByAuthUserId",
17192
17494
  "smartAccount/queries:loadByAuthUserId",
17193
17495
  "org/lifecycle:load"
17194
17496
  ]);
17195
17497
  const OBSERVED_CONVEX_MUTATIONS = /* @__PURE__ */ new Set([
17498
+ "movement/activity:annotate",
17499
+ "financialOps/addressBook:add",
17500
+ "financialOps/addressBook:hide",
17501
+ "financialOps/addressBook:unhide",
17502
+ "financialOps/addressBook:label",
17503
+ "financialOps/requestsInbox:issue",
17504
+ "financialOps/requestsInbox:cancel",
17505
+ "financialOps/requestsInbox:approve",
17506
+ "financialOps/requestsInbox:decline",
17507
+ "payroll/mutations:saveGroup",
17508
+ "payroll/mutations:removeGroup",
17196
17509
  "identity/mutations:create",
17197
17510
  "identity/mutations:update",
17198
17511
  "identity/mutations:completeOnboarding",
@@ -17261,7 +17574,7 @@ var ConvexCallAdapter = class {
17261
17574
  const carriedContext = sanitizeObservationContext(args.observationContext);
17262
17575
  let hostContext;
17263
17576
  const invocationSnapshot = readInvocationObservation(args);
17264
- if (invocationSnapshot !== void 0) hostContext = invocationSnapshot.context;
17577
+ if (invocationSnapshot !== void 0) hostContext = invocationSnapshot.active ? invocationSnapshot.context : void 0;
17265
17578
  else {
17266
17579
  const resolveContext = this.#observation?.resolveContext;
17267
17580
  if (resolveContext !== void 0) try {
@@ -17431,12 +17744,13 @@ function ConvexIdentityLayer() {
17431
17744
  function brandProfile(raw) {
17432
17745
  return {
17433
17746
  authUserId: toAuthUserId(raw.authUserId),
17747
+ ...raw.testerKind === void 0 ? {} : { testerKind: toTesterKind(raw.testerKind) },
17434
17748
  email: toEmail(raw.email),
17435
17749
  displayName: raw.displayName,
17436
17750
  country: raw.country === null ? null : toCountryCode(raw.country),
17437
17751
  onboarded: raw.onboarded ?? false,
17438
17752
  withdrawalAddress: raw.withdrawalAddress === null || raw.withdrawalAddress === void 0 ? null : toAddress(raw.withdrawalAddress),
17439
- username: raw.username ?? null,
17753
+ handle: raw.handle === null || raw.handle === void 0 ? null : toHandle(raw.handle),
17440
17754
  imageUrl: raw.imageUrl ?? null,
17441
17755
  kycTier: toKycTier(raw.kycTier),
17442
17756
  createdAt: toEpochMs(raw.createdAt),
@@ -17712,8 +18026,9 @@ var OrgPortTag = class extends Context.Service()("@capxul/sdk/ports/OrgPort") {}
17712
18026
  function brandOrgView(wire, treasury, viewerRole) {
17713
18027
  return {
17714
18028
  id: toOrgId(wire.orgId),
18029
+ ...wire.creationSource === void 0 ? {} : { creationSource: toTesterKind(wire.creationSource) },
17715
18030
  name: wire.name,
17716
- handle: wire.slug,
18031
+ handle: wire.handle,
17717
18032
  safeAddress: toAddress(wire.safeAddress.toLowerCase()),
17718
18033
  role: viewerRole,
17719
18034
  treasury,
@@ -42467,7 +42782,7 @@ function makeSmartAccountMethods(deps) {
42467
42782
  }
42468
42783
  //#endregion
42469
42784
  //#region ../../packages/sdk/src/contract/identity.ts
42470
- const usernameAvailableQuery = makeFunctionReference(CAPXUL_FUNCTIONS["identity/queries"].usernameAvailable);
42785
+ const handleAvailableQuery = makeFunctionReference(CAPXUL_FUNCTIONS["identity/queries"].handleAvailable);
42471
42786
  //#endregion
42472
42787
  //#region ../../packages/sdk/src/surface/identity-deps.ts
42473
42788
  /** The single Context tag the profile atom + `identity.loadCurrent` resolve. */
@@ -42511,19 +42826,19 @@ function makeIdentityMethods(deps) {
42511
42826
  ok: false,
42512
42827
  error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.identity.completeProfile })
42513
42828
  };
42514
- if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" || typeof profile.username !== "string") return {
42829
+ if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" || typeof profile.handle !== "string") return {
42515
42830
  ok: false,
42516
42831
  error: Errors.invalidInput("profile", "invalid profile")
42517
42832
  };
42518
42833
  const displayName = profile.displayName.trim();
42519
- const username = profile.username.trim();
42834
+ const handle = profile.handle.trim();
42520
42835
  if (displayName.length === 0) return {
42521
42836
  ok: false,
42522
42837
  error: Errors.invalidInput("displayName", "must not be empty")
42523
42838
  };
42524
- if (username.length === 0) return {
42839
+ if (handle.length === 0) return {
42525
42840
  ok: false,
42526
- error: Errors.invalidInput("username", "must not be empty")
42841
+ error: Errors.invalidInput("handle", "must not be empty")
42527
42842
  };
42528
42843
  let country;
42529
42844
  try {
@@ -42544,98 +42859,259 @@ function makeIdentityMethods(deps) {
42544
42859
  email: session.email,
42545
42860
  displayName,
42546
42861
  country,
42547
- username
42862
+ handle
42548
42863
  }), options, CAPXUL_OPERATIONS.identity.completeProfile);
42549
42864
  },
42550
- async usernameAvailable(username, options) {
42865
+ async handleAvailable(handle, options) {
42551
42866
  if (options?.signal?.aborted) return {
42552
42867
  ok: false,
42553
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.identity.usernameAvailable })
42868
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.identity.handleAvailable })
42554
42869
  };
42555
42870
  if (convexCall === void 0) return {
42556
42871
  ok: false,
42557
- error: Errors.notImplemented("identity", "usernameAvailable")
42872
+ error: Errors.notImplemented("identity", "handleAvailable")
42558
42873
  };
42559
- return runPortEffect(convexCall.query(usernameAvailableQuery, { username }));
42874
+ return runPortEffect(convexCall.query(handleAvailableQuery, { handle }));
42560
42875
  }
42561
42876
  };
42562
42877
  }
42563
42878
  //#endregion
42564
42879
  //#region ../../packages/sdk/src/surface/onboarding.ts
42565
- const USERNAME_PATTERN = /^[a-z0-9_]{3,30}$/;
42566
- function makeOnboardingMethods(deps) {
42567
- return { async completePerson(input, options) {
42568
- const isCancelled = () => options?.signal?.aborted === true;
42569
- if (typeof input !== "object" || input === null || typeof input.displayName !== "string" || typeof input.country !== "string" || typeof input.username !== "string" || !USERNAME_PATTERN.test(input.username.trim())) return {
42570
- ok: false,
42571
- error: Errors.invalidInput("username", "must be 3-30 characters of a-z, 0-9, or underscore")
42880
+ function normalizeHandleInput(input) {
42881
+ if (typeof input !== "string") return {
42882
+ ok: false,
42883
+ error: Errors.invalidInput("handle", "is required")
42884
+ };
42885
+ try {
42886
+ return {
42887
+ ok: true,
42888
+ value: validateHandle(input)
42572
42889
  };
42573
- const username = input.username.trim();
42574
- const session = await deps.restoreSession(options);
42575
- if (!session.ok) return session;
42576
- if (session.value === null) return {
42890
+ } catch (error) {
42891
+ if (isCapxulError(error)) return {
42577
42892
  ok: false,
42578
- error: Errors.notAuthenticated()
42893
+ error
42579
42894
  };
42580
- const available = await deps.usernameAvailable(username, options);
42581
- if (!available.ok) return available;
42582
- if (!available.value.available) return {
42895
+ return {
42583
42896
  ok: false,
42584
- error: Errors.invalidInput("username", "username is already taken")
42897
+ error: Errors.unknown(error)
42585
42898
  };
42586
- const completed = await deps.completeProfile({
42587
- ...input,
42588
- username: available.value.normalized
42589
- }, options);
42590
- if (!completed.ok) return completed;
42591
- const refreshed = await deps.refreshIdentity(options);
42592
- if (!refreshed.ok) return refreshed;
42593
- if (isCancelled()) return {
42899
+ }
42900
+ }
42901
+ function normalizeOrganization(input) {
42902
+ if (typeof input !== "object" || input === null) return {
42903
+ ok: false,
42904
+ error: Errors.invalidInput("organization", "is required")
42905
+ };
42906
+ const name = typeof input.name === "string" ? input.name.trim() : "";
42907
+ if (name.length === 0) return {
42908
+ ok: false,
42909
+ error: Errors.invalidInput("name", "is required")
42910
+ };
42911
+ const handle = normalizeHandleInput(input.handle);
42912
+ if (!handle.ok) return handle;
42913
+ if (input.bio !== void 0 && typeof input.bio !== "string") return {
42914
+ ok: false,
42915
+ error: Errors.invalidInput("bio", "must be text")
42916
+ };
42917
+ if (input.size !== void 0 && typeof input.size !== "string") return {
42918
+ ok: false,
42919
+ error: Errors.invalidInput("size", "must be text")
42920
+ };
42921
+ let country;
42922
+ try {
42923
+ country = toCountryCode(input.country);
42924
+ } catch {
42925
+ return {
42594
42926
  ok: false,
42595
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
42927
+ error: Errors.invalidInput("country", "must be an ISO country code")
42596
42928
  };
42597
- const ensured = await deps.ensureAccount();
42929
+ }
42930
+ const bio = input.bio?.trim() ?? "";
42931
+ const size = input.size?.trim() ?? "";
42932
+ return {
42933
+ ok: true,
42934
+ value: {
42935
+ name,
42936
+ handle: handle.value,
42937
+ country,
42938
+ ...bio.length === 0 ? {} : { bio },
42939
+ ...size.length === 0 ? {} : { size }
42940
+ }
42941
+ };
42942
+ }
42943
+ function isClaimedIdentityState(state) {
42944
+ return state.phase === "authenticated" && state.account.at === "claimed";
42945
+ }
42946
+ function organizationWrongState(currentState, validStates) {
42947
+ return {
42948
+ ok: false,
42949
+ error: Errors.wrongState({
42950
+ method: CAPXUL_OPERATIONS.onboarding.completeOrganization,
42951
+ currentState,
42952
+ validStates: [...validStates]
42953
+ })
42954
+ };
42955
+ }
42956
+ function requestCancelled(options) {
42957
+ return options?.signal?.aborted === true;
42958
+ }
42959
+ async function reachClaimedAccount(deps, options) {
42960
+ let state = deps.snapshotIdentity();
42961
+ if (state.phase !== "authenticated" || state.account.at === "unknown") {
42962
+ const ensured = await deps.sendIdentity({ _tag: "EnsureAccount" }, options);
42598
42963
  if (!ensured.ok) return ensured;
42599
- if (isCancelled()) return {
42600
- ok: false,
42601
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
42602
- };
42603
- const lifecycle = await deps.getLifecycle();
42604
- if (!lifecycle.ok) return lifecycle;
42605
- if (isCancelled()) return {
42606
- ok: false,
42607
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
42608
- };
42609
- if (lifecycle.value.status !== "ready") return {
42610
- ok: false,
42611
- error: Errors.wrongState({
42612
- method: CAPXUL_OPERATIONS.onboarding.completePerson,
42613
- currentState: lifecycle.value.status,
42614
- validStates: ["ready"]
42615
- })
42616
- };
42617
- const profile = await deps.loadProfile(options);
42618
- if (!profile.ok) return profile;
42619
- if (profile.value === null || profile.value.displayName === null || profile.value.username !== available.value.normalized) return {
42620
- ok: false,
42621
- error: Errors.wrongState({
42622
- method: CAPXUL_OPERATIONS.onboarding.completePerson,
42623
- currentState: "profile-incomplete",
42624
- validStates: ["profile-complete"]
42625
- })
42626
- };
42627
- return {
42628
- ok: true,
42629
- value: {
42630
- profile: {
42631
- ...profile.value,
42632
- displayName: profile.value.displayName,
42633
- username: profile.value.username
42634
- },
42635
- account: lifecycle.value
42636
- }
42637
- };
42638
- } };
42964
+ state = ensured.value;
42965
+ }
42966
+ if (state.phase !== "authenticated") return organizationWrongState(state.phase, ["authenticated:claimed"]);
42967
+ if (state.account.at !== "claimed") {
42968
+ const event = state.account.at === "failed" ? { _tag: "RetryAccount" } : state.account.at === "counterfactual" ? { _tag: "ClaimAccount" } : { _tag: "EnsureAccount" };
42969
+ const claimed = await deps.sendIdentity(event, options);
42970
+ if (!claimed.ok) return claimed;
42971
+ state = claimed.value;
42972
+ }
42973
+ return isClaimedIdentityState(state) ? {
42974
+ ok: true,
42975
+ value: state
42976
+ } : organizationWrongState(state.phase === "authenticated" ? state.account.at : state.phase, ["claimed"]);
42977
+ }
42978
+ async function createOrResumeOrganization(deps, state, draft, options) {
42979
+ const active = state.account.org;
42980
+ if (active?.at === "ready") return {
42981
+ ok: true,
42982
+ value: { organizationId: active.orgId }
42983
+ };
42984
+ if (active?.at === "failed" && !active.retryable) return {
42985
+ ok: false,
42986
+ error: publicIdentityFailure(active.failure)
42987
+ };
42988
+ if (active?.at === "failed" && active.orgId === null) {
42989
+ const cleared = await deps.sendIdentity({ _tag: "LeaveOrganization" }, options);
42990
+ if (!cleared.ok) return cleared;
42991
+ }
42992
+ const event = active?.at === "failed" && active.orgId !== null ? { _tag: "RetryOrganization" } : {
42993
+ _tag: "CreateOrganization",
42994
+ draft
42995
+ };
42996
+ const created = await deps.sendIdentity(event, options);
42997
+ if (!created.ok) return created;
42998
+ const final = created.value;
42999
+ const organization = isClaimedIdentityState(final) ? final.account.org : null;
43000
+ return organization?.at === "ready" ? {
43001
+ ok: true,
43002
+ value: { organizationId: organization.orgId }
43003
+ } : organizationWrongState(organization?.at ?? "organization-missing", ["ready"]);
43004
+ }
43005
+ function makeOnboardingMethods(deps) {
43006
+ return {
43007
+ async completePerson(input, options) {
43008
+ const isCancelled = () => options?.signal?.aborted === true;
43009
+ if (typeof input !== "object" || input === null || typeof input.displayName !== "string" || typeof input.country !== "string") return {
43010
+ ok: false,
43011
+ error: Errors.invalidInput("profile", "displayName and country are required")
43012
+ };
43013
+ const handle = normalizeHandleInput(input.handle);
43014
+ if (!handle.ok) return handle;
43015
+ const session = await deps.restoreSession(options);
43016
+ if (!session.ok) return session;
43017
+ if (session.value === null) return {
43018
+ ok: false,
43019
+ error: Errors.notAuthenticated()
43020
+ };
43021
+ const available = await deps.handleAvailable(handle.value, options);
43022
+ if (!available.ok) return available;
43023
+ if (!available.value.available) return {
43024
+ ok: false,
43025
+ error: Errors.invalidInput("handle", "handle is already taken")
43026
+ };
43027
+ const completed = await deps.completeProfile({
43028
+ ...input,
43029
+ handle: available.value.normalized
43030
+ }, options);
43031
+ if (!completed.ok) return completed;
43032
+ const refreshed = await deps.refreshIdentity(options);
43033
+ if (!refreshed.ok) return refreshed;
43034
+ if (isCancelled()) return {
43035
+ ok: false,
43036
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
43037
+ };
43038
+ const ensured = await deps.ensureAccount();
43039
+ if (!ensured.ok) return ensured;
43040
+ if (isCancelled()) return {
43041
+ ok: false,
43042
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
43043
+ };
43044
+ const lifecycle = await deps.getLifecycle();
43045
+ if (!lifecycle.ok) return lifecycle;
43046
+ if (isCancelled()) return {
43047
+ ok: false,
43048
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
43049
+ };
43050
+ if (lifecycle.value.status !== "ready") return {
43051
+ ok: false,
43052
+ error: Errors.wrongState({
43053
+ method: CAPXUL_OPERATIONS.onboarding.completePerson,
43054
+ currentState: lifecycle.value.status,
43055
+ validStates: ["ready"]
43056
+ })
43057
+ };
43058
+ const profile = await deps.loadProfile(options);
43059
+ if (!profile.ok) return profile;
43060
+ if (profile.value === null || profile.value.displayName === null || profile.value.handle !== available.value.normalized) return {
43061
+ ok: false,
43062
+ error: Errors.wrongState({
43063
+ method: CAPXUL_OPERATIONS.onboarding.completePerson,
43064
+ currentState: "profile-incomplete",
43065
+ validStates: ["profile-complete"]
43066
+ })
43067
+ };
43068
+ return {
43069
+ ok: true,
43070
+ value: {
43071
+ profile: {
43072
+ ...profile.value,
43073
+ displayName: profile.value.displayName,
43074
+ handle: profile.value.handle
43075
+ },
43076
+ account: lifecycle.value
43077
+ }
43078
+ };
43079
+ },
43080
+ async completeOrganization(input, options) {
43081
+ const operation = CAPXUL_OPERATIONS.onboarding.completeOrganization;
43082
+ const normalized = normalizeOrganization(input);
43083
+ if (!normalized.ok) return normalized;
43084
+ const session = await deps.restoreSession(options);
43085
+ if (!session.ok) return session;
43086
+ if (session.value === null) return {
43087
+ ok: false,
43088
+ error: Errors.notAuthenticated()
43089
+ };
43090
+ const profile = await deps.loadProfile(options);
43091
+ if (!profile.ok) return profile;
43092
+ if (profile.value === null || profile.value.displayName === null || profile.value.handle === null) return {
43093
+ ok: false,
43094
+ error: Errors.wrongState({
43095
+ method: operation,
43096
+ currentState: "profile-incomplete",
43097
+ validStates: ["profile-complete"]
43098
+ })
43099
+ };
43100
+ const refreshed = await deps.refreshIdentity(options);
43101
+ if (!refreshed.ok) return refreshed;
43102
+ if (requestCancelled(options)) return {
43103
+ ok: false,
43104
+ error: Errors.cancelled({ operation })
43105
+ };
43106
+ const claimed = await reachClaimedAccount(deps, options);
43107
+ if (!claimed.ok) return claimed;
43108
+ if (requestCancelled(options)) return {
43109
+ ok: false,
43110
+ error: Errors.cancelled({ operation })
43111
+ };
43112
+ return createOrResumeOrganization(deps, claimed.value, normalized.value, options);
43113
+ }
43114
+ };
42639
43115
  }
42640
43116
  //#endregion
42641
43117
  //#region ../../packages/sdk/src/surface/accounts-deps.ts
@@ -42938,13 +43414,15 @@ function executionDependencies$1(input) {
42938
43414
  chainId: input.chainId,
42939
43415
  convexCall: input.convexCall,
42940
43416
  functions: moneyExecutionContract,
42941
- signer: input.signer
43417
+ signer: input.signer,
43418
+ ...input.runPromise === void 0 ? {} : { runPromise: input.runPromise },
43419
+ ...input.telemetry === void 0 ? {} : { telemetry: input.telemetry }
42942
43420
  };
42943
43421
  }
42944
43422
  function makeOrganizationPaymentsMethods(deps, orgId) {
42945
43423
  const requestKeyScope = deps.requestKeyScope ?? `client-${crypto.randomUUID()}`;
42946
43424
  const inFlightOrganizationPayments = /* @__PURE__ */ new Map();
42947
- const execute = async (input, signal, operation = "organization-pay-batch") => {
43425
+ const execute = async (input, signal, operation = "organization-pay-batch", controls) => {
42948
43426
  if (signal?.aborted === true) return {
42949
43427
  ok: false,
42950
43428
  error: Errors.cancelled({ operation })
@@ -42970,16 +43448,18 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
42970
43448
  let flight = inFlightOrganizationPayments.get(flightKey);
42971
43449
  if (flight === void 0) {
42972
43450
  const controller = new AbortController();
43451
+ const requestState = { resolved: false };
42973
43452
  const submission = executeOrganizationPayment(execution, {
42974
43453
  orgId,
42975
43454
  permissionId: input.permissionId,
42976
43455
  requestKey: requestKey.key,
42977
43456
  items: input.items,
42978
43457
  ...input.lineage === void 0 ? {} : { lineage: input.lineage }
42979
- }, controller.signal);
43458
+ }, controller.signal, () => requestState.resolved = true, controls);
42980
43459
  flight = {
42981
43460
  controller,
42982
43461
  promise: submission,
43462
+ requestState,
42983
43463
  waiters: 0,
42984
43464
  settled: false
42985
43465
  };
@@ -43017,30 +43497,80 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
43017
43497
  }
43018
43498
  release(false);
43019
43499
  try {
43020
- await requestKey.finish(result.ok);
43500
+ await requestKey.finish(result.ok || flight.requestState.resolved);
43021
43501
  } catch {}
43022
- return mapOk(result, (value) => value.payments.map((payment) => normalizePaymentTiming(payment)));
43502
+ const normalized = mapOk(result, (value) => value.payments.map((payment) => normalizePaymentTiming(payment)));
43503
+ if (!normalized.ok) return normalized;
43504
+ return normalized;
43023
43505
  };
43024
43506
  return {
43025
- pay: async (input, options) => {
43026
- const { permissionId, requestKey: providedRequestKey, lineage, ...item } = input;
43027
- const result = await execute({
43028
- permissionId,
43029
- ...providedRequestKey === void 0 ? {} : { requestKey: providedRequestKey },
43030
- items: [item],
43031
- ...lineage === void 0 ? {} : { lineage }
43032
- }, options?.signal, "organization-pay");
43033
- if (!result.ok) return result;
43034
- const payment = result.value[0];
43035
- return payment === void 0 ? {
43036
- ok: false,
43037
- error: Errors.unknown()
43038
- } : {
43039
- ok: true,
43040
- value: payment
43041
- };
43507
+ retry: (paymentId, options) => {
43508
+ const controls = deps.invocationControls?.(options) ?? options;
43509
+ return runCapxulEffect(Effect.gen(function* () {
43510
+ const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
43511
+ const captured = carryInvocationParentSpan(controls, parent);
43512
+ const completed = yield* Effect.tryPromise({
43513
+ try: async () => {
43514
+ const execution = executionDependencies$1(deps);
43515
+ if (execution === null) return {
43516
+ ok: false,
43517
+ error: Errors.notImplemented("organizationPayments", "executionComposition")
43518
+ };
43519
+ const result = await executePaymentLifecycle(execution, {
43520
+ kind: "retry",
43521
+ paymentId
43522
+ }, controls?.signal, captured);
43523
+ if (!result.ok) return result;
43524
+ return {
43525
+ ok: true,
43526
+ value: result.value.payments.map((payment) => normalizePaymentTiming(payment))
43527
+ };
43528
+ },
43529
+ catch: (cause) => cause instanceof CapxulError ? cause : Errors.unknown(cause)
43530
+ });
43531
+ return yield* completed.ok ? Effect.succeed(completed.value) : Effect.fail(completed.error);
43532
+ }), observationOnlyControls(controls), CAPXUL_OPERATIONS.organizationPayments.retry, deps.runPromise);
43042
43533
  },
43043
- payBatch: (input, options) => execute(input, options?.signal)
43534
+ pay: (input, options) => {
43535
+ const controls = deps.invocationControls?.(options) ?? options;
43536
+ return runCapxulEffect(Effect.gen(function* () {
43537
+ const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
43538
+ const captured = carryInvocationParentSpan(controls, parent);
43539
+ const completed = yield* Effect.tryPromise({
43540
+ try: async () => {
43541
+ const { permissionId, requestKey: providedRequestKey, lineage, ...item } = input;
43542
+ const result = await execute({
43543
+ permissionId,
43544
+ ...providedRequestKey === void 0 ? {} : { requestKey: providedRequestKey },
43545
+ items: [item],
43546
+ ...lineage === void 0 ? {} : { lineage }
43547
+ }, controls?.signal, "organization-pay", captured);
43548
+ if (!result.ok) return result;
43549
+ const payment = result.value[0];
43550
+ return payment === void 0 ? {
43551
+ ok: false,
43552
+ error: Errors.unknown()
43553
+ } : {
43554
+ ok: true,
43555
+ value: payment
43556
+ };
43557
+ },
43558
+ catch: (cause) => cause instanceof CapxulError ? cause : Errors.unknown(cause)
43559
+ });
43560
+ return yield* completed.ok ? Effect.succeed(completed.value) : Effect.fail(completed.error);
43561
+ }), observationOnlyControls(controls), CAPXUL_OPERATIONS.organizationPayments.pay, deps.runPromise);
43562
+ },
43563
+ payBatch: (input, options) => {
43564
+ const controls = deps.invocationControls?.(options) ?? options;
43565
+ return runCapxulEffect(Effect.gen(function* () {
43566
+ const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
43567
+ const completed = yield* Effect.tryPromise({
43568
+ try: () => execute(input, controls?.signal, void 0, carryInvocationParentSpan(controls, parent)),
43569
+ catch: (cause) => cause instanceof CapxulError ? cause : Errors.unknown(cause)
43570
+ });
43571
+ return yield* completed.ok ? Effect.succeed(completed.value) : Effect.fail(completed.error);
43572
+ }), observationOnlyControls(controls), CAPXUL_OPERATIONS.organizationPayments.payBatch, deps.runPromise);
43573
+ }
43044
43574
  };
43045
43575
  }
43046
43576
  //#endregion
@@ -43137,12 +43667,14 @@ function executionDependencies(deps) {
43137
43667
  chainId: deps.chainId,
43138
43668
  convexCall: deps.convexCall,
43139
43669
  functions: moneyExecutionContract,
43670
+ ...deps.runPromise === void 0 ? {} : { runPromise: deps.runPromise },
43140
43671
  signer: deps.signer
43141
43672
  };
43142
43673
  }
43143
43674
  function makePayrollMethods(deps, orgId) {
43144
43675
  const requestKeyScope = deps.requestKeyScope ?? `client-${crypto.randomUUID()}`;
43145
- async function authorize(input, signal) {
43676
+ async function authorize(input, controls) {
43677
+ const signal = controls?.signal;
43146
43678
  const execution = executionDependencies(deps);
43147
43679
  if (execution === null) return {
43148
43680
  ok: false,
@@ -43153,15 +43685,16 @@ function makePayrollMethods(deps, orgId) {
43153
43685
  input
43154
43686
  }, input.requestKey);
43155
43687
  let authorized;
43688
+ let preparedClosed = false;
43156
43689
  const submitted = await executePrepared(execution, async (signerAddress) => {
43157
- const prepared = await runIfActive(signal, AUTHORIZE_RUN, () => deps.convexCall.action(payrollContract.authorizeRun, { input: {
43690
+ const prepared = await runIfActive(signal, AUTHORIZE_RUN, () => withInvocationParentSpan(Effect.suspend(() => deps.convexCall.action(payrollContract.authorizeRun, copyInvocationObservation(controls, { input: {
43158
43691
  orgId,
43159
43692
  permissionId: input.permissionId,
43160
43693
  requestKey: requestKey.key,
43161
43694
  signerAddress,
43162
43695
  period: input.period,
43163
43696
  items: input.items
43164
- } }));
43697
+ } }))), controls), deps.runPromise);
43165
43698
  if (!prepared.ok) return prepared;
43166
43699
  authorized = prepared.value.run;
43167
43700
  return {
@@ -43174,9 +43707,9 @@ function makePayrollMethods(deps, orgId) {
43174
43707
  requestKey: requestKey.key,
43175
43708
  runId: authorized.id,
43176
43709
  items: input.items
43177
- })(request), signal);
43710
+ })(request), true, () => preparedClosed = true, signal, controls);
43178
43711
  try {
43179
- await requestKey.finish(submitted.ok);
43712
+ await requestKey.finish(submitted.ok || preparedClosed);
43180
43713
  } catch {}
43181
43714
  if (!submitted.ok) return submitted;
43182
43715
  return authorized === void 0 ? {
@@ -43188,35 +43721,48 @@ function makePayrollMethods(deps, orgId) {
43188
43721
  };
43189
43722
  }
43190
43723
  return {
43191
- runs: (options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payroll.runs, () => Effect.map(deps.convexCall.query(payrollContract.runs, { orgId }), toPayrollRuns)),
43192
- authorizeRun: async (input, options) => {
43193
- if (options?.signal?.aborted === true) return {
43194
- ok: false,
43195
- error: Errors.cancelled({ operation: AUTHORIZE_RUN })
43196
- };
43197
- try {
43198
- return await authorize(input, options?.signal);
43199
- } catch (cause) {
43200
- return {
43201
- ok: false,
43202
- error: cause instanceof CapxulError ? cause : Errors.unknown(cause)
43203
- };
43204
- }
43724
+ runs: (options) => {
43725
+ const controls = deps.invocationControls?.(options) ?? options;
43726
+ return runPortEffect(Effect.suspend(() => deps.convexCall.query(payrollContract.runs, copyInvocationObservation(controls, { orgId }))).pipe(Effect.map(toPayrollRuns)), controls, CAPXUL_OPERATIONS.payroll.runs, deps.runPromise);
43727
+ },
43728
+ authorizeRun: (input, options) => {
43729
+ const controls = deps.invocationControls?.(options) ?? options;
43730
+ return runCapxulEffect(Effect.gen(function* () {
43731
+ if (controls?.signal?.aborted === true) return yield* Effect.fail(Errors.cancelled({ operation: AUTHORIZE_RUN }));
43732
+ const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
43733
+ const result = yield* Effect.tryPromise({
43734
+ try: () => authorize(input, carryInvocationParentSpan(controls, parent)),
43735
+ catch: (cause) => cause instanceof CapxulError ? cause : Errors.unknown(cause)
43736
+ });
43737
+ return yield* result.ok ? Effect.succeed(result.value) : Effect.fail(result.error);
43738
+ }), observationOnlyControls(controls), AUTHORIZE_RUN, deps.runPromise);
43739
+ },
43740
+ terms: (options) => {
43741
+ const controls = deps.invocationControls?.(options) ?? options;
43742
+ return runPortEffect(Effect.suspend(() => deps.convexCall.query(payrollContract.terms, copyInvocationObservation(controls, { orgId }))), controls, CAPXUL_OPERATIONS.payroll.terms, deps.runPromise);
43205
43743
  },
43206
- terms: (options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payroll.terms, () => deps.convexCall.query(payrollContract.terms, { orgId })),
43207
43744
  groups: {
43208
- list: (options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payroll.groups.list, () => Effect.map(deps.convexCall.query(payrollContract.groups, { orgId }), (groups) => groups.map(toPayrollGroup))),
43209
- save: (input, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payroll.groups.save, () => Effect.map(deps.convexCall.mutation(payrollContract.saveGroup, {
43210
- orgId,
43211
- ...input.id === void 0 ? {} : { id: String(input.id) },
43212
- name: input.name,
43213
- tone: input.tone,
43214
- members: input.members
43215
- }), toPayrollGroup)),
43216
- remove: (id, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payroll.groups.remove, () => Effect.map(deps.convexCall.mutation(payrollContract.removeGroup, {
43217
- orgId,
43218
- id
43219
- }), () => void 0))
43745
+ list: (options) => {
43746
+ const controls = deps.invocationControls?.(options) ?? options;
43747
+ return runPortEffect(Effect.suspend(() => deps.convexCall.query(payrollContract.groups, copyInvocationObservation(controls, { orgId }))).pipe(Effect.map((groups) => groups.map(toPayrollGroup))), controls, CAPXUL_OPERATIONS.payroll.groups.list, deps.runPromise);
43748
+ },
43749
+ save: (input, options) => {
43750
+ const controls = deps.invocationControls?.(options) ?? options;
43751
+ return runPortEffect(Effect.suspend(() => deps.convexCall.mutation(payrollContract.saveGroup, copyInvocationObservation(controls, {
43752
+ orgId,
43753
+ ...input.id === void 0 ? {} : { id: String(input.id) },
43754
+ name: input.name,
43755
+ tone: input.tone,
43756
+ members: input.members
43757
+ }))).pipe(Effect.map(toPayrollGroup)), controls, CAPXUL_OPERATIONS.payroll.groups.save, deps.runPromise);
43758
+ },
43759
+ remove: (id, options) => {
43760
+ const controls = deps.invocationControls?.(options) ?? options;
43761
+ return runPortEffect(Effect.suspend(() => deps.convexCall.mutation(payrollContract.removeGroup, copyInvocationObservation(controls, {
43762
+ orgId,
43763
+ id
43764
+ }))).pipe(Effect.asVoid), controls, CAPXUL_OPERATIONS.payroll.groups.remove, deps.runPromise);
43765
+ }
43220
43766
  }
43221
43767
  };
43222
43768
  }
@@ -43665,6 +44211,8 @@ function makeOrgMethods(deps) {
43665
44211
  const convexCall = deps.convexCall;
43666
44212
  return {
43667
44213
  ...makeActorRelationshipMethods({
44214
+ ...deps.runPromise === void 0 ? {} : { runPromise: deps.runPromise },
44215
+ ...deps.invocationControls === void 0 ? {} : { invocationControls: deps.invocationControls },
43668
44216
  actor: {
43669
44217
  kind: "org",
43670
44218
  orgId: String(orgId)
@@ -43794,13 +44342,18 @@ function makeOrgMethods(deps) {
43794
44342
  }, String(orgId)),
43795
44343
  payments: convexCall === void 0 ? makeNotImplementedOrganizationPaymentsMethods() : makeOrganizationPaymentsMethods({
43796
44344
  convexCall,
44345
+ ...deps.runPromise === void 0 ? {} : { runPromise: deps.runPromise },
44346
+ ...deps.invocationControls === void 0 ? {} : { invocationControls: deps.invocationControls },
43797
44347
  ...deps.requestKeyScope === void 0 ? {} : { requestKeyScope: deps.requestKeyScope },
43798
44348
  ...deps.actor === void 0 ? {} : { actor: deps.actor },
43799
44349
  ...deps.chainId === void 0 ? {} : { chainId: Number(deps.chainId) },
43800
- ...deps.signer === void 0 ? {} : { signer: deps.signer }
44350
+ ...deps.signer === void 0 ? {} : { signer: deps.signer },
44351
+ ...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
43801
44352
  }, String(orgId)),
43802
44353
  payroll: convexCall === void 0 ? makeUnavailablePayrollMethods() : makePayrollMethods({
43803
44354
  convexCall,
44355
+ ...deps.runPromise === void 0 ? {} : { runPromise: deps.runPromise },
44356
+ ...deps.invocationControls === void 0 ? {} : { invocationControls: deps.invocationControls },
43804
44357
  ...deps.requestKeyScope === void 0 ? {} : { requestKeyScope: deps.requestKeyScope },
43805
44358
  ...deps.actor === void 0 ? {} : { actor: deps.actor },
43806
44359
  ...deps.chainId === void 0 ? {} : { chainId: Number(deps.chainId) },
@@ -43824,7 +44377,8 @@ function makeNotImplementedPermissionMethods() {
43824
44377
  function makeNotImplementedOrganizationPaymentsMethods() {
43825
44378
  return {
43826
44379
  pay: organizationPaymentExecutionUnavailable,
43827
- payBatch: organizationPaymentExecutionUnavailable
44380
+ payBatch: organizationPaymentExecutionUnavailable,
44381
+ retry: organizationPaymentExecutionUnavailable
43828
44382
  };
43829
44383
  }
43830
44384
  const orgMeUnavailable = () => Promise.resolve({
@@ -44209,6 +44763,8 @@ function assembleCapxulClient(input) {
44209
44763
  let detectPendingOrgInvitations;
44210
44764
  let kickProvisioning;
44211
44765
  const financialOps = makeFinancialOpsMethods({
44766
+ runPromise: effectRunner.runPromise,
44767
+ invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls, actor.authSession()?.authUserId),
44212
44768
  actor,
44213
44769
  chainId: input.bootstrap.chainId,
44214
44770
  convexCall: input.ports.convexCall,
@@ -44228,7 +44784,7 @@ function assembleCapxulClient(input) {
44228
44784
  profileMethods: financialOps.me,
44229
44785
  convexCall: input.ports.convexCall,
44230
44786
  runPromise: effectRunner.runPromise,
44231
- invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls),
44787
+ invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls, actor.authSession()?.authUserId),
44232
44788
  ...input.signer === void 0 ? {} : { signer: input.signer }
44233
44789
  });
44234
44790
  kickProvisioning = accountBundle.kickProvisioning;
@@ -44267,11 +44823,13 @@ function assembleCapxulClient(input) {
44267
44823
  const onboarding = makeOnboardingMethods({
44268
44824
  restoreSession: auth.getSession,
44269
44825
  refreshIdentity: (options) => runCapxulEffect(askIdentity(actor, { _tag: "ReadSession" }, options).pipe(Effect.asVoid), options, CAPXUL_OPERATIONS.identity.readSession, effectRunner.runPromise),
44270
- usernameAvailable: identity.usernameAvailable,
44826
+ handleAvailable: identity.handleAvailable,
44271
44827
  completeProfile: identity.completeProfile,
44272
44828
  loadProfile: identity.loadCurrent,
44273
44829
  ensureAccount: account._internal.ensureReady,
44274
- getLifecycle: account.getLifecycle
44830
+ getLifecycle: account.getLifecycle,
44831
+ snapshotIdentity: actor.snapshot,
44832
+ sendIdentity: (event, options) => runCapxulEffect(askIdentity(actor, event, options), options, CAPXUL_OPERATIONS._internal.identity.send, effectRunner.runPromise)
44275
44833
  });
44276
44834
  const system = makeSystemMethods({ convexCall: input.ports.convexCall });
44277
44835
  const media = makeMediaMethods({ convexCall: input.ports.convexCall });
@@ -44279,21 +44837,21 @@ function assembleCapxulClient(input) {
44279
44837
  convexCall: input.ports.convexCall,
44280
44838
  telemetry: input.ports.telemetry,
44281
44839
  runPromise: effectRunner.runPromise,
44282
- invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls)
44840
+ invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls, actor.authSession()?.authUserId)
44283
44841
  });
44284
44842
  const accounts = makeAccountsMethods({
44285
44843
  accountReadPort: input.ports.accountRead,
44286
44844
  chainId: input.bootstrap.chainId,
44287
44845
  telemetry: input.ports.telemetry,
44288
44846
  runPromise: effectRunner.runPromise,
44289
- invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls)
44847
+ invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls, actor.authSession()?.authUserId)
44290
44848
  });
44291
44849
  const orgMethods = makeOrgMethods({
44292
44850
  actor,
44293
44851
  chainId: input.bootstrap.chainId,
44294
44852
  telemetry: input.ports.telemetry,
44295
44853
  runPromise: effectRunner.runPromise,
44296
- invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls),
44854
+ invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls, actor.authSession()?.authUserId),
44297
44855
  requestKeyScope: `${input.bootstrap.convexUrl}:${String(input.bootstrap.chainId)}`,
44298
44856
  ...selectedOrgPort === void 0 ? {} : { orgPort: selectedOrgPort },
44299
44857
  convexCall: input.ports.convexCall,
@@ -44330,7 +44888,7 @@ function assembleCapxulClient(input) {
44330
44888
  }
44331
44889
  },
44332
44890
  async completeProfile(profile, controls) {
44333
- if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" || profile.username !== void 0 && typeof profile.username !== "string") return {
44891
+ if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" || typeof profile.handle !== "string") return {
44334
44892
  ok: false,
44335
44893
  reason: "INVALID_INPUT"
44336
44894
  };
@@ -44348,8 +44906,8 @@ function assembleCapxulClient(input) {
44348
44906
  reason: "INVALID_INPUT"
44349
44907
  };
44350
44908
  }
44351
- const username = profile.username?.trim();
44352
- if (profile.username !== void 0 && username?.length === 0) return {
44909
+ const handle = profile.handle.trim();
44910
+ if (handle.length === 0) return {
44353
44911
  ok: false,
44354
44912
  reason: "INVALID_INPUT"
44355
44913
  };
@@ -44363,7 +44921,7 @@ function assembleCapxulClient(input) {
44363
44921
  email: session.email,
44364
44922
  displayName,
44365
44923
  country,
44366
- ...username === void 0 ? {} : { username }
44924
+ handle
44367
44925
  }), controls, CAPXUL_OPERATIONS.identity.completeProfile, effectRunner.runPromise);
44368
44926
  return result.ok ? { ok: true } : {
44369
44927
  ok: false,
@@ -44382,8 +44940,6 @@ function assembleCapxulClient(input) {
44382
44940
  accounts,
44383
44941
  currentUser,
44384
44942
  me: financialOps.me,
44385
- handles: financialOps.handles,
44386
- payees: financialOps.payees,
44387
44943
  targets: financialOps.targets,
44388
44944
  destinations: financialOps.destinations,
44389
44945
  payments: financialOps.payments,
@@ -44402,6 +44958,20 @@ function assembleCapxulClient(input) {
44402
44958
  accounts: { fund: accounts.fund },
44403
44959
  organizationSetup: { getProofReceipt: (orgId) => runPortEffect(input.ports.convexCall.query(organizationSetupProofReceiptQuery, { orgId })) },
44404
44960
  telemetry: input.ports.telemetry,
44961
+ captureExternalAddressAcknowledged: (address, organizationId) => {
44962
+ const telemetry = input.ports.telemetry;
44963
+ if (telemetry === void 0) return;
44964
+ Effect.runPromise(Effect.suspend(() => telemetry.emit({
44965
+ name: "quick_pay_external_address_acknowledged",
44966
+ props: {
44967
+ recipient_locator_kind: "address",
44968
+ recipient_resolution_status: "external_address",
44969
+ recipient_address: address,
44970
+ external_address_acknowledged: true,
44971
+ ...organizationId === void 0 ? {} : { organization_id: organizationId }
44972
+ }
44973
+ })).pipe(Effect.catchCause(() => Effect.void)));
44974
+ },
44405
44975
  close: stopActor
44406
44976
  }
44407
44977
  }, observation.failureObservation, observation.hostObservationSnapshot);
@@ -44432,7 +45002,7 @@ function transitionError(record) {
44432
45002
  }
44433
45003
  function withHostObservation(actor, snapshot) {
44434
45004
  if (snapshot === void 0) return actor;
44435
- const controls = (input) => withHostObservationControls(snapshot, input);
45005
+ const controls = (input) => withHostObservationControls(snapshot, input, actor.authSession()?.authUserId);
44436
45006
  return {
44437
45007
  ...actor,
44438
45008
  ask: (event, input) => actor.ask(event, controls(input)),
@@ -44440,10 +45010,14 @@ function withHostObservation(actor, snapshot) {
44440
45010
  restoreAuthSession: (session, input) => actor.restoreAuthSession(session, controls(input))
44441
45011
  };
44442
45012
  }
44443
- function withHostObservationControls(snapshot, input) {
44444
- const copied = { ...input };
44445
- const captured = snapshot?.();
44446
- return captured === void 0 ? copied : attachInvocationObservation(copied, captured);
45013
+ function withHostObservationControls(snapshot, input, actorId) {
45014
+ const previous = readInvocationObservation(input);
45015
+ if (previous !== void 0) return attachInvocationObservation({ ...input }, previous);
45016
+ const captured = snapshot?.() ?? { active: true };
45017
+ return attachInvocationObservation({ ...input }, {
45018
+ ...captured,
45019
+ ...actorId === void 0 ? {} : { actorId }
45020
+ });
44447
45021
  }
44448
45022
  //#endregion
44449
45023
  //#region ../../packages/sdk/src/host-observability.ts
@@ -45239,7 +45813,7 @@ const moneySchema = z.object({
45239
45813
  value: z.string(),
45240
45814
  decimals: z.number()
45241
45815
  });
45242
- const usernameSchema = z.string().regex(/^[a-z0-9_]{3,30}$/, "3-30 characters: a-z, 0-9, or underscore");
45816
+ const handleSchema$1 = z.string().regex(/^[a-z0-9_]{3,30}$/, "3-30 characters: a-z, 0-9, or underscore");
45243
45817
  const accountTools = [
45244
45818
  {
45245
45819
  name: CAPXUL_OPERATIONS.onboarding.completePerson,
@@ -45247,18 +45821,18 @@ const accountTools = [
45247
45821
  register: (server, scope) => {
45248
45822
  server.registerTool(CAPXUL_OPERATIONS.onboarding.completePerson, {
45249
45823
  title: "Complete Person onboarding",
45250
- description: "Claim a globally unique username, complete the signed-in Person profile, and make the personal Account ready. Call this before Organization creation or money tools.",
45824
+ description: "Claim a globally unique handle, complete the signed-in Person profile, and make the personal Account ready. Call this before Organization creation or money tools.",
45251
45825
  inputSchema: z.object({
45252
45826
  displayName: z.string().trim().min(1),
45253
45827
  country: z.string().trim().min(2),
45254
- username: usernameSchema
45828
+ handle: handleSchema$1
45255
45829
  }),
45256
45830
  outputSchema: z.object({
45257
45831
  profile: z.object({
45258
45832
  email: z.string(),
45259
45833
  displayName: z.string(),
45260
45834
  country: z.string(),
45261
- username: usernameSchema
45835
+ handle: handleSchema$1
45262
45836
  }),
45263
45837
  account: z.object({
45264
45838
  status: z.literal("ready"),
@@ -45368,6 +45942,156 @@ function identityError(failure, operation) {
45368
45942
  }
45369
45943
  }
45370
45944
  //#endregion
45945
+ //#region src/tools/organization.ts
45946
+ const MANAGE$1 = "org:manage";
45947
+ const handleSchema = z.string().trim().toLowerCase().regex(/^[a-z0-9-]{3,32}$/, "3-32 characters: a-z, 0-9, or hyphen");
45948
+ const organizationTools = [{
45949
+ name: CAPXUL_OPERATIONS.onboarding.completeOrganization,
45950
+ scope: MANAGE$1,
45951
+ register: (server, scope) => {
45952
+ server.registerTool(CAPXUL_OPERATIONS.onboarding.completeOrganization, {
45953
+ title: "Complete Organization onboarding",
45954
+ description: "Claim the personal Account, then create or resume one Organization through the canonical onboarding lifecycle. Reuse the same handle after an interrupted call.",
45955
+ inputSchema: z.object({
45956
+ name: z.string().trim().min(1),
45957
+ handle: handleSchema,
45958
+ country: z.string().trim().min(2),
45959
+ bio: z.string().trim().min(1).optional(),
45960
+ size: z.string().trim().min(1).optional()
45961
+ }),
45962
+ outputSchema: z.object({ organizationId: z.string() })
45963
+ }, (input) => withClient(scope, CAPXUL_OPERATIONS.onboarding.completeOrganization, MANAGE$1, async (client) => {
45964
+ const completed = await client.completeOrganization(input);
45965
+ if (!completed.ok) return errorResult(completed.error);
45966
+ return okResult({ ...completed.value });
45967
+ }));
45968
+ }
45969
+ }];
45970
+ //#endregion
45971
+ //#region src/tools/staff.ts
45972
+ const MANAGE = "org:manage";
45973
+ const orgInput = { organizationId: z.string().trim().min(1) };
45974
+ const email = z.string().trim().email();
45975
+ const memberStatus = z.enum([
45976
+ "pending",
45977
+ "pending_safe",
45978
+ "pending_grant",
45979
+ "active",
45980
+ "revoked",
45981
+ "expired"
45982
+ ]);
45983
+ const staffTools = [
45984
+ {
45985
+ name: CAPXUL_OPERATIONS.org.list,
45986
+ scope: MANAGE,
45987
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.list, {
45988
+ title: "List Organizations",
45989
+ description: "List the Organizations that the signed-in Person can access.",
45990
+ inputSchema: z.object({}),
45991
+ outputSchema: z.object({ organizations: z.array(z.object({
45992
+ organizationId: z.string(),
45993
+ name: z.string(),
45994
+ handle: z.string(),
45995
+ role: z.string()
45996
+ })) })
45997
+ }, () => withClient(scope, CAPXUL_OPERATIONS.org.list, MANAGE, async (client) => {
45998
+ const result = await client.listOrganizations();
45999
+ return result.ok ? okResult({ organizations: [...result.value] }) : errorResult(result.error);
46000
+ }))
46001
+ },
46002
+ {
46003
+ name: CAPXUL_OPERATIONS.org.roles,
46004
+ scope: MANAGE,
46005
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.roles, {
46006
+ title: "List Organization roles",
46007
+ description: "List the active role labels that an Organization invitation can use.",
46008
+ inputSchema: z.object(orgInput),
46009
+ outputSchema: z.object({ roles: z.array(z.object({ label: z.string() })) })
46010
+ }, ({ organizationId }) => withClient(scope, CAPXUL_OPERATIONS.org.roles, MANAGE, async (client) => {
46011
+ const result = await client.listOrganizationRoles(organizationId);
46012
+ return result.ok ? okResult({ roles: [...result.value] }) : errorResult(result.error);
46013
+ }))
46014
+ },
46015
+ {
46016
+ name: CAPXUL_OPERATIONS.org.members,
46017
+ scope: MANAGE,
46018
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.members, {
46019
+ title: "List Organization members",
46020
+ description: "List Organization member lifecycle states. Poll after activation until the member is active.",
46021
+ inputSchema: z.object(orgInput),
46022
+ outputSchema: z.object({ members: z.array(z.object({
46023
+ email,
46024
+ name: z.string().nullable(),
46025
+ role: z.string(),
46026
+ status: memberStatus
46027
+ })) })
46028
+ }, ({ organizationId }) => withClient(scope, CAPXUL_OPERATIONS.org.members, MANAGE, async (client) => {
46029
+ const result = await client.listOrganizationMembers(organizationId);
46030
+ return result.ok ? okResult({ members: [...result.value] }) : errorResult(result.error);
46031
+ }))
46032
+ },
46033
+ {
46034
+ name: CAPXUL_OPERATIONS.org.invite,
46035
+ scope: MANAGE,
46036
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.invite, {
46037
+ title: "Invite Organization member",
46038
+ description: "Invite one Person by email into an Organization. Use a role label returned by org.roles.",
46039
+ inputSchema: z.object({
46040
+ ...orgInput,
46041
+ email,
46042
+ role: z.string().trim().min(1)
46043
+ }),
46044
+ outputSchema: z.object({
46045
+ email,
46046
+ role: z.string(),
46047
+ status: memberStatus
46048
+ })
46049
+ }, ({ organizationId, email: invitee, role }) => withClient(scope, CAPXUL_OPERATIONS.org.invite, MANAGE, async (client) => {
46050
+ const result = await client.inviteOrganizationMember(organizationId, {
46051
+ email: invitee,
46052
+ role
46053
+ });
46054
+ return result.ok ? okResult({ ...result.value }) : errorResult(result.error);
46055
+ }))
46056
+ },
46057
+ {
46058
+ name: CAPXUL_OPERATIONS.org.acceptInvitations,
46059
+ scope: MANAGE,
46060
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.acceptInvitations, {
46061
+ title: "Accept Organization invitations",
46062
+ description: "Accept every pending Organization invitation for the signed-in Person's verified email.",
46063
+ inputSchema: z.object({}),
46064
+ outputSchema: z.object({ organizationIds: z.array(z.string()) })
46065
+ }, () => withClient(scope, CAPXUL_OPERATIONS.org.acceptInvitations, MANAGE, async (client) => {
46066
+ const result = await client.acceptOrganizationInvitations();
46067
+ return result.ok ? okResult({ ...result.value }) : errorResult(result.error);
46068
+ }))
46069
+ },
46070
+ {
46071
+ name: CAPXUL_OPERATIONS.org.activateMember,
46072
+ scope: MANAGE,
46073
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.activateMember, {
46074
+ title: "Activate Organization member",
46075
+ description: "Grant the invited role to a pending member's ready Account. The Organization founder signs this operation.",
46076
+ inputSchema: z.object({
46077
+ ...orgInput,
46078
+ email,
46079
+ accountId: z.string().trim().min(1)
46080
+ }),
46081
+ outputSchema: z.object({
46082
+ email,
46083
+ status: z.enum(["active", "submitted"])
46084
+ })
46085
+ }, ({ organizationId, email: invitee, accountId }) => withClient(scope, CAPXUL_OPERATIONS.org.activateMember, MANAGE, async (client) => {
46086
+ const result = await client.activateOrganizationMember(organizationId, {
46087
+ email: invitee,
46088
+ accountId
46089
+ });
46090
+ return result.ok ? okResult({ ...result.value }) : errorResult(result.error);
46091
+ }))
46092
+ }
46093
+ ];
46094
+ //#endregion
45371
46095
  //#region src/tools/system.ts
45372
46096
  const systemTools = [{
45373
46097
  name: CAPXUL_OPERATIONS.system.ping,
@@ -45442,7 +46166,12 @@ const AGENT_SCOPES = [
45442
46166
  "org:manage",
45443
46167
  "media:write"
45444
46168
  ];
45445
- const TOOLS = [...systemTools, ...accountTools];
46169
+ const TOOLS = [
46170
+ ...systemTools,
46171
+ ...accountTools,
46172
+ ...organizationTools,
46173
+ ...staffTools
46174
+ ];
45446
46175
  const TOOL_NAMES = TOOLS.map((tool) => tool.name);
45447
46176
  /**
45448
46177
  * The scope a named tool needs. `null` for a public tool, and `null` for a
@@ -45686,7 +46415,7 @@ function stdioIdentity(env = process.env, options = {}) {
45686
46415
  }
45687
46416
  //#endregion
45688
46417
  //#region package.json
45689
- var version = "3.2.0";
46418
+ var version = "4.0.1";
45690
46419
  //#endregion
45691
46420
  //#region src/deps.ts
45692
46421
  const NO_IDENTITY = async () => void 0;
@@ -45721,6 +46450,22 @@ function buildMcpServer(deps, identity) {
45721
46450
  });
45722
46451
  const scope = makeRequestScope(deps, identity);
45723
46452
  registerAllTools(server, scope);
46453
+ if (deps.posthog !== void 0) instrument(server, deps.posthog, {
46454
+ context: { description: "Explain the user goal that requires this Capxul tool call." },
46455
+ enableConversationId: true,
46456
+ enableExceptionAutocapture: false,
46457
+ identify: async () => {
46458
+ const resolved = await scope.identity();
46459
+ return resolved?.ok === true ? { distinctId: resolved.value.authUserId } : null;
46460
+ },
46461
+ eventProperties: async () => ({
46462
+ capxul_env: deps.posthogEnvironment ?? "unknown",
46463
+ producer: "mcp",
46464
+ $geoip_disable: true
46465
+ }),
46466
+ beforeSend: privacySafeMcpEvent,
46467
+ logger: (message) => console.error(`[capxul-mcp] posthog: ${message}`)
46468
+ });
45724
46469
  const previous = server.server.onclose;
45725
46470
  server.server.onclose = () => {
45726
46471
  scope.close();
@@ -45728,9 +46473,75 @@ function buildMcpServer(deps, identity) {
45728
46473
  };
45729
46474
  return server;
45730
46475
  }
46476
+ const SAFE_MCP_PROPERTIES = /* @__PURE__ */ new Set([
46477
+ "$geoip_disable",
46478
+ "$lib",
46479
+ "$lib_version",
46480
+ "$mcp_client_name",
46481
+ "$mcp_conversation_id",
46482
+ "$mcp_duration_ms",
46483
+ "$mcp_intent",
46484
+ "$mcp_intent_source",
46485
+ "$mcp_is_error",
46486
+ "$mcp_listed_tool_names",
46487
+ "$mcp_protocol_version",
46488
+ "$mcp_server_name",
46489
+ "$mcp_server_version",
46490
+ "$mcp_source",
46491
+ "$mcp_tool_description",
46492
+ "$mcp_tool_name",
46493
+ "$process_person_profile",
46494
+ "$session_id",
46495
+ "capxul_env",
46496
+ "producer"
46497
+ ]);
46498
+ const SAFE_TOOL_INTENTS = {
46499
+ [CAPXUL_OPERATIONS.system.ping]: "Verify MCP transport.",
46500
+ [CAPXUL_OPERATIONS.system.health]: "Verify MCP backend health.",
46501
+ [CAPXUL_OPERATIONS.onboarding.completePerson]: "Complete Person onboarding.",
46502
+ [CAPXUL_OPERATIONS.onboarding.completeOrganization]: "Complete Organization onboarding.",
46503
+ [CAPXUL_OPERATIONS.org.acceptInvitations]: "Accept Organization invitations.",
46504
+ [CAPXUL_OPERATIONS.org.activateMember]: "Activate an Organization member.",
46505
+ [CAPXUL_OPERATIONS.org.invite]: "Invite an Organization member.",
46506
+ [CAPXUL_OPERATIONS.org.list]: "List Organizations.",
46507
+ [CAPXUL_OPERATIONS.org.members]: "List Organization members.",
46508
+ [CAPXUL_OPERATIONS.org.roles]: "List Organization roles.",
46509
+ [CAPXUL_OPERATIONS.me.get]: "Verify authenticated Person identity.",
46510
+ [CAPXUL_OPERATIONS.account.status]: "Verify Account readiness.",
46511
+ [CAPXUL_OPERATIONS.account.balance]: "Verify Account funding."
46512
+ };
46513
+ const SAFE_MCP_TOOL_NAMES = new Set(TOOL_NAMES);
46514
+ const MCP_CONVERSATION_ID = /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/u;
46515
+ const MCP_SESSION_ID = /^ses_(?:[0-9a-f]{32}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/u;
46516
+ function normalizeClientName(value) {
46517
+ if (typeof value !== "string") return "other";
46518
+ const name = value.trim().toLowerCase();
46519
+ if (name.startsWith("codex")) return "codex";
46520
+ if (name.startsWith("claude-code")) return "claude-code";
46521
+ if (name === "capxul-journeys") return name;
46522
+ if (name === "hermetic-client") return name;
46523
+ return "other";
46524
+ }
46525
+ /** Keep MCP analytics useful without sending tool payloads or free-form PII. */
46526
+ const privacySafeMcpEvent = (event) => {
46527
+ const properties = Object.fromEntries(Object.entries(event.properties).filter(([name]) => SAFE_MCP_PROPERTIES.has(name)));
46528
+ const toolName = properties.$mcp_tool_name;
46529
+ if (typeof toolName !== "string" || !SAFE_MCP_TOOL_NAMES.has(toolName)) delete properties.$mcp_tool_name;
46530
+ if (typeof properties.$mcp_intent === "string") properties.$mcp_intent = typeof toolName === "string" ? SAFE_TOOL_INTENTS[toolName] ?? "Use a Capxul tool." : "Use a Capxul tool.";
46531
+ properties.$mcp_client_name = normalizeClientName(properties.$mcp_client_name);
46532
+ if (typeof properties.$mcp_conversation_id !== "string" || !MCP_CONVERSATION_ID.test(properties.$mcp_conversation_id)) delete properties.$mcp_conversation_id;
46533
+ if (typeof properties.$session_id !== "string" || !MCP_SESSION_ID.test(properties.$session_id)) delete properties.$session_id;
46534
+ if (properties.$mcp_protocol_version !== "2025-06-18" && properties.$mcp_protocol_version !== "2026-07-28") delete properties.$mcp_protocol_version;
46535
+ const distinctId = properties.$process_person_profile === false ? `anon_${createHash("sha256").update(event.distinct_id).digest("hex").slice(0, 24)}` : event.distinct_id;
46536
+ return {
46537
+ ...event,
46538
+ distinct_id: distinctId,
46539
+ properties
46540
+ };
46541
+ };
45731
46542
  function createHandler(input) {
45732
46543
  return createMcpHandler(({ authInfo }) => buildMcpServer(input.deps, identityOf(input, authInfo)), {
45733
- legacy: "reject",
46544
+ legacy: "stateless",
45734
46545
  responseMode: "json",
45735
46546
  ...input.onError === void 0 ? {} : { onerror: input.onError }
45736
46547
  });
@@ -45778,7 +46589,8 @@ async function startHttpServer(input) {
45778
46589
  resource,
45779
46590
  identities,
45780
46591
  mcp,
45781
- guards
46592
+ guards,
46593
+ posthog: input.deps.posthog
45782
46594
  }).catch((cause) => {
45783
46595
  if (!res.headersSent) writeJson(res, 500, { error: "internal_error" });
45784
46596
  console.error("[capxul-mcp] request failed:", cause);
@@ -45818,6 +46630,11 @@ async function handle(input) {
45818
46630
  const token = bearerToken(headerValue(req, "authorization"));
45819
46631
  if (decision.identity !== void 0 && token !== void 0) authenticated.auth = toAuthInfo(decision.identity, token);
45820
46632
  await input.mcp(req, res, body);
46633
+ if (input.posthog !== void 0) try {
46634
+ await input.posthog.flush();
46635
+ } catch {
46636
+ console.error("[capxul-mcp] PostHog flush failed");
46637
+ }
45821
46638
  }
45822
46639
  function protectedResourceMetadata(resource) {
45823
46640
  return {
@@ -45989,9 +46806,9 @@ function formatToolCallLine(event) {
45989
46806
  //#endregion
45990
46807
  //#region src/sdk.ts
45991
46808
  /**
45992
- * One fresh client per request. `requirement: "counterfactual"` derives the
45993
- * Safe from the email alone; the claim and deploy need the browser approval
45994
- * surface, which no agent can reach.
46809
+ * One fresh client per request. Live mode derives the counterfactual Account
46810
+ * and fails closed before a signature. Dev mode has its explicit test signer,
46811
+ * so it requires a deployed Account and can exercise signed lifecycle paths.
45995
46812
  *
45996
46813
  * This code passes no `authCache`. The SDK detects one instead. A node process
45997
46814
  * has no `window`, so the SDK builds a fresh `InMemoryAuthCacheAdapter` for
@@ -46011,7 +46828,7 @@ async function createSdkClient(input, createClient = createCapxulClient) {
46011
46828
  bootstrapBaseUrl: config.bootstrapBaseUrl,
46012
46829
  origin: config.origin,
46013
46830
  authBaseUrl: config.authBaseUrl,
46014
- requirement: "counterfactual",
46831
+ requirement: signer === void 0 ? "counterfactual" : "deployed",
46015
46832
  runtime: "node",
46016
46833
  ...identity === void 0 ? {} : { authClient: identity.authClient },
46017
46834
  ...signer === void 0 ? {} : { signer }
@@ -46059,7 +46876,7 @@ async function createSdkClient(input, createClient = createCapxulClient) {
46059
46876
  email: String(result.value.profile.email),
46060
46877
  displayName: result.value.profile.displayName,
46061
46878
  country: String(result.value.profile.country),
46062
- username: result.value.profile.username
46879
+ handle: result.value.profile.handle
46063
46880
  },
46064
46881
  account: {
46065
46882
  status: "ready",
@@ -46069,6 +46886,120 @@ async function createSdkClient(input, createClient = createCapxulClient) {
46069
46886
  }
46070
46887
  };
46071
46888
  },
46889
+ completeOrganization: (organization) => client.onboarding.completeOrganization(organization),
46890
+ listOrganizations: async () => {
46891
+ const result = await client.orgs();
46892
+ if (!result.ok) return result;
46893
+ return {
46894
+ ok: true,
46895
+ value: result.value.map((organization) => ({
46896
+ organizationId: String(organization.id),
46897
+ name: organization.name,
46898
+ handle: organization.handle,
46899
+ role: organization.role
46900
+ }))
46901
+ };
46902
+ },
46903
+ listOrganizationRoles: async (orgId) => {
46904
+ const result = await client.org(orgId).roles();
46905
+ if (!result.ok) return result;
46906
+ return {
46907
+ ok: true,
46908
+ value: result.value.map((role) => ({ label: role.label }))
46909
+ };
46910
+ },
46911
+ listOrganizationMembers: async (orgId) => {
46912
+ const result = await client.org(orgId).members();
46913
+ if (!result.ok) return result;
46914
+ return {
46915
+ ok: true,
46916
+ value: result.value.map((member) => ({
46917
+ email: String(member.email),
46918
+ name: member.name,
46919
+ role: member.role,
46920
+ status: member.status
46921
+ }))
46922
+ };
46923
+ },
46924
+ inviteOrganizationMember: async (orgId, invitation) => {
46925
+ const result = await client.org(orgId).invite(invitation);
46926
+ if (!result.ok) return result;
46927
+ return {
46928
+ ok: true,
46929
+ value: {
46930
+ email: String(result.value.email),
46931
+ role: result.value.role,
46932
+ status: result.value.status
46933
+ }
46934
+ };
46935
+ },
46936
+ acceptOrganizationInvitations: async () => {
46937
+ const result = await client.orgs.detectAndAcceptPendingInvitations();
46938
+ if (!result.ok) return result;
46939
+ return {
46940
+ ok: true,
46941
+ value: { organizationIds: result.value.matched.map(String) }
46942
+ };
46943
+ },
46944
+ activateOrganizationMember: async (orgId, activation) => {
46945
+ const memberEmail = activation.email.trim().toLowerCase();
46946
+ const scoped = client.org(orgId);
46947
+ const members = await scoped.members();
46948
+ if (!members.ok) return members;
46949
+ const matches = members.value.filter((member) => String(member.email) === memberEmail);
46950
+ const member = matches.length === 1 ? matches[0] : void 0;
46951
+ if (member === void 0) return {
46952
+ ok: false,
46953
+ error: Errors.invalidInput("email", "member was not found")
46954
+ };
46955
+ if (member.status === "active") return {
46956
+ ok: true,
46957
+ value: {
46958
+ email: memberEmail,
46959
+ status: "active"
46960
+ }
46961
+ };
46962
+ if (member.status !== "pending_grant" || member.roleKey === null) return {
46963
+ ok: false,
46964
+ error: Errors.wrongState({
46965
+ method: CAPXUL_OPERATIONS.org.activateMember,
46966
+ currentState: member.status,
46967
+ validStates: ["pending_grant", "active"]
46968
+ })
46969
+ };
46970
+ const permissions = await scoped.permissions.list();
46971
+ if (!permissions.ok) return permissions;
46972
+ const matchingPermissions = permissions.value.permissions.filter((permission) => permission.type === "managePeople" && permission.state === "active" && String(permission.roleKey).toLowerCase() === String(member.roleKey).toLowerCase());
46973
+ const permission = matchingPermissions.length === 1 ? matchingPermissions[0] : void 0;
46974
+ if (permission === void 0) return {
46975
+ ok: false,
46976
+ error: Errors.wrongState({
46977
+ method: CAPXUL_OPERATIONS.org.activateMember,
46978
+ currentState: "matching-permission-missing",
46979
+ validStates: ["one-active-role-permission"]
46980
+ })
46981
+ };
46982
+ const requestKey = `mcp-staff-${createHash("sha256").update(JSON.stringify({
46983
+ orgId,
46984
+ email: memberEmail,
46985
+ accountId: activation.accountId,
46986
+ permissionId: permission.permissionId
46987
+ })).digest("hex")}`;
46988
+ const assigned = await scoped.permissions.assign({
46989
+ requestKey,
46990
+ permissionId: String(permission.permissionId),
46991
+ accountId: activation.accountId,
46992
+ expectedMemberEmail: memberEmail
46993
+ });
46994
+ if (!assigned.ok) return assigned;
46995
+ return {
46996
+ ok: true,
46997
+ value: {
46998
+ email: memberEmail,
46999
+ status: "submitted"
47000
+ }
47001
+ };
47002
+ },
46072
47003
  getLifecycle: async () => {
46073
47004
  const result = await client.account.getLifecycle();
46074
47005
  if (!result.ok) return result;
@@ -46143,6 +47074,8 @@ if (!modeConfig.ok) {
46143
47074
  }
46144
47075
  const mode = modeConfig.value;
46145
47076
  const port = cli.port;
47077
+ const analyticsConfig = readMcpAnalyticsEnvConfig();
47078
+ const posthog = analyticsConfig === void 0 ? void 0 : new PostHog(analyticsConfig.projectToken, { host: analyticsConfig.host });
46146
47079
  const deps = {
46147
47080
  createSdkClient: (identity) => createSdkClient({
46148
47081
  config: readSdkEnvConfig(),
@@ -46151,6 +47084,10 @@ const deps = {
46151
47084
  }),
46152
47085
  onToolCall: (event) => {
46153
47086
  console.error(formatToolCallLine(event));
47087
+ },
47088
+ ...posthog === void 0 ? {} : {
47089
+ posthog,
47090
+ posthogEnvironment: analyticsConfig?.environment ?? "unknown"
46154
47091
  }
46155
47092
  };
46156
47093
  if (cli.stdio) {
@@ -46164,7 +47101,7 @@ if (cli.stdio) {
46164
47101
  bearer: identity === void 0 ? "none" : "environment"
46165
47102
  }));
46166
47103
  const shutdownStdio = () => {
46167
- handle.close().finally(() => process.exit(0));
47104
+ handle.close().catch(() => void 0).then(() => posthog?.shutdown()).catch(() => void 0).finally(() => process.exit(0));
46168
47105
  };
46169
47106
  process.on("SIGINT", shutdownStdio);
46170
47107
  process.on("SIGTERM", shutdownStdio);
@@ -46183,7 +47120,7 @@ if (cli.stdio) {
46183
47120
  bearer: "oauth"
46184
47121
  }));
46185
47122
  const shutdown = () => {
46186
- running.close().finally(() => process.exit(0));
47123
+ running.close().catch(() => void 0).then(() => posthog?.shutdown()).catch(() => void 0).finally(() => process.exit(0));
46187
47124
  };
46188
47125
  process.on("SIGINT", shutdown);
46189
47126
  process.on("SIGTERM", shutdown);