@capxul/mcp 3.2.0 → 4.0.0

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 +1136 -367
  3. package/package.json +6 -3
package/dist/main.mjs CHANGED
@@ -3,6 +3,7 @@ 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";
@@ -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",
@@ -4098,7 +4145,7 @@ const CAPXUL_OPERATIONS = {
4098
4145
  signOut: "identity.SignOut",
4099
4146
  signOutFailed: "identity.SignOutFailed",
4100
4147
  update: "identity.update",
4101
- usernameAvailable: "identity.usernameAvailable",
4148
+ handleAvailable: "identity.handleAvailable",
4102
4149
  verified: "identity.Verified",
4103
4150
  verifyFailed: "identity.VerifyFailed",
4104
4151
  verifyOtp: "identity.VerifyOtp"
@@ -4114,10 +4161,12 @@ const CAPXUL_OPERATIONS = {
4114
4161
  get: "me.get"
4115
4162
  },
4116
4163
  moneyExecution: {
4164
+ abandonPaymentExecution: "moneyExecution.abandonPaymentExecution",
4117
4165
  prepareOrganizationPaymentExecution: "moneyExecution.prepareOrganizationPaymentExecution",
4118
4166
  preparePaymentExecution: "moneyExecution.preparePaymentExecution",
4119
4167
  preparePaymentLifecycleExecution: "moneyExecution.preparePaymentLifecycleExecution",
4120
4168
  preparePermissionExecution: "moneyExecution.preparePermissionExecution",
4169
+ recoverSubmissionClaims: "moneyExecution.recoverSubmissionClaims",
4121
4170
  submit: "moneyExecution.submit",
4122
4171
  submitPaymentCommandExecution: "moneyExecution.submitPaymentCommandExecution",
4123
4172
  submitPaymentExecution: "moneyExecution.submitPaymentExecution",
@@ -4136,9 +4185,14 @@ const CAPXUL_OPERATIONS = {
4136
4185
  quote: "offramp.quote",
4137
4186
  status: "offramp.status"
4138
4187
  },
4139
- onboarding: { completePerson: "onboarding.completePerson" },
4188
+ onboarding: {
4189
+ completeOrganization: "onboarding.completeOrganization",
4190
+ completePerson: "onboarding.completePerson"
4191
+ },
4140
4192
  org: {
4193
+ acceptInvitations: "org.acceptInvitations",
4141
4194
  account: { get: "org.account.get" },
4195
+ activateMember: "org.activateMember",
4142
4196
  auditLog: "org.auditLog",
4143
4197
  confirmBootstrap: "org.confirmBootstrap",
4144
4198
  createOrg: "org.createOrg",
@@ -4149,6 +4203,7 @@ const CAPXUL_OPERATIONS = {
4149
4203
  getProofReceipt: "org.getProofReceipt",
4150
4204
  invite: "org.invite",
4151
4205
  inviteMember: "org.inviteMember",
4206
+ list: "org.list",
4152
4207
  load: "org.load",
4153
4208
  me: "org.me",
4154
4209
  members: "org.members",
@@ -4241,11 +4296,7 @@ const CAPXUL_OPERATIONS = {
4241
4296
  render: "paymentDocuments.render",
4242
4297
  verify: "paymentDocuments.verify"
4243
4298
  },
4244
- payees: {
4245
- create: "payees.create",
4246
- get: "payees.get",
4247
- resolve: "payees.resolve"
4248
- },
4299
+ recipient: { resolve: "recipient.resolve" },
4249
4300
  payroll: {
4250
4301
  authorizeRun: "payroll.authorizeRun",
4251
4302
  groups: {
@@ -4327,12 +4378,6 @@ const CAPXUL_OPERATIONS = {
4327
4378
  ping: "system.ping",
4328
4379
  runtimeChain: "system.runtimeChain"
4329
4380
  },
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
4381
  testUsdc: { mint: "TestUSDC.mint" },
4337
4382
  _internal: {
4338
4383
  accounts: { fund: "_internal.accounts.fund" },
@@ -4745,32 +4790,116 @@ const OrgInviteExpiredProps = Schema.Struct({
4745
4790
  role: OptionalString,
4746
4791
  status: OptionalString
4747
4792
  });
4793
+ const RecipientLocatorKindSchema = Schema.Literals([
4794
+ "handle",
4795
+ "email",
4796
+ "address",
4797
+ "party"
4798
+ ]);
4799
+ const RecipientResolutionStatusSchema = Schema.Literals([
4800
+ "known_party",
4801
+ "new_email",
4802
+ "external_address"
4803
+ ]);
4804
+ const RecipientPartyKindSchema = Schema.Literals([
4805
+ "person",
4806
+ "organization",
4807
+ "unresolved"
4808
+ ]);
4809
+ const RecipientTelemetryProps = {
4810
+ recipient_locator_kind: Schema.optional(RecipientLocatorKindSchema),
4811
+ recipient_resolution_status: Schema.optional(RecipientResolutionStatusSchema),
4812
+ recipient_party_id: OptionalString,
4813
+ recipient_party_kind: Schema.optional(RecipientPartyKindSchema),
4814
+ recipient_is_capxul_account: Schema.optional(Schema.Boolean),
4815
+ recipient_handle: OptionalString,
4816
+ recipient_address: OptionalAddress,
4817
+ external_address_acknowledged: Schema.optional(Schema.Boolean)
4818
+ };
4748
4819
  const PaymentInitiatedProps = Schema.Struct({
4820
+ command_id: OptionalString,
4821
+ execution_id: OptionalString,
4822
+ payment_lifecycle_id: OptionalString,
4749
4823
  ...TelemetryEnvelopeProps,
4824
+ ...RecipientTelemetryProps,
4750
4825
  kind: Schema.String,
4751
4826
  payment_id: Schema.String
4752
4827
  });
4828
+ const PaymentLifecycleProps = {
4829
+ payment_state: OptionalString,
4830
+ execution_state: OptionalString,
4831
+ occurred_at: Schema.optional(Schema.Number),
4832
+ causal_sequence: Schema.optional(Schema.Number),
4833
+ sponsorship_valid_until: Schema.optional(Schema.Number),
4834
+ terminal_event_id: OptionalString
4835
+ };
4753
4836
  const PaymentSettledL2Props = Schema.Struct({
4837
+ ...PaymentLifecycleProps,
4754
4838
  ...TelemetryEnvelopeProps,
4839
+ ...RecipientTelemetryProps,
4755
4840
  kind: Schema.String,
4756
4841
  chain_id: Schema.Number,
4757
- settlement_id: Schema.String
4842
+ settlement_id: Schema.String,
4843
+ payment_id: OptionalString,
4844
+ payment_ids: OptionalString,
4845
+ command_id: OptionalString,
4846
+ payment_lifecycle_id: OptionalString,
4847
+ execution_id: OptionalString,
4848
+ user_op_hash: OptionalString,
4849
+ transaction_hash: OptionalString
4758
4850
  });
4759
4851
  const PaymentFailedL2Props = Schema.Struct({
4852
+ ...PaymentLifecycleProps,
4760
4853
  ...TelemetryEnvelopeProps,
4761
4854
  ...ChainCauseTelemetryProps,
4855
+ ...RecipientTelemetryProps,
4762
4856
  kind: Schema.String,
4763
4857
  payment_id: Schema.String,
4764
- reason_code: Schema.String
4858
+ payment_ids: OptionalString,
4859
+ reason_code: Schema.String,
4860
+ command_id: OptionalString,
4861
+ payment_lifecycle_id: OptionalString,
4862
+ execution_id: OptionalString,
4863
+ user_op_hash: OptionalString
4765
4864
  });
4766
4865
  const PaymentVerificationRetryProps = Schema.Struct({
4866
+ ...PaymentLifecycleProps,
4767
4867
  ...TelemetryEnvelopeProps,
4868
+ ...RecipientTelemetryProps,
4768
4869
  command_id: Schema.String,
4870
+ payment_lifecycle_id: Schema.String,
4769
4871
  attempt: Schema.Number,
4770
4872
  reason_code: Schema.String,
4771
4873
  chain_id: Schema.Number,
4772
4874
  delay_ms: DurationMsSchema$1,
4773
- outcome: Schema.Literals(["scheduled", "unresolved"])
4875
+ outcome: Schema.Literals(["scheduled", "unresolved"]),
4876
+ payment_id: OptionalString,
4877
+ payment_ids: OptionalString,
4878
+ execution_id: OptionalString,
4879
+ user_op_hash: OptionalString
4880
+ });
4881
+ const PaymentLifecycleTransitionProps = Schema.Struct({
4882
+ ...TelemetryEnvelopeProps,
4883
+ ...RecipientTelemetryProps,
4884
+ payment_id: Schema.String,
4885
+ payment_lifecycle_id: Schema.String,
4886
+ command_id: Schema.String,
4887
+ payment_state: Schema.String,
4888
+ occurred_at: Schema.Number,
4889
+ causal_sequence: Schema.Number,
4890
+ execution_id: OptionalString,
4891
+ execution_state: OptionalString,
4892
+ user_op_hash: OptionalString,
4893
+ sponsorship_valid_until: Schema.optional(Schema.Number),
4894
+ reason_code: OptionalString
4895
+ });
4896
+ const QuickPayExternalAddressAcknowledgedProps = Schema.Struct({
4897
+ ...TelemetryEnvelopeProps,
4898
+ recipient_locator_kind: Schema.Literal("address"),
4899
+ recipient_resolution_status: Schema.Literal("external_address"),
4900
+ recipient_address: AddressSchema$1,
4901
+ external_address_acknowledged: Schema.Literal(true),
4902
+ organization_id: OptionalOrgId
4774
4903
  });
4775
4904
  const DepositInitiatedProps = Schema.Struct({ ...TelemetryEnvelopeProps });
4776
4905
  const DepositSettledProps = Schema.Struct({
@@ -4978,6 +5107,14 @@ Schema.Struct({
4978
5107
  name: Schema.Literal("payment_verification_retry"),
4979
5108
  props: PaymentVerificationRetryProps
4980
5109
  });
5110
+ Schema.Struct({
5111
+ name: Schema.Literal("payment_lifecycle_transition"),
5112
+ props: PaymentLifecycleTransitionProps
5113
+ });
5114
+ Schema.Struct({
5115
+ name: Schema.Literal("quick_pay_external_address_acknowledged"),
5116
+ props: QuickPayExternalAddressAcknowledgedProps
5117
+ });
4981
5118
  Schema.Struct({
4982
5119
  name: Schema.Literal("deposit_initiated"),
4983
5120
  props: DepositInitiatedProps
@@ -5320,16 +5457,13 @@ const CAPXUL_FUNCTIONS = {
5320
5457
  list: "financialOps/destinations:list",
5321
5458
  remove: "financialOps/destinations:remove"
5322
5459
  },
5323
- "financialOps/mutations": { createPayee: "financialOps/mutations:createPayee" },
5324
5460
  "financialOps/queries": {
5325
5461
  depositInstructions: "financialOps/queries:depositInstructions",
5326
- getPayee: "financialOps/queries:getPayee",
5327
5462
  getPayment: "financialOps/queries:getPayment",
5328
5463
  listPayments: "financialOps/queries:listPayments",
5329
5464
  me: "financialOps/queries:me",
5330
5465
  renderStoredDocument: "financialOps/queries:renderStoredDocument",
5331
- resolveHandle: "financialOps/queries:resolveHandle",
5332
- resolvePayee: "financialOps/queries:resolvePayee",
5466
+ resolveRecipient: "financialOps/queries:resolveRecipient",
5333
5467
  verifyPaymentDocument: "financialOps/queries:verifyPaymentDocument"
5334
5468
  },
5335
5469
  "financialOps/requestsInbox": {
@@ -5348,7 +5482,7 @@ const CAPXUL_FUNCTIONS = {
5348
5482
  },
5349
5483
  "identity/queries": {
5350
5484
  loadByAuthUserId: "identity/queries:loadByAuthUserId",
5351
- usernameAvailable: "identity/queries:usernameAvailable"
5485
+ handleAvailable: "identity/queries:handleAvailable"
5352
5486
  },
5353
5487
  "holdings/actions": { current: "holdings/actions:current" },
5354
5488
  "movement/activity": {
@@ -5358,6 +5492,7 @@ const CAPXUL_FUNCTIONS = {
5358
5492
  summary: "movement/activity:summary"
5359
5493
  },
5360
5494
  "moneyExecution/actions": {
5495
+ abandonPaymentExecution: "moneyExecution/actions:abandonPaymentExecution",
5361
5496
  preparePermissionExecution: "moneyExecution/actions:preparePermissionExecution",
5362
5497
  preparePaymentExecution: "moneyExecution/actions:preparePaymentExecution",
5363
5498
  submitPermissionExecution: "moneyExecution/actions:submitPermissionExecution",
@@ -5435,6 +5570,7 @@ const CAPXUL_FUNCTIONS = {
5435
5570
  const PAYMENT_STATUSES = [
5436
5571
  "pending",
5437
5572
  "settling",
5573
+ "unresolved",
5438
5574
  "scheduled",
5439
5575
  "streaming",
5440
5576
  "pending_claim",
@@ -5442,6 +5578,30 @@ const PAYMENT_STATUSES = [
5442
5578
  "cancelled",
5443
5579
  "failed"
5444
5580
  ];
5581
+ /** The lifecycle of one signed Payment execution attempt. */
5582
+ const PAYMENT_EXECUTION_STATUS = {
5583
+ PENDING: "pending",
5584
+ INCLUDED: "included",
5585
+ DROPPED: "dropped",
5586
+ REPLACED: "replaced",
5587
+ EXPIRED: "expired",
5588
+ UNRESOLVED: "unresolved",
5589
+ SUPERSEDED: "superseded",
5590
+ FAILED: "failed",
5591
+ SETTLED: "settled"
5592
+ };
5593
+ const PAYMENT_EXECUTION_STATUSES = [
5594
+ PAYMENT_EXECUTION_STATUS.PENDING,
5595
+ PAYMENT_EXECUTION_STATUS.INCLUDED,
5596
+ PAYMENT_EXECUTION_STATUS.DROPPED,
5597
+ PAYMENT_EXECUTION_STATUS.REPLACED,
5598
+ PAYMENT_EXECUTION_STATUS.EXPIRED,
5599
+ PAYMENT_EXECUTION_STATUS.UNRESOLVED,
5600
+ PAYMENT_EXECUTION_STATUS.SUPERSEDED,
5601
+ PAYMENT_EXECUTION_STATUS.FAILED,
5602
+ PAYMENT_EXECUTION_STATUS.SETTLED
5603
+ ];
5604
+ PAYMENT_EXECUTION_STATUS.DROPPED, PAYMENT_EXECUTION_STATUS.REPLACED, PAYMENT_EXECUTION_STATUS.EXPIRED, PAYMENT_EXECUTION_STATUS.SUPERSEDED;
5445
5605
  /** The payment direction relative to the current actor. */
5446
5606
  const PAYMENT_DIRECTIONS = [
5447
5607
  "in",
@@ -5477,22 +5637,16 @@ const EVM_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
5477
5637
  */
5478
5638
  const PAYMENT_DOCUMENT_VERIFYING_CONTRACT = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
5479
5639
  const PAYMENT_ID_RE = /^payment_[0-9A-Za-z]+$/;
5480
- const PAYEE_ID_RE = /^payee_[0-9A-Za-z]+$/;
5481
5640
  const ORG_ID_RE = /^org_[0-9A-Za-z]+$/;
5482
- const USER_ID_RE = /^user_[0-9A-Za-z]+$/;
5483
5641
  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}$/;
5642
+ const HANDLE_RE = /^@?[a-z0-9_-]{3,30}$/;
5486
5643
  const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
5487
5644
  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
5645
  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
5646
  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
5647
  const PartyIdSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => PARTY_ID_RE.test(value), { message: "must be party_ plus an alphanumeric id" })));
5493
5648
  const DecimalStringSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => DECIMAL_STRING_RE.test(value), { message: "must be a non-negative decimal string" })));
5494
5649
  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
5650
  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
5651
  const Uint8Schema$1 = Schema.Number.pipe(Schema.check(Schema.makeFilter((value) => Number.isSafeInteger(value) && value >= 0 && value <= 255, { message: "must be a uint8" })));
5498
5652
  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 +5766,39 @@ const WithdrawalDocumentEnvelope = Schema.Struct({
5612
5766
  primaryType: Schema.Literal("Withdrawal"),
5613
5767
  message: WithdrawalDocument
5614
5768
  });
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
- });
5769
+ const PaymentDocumentEnvelope = Schema.Union([AttachablePaymentDocumentEnvelope, WithdrawalDocumentEnvelope]);
5770
+ const ENVELOPE_PRIMARY_TYPE_TO_KIND = {
5771
+ Memo: "memo",
5772
+ Invoice: "invoice",
5773
+ Payslip: "payslip",
5774
+ Receipt: "receipt",
5775
+ Withdrawal: "withdrawal"
5776
+ };
5777
+ /**
5778
+ * Derive the wire `paymentType` an UNKNOWN document envelope classifies to
5779
+ * (payment-document-spec.md D11: memo/withdrawal → unspecified, invoice →
5780
+ * invoice, payslip → payroll, receipt → reimbursement), or `undefined` if the
5781
+ * envelope is absent / malformed — the same tolerance as
5782
+ * `tryHashPaymentDocument`. Callers holding an untyped envelope (e.g. the MCP
5783
+ * org spend port, #712) use this so the type they record agrees with the type
5784
+ * the backend re-derives from the same document.
5785
+ */
5786
+ function paymentTypeForDocumentEnvelope(envelope) {
5787
+ if (envelope === void 0 || envelope === null) return void 0;
5788
+ const decoded = SchemaParser.decodeUnknownResult(PaymentDocumentEnvelope)(envelope);
5789
+ if (decoded._tag === "Failure") return void 0;
5790
+ return paymentTypeForDocumentKind(ENVELOPE_PRIMARY_TYPE_TO_KIND[decoded.success.primaryType]);
5791
+ }
5792
+ const PaymentRecipient = Schema.Union([Schema.Struct({
5793
+ kind: Schema.Literal("party"),
5794
+ partyId: PartyIdSchema,
5795
+ label: Schema.String
5796
+ }), Schema.Struct({
5797
+ kind: Schema.Literal("external_address"),
5798
+ label: Schema.String
5799
+ })]);
5645
5800
  /**
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.
5801
+ * A raw external EVM address for a payment or withdrawal destination.
5651
5802
  */
5652
5803
  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
5804
  const PaymentTiming = Schema.Union([
@@ -5673,16 +5824,8 @@ const PaymentRef = Schema.Union([
5673
5824
  email: EmailValueSchema
5674
5825
  }),
5675
5826
  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
5827
+ kind: Schema.Literal("address"),
5828
+ address: ExternalAddressSchema
5686
5829
  }),
5687
5830
  Schema.Struct({
5688
5831
  kind: Schema.Literal("party"),
@@ -5705,6 +5848,10 @@ const Payment = Schema.Struct({
5705
5848
  timing: PaymentTiming,
5706
5849
  released: FinancialOpsMoney,
5707
5850
  availableToClaim: FinancialOpsMoney,
5851
+ execution: Schema.optional(Schema.Struct({
5852
+ status: Schema.Literals(PAYMENT_EXECUTION_STATUSES),
5853
+ retryRequired: Schema.Boolean
5854
+ })),
5708
5855
  createdAt: EpochMsSchema,
5709
5856
  updatedAt: EpochMsSchema
5710
5857
  }).pipe(Schema.check(Schema.makeFilter((payment) => payment.documents.every((document) => paymentTypeForDocumentKind(document.kind) === payment.paymentType), { message: "document kind must map to paymentType" })));
@@ -5849,11 +5996,21 @@ const MovementIdentitySchema = Schema.Struct({
5849
5996
  txHash: TxHashSchema,
5850
5997
  logIndex: LogIndexSchema
5851
5998
  });
5852
- const MovementCanonicalStateSchema = Schema.Literals([
5999
+ const MovementCanonicalStateInputSchema = Schema.Literals([
5853
6000
  "observed",
6001
+ "included",
5854
6002
  "finalized",
5855
6003
  "removed"
5856
6004
  ]);
6005
+ const MovementCanonicalStateOutputSchema = Schema.Literals([
6006
+ "observed",
6007
+ "included",
6008
+ "removed"
6009
+ ]);
6010
+ const MovementCanonicalStateSchema = MovementCanonicalStateInputSchema.pipe(Schema.decodeTo(MovementCanonicalStateOutputSchema, {
6011
+ decode: SchemaGetter.transform((state) => state === "finalized" ? "included" : state),
6012
+ encode: SchemaGetter.transform((state) => state)
6013
+ }));
5857
6014
  const MovementSchema = Schema.Struct({
5858
6015
  ...MovementIdentitySchema.fields,
5859
6016
  movementId: MovementIdSchema,
@@ -6204,7 +6361,7 @@ Schema.Struct({
6204
6361
  transfers: Schema.Array(TransferEvidenceSchema),
6205
6362
  requestCount: nonNegativeInteger("requestCount")
6206
6363
  });
6207
- const FinalizedMoneyEvidenceCommonSchema = Schema.Struct({
6364
+ const VerifiedMoneyEvidenceCommonSchema = Schema.Struct({
6208
6365
  chainId: BaseSepoliaChainIdSchema,
6209
6366
  contractAddress: AddressSchema,
6210
6367
  userOpHash: Bytes32Schema,
@@ -6214,8 +6371,8 @@ const FinalizedMoneyEvidenceCommonSchema = Schema.Struct({
6214
6371
  blockTimestamp: Uint48Schema,
6215
6372
  eventLogIndex: LogIndexSchema
6216
6373
  });
6217
- const FinalizedPaymentEvidenceSchema = Schema.Struct({
6218
- ...FinalizedMoneyEvidenceCommonSchema.fields,
6374
+ const VerifiedPaymentEvidenceSchema = Schema.Struct({
6375
+ ...VerifiedMoneyEvidenceCommonSchema.fields,
6219
6376
  operation: Schema.Literal("send"),
6220
6377
  settlementId: SettlementIdSchema,
6221
6378
  purposeKind: PaymentPurposeKindSchema,
@@ -6227,8 +6384,8 @@ const FinalizedPaymentEvidenceSchema = Schema.Struct({
6227
6384
  destination: AddressSchema,
6228
6385
  rawAmount: WeiAmountSchema
6229
6386
  });
6230
- const FinalizedCommitmentCreationEvidenceSchema = Schema.Struct({
6231
- ...FinalizedMoneyEvidenceCommonSchema.fields,
6387
+ const VerifiedCommitmentCreationEvidenceSchema = Schema.Struct({
6388
+ ...VerifiedMoneyEvidenceCommonSchema.fields,
6232
6389
  operation: Schema.Literal("create_commitment"),
6233
6390
  commitmentId: Uint256StringSchema,
6234
6391
  settlementId: SettlementIdSchema,
@@ -6244,8 +6401,8 @@ const FinalizedCommitmentCreationEvidenceSchema = Schema.Struct({
6244
6401
  documentHash: NonzeroDocumentHashSchema,
6245
6402
  transferLogIndex: LogIndexSchema
6246
6403
  });
6247
- const FinalizedCommitmentClaimEvidenceSchema = Schema.Struct({
6248
- ...FinalizedMoneyEvidenceCommonSchema.fields,
6404
+ const VerifiedCommitmentClaimEvidenceSchema = Schema.Struct({
6405
+ ...VerifiedMoneyEvidenceCommonSchema.fields,
6249
6406
  operation: Schema.Literal("claim_commitment"),
6250
6407
  commitmentId: Uint256StringSchema,
6251
6408
  settlementId: SettlementIdSchema,
@@ -6258,8 +6415,8 @@ const FinalizedCommitmentClaimEvidenceSchema = Schema.Struct({
6258
6415
  documentHash: NonzeroDocumentHashSchema,
6259
6416
  transferLogIndex: LogIndexSchema
6260
6417
  });
6261
- const FinalizedCommitmentCancelEvidenceSchema = Schema.Struct({
6262
- ...FinalizedMoneyEvidenceCommonSchema.fields,
6418
+ const VerifiedCommitmentCancelEvidenceSchema = Schema.Struct({
6419
+ ...VerifiedMoneyEvidenceCommonSchema.fields,
6263
6420
  operation: Schema.Literal("cancel_commitment"),
6264
6421
  commitmentId: Uint256StringSchema,
6265
6422
  settlementId: SettlementIdSchema,
@@ -6273,8 +6430,8 @@ const FinalizedCommitmentCancelEvidenceSchema = Schema.Struct({
6273
6430
  documentHash: NonzeroDocumentHashSchema,
6274
6431
  transfer: Schema.NullOr(TransferEvidenceSchema)
6275
6432
  });
6276
- const FinalizedCommitmentRedirectEvidenceSchema = Schema.Struct({
6277
- ...FinalizedMoneyEvidenceCommonSchema.fields,
6433
+ const VerifiedCommitmentRedirectEvidenceSchema = Schema.Struct({
6434
+ ...VerifiedMoneyEvidenceCommonSchema.fields,
6278
6435
  operation: Schema.Literal("redirect_commitment"),
6279
6436
  commitmentId: Uint256StringSchema,
6280
6437
  settlementId: SettlementIdSchema,
@@ -6285,12 +6442,12 @@ const FinalizedCommitmentRedirectEvidenceSchema = Schema.Struct({
6285
6442
  documentHash: NonzeroDocumentHashSchema,
6286
6443
  transfer: Schema.Null
6287
6444
  });
6288
- const FinalizedMoneyEvidenceSchema = Schema.Union([
6289
- FinalizedPaymentEvidenceSchema,
6290
- FinalizedCommitmentCreationEvidenceSchema,
6291
- FinalizedCommitmentClaimEvidenceSchema,
6292
- FinalizedCommitmentCancelEvidenceSchema,
6293
- FinalizedCommitmentRedirectEvidenceSchema
6445
+ const VerifiedMoneyEvidenceSchema = Schema.Union([
6446
+ VerifiedPaymentEvidenceSchema,
6447
+ VerifiedCommitmentCreationEvidenceSchema,
6448
+ VerifiedCommitmentClaimEvidenceSchema,
6449
+ VerifiedCommitmentCancelEvidenceSchema,
6450
+ VerifiedCommitmentRedirectEvidenceSchema
6294
6451
  ]);
6295
6452
  Schema.Union([
6296
6453
  Schema.Struct({
@@ -6300,7 +6457,7 @@ Schema.Union([
6300
6457
  }),
6301
6458
  Schema.Struct({
6302
6459
  status: Schema.Literal("verified"),
6303
- evidence: FinalizedMoneyEvidenceSchema
6460
+ evidence: VerifiedMoneyEvidenceSchema
6304
6461
  }),
6305
6462
  Schema.Struct({
6306
6463
  status: Schema.Literal("mismatch"),
@@ -6312,7 +6469,7 @@ Schema.Union([
6312
6469
  retryable: Schema.Literal(true)
6313
6470
  })
6314
6471
  ]);
6315
- const FinalizedAttributedInboundMovementSchema = Schema.Struct({
6472
+ const VerifiedAttributedInboundMovementSchema = Schema.Struct({
6316
6473
  movement: MovementSchema,
6317
6474
  attribution: MovementAttributionSchema
6318
6475
  });
@@ -6338,6 +6495,25 @@ const ProtocolBirthInputSchema = Schema.Struct({
6338
6495
  release: ReleaseTermsSchema,
6339
6496
  lineage: Schema.optional(PaymentCommandLineageSchema)
6340
6497
  }).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" }));
6498
+ const ApplyVerifiedEvidenceCommandSchema = Schema.Struct({
6499
+ kind: Schema.Literal("apply_verified_evidence"),
6500
+ paymentId: PaymentIdSchema,
6501
+ evidence: VerifiedMoneyEvidenceSchema
6502
+ });
6503
+ const ApplyFinalizedEvidenceCommandSchema = Schema.Struct({
6504
+ kind: Schema.Literal("apply_finalized_evidence"),
6505
+ paymentId: PaymentIdSchema,
6506
+ evidence: VerifiedMoneyEvidenceSchema
6507
+ }).pipe(Schema.decodeTo(ApplyVerifiedEvidenceCommandSchema, {
6508
+ decode: SchemaGetter.transform((value) => ({
6509
+ ...value,
6510
+ kind: "apply_verified_evidence"
6511
+ })),
6512
+ encode: SchemaGetter.transform((value) => ({
6513
+ ...value,
6514
+ kind: "apply_finalized_evidence"
6515
+ }))
6516
+ }));
6341
6517
  Schema.Union([
6342
6518
  Schema.Struct({
6343
6519
  kind: Schema.Literal("birth"),
@@ -6345,7 +6521,7 @@ Schema.Union([
6345
6521
  }),
6346
6522
  Schema.Struct({
6347
6523
  kind: Schema.Literal("birth_deposit"),
6348
- movement: FinalizedAttributedInboundMovementSchema
6524
+ movement: VerifiedAttributedInboundMovementSchema
6349
6525
  }),
6350
6526
  Schema.Struct({
6351
6527
  kind: Schema.Literal("rollback_deposit"),
@@ -6357,11 +6533,8 @@ Schema.Union([
6357
6533
  paymentIds: Schema.Array(PaymentIdSchema),
6358
6534
  userOpHash: Bytes32Schema
6359
6535
  }),
6360
- Schema.Struct({
6361
- kind: Schema.Literal("apply_finalized_evidence"),
6362
- paymentId: PaymentIdSchema,
6363
- evidence: FinalizedMoneyEvidenceSchema
6364
- }),
6536
+ ApplyVerifiedEvidenceCommandSchema,
6537
+ ApplyFinalizedEvidenceCommandSchema,
6365
6538
  Schema.Struct({
6366
6539
  kind: Schema.Literal("transition"),
6367
6540
  paymentId: PaymentIdSchema,
@@ -6503,6 +6676,7 @@ const MoneyExecutionIdSchema = Schema.String.pipe(Schema.refine((value) => /^mon
6503
6676
  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
6677
  const PaymentExecutionIntentSchema = Schema.Struct({
6505
6678
  to: PaymentRef,
6679
+ externalAddressAcknowledged: Schema.optional(Schema.Literal(true)),
6506
6680
  amount: FinancialOpsMoney,
6507
6681
  paymentType: Schema.optional(Schema.Literals([
6508
6682
  "unspecified",
@@ -6519,7 +6693,31 @@ Schema.Struct({
6519
6693
  signerAddress: AddressSchema,
6520
6694
  payment: PaymentExecutionIntentSchema
6521
6695
  });
6696
+ const RecipientObservationSchema = Schema.Struct({
6697
+ recipient_locator_kind: Schema.Literals([
6698
+ "handle",
6699
+ "email",
6700
+ "party",
6701
+ "address"
6702
+ ]),
6703
+ recipient_resolution_status: Schema.Literals([
6704
+ "known_party",
6705
+ "new_email",
6706
+ "external_address"
6707
+ ]),
6708
+ recipient_is_capxul_account: Schema.Boolean,
6709
+ recipient_party_id: Schema.optional(Schema.String),
6710
+ recipient_party_kind: Schema.optional(Schema.Literals([
6711
+ "person",
6712
+ "organization",
6713
+ "unresolved"
6714
+ ])),
6715
+ recipient_handle: Schema.optional(Schema.String),
6716
+ recipient_address: AddressSchema,
6717
+ external_address_acknowledged: Schema.Boolean
6718
+ });
6522
6719
  Schema.Struct({
6720
+ recipientObservation: RecipientObservationSchema,
6523
6721
  executionId: MoneyExecutionIdSchema,
6524
6722
  commandId: PaymentCommandIdSchema,
6525
6723
  paymentId: PaymentIdSchema,
@@ -6536,6 +6734,14 @@ Schema.Struct({
6536
6734
  executionId: MoneyExecutionIdSchema,
6537
6735
  signature: OwnerSignatureSchema
6538
6736
  });
6737
+ Schema.Struct({
6738
+ executionId: MoneyExecutionIdSchema,
6739
+ reason: Schema.Literals([
6740
+ "signer_rejected",
6741
+ "cancelled",
6742
+ "prepared_mismatch"
6743
+ ])
6744
+ });
6539
6745
  Schema.Struct({
6540
6746
  executionId: MoneyExecutionIdSchema,
6541
6747
  commandId: PaymentCommandIdSchema,
@@ -6549,6 +6755,10 @@ Schema.Struct({
6549
6755
  payments: Schema.Array(Payment)
6550
6756
  });
6551
6757
  const PaymentLifecycleExecutionIntentSchema = Schema.Union([
6758
+ Schema.Struct({
6759
+ kind: Schema.Literal("retry"),
6760
+ paymentId: PaymentIdSchema
6761
+ }),
6552
6762
  Schema.Struct({
6553
6763
  kind: Schema.Literal("claim"),
6554
6764
  paymentId: PaymentIdSchema
@@ -6569,6 +6779,7 @@ Schema.Struct({
6569
6779
  });
6570
6780
  const OrganizationPaymentExecutionItemSchema = Schema.Struct({
6571
6781
  to: PaymentRef,
6782
+ externalAddressAcknowledged: Schema.optional(Schema.Literal(true)),
6572
6783
  amount: FinancialOpsMoney,
6573
6784
  paymentType: Schema.optional(Schema.Literals([
6574
6785
  "unspecified",
@@ -6587,6 +6798,8 @@ Schema.Struct({
6587
6798
  lineage: Schema.optional(PaymentCommandLineageSchema)
6588
6799
  });
6589
6800
  const PreparedPaymentCommandExecutionSchema = Schema.Struct({
6801
+ recipientObservations: Schema.Array(RecipientObservationSchema),
6802
+ emitPaymentInitiated: Schema.Boolean,
6590
6803
  executionId: MoneyExecutionIdSchema,
6591
6804
  commandId: PaymentCommandIdSchema,
6592
6805
  paymentIds: Schema.Array(PaymentIdSchema),
@@ -6622,7 +6835,8 @@ const PermissionCommandSchema = Schema.Union([
6622
6835
  operation: Schema.Literal("assign"),
6623
6836
  requestKey: nonEmpty("requestKey"),
6624
6837
  permissionId: PermissionIdSchema,
6625
- accountId: nonEmpty("accountId")
6838
+ accountId: nonEmpty("accountId"),
6839
+ expectedMemberEmail: Schema.optional(nonEmpty("expectedMemberEmail"))
6626
6840
  }),
6627
6841
  Schema.Struct({
6628
6842
  operation: Schema.Literal("revoke"),
@@ -10806,25 +11020,11 @@ function normalizeRefForBackend$1(ref, field) {
10806
11020
  email: nonEmptyRefValue$1(ref.email, "email")
10807
11021
  }
10808
11022
  };
10809
- case "orgHandle": return {
11023
+ case "address": return {
10810
11024
  ok: true,
10811
11025
  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 {
10824
- ok: true,
10825
- value: {
10826
- kind: "payeeId",
10827
- payeeId: nonEmptyRefValue$1(ref.payeeId, "payeeId")
11026
+ kind: "address",
11027
+ address: toAddress(ref.address)
10828
11028
  }
10829
11029
  };
10830
11030
  case "party": return {
@@ -11088,10 +11288,7 @@ function makeAccountMethods(deps) {
11088
11288
  const financialOpsContract = {
11089
11289
  me: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].me),
11090
11290
  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),
11291
+ resolveRecipient: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].resolveRecipient),
11095
11292
  addDestination: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/destinations"].add),
11096
11293
  listDestinations: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/destinations"].list),
11097
11294
  removeDestination: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/destinations"].remove),
@@ -11107,6 +11304,7 @@ const financialOpsContract = {
11107
11304
  //#endregion
11108
11305
  //#region ../../packages/sdk/src/contract/money-execution.ts
11109
11306
  const moneyExecutionContract = {
11307
+ abandonPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].abandonPaymentExecution),
11110
11308
  preparePermissionExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].preparePermissionExecution),
11111
11309
  preparePaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].preparePaymentExecution),
11112
11310
  prepareOrganizationPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/paymentCommandActions"].prepareOrganizationPaymentExecution),
@@ -11117,7 +11315,7 @@ const moneyExecutionContract = {
11117
11315
  };
11118
11316
  //#endregion
11119
11317
  //#region ../../packages/sdk/package.json
11120
- var version$1 = "3.2.0";
11318
+ var version$1 = "4.0.0";
11121
11319
  //#endregion
11122
11320
  //#region ../../packages/sdk/src/telemetry/exception-projection.ts
11123
11321
  /** Fixed fallback for failures that have no safe message. */
@@ -11633,7 +11831,11 @@ function emitPaymentInitiated(telemetry, input) {
11633
11831
  name: "payment_initiated",
11634
11832
  props: {
11635
11833
  kind: input.kind,
11636
- payment_id: input.paymentId
11834
+ payment_id: input.paymentId,
11835
+ payment_lifecycle_id: `payment_lifecycle_${input.paymentId}`,
11836
+ ...input.commandId === void 0 ? {} : { command_id: input.commandId },
11837
+ ...input.executionId === void 0 ? {} : { execution_id: input.executionId },
11838
+ ...input.recipient
11637
11839
  }
11638
11840
  });
11639
11841
  }
@@ -11665,7 +11867,17 @@ async function fingerprintPaymentIntent(intent) {
11665
11867
  function matchesIntent(expected) {
11666
11868
  return async (request) => await fingerprintPaymentIntent(request) === await fingerprintPaymentIntent(expected);
11667
11869
  }
11668
- async function executePrepared(deps, prepare, isExpectedRequest, signal) {
11870
+ async function abandonPrepared$1(deps, executionId, closePayment, reason, result, onPreparedClosed) {
11871
+ if (!closePayment) return result;
11872
+ const abandoned = await runIfActive(void 0, CAPXUL_OPERATIONS.moneyExecution.abandonPaymentExecution, () => deps.convexCall.action(deps.functions.abandonPaymentExecution, { input: {
11873
+ executionId,
11874
+ reason
11875
+ } }));
11876
+ if (!abandoned.ok) return abandoned;
11877
+ if (abandoned.value) onPreparedClosed?.();
11878
+ return result;
11879
+ }
11880
+ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnExit, onPreparedClosed, signal) {
11669
11881
  if (isAborted$2(signal)) return {
11670
11882
  ok: false,
11671
11883
  error: Errors.cancelled({ operation: "payments" })
@@ -11686,32 +11898,45 @@ async function executePrepared(deps, prepare, isExpectedRequest, signal) {
11686
11898
  }
11687
11899
  const prepared = await prepare(signerAddress);
11688
11900
  if (!prepared.ok) return prepared;
11689
- if (!await isExpectedRequest(prepared.value.request)) return {
11901
+ if (!await isExpectedRequest(prepared.value.request)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "prepared_mismatch", {
11690
11902
  ok: false,
11691
11903
  error: Errors.invalidInput("payment", "prepared command mismatch")
11692
- };
11904
+ }, onPreparedClosed);
11693
11905
  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 {
11906
+ 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
11907
  ok: false,
11696
11908
  error: Errors.invalidInput("payment", "prepared authority mismatch")
11697
- };
11698
- if (isAborted$2(signal)) return {
11909
+ }, onPreparedClosed);
11910
+ if (isAborted$2(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
11699
11911
  ok: false,
11700
11912
  error: Errors.cancelled({ operation: "payments" })
11701
- };
11913
+ }, onPreparedClosed);
11914
+ if (prepared.value.emitPaymentInitiated && "items" in prepared.value.request) for (const [index, item] of prepared.value.request.items.entries()) {
11915
+ const paymentId = prepared.value.paymentIds[index];
11916
+ const recipient = prepared.value.recipientObservations[index];
11917
+ if (paymentId === void 0 || recipient === void 0) continue;
11918
+ const paymentType = paymentTypeForDocumentEnvelope(item.document) ?? item.paymentType ?? "unspecified";
11919
+ await emitPaymentInitiated(deps.telemetry, {
11920
+ commandId: prepared.value.commandId,
11921
+ executionId: prepared.value.executionId,
11922
+ paymentId,
11923
+ kind: paymentType === "unspecified" ? "quick_pay" : paymentType,
11924
+ recipient
11925
+ });
11926
+ }
11702
11927
  let signature;
11703
11928
  try {
11704
11929
  signature = await deps.signer.signUserOpHash(prepared.value.digest);
11705
11930
  } catch (cause) {
11706
- return {
11931
+ return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "signer_rejected", {
11707
11932
  ok: false,
11708
11933
  error: signerFailure(deps.signer.source, "signUserOpHash", cause)
11709
- };
11934
+ }, onPreparedClosed);
11710
11935
  }
11711
- if (isAborted$2(signal)) return {
11936
+ if (isAborted$2(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
11712
11937
  ok: false,
11713
11938
  error: Errors.cancelled({ operation: "payments" })
11714
- };
11939
+ }, onPreparedClosed);
11715
11940
  return runIfActive(void 0, CAPXUL_OPERATIONS.payments.submitCommandExecution, () => deps.convexCall.action(deps.functions.submitPaymentCommandExecution, { input: {
11716
11941
  executionId: prepared.value.executionId,
11717
11942
  signature
@@ -11721,13 +11946,13 @@ function executePaymentLifecycle(deps, intent, signal) {
11721
11946
  return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.payments.prepareLifecycleExecution, () => deps.convexCall.action(deps.functions.preparePaymentLifecycleExecution, { input: {
11722
11947
  signerAddress,
11723
11948
  intent
11724
- } })), matchesIntent(intent), signal);
11949
+ } })), matchesIntent(intent), false, void 0, signal);
11725
11950
  }
11726
- function executeOrganizationPayment(deps, input, signal) {
11951
+ function executeOrganizationPayment(deps, input, signal, onPreparedClosed) {
11727
11952
  return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.organizationPayments.prepareExecution, () => deps.convexCall.action(deps.functions.prepareOrganizationPaymentExecution, { input: {
11728
11953
  ...input,
11729
11954
  signerAddress
11730
- } })), matchesIntent(input), signal);
11955
+ } })), matchesIntent(input), true, onPreparedClosed, signal);
11731
11956
  }
11732
11957
  //#endregion
11733
11958
  //#region ../../packages/sdk/src/surface/payment-execution.ts
@@ -11759,7 +11984,16 @@ async function signerCall(source, operation, run) {
11759
11984
  };
11760
11985
  }
11761
11986
  }
11762
- async function executePersonalPayment(deps, payment, signal, requestKey) {
11987
+ async function abandonPrepared(deps, executionId, reason, result, onPreparedClosed) {
11988
+ const abandoned = await runIfActive(void 0, CAPXUL_OPERATIONS.moneyExecution.abandonPaymentExecution, () => deps.convexCall.action(deps.functions.abandonPaymentExecution, { input: {
11989
+ executionId,
11990
+ reason
11991
+ } }));
11992
+ if (!abandoned.ok) return abandoned;
11993
+ if (abandoned.value) onPreparedClosed?.();
11994
+ return result;
11995
+ }
11996
+ async function executePersonalPayment(deps, payment, signal, requestKey, onPreparedClosed) {
11763
11997
  if (isAborted$1(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
11764
11998
  if (deps.signer === void 0) return mismatch("signer", "payments.pay requires a configured CapxulSigner");
11765
11999
  const session = deps.actor.authSession();
@@ -11777,18 +12011,21 @@ async function executePersonalPayment(deps, payment, signal, requestKey) {
11777
12011
  payment
11778
12012
  } }));
11779
12013
  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");
12014
+ 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);
12015
+ if (prepared.value.chainId !== deps.chainId) return abandonPrepared(deps, prepared.value.executionId, "prepared_mismatch", mismatch("chainId", "prepared Payment execution uses another chain"), onPreparedClosed);
12016
+ 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);
12017
+ 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
12018
  if (prepared.value.emitPaymentInitiated) await emitPaymentInitiated(deps.telemetry, {
11785
12019
  kind: prepared.value.purposeKind,
11786
- paymentId: prepared.value.paymentId
12020
+ paymentId: prepared.value.paymentId,
12021
+ commandId: prepared.value.commandId,
12022
+ executionId: prepared.value.executionId,
12023
+ recipient: prepared.value.recipientObservation
11787
12024
  });
11788
- if (isAborted$1(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
12025
+ if (isAborted$1(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
11789
12026
  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);
12027
+ if (!signature.ok) return abandonPrepared(deps, prepared.value.executionId, "signer_rejected", signature, onPreparedClosed);
12028
+ if (isAborted$1(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
11792
12029
  return runIfActive(void 0, CAPXUL_OPERATIONS.payments.submitExecution, () => deps.convexCall.action(deps.functions.submitPaymentExecution, { input: {
11793
12030
  executionId: prepared.value.executionId,
11794
12031
  signature: signature.value
@@ -12016,6 +12253,30 @@ async function waitForPaymentSubmission(submission, signal, operation, onCancel
12016
12253
  });
12017
12254
  });
12018
12255
  }
12256
+ function normalizeActivityDetail(detail) {
12257
+ if (detail === null) return null;
12258
+ if (detail.kind === "payment") {
12259
+ if (detail.evidence === null) return detail;
12260
+ return {
12261
+ ...detail,
12262
+ evidence: {
12263
+ ...detail.evidence,
12264
+ inclusion: "included",
12265
+ verification: "verified",
12266
+ finality: "finalized"
12267
+ }
12268
+ };
12269
+ }
12270
+ return {
12271
+ ...detail,
12272
+ evidence: {
12273
+ ...detail.evidence,
12274
+ inclusion: "included",
12275
+ verification: "verified",
12276
+ canonicalState: "finalized"
12277
+ }
12278
+ };
12279
+ }
12019
12280
  function paymentExecutionIntent(input) {
12020
12281
  if (actorReferenceToBackend(input.actor)?.kind === "org") return {
12021
12282
  ok: false,
@@ -12028,6 +12289,7 @@ function paymentExecutionIntent(input) {
12028
12289
  value: {
12029
12290
  to: to.value,
12030
12291
  amount: input.amount,
12292
+ ...input.externalAddressAcknowledged === void 0 ? {} : { externalAddressAcknowledged: input.externalAddressAcknowledged },
12031
12293
  ...input.paymentType === void 0 ? {} : { paymentType: input.paymentType },
12032
12294
  ...input.document === void 0 ? {} : { document: input.document },
12033
12295
  ...input.timing === void 0 ? {} : { timing: input.timing },
@@ -12065,6 +12327,7 @@ function makeFinancialOpsMethods(deps) {
12065
12327
  let flight = inFlightPersonalPayments.get(sharedKey);
12066
12328
  if (flight === void 0) {
12067
12329
  const controller = new AbortController();
12330
+ const requestState = { resolved: false };
12068
12331
  const submission = executePersonalPayment({
12069
12332
  actor: deps.actor,
12070
12333
  chainId: deps.chainId,
@@ -12072,10 +12335,11 @@ function makeFinancialOpsMethods(deps) {
12072
12335
  functions: executionFns,
12073
12336
  ...deps.signer === void 0 ? {} : { signer: deps.signer },
12074
12337
  ...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
12075
- }, payment.value, controller.signal, requestKey.key);
12338
+ }, payment.value, controller.signal, requestKey.key, () => requestState.resolved = true);
12076
12339
  flight = {
12077
12340
  controller,
12078
12341
  promise: submission,
12342
+ requestState,
12079
12343
  waiters: 0,
12080
12344
  settled: false
12081
12345
  };
@@ -12113,7 +12377,7 @@ function makeFinancialOpsMethods(deps) {
12113
12377
  }
12114
12378
  release(false);
12115
12379
  try {
12116
- await requestKey.finish(submitted.ok);
12380
+ await requestKey.finish(submitted.ok || flight.requestState.resolved);
12117
12381
  } catch {}
12118
12382
  return mapOk(submitted, (value) => normalizePaymentTiming(value.payment));
12119
12383
  };
@@ -12153,61 +12417,34 @@ function makeFinancialOpsMethods(deps) {
12153
12417
  };
12154
12418
  }
12155
12419
  };
12420
+ const retryPayment = async (paymentId, signal) => {
12421
+ const execution = lifecycleDependencies();
12422
+ if (!execution.ok) return execution;
12423
+ try {
12424
+ const submitted = await executePaymentLifecycle(execution.value, {
12425
+ kind: "retry",
12426
+ paymentId
12427
+ }, signal);
12428
+ return submitted.ok ? {
12429
+ ok: true,
12430
+ value: submitted.value.payments.map((payment) => normalizePaymentTiming(payment))
12431
+ } : submitted;
12432
+ } catch (cause) {
12433
+ return {
12434
+ ok: false,
12435
+ error: cause instanceof CapxulError ? cause : Errors.unknown(cause)
12436
+ };
12437
+ }
12438
+ };
12156
12439
  return {
12157
12440
  me: {
12158
12441
  get: (options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.me.get, () => deps.convexCall.query(fns.me, {})),
12159
12442
  depositInstructions: (options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.me.depositInstructions, () => deps.convexCall.query(fns.depositInstructions, {}).pipe(Effect.tap(() => Effect.promise(() => emitDepositInitiated(deps.telemetry)))))
12160
12443
  },
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
12444
  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
- }
12445
+ const recipient = normalizeTargetForBackend(reference, "reference");
12446
+ if (!recipient.ok) return recipient;
12447
+ return mapOk(await runIfActive(options?.signal, CAPXUL_OPERATIONS.recipient.resolve, () => deps.convexCall.query(fns.resolveRecipient, { recipient: recipient.value })), resolvedTargetFromResolution);
12211
12448
  } },
12212
12449
  destinations: {
12213
12450
  add: async (input, options) => {
@@ -12250,6 +12487,7 @@ function makeFinancialOpsMethods(deps) {
12250
12487
  },
12251
12488
  payments: {
12252
12489
  pay,
12490
+ retry: (paymentId, options) => retryPayment(paymentId, options?.signal),
12253
12491
  createCommitment: (input, options) => pay(input, options),
12254
12492
  claim: (paymentId, options) => runLifecycle({
12255
12493
  kind: "claim",
@@ -12292,7 +12530,7 @@ function makeFinancialOpsMethods(deps) {
12292
12530
  ...reference.kind === "payment" ? activityActorField(reference.actor) : {}
12293
12531
  },
12294
12532
  ...actor === void 0 ? {} : { actor }
12295
- }));
12533
+ }).pipe(Effect.map(normalizeActivityDetail)));
12296
12534
  },
12297
12535
  annotate: (input, options) => {
12298
12536
  if (input.actor !== void 0 && input.reference.kind === "payment" && input.reference.actor !== void 0 && !sameActor(input.actor, input.reference.actor)) return Promise.resolve({
@@ -12379,18 +12617,11 @@ function refFromTargetReference(reference, field) {
12379
12617
  email: reference.email
12380
12618
  }
12381
12619
  };
12382
- case "organization": return {
12620
+ case "address": return {
12383
12621
  ok: true,
12384
12622
  value: {
12385
- kind: "orgHandle",
12386
- orgHandle: reference.handle
12387
- }
12388
- };
12389
- case "payee": return {
12390
- ok: true,
12391
- value: {
12392
- kind: "payeeId",
12393
- payeeId: reference.id
12623
+ kind: "address",
12624
+ address: reference.address
12394
12625
  }
12395
12626
  };
12396
12627
  case "party": return {
@@ -12400,10 +12631,6 @@ function refFromTargetReference(reference, field) {
12400
12631
  partyId: reference.partyId
12401
12632
  }
12402
12633
  };
12403
- case "destination": return {
12404
- ok: false,
12405
- error: Errors.notImplemented("targets", "reference.destination")
12406
- };
12407
12634
  default: return {
12408
12635
  ok: false,
12409
12636
  error: Errors.invalidInput(field, "target must be a known TargetReference variant")
@@ -12458,39 +12685,28 @@ function targetReferenceFromBackendRef(ref) {
12458
12685
  kind: "email",
12459
12686
  email: ref.email
12460
12687
  };
12461
- case "orgHandle": return {
12462
- kind: "organization",
12463
- handle: ref.orgHandle
12464
- };
12465
- case "payeeId": return {
12466
- kind: "payee",
12467
- id: ref.payeeId
12688
+ case "address": return {
12689
+ kind: "address",
12690
+ address: ref.address
12468
12691
  };
12469
12692
  case "party": return {
12470
12693
  kind: "party",
12471
12694
  partyId: ref.partyId
12472
12695
  };
12473
- case "capxulUserId": throw Errors.notImplemented("targets", "reference.capxulUserId");
12474
12696
  }
12475
12697
  }
12476
- function resolvedTargetFromResolution(reference, resolution) {
12477
- const kind = resolution.kind === "org" ? "organization" : resolution.kind === "payee" ? "payee" : "person";
12698
+ function resolvedTargetFromResolution(resolution) {
12699
+ const kind = resolution.status === "known_party" ? resolution.partyKind === "org" ? "organization" : "person" : resolution.status === "external_address" ? "external_address" : "unresolved";
12478
12700
  return {
12479
- reference,
12701
+ reference: targetReferenceFromBackendRef(resolution.recipient),
12480
12702
  label: resolution.label,
12703
+ status: resolution.status,
12481
12704
  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",
12705
+ safeAddress: toAddress(resolution.safeAddress),
12706
+ isCapxulAccount: resolution.isCapxulAccount,
12707
+ ...resolution.partyId === void 0 ? {} : { partyId: toPartyId(resolution.partyId) },
12708
+ ...resolution.handle === void 0 ? {} : { handle: resolution.handle },
12709
+ ...resolution.requiresAcknowledgement === void 0 ? {} : { requiresAcknowledgement: resolution.requiresAcknowledgement },
12494
12710
  capabilities: {
12495
12711
  canPay: true,
12496
12712
  canRequest: true,
@@ -12548,10 +12764,6 @@ function destinationFromBackend(destination) {
12548
12764
  };
12549
12765
  }
12550
12766
  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
12767
  return normalizeRefForBackend(ref, field);
12556
12768
  }
12557
12769
  function normalizeRefForBackend(ref, field) {
@@ -12579,25 +12791,11 @@ function normalizeRefForBackend(ref, field) {
12579
12791
  email: nonEmptyRefValue(ref.email, "email")
12580
12792
  }
12581
12793
  };
12582
- case "orgHandle": return {
12583
- ok: true,
12584
- 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 {
12794
+ case "address": return {
12597
12795
  ok: true,
12598
12796
  value: {
12599
- kind: "payeeId",
12600
- payeeId: nonEmptyRefValue(ref.payeeId, "payeeId")
12797
+ kind: "address",
12798
+ address: toAddress(ref.address)
12601
12799
  }
12602
12800
  };
12603
12801
  case "party": return {
@@ -17185,9 +17383,16 @@ const OBSERVED_CONVEX_ACTIONS = /* @__PURE__ */ new Set([
17185
17383
  "org/actions:submitBootstrap",
17186
17384
  "org/actions:resumeBootstrapSubmission",
17187
17385
  "org/actions:confirmBootstrap",
17188
- "org/actions:readTreasury"
17386
+ "org/actions:readTreasury",
17387
+ "moneyExecution/actions:preparePaymentExecution",
17388
+ "moneyExecution/actions:abandonPaymentExecution",
17389
+ "moneyExecution/actions:submitPaymentExecution",
17390
+ "moneyExecution/paymentCommandActions:preparePaymentLifecycleExecution",
17391
+ "moneyExecution/paymentCommandActions:prepareOrganizationPaymentExecution",
17392
+ "moneyExecution/paymentCommandActions:submitPaymentCommandExecution"
17189
17393
  ]);
17190
17394
  const OBSERVED_CONVEX_QUERIES = /* @__PURE__ */ new Set([
17395
+ "financialOps/queries:resolveRecipient",
17191
17396
  "identity/queries:loadByAuthUserId",
17192
17397
  "smartAccount/queries:loadByAuthUserId",
17193
17398
  "org/lifecycle:load"
@@ -17431,12 +17636,13 @@ function ConvexIdentityLayer() {
17431
17636
  function brandProfile(raw) {
17432
17637
  return {
17433
17638
  authUserId: toAuthUserId(raw.authUserId),
17639
+ ...raw.testerKind === void 0 ? {} : { testerKind: toTesterKind(raw.testerKind) },
17434
17640
  email: toEmail(raw.email),
17435
17641
  displayName: raw.displayName,
17436
17642
  country: raw.country === null ? null : toCountryCode(raw.country),
17437
17643
  onboarded: raw.onboarded ?? false,
17438
17644
  withdrawalAddress: raw.withdrawalAddress === null || raw.withdrawalAddress === void 0 ? null : toAddress(raw.withdrawalAddress),
17439
- username: raw.username ?? null,
17645
+ handle: raw.handle === null || raw.handle === void 0 ? null : toHandle(raw.handle),
17440
17646
  imageUrl: raw.imageUrl ?? null,
17441
17647
  kycTier: toKycTier(raw.kycTier),
17442
17648
  createdAt: toEpochMs(raw.createdAt),
@@ -17712,8 +17918,9 @@ var OrgPortTag = class extends Context.Service()("@capxul/sdk/ports/OrgPort") {}
17712
17918
  function brandOrgView(wire, treasury, viewerRole) {
17713
17919
  return {
17714
17920
  id: toOrgId(wire.orgId),
17921
+ ...wire.creationSource === void 0 ? {} : { creationSource: toTesterKind(wire.creationSource) },
17715
17922
  name: wire.name,
17716
- handle: wire.slug,
17923
+ handle: wire.handle,
17717
17924
  safeAddress: toAddress(wire.safeAddress.toLowerCase()),
17718
17925
  role: viewerRole,
17719
17926
  treasury,
@@ -42467,7 +42674,7 @@ function makeSmartAccountMethods(deps) {
42467
42674
  }
42468
42675
  //#endregion
42469
42676
  //#region ../../packages/sdk/src/contract/identity.ts
42470
- const usernameAvailableQuery = makeFunctionReference(CAPXUL_FUNCTIONS["identity/queries"].usernameAvailable);
42677
+ const handleAvailableQuery = makeFunctionReference(CAPXUL_FUNCTIONS["identity/queries"].handleAvailable);
42471
42678
  //#endregion
42472
42679
  //#region ../../packages/sdk/src/surface/identity-deps.ts
42473
42680
  /** The single Context tag the profile atom + `identity.loadCurrent` resolve. */
@@ -42511,19 +42718,19 @@ function makeIdentityMethods(deps) {
42511
42718
  ok: false,
42512
42719
  error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.identity.completeProfile })
42513
42720
  };
42514
- if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" || typeof profile.username !== "string") return {
42721
+ if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" || typeof profile.handle !== "string") return {
42515
42722
  ok: false,
42516
42723
  error: Errors.invalidInput("profile", "invalid profile")
42517
42724
  };
42518
42725
  const displayName = profile.displayName.trim();
42519
- const username = profile.username.trim();
42726
+ const handle = profile.handle.trim();
42520
42727
  if (displayName.length === 0) return {
42521
42728
  ok: false,
42522
42729
  error: Errors.invalidInput("displayName", "must not be empty")
42523
42730
  };
42524
- if (username.length === 0) return {
42731
+ if (handle.length === 0) return {
42525
42732
  ok: false,
42526
- error: Errors.invalidInput("username", "must not be empty")
42733
+ error: Errors.invalidInput("handle", "must not be empty")
42527
42734
  };
42528
42735
  let country;
42529
42736
  try {
@@ -42544,98 +42751,259 @@ function makeIdentityMethods(deps) {
42544
42751
  email: session.email,
42545
42752
  displayName,
42546
42753
  country,
42547
- username
42754
+ handle
42548
42755
  }), options, CAPXUL_OPERATIONS.identity.completeProfile);
42549
42756
  },
42550
- async usernameAvailable(username, options) {
42757
+ async handleAvailable(handle, options) {
42551
42758
  if (options?.signal?.aborted) return {
42552
42759
  ok: false,
42553
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.identity.usernameAvailable })
42760
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.identity.handleAvailable })
42554
42761
  };
42555
42762
  if (convexCall === void 0) return {
42556
42763
  ok: false,
42557
- error: Errors.notImplemented("identity", "usernameAvailable")
42764
+ error: Errors.notImplemented("identity", "handleAvailable")
42558
42765
  };
42559
- return runPortEffect(convexCall.query(usernameAvailableQuery, { username }));
42766
+ return runPortEffect(convexCall.query(handleAvailableQuery, { handle }));
42560
42767
  }
42561
42768
  };
42562
42769
  }
42563
42770
  //#endregion
42564
42771
  //#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")
42772
+ function normalizeHandleInput(input) {
42773
+ if (typeof input !== "string") return {
42774
+ ok: false,
42775
+ error: Errors.invalidInput("handle", "is required")
42776
+ };
42777
+ try {
42778
+ return {
42779
+ ok: true,
42780
+ value: validateHandle(input)
42572
42781
  };
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 {
42782
+ } catch (error) {
42783
+ if (isCapxulError(error)) return {
42577
42784
  ok: false,
42578
- error: Errors.notAuthenticated()
42785
+ error
42579
42786
  };
42580
- const available = await deps.usernameAvailable(username, options);
42581
- if (!available.ok) return available;
42582
- if (!available.value.available) return {
42787
+ return {
42583
42788
  ok: false,
42584
- error: Errors.invalidInput("username", "username is already taken")
42789
+ error: Errors.unknown(error)
42585
42790
  };
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 {
42791
+ }
42792
+ }
42793
+ function normalizeOrganization(input) {
42794
+ if (typeof input !== "object" || input === null) return {
42795
+ ok: false,
42796
+ error: Errors.invalidInput("organization", "is required")
42797
+ };
42798
+ const name = typeof input.name === "string" ? input.name.trim() : "";
42799
+ if (name.length === 0) return {
42800
+ ok: false,
42801
+ error: Errors.invalidInput("name", "is required")
42802
+ };
42803
+ const handle = normalizeHandleInput(input.handle);
42804
+ if (!handle.ok) return handle;
42805
+ if (input.bio !== void 0 && typeof input.bio !== "string") return {
42806
+ ok: false,
42807
+ error: Errors.invalidInput("bio", "must be text")
42808
+ };
42809
+ if (input.size !== void 0 && typeof input.size !== "string") return {
42810
+ ok: false,
42811
+ error: Errors.invalidInput("size", "must be text")
42812
+ };
42813
+ let country;
42814
+ try {
42815
+ country = toCountryCode(input.country);
42816
+ } catch {
42817
+ return {
42594
42818
  ok: false,
42595
- error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
42819
+ error: Errors.invalidInput("country", "must be an ISO country code")
42596
42820
  };
42597
- const ensured = await deps.ensureAccount();
42821
+ }
42822
+ const bio = input.bio?.trim() ?? "";
42823
+ const size = input.size?.trim() ?? "";
42824
+ return {
42825
+ ok: true,
42826
+ value: {
42827
+ name,
42828
+ handle: handle.value,
42829
+ country,
42830
+ ...bio.length === 0 ? {} : { bio },
42831
+ ...size.length === 0 ? {} : { size }
42832
+ }
42833
+ };
42834
+ }
42835
+ function isClaimedIdentityState(state) {
42836
+ return state.phase === "authenticated" && state.account.at === "claimed";
42837
+ }
42838
+ function organizationWrongState(currentState, validStates) {
42839
+ return {
42840
+ ok: false,
42841
+ error: Errors.wrongState({
42842
+ method: CAPXUL_OPERATIONS.onboarding.completeOrganization,
42843
+ currentState,
42844
+ validStates: [...validStates]
42845
+ })
42846
+ };
42847
+ }
42848
+ function requestCancelled(options) {
42849
+ return options?.signal?.aborted === true;
42850
+ }
42851
+ async function reachClaimedAccount(deps, options) {
42852
+ let state = deps.snapshotIdentity();
42853
+ if (state.phase !== "authenticated" || state.account.at === "unknown") {
42854
+ const ensured = await deps.sendIdentity({ _tag: "EnsureAccount" }, options);
42598
42855
  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
- } };
42856
+ state = ensured.value;
42857
+ }
42858
+ if (state.phase !== "authenticated") return organizationWrongState(state.phase, ["authenticated:claimed"]);
42859
+ if (state.account.at !== "claimed") {
42860
+ const event = state.account.at === "failed" ? { _tag: "RetryAccount" } : state.account.at === "counterfactual" ? { _tag: "ClaimAccount" } : { _tag: "EnsureAccount" };
42861
+ const claimed = await deps.sendIdentity(event, options);
42862
+ if (!claimed.ok) return claimed;
42863
+ state = claimed.value;
42864
+ }
42865
+ return isClaimedIdentityState(state) ? {
42866
+ ok: true,
42867
+ value: state
42868
+ } : organizationWrongState(state.phase === "authenticated" ? state.account.at : state.phase, ["claimed"]);
42869
+ }
42870
+ async function createOrResumeOrganization(deps, state, draft, options) {
42871
+ const active = state.account.org;
42872
+ if (active?.at === "ready") return {
42873
+ ok: true,
42874
+ value: { organizationId: active.orgId }
42875
+ };
42876
+ if (active?.at === "failed" && !active.retryable) return {
42877
+ ok: false,
42878
+ error: publicIdentityFailure(active.failure)
42879
+ };
42880
+ if (active?.at === "failed" && active.orgId === null) {
42881
+ const cleared = await deps.sendIdentity({ _tag: "LeaveOrganization" }, options);
42882
+ if (!cleared.ok) return cleared;
42883
+ }
42884
+ const event = active?.at === "failed" && active.orgId !== null ? { _tag: "RetryOrganization" } : {
42885
+ _tag: "CreateOrganization",
42886
+ draft
42887
+ };
42888
+ const created = await deps.sendIdentity(event, options);
42889
+ if (!created.ok) return created;
42890
+ const final = created.value;
42891
+ const organization = isClaimedIdentityState(final) ? final.account.org : null;
42892
+ return organization?.at === "ready" ? {
42893
+ ok: true,
42894
+ value: { organizationId: organization.orgId }
42895
+ } : organizationWrongState(organization?.at ?? "organization-missing", ["ready"]);
42896
+ }
42897
+ function makeOnboardingMethods(deps) {
42898
+ return {
42899
+ async completePerson(input, options) {
42900
+ const isCancelled = () => options?.signal?.aborted === true;
42901
+ if (typeof input !== "object" || input === null || typeof input.displayName !== "string" || typeof input.country !== "string") return {
42902
+ ok: false,
42903
+ error: Errors.invalidInput("profile", "displayName and country are required")
42904
+ };
42905
+ const handle = normalizeHandleInput(input.handle);
42906
+ if (!handle.ok) return handle;
42907
+ const session = await deps.restoreSession(options);
42908
+ if (!session.ok) return session;
42909
+ if (session.value === null) return {
42910
+ ok: false,
42911
+ error: Errors.notAuthenticated()
42912
+ };
42913
+ const available = await deps.handleAvailable(handle.value, options);
42914
+ if (!available.ok) return available;
42915
+ if (!available.value.available) return {
42916
+ ok: false,
42917
+ error: Errors.invalidInput("handle", "handle is already taken")
42918
+ };
42919
+ const completed = await deps.completeProfile({
42920
+ ...input,
42921
+ handle: available.value.normalized
42922
+ }, options);
42923
+ if (!completed.ok) return completed;
42924
+ const refreshed = await deps.refreshIdentity(options);
42925
+ if (!refreshed.ok) return refreshed;
42926
+ if (isCancelled()) return {
42927
+ ok: false,
42928
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
42929
+ };
42930
+ const ensured = await deps.ensureAccount();
42931
+ if (!ensured.ok) return ensured;
42932
+ if (isCancelled()) return {
42933
+ ok: false,
42934
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
42935
+ };
42936
+ const lifecycle = await deps.getLifecycle();
42937
+ if (!lifecycle.ok) return lifecycle;
42938
+ if (isCancelled()) return {
42939
+ ok: false,
42940
+ error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
42941
+ };
42942
+ if (lifecycle.value.status !== "ready") return {
42943
+ ok: false,
42944
+ error: Errors.wrongState({
42945
+ method: CAPXUL_OPERATIONS.onboarding.completePerson,
42946
+ currentState: lifecycle.value.status,
42947
+ validStates: ["ready"]
42948
+ })
42949
+ };
42950
+ const profile = await deps.loadProfile(options);
42951
+ if (!profile.ok) return profile;
42952
+ if (profile.value === null || profile.value.displayName === null || profile.value.handle !== available.value.normalized) return {
42953
+ ok: false,
42954
+ error: Errors.wrongState({
42955
+ method: CAPXUL_OPERATIONS.onboarding.completePerson,
42956
+ currentState: "profile-incomplete",
42957
+ validStates: ["profile-complete"]
42958
+ })
42959
+ };
42960
+ return {
42961
+ ok: true,
42962
+ value: {
42963
+ profile: {
42964
+ ...profile.value,
42965
+ displayName: profile.value.displayName,
42966
+ handle: profile.value.handle
42967
+ },
42968
+ account: lifecycle.value
42969
+ }
42970
+ };
42971
+ },
42972
+ async completeOrganization(input, options) {
42973
+ const operation = CAPXUL_OPERATIONS.onboarding.completeOrganization;
42974
+ const normalized = normalizeOrganization(input);
42975
+ if (!normalized.ok) return normalized;
42976
+ const session = await deps.restoreSession(options);
42977
+ if (!session.ok) return session;
42978
+ if (session.value === null) return {
42979
+ ok: false,
42980
+ error: Errors.notAuthenticated()
42981
+ };
42982
+ const profile = await deps.loadProfile(options);
42983
+ if (!profile.ok) return profile;
42984
+ if (profile.value === null || profile.value.displayName === null || profile.value.handle === null) return {
42985
+ ok: false,
42986
+ error: Errors.wrongState({
42987
+ method: operation,
42988
+ currentState: "profile-incomplete",
42989
+ validStates: ["profile-complete"]
42990
+ })
42991
+ };
42992
+ const refreshed = await deps.refreshIdentity(options);
42993
+ if (!refreshed.ok) return refreshed;
42994
+ if (requestCancelled(options)) return {
42995
+ ok: false,
42996
+ error: Errors.cancelled({ operation })
42997
+ };
42998
+ const claimed = await reachClaimedAccount(deps, options);
42999
+ if (!claimed.ok) return claimed;
43000
+ if (requestCancelled(options)) return {
43001
+ ok: false,
43002
+ error: Errors.cancelled({ operation })
43003
+ };
43004
+ return createOrResumeOrganization(deps, claimed.value, normalized.value, options);
43005
+ }
43006
+ };
42639
43007
  }
42640
43008
  //#endregion
42641
43009
  //#region ../../packages/sdk/src/surface/accounts-deps.ts
@@ -42938,7 +43306,8 @@ function executionDependencies$1(input) {
42938
43306
  chainId: input.chainId,
42939
43307
  convexCall: input.convexCall,
42940
43308
  functions: moneyExecutionContract,
42941
- signer: input.signer
43309
+ signer: input.signer,
43310
+ ...input.telemetry === void 0 ? {} : { telemetry: input.telemetry }
42942
43311
  };
42943
43312
  }
42944
43313
  function makeOrganizationPaymentsMethods(deps, orgId) {
@@ -42970,16 +43339,18 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
42970
43339
  let flight = inFlightOrganizationPayments.get(flightKey);
42971
43340
  if (flight === void 0) {
42972
43341
  const controller = new AbortController();
43342
+ const requestState = { resolved: false };
42973
43343
  const submission = executeOrganizationPayment(execution, {
42974
43344
  orgId,
42975
43345
  permissionId: input.permissionId,
42976
43346
  requestKey: requestKey.key,
42977
43347
  items: input.items,
42978
43348
  ...input.lineage === void 0 ? {} : { lineage: input.lineage }
42979
- }, controller.signal);
43349
+ }, controller.signal, () => requestState.resolved = true);
42980
43350
  flight = {
42981
43351
  controller,
42982
43352
  promise: submission,
43353
+ requestState,
42983
43354
  waiters: 0,
42984
43355
  settled: false
42985
43356
  };
@@ -43017,11 +43388,29 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
43017
43388
  }
43018
43389
  release(false);
43019
43390
  try {
43020
- await requestKey.finish(result.ok);
43391
+ await requestKey.finish(result.ok || flight.requestState.resolved);
43021
43392
  } catch {}
43022
- return mapOk(result, (value) => value.payments.map((payment) => normalizePaymentTiming(payment)));
43393
+ const normalized = mapOk(result, (value) => value.payments.map((payment) => normalizePaymentTiming(payment)));
43394
+ if (!normalized.ok) return normalized;
43395
+ return normalized;
43023
43396
  };
43024
43397
  return {
43398
+ retry: async (paymentId, options) => {
43399
+ const execution = executionDependencies$1(deps);
43400
+ if (execution === null) return {
43401
+ ok: false,
43402
+ error: Errors.notImplemented("organizationPayments", "executionComposition")
43403
+ };
43404
+ const result = await executePaymentLifecycle(execution, {
43405
+ kind: "retry",
43406
+ paymentId
43407
+ }, options?.signal);
43408
+ if (!result.ok) return result;
43409
+ return {
43410
+ ok: true,
43411
+ value: result.value.payments.map((payment) => normalizePaymentTiming(payment))
43412
+ };
43413
+ },
43025
43414
  pay: async (input, options) => {
43026
43415
  const { permissionId, requestKey: providedRequestKey, lineage, ...item } = input;
43027
43416
  const result = await execute({
@@ -43153,6 +43542,7 @@ function makePayrollMethods(deps, orgId) {
43153
43542
  input
43154
43543
  }, input.requestKey);
43155
43544
  let authorized;
43545
+ let preparedClosed = false;
43156
43546
  const submitted = await executePrepared(execution, async (signerAddress) => {
43157
43547
  const prepared = await runIfActive(signal, AUTHORIZE_RUN, () => deps.convexCall.action(payrollContract.authorizeRun, { input: {
43158
43548
  orgId,
@@ -43174,9 +43564,9 @@ function makePayrollMethods(deps, orgId) {
43174
43564
  requestKey: requestKey.key,
43175
43565
  runId: authorized.id,
43176
43566
  items: input.items
43177
- })(request), signal);
43567
+ })(request), true, () => preparedClosed = true, signal);
43178
43568
  try {
43179
- await requestKey.finish(submitted.ok);
43569
+ await requestKey.finish(submitted.ok || preparedClosed);
43180
43570
  } catch {}
43181
43571
  if (!submitted.ok) return submitted;
43182
43572
  return authorized === void 0 ? {
@@ -43797,7 +44187,8 @@ function makeOrgMethods(deps) {
43797
44187
  ...deps.requestKeyScope === void 0 ? {} : { requestKeyScope: deps.requestKeyScope },
43798
44188
  ...deps.actor === void 0 ? {} : { actor: deps.actor },
43799
44189
  ...deps.chainId === void 0 ? {} : { chainId: Number(deps.chainId) },
43800
- ...deps.signer === void 0 ? {} : { signer: deps.signer }
44190
+ ...deps.signer === void 0 ? {} : { signer: deps.signer },
44191
+ ...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
43801
44192
  }, String(orgId)),
43802
44193
  payroll: convexCall === void 0 ? makeUnavailablePayrollMethods() : makePayrollMethods({
43803
44194
  convexCall,
@@ -43824,7 +44215,8 @@ function makeNotImplementedPermissionMethods() {
43824
44215
  function makeNotImplementedOrganizationPaymentsMethods() {
43825
44216
  return {
43826
44217
  pay: organizationPaymentExecutionUnavailable,
43827
- payBatch: organizationPaymentExecutionUnavailable
44218
+ payBatch: organizationPaymentExecutionUnavailable,
44219
+ retry: organizationPaymentExecutionUnavailable
43828
44220
  };
43829
44221
  }
43830
44222
  const orgMeUnavailable = () => Promise.resolve({
@@ -44267,11 +44659,13 @@ function assembleCapxulClient(input) {
44267
44659
  const onboarding = makeOnboardingMethods({
44268
44660
  restoreSession: auth.getSession,
44269
44661
  refreshIdentity: (options) => runCapxulEffect(askIdentity(actor, { _tag: "ReadSession" }, options).pipe(Effect.asVoid), options, CAPXUL_OPERATIONS.identity.readSession, effectRunner.runPromise),
44270
- usernameAvailable: identity.usernameAvailable,
44662
+ handleAvailable: identity.handleAvailable,
44271
44663
  completeProfile: identity.completeProfile,
44272
44664
  loadProfile: identity.loadCurrent,
44273
44665
  ensureAccount: account._internal.ensureReady,
44274
- getLifecycle: account.getLifecycle
44666
+ getLifecycle: account.getLifecycle,
44667
+ snapshotIdentity: actor.snapshot,
44668
+ sendIdentity: (event, options) => runCapxulEffect(askIdentity(actor, event, options), options, CAPXUL_OPERATIONS._internal.identity.send, effectRunner.runPromise)
44275
44669
  });
44276
44670
  const system = makeSystemMethods({ convexCall: input.ports.convexCall });
44277
44671
  const media = makeMediaMethods({ convexCall: input.ports.convexCall });
@@ -44330,7 +44724,7 @@ function assembleCapxulClient(input) {
44330
44724
  }
44331
44725
  },
44332
44726
  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 {
44727
+ if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" || typeof profile.handle !== "string") return {
44334
44728
  ok: false,
44335
44729
  reason: "INVALID_INPUT"
44336
44730
  };
@@ -44348,8 +44742,8 @@ function assembleCapxulClient(input) {
44348
44742
  reason: "INVALID_INPUT"
44349
44743
  };
44350
44744
  }
44351
- const username = profile.username?.trim();
44352
- if (profile.username !== void 0 && username?.length === 0) return {
44745
+ const handle = profile.handle.trim();
44746
+ if (handle.length === 0) return {
44353
44747
  ok: false,
44354
44748
  reason: "INVALID_INPUT"
44355
44749
  };
@@ -44363,7 +44757,7 @@ function assembleCapxulClient(input) {
44363
44757
  email: session.email,
44364
44758
  displayName,
44365
44759
  country,
44366
- ...username === void 0 ? {} : { username }
44760
+ handle
44367
44761
  }), controls, CAPXUL_OPERATIONS.identity.completeProfile, effectRunner.runPromise);
44368
44762
  return result.ok ? { ok: true } : {
44369
44763
  ok: false,
@@ -44382,8 +44776,6 @@ function assembleCapxulClient(input) {
44382
44776
  accounts,
44383
44777
  currentUser,
44384
44778
  me: financialOps.me,
44385
- handles: financialOps.handles,
44386
- payees: financialOps.payees,
44387
44779
  targets: financialOps.targets,
44388
44780
  destinations: financialOps.destinations,
44389
44781
  payments: financialOps.payments,
@@ -44402,6 +44794,20 @@ function assembleCapxulClient(input) {
44402
44794
  accounts: { fund: accounts.fund },
44403
44795
  organizationSetup: { getProofReceipt: (orgId) => runPortEffect(input.ports.convexCall.query(organizationSetupProofReceiptQuery, { orgId })) },
44404
44796
  telemetry: input.ports.telemetry,
44797
+ captureExternalAddressAcknowledged: (address, organizationId) => {
44798
+ const telemetry = input.ports.telemetry;
44799
+ if (telemetry === void 0) return;
44800
+ Effect.runPromise(Effect.suspend(() => telemetry.emit({
44801
+ name: "quick_pay_external_address_acknowledged",
44802
+ props: {
44803
+ recipient_locator_kind: "address",
44804
+ recipient_resolution_status: "external_address",
44805
+ recipient_address: address,
44806
+ external_address_acknowledged: true,
44807
+ ...organizationId === void 0 ? {} : { organization_id: organizationId }
44808
+ }
44809
+ })).pipe(Effect.catchCause(() => Effect.void)));
44810
+ },
44405
44811
  close: stopActor
44406
44812
  }
44407
44813
  }, observation.failureObservation, observation.hostObservationSnapshot);
@@ -45239,7 +45645,7 @@ const moneySchema = z.object({
45239
45645
  value: z.string(),
45240
45646
  decimals: z.number()
45241
45647
  });
45242
- const usernameSchema = z.string().regex(/^[a-z0-9_]{3,30}$/, "3-30 characters: a-z, 0-9, or underscore");
45648
+ const handleSchema$1 = z.string().regex(/^[a-z0-9_]{3,30}$/, "3-30 characters: a-z, 0-9, or underscore");
45243
45649
  const accountTools = [
45244
45650
  {
45245
45651
  name: CAPXUL_OPERATIONS.onboarding.completePerson,
@@ -45247,18 +45653,18 @@ const accountTools = [
45247
45653
  register: (server, scope) => {
45248
45654
  server.registerTool(CAPXUL_OPERATIONS.onboarding.completePerson, {
45249
45655
  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.",
45656
+ 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
45657
  inputSchema: z.object({
45252
45658
  displayName: z.string().trim().min(1),
45253
45659
  country: z.string().trim().min(2),
45254
- username: usernameSchema
45660
+ handle: handleSchema$1
45255
45661
  }),
45256
45662
  outputSchema: z.object({
45257
45663
  profile: z.object({
45258
45664
  email: z.string(),
45259
45665
  displayName: z.string(),
45260
45666
  country: z.string(),
45261
- username: usernameSchema
45667
+ handle: handleSchema$1
45262
45668
  }),
45263
45669
  account: z.object({
45264
45670
  status: z.literal("ready"),
@@ -45368,6 +45774,156 @@ function identityError(failure, operation) {
45368
45774
  }
45369
45775
  }
45370
45776
  //#endregion
45777
+ //#region src/tools/organization.ts
45778
+ const MANAGE$1 = "org:manage";
45779
+ const handleSchema = z.string().trim().toLowerCase().regex(/^[a-z0-9-]{3,32}$/, "3-32 characters: a-z, 0-9, or hyphen");
45780
+ const organizationTools = [{
45781
+ name: CAPXUL_OPERATIONS.onboarding.completeOrganization,
45782
+ scope: MANAGE$1,
45783
+ register: (server, scope) => {
45784
+ server.registerTool(CAPXUL_OPERATIONS.onboarding.completeOrganization, {
45785
+ title: "Complete Organization onboarding",
45786
+ description: "Claim the personal Account, then create or resume one Organization through the canonical onboarding lifecycle. Reuse the same handle after an interrupted call.",
45787
+ inputSchema: z.object({
45788
+ name: z.string().trim().min(1),
45789
+ handle: handleSchema,
45790
+ country: z.string().trim().min(2),
45791
+ bio: z.string().trim().min(1).optional(),
45792
+ size: z.string().trim().min(1).optional()
45793
+ }),
45794
+ outputSchema: z.object({ organizationId: z.string() })
45795
+ }, (input) => withClient(scope, CAPXUL_OPERATIONS.onboarding.completeOrganization, MANAGE$1, async (client) => {
45796
+ const completed = await client.completeOrganization(input);
45797
+ if (!completed.ok) return errorResult(completed.error);
45798
+ return okResult({ ...completed.value });
45799
+ }));
45800
+ }
45801
+ }];
45802
+ //#endregion
45803
+ //#region src/tools/staff.ts
45804
+ const MANAGE = "org:manage";
45805
+ const orgInput = { organizationId: z.string().trim().min(1) };
45806
+ const email = z.string().trim().email();
45807
+ const memberStatus = z.enum([
45808
+ "pending",
45809
+ "pending_safe",
45810
+ "pending_grant",
45811
+ "active",
45812
+ "revoked",
45813
+ "expired"
45814
+ ]);
45815
+ const staffTools = [
45816
+ {
45817
+ name: CAPXUL_OPERATIONS.org.list,
45818
+ scope: MANAGE,
45819
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.list, {
45820
+ title: "List Organizations",
45821
+ description: "List the Organizations that the signed-in Person can access.",
45822
+ inputSchema: z.object({}),
45823
+ outputSchema: z.object({ organizations: z.array(z.object({
45824
+ organizationId: z.string(),
45825
+ name: z.string(),
45826
+ handle: z.string(),
45827
+ role: z.string()
45828
+ })) })
45829
+ }, () => withClient(scope, CAPXUL_OPERATIONS.org.list, MANAGE, async (client) => {
45830
+ const result = await client.listOrganizations();
45831
+ return result.ok ? okResult({ organizations: [...result.value] }) : errorResult(result.error);
45832
+ }))
45833
+ },
45834
+ {
45835
+ name: CAPXUL_OPERATIONS.org.roles,
45836
+ scope: MANAGE,
45837
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.roles, {
45838
+ title: "List Organization roles",
45839
+ description: "List the active role labels that an Organization invitation can use.",
45840
+ inputSchema: z.object(orgInput),
45841
+ outputSchema: z.object({ roles: z.array(z.object({ label: z.string() })) })
45842
+ }, ({ organizationId }) => withClient(scope, CAPXUL_OPERATIONS.org.roles, MANAGE, async (client) => {
45843
+ const result = await client.listOrganizationRoles(organizationId);
45844
+ return result.ok ? okResult({ roles: [...result.value] }) : errorResult(result.error);
45845
+ }))
45846
+ },
45847
+ {
45848
+ name: CAPXUL_OPERATIONS.org.members,
45849
+ scope: MANAGE,
45850
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.members, {
45851
+ title: "List Organization members",
45852
+ description: "List Organization member lifecycle states. Poll after activation until the member is active.",
45853
+ inputSchema: z.object(orgInput),
45854
+ outputSchema: z.object({ members: z.array(z.object({
45855
+ email,
45856
+ name: z.string().nullable(),
45857
+ role: z.string(),
45858
+ status: memberStatus
45859
+ })) })
45860
+ }, ({ organizationId }) => withClient(scope, CAPXUL_OPERATIONS.org.members, MANAGE, async (client) => {
45861
+ const result = await client.listOrganizationMembers(organizationId);
45862
+ return result.ok ? okResult({ members: [...result.value] }) : errorResult(result.error);
45863
+ }))
45864
+ },
45865
+ {
45866
+ name: CAPXUL_OPERATIONS.org.invite,
45867
+ scope: MANAGE,
45868
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.invite, {
45869
+ title: "Invite Organization member",
45870
+ description: "Invite one Person by email into an Organization. Use a role label returned by org.roles.",
45871
+ inputSchema: z.object({
45872
+ ...orgInput,
45873
+ email,
45874
+ role: z.string().trim().min(1)
45875
+ }),
45876
+ outputSchema: z.object({
45877
+ email,
45878
+ role: z.string(),
45879
+ status: memberStatus
45880
+ })
45881
+ }, ({ organizationId, email: invitee, role }) => withClient(scope, CAPXUL_OPERATIONS.org.invite, MANAGE, async (client) => {
45882
+ const result = await client.inviteOrganizationMember(organizationId, {
45883
+ email: invitee,
45884
+ role
45885
+ });
45886
+ return result.ok ? okResult({ ...result.value }) : errorResult(result.error);
45887
+ }))
45888
+ },
45889
+ {
45890
+ name: CAPXUL_OPERATIONS.org.acceptInvitations,
45891
+ scope: MANAGE,
45892
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.acceptInvitations, {
45893
+ title: "Accept Organization invitations",
45894
+ description: "Accept every pending Organization invitation for the signed-in Person's verified email.",
45895
+ inputSchema: z.object({}),
45896
+ outputSchema: z.object({ organizationIds: z.array(z.string()) })
45897
+ }, () => withClient(scope, CAPXUL_OPERATIONS.org.acceptInvitations, MANAGE, async (client) => {
45898
+ const result = await client.acceptOrganizationInvitations();
45899
+ return result.ok ? okResult({ ...result.value }) : errorResult(result.error);
45900
+ }))
45901
+ },
45902
+ {
45903
+ name: CAPXUL_OPERATIONS.org.activateMember,
45904
+ scope: MANAGE,
45905
+ register: (server, scope) => server.registerTool(CAPXUL_OPERATIONS.org.activateMember, {
45906
+ title: "Activate Organization member",
45907
+ description: "Grant the invited role to a pending member's ready Account. The Organization founder signs this operation.",
45908
+ inputSchema: z.object({
45909
+ ...orgInput,
45910
+ email,
45911
+ accountId: z.string().trim().min(1)
45912
+ }),
45913
+ outputSchema: z.object({
45914
+ email,
45915
+ status: z.enum(["active", "submitted"])
45916
+ })
45917
+ }, ({ organizationId, email: invitee, accountId }) => withClient(scope, CAPXUL_OPERATIONS.org.activateMember, MANAGE, async (client) => {
45918
+ const result = await client.activateOrganizationMember(organizationId, {
45919
+ email: invitee,
45920
+ accountId
45921
+ });
45922
+ return result.ok ? okResult({ ...result.value }) : errorResult(result.error);
45923
+ }))
45924
+ }
45925
+ ];
45926
+ //#endregion
45371
45927
  //#region src/tools/system.ts
45372
45928
  const systemTools = [{
45373
45929
  name: CAPXUL_OPERATIONS.system.ping,
@@ -45442,7 +45998,12 @@ const AGENT_SCOPES = [
45442
45998
  "org:manage",
45443
45999
  "media:write"
45444
46000
  ];
45445
- const TOOLS = [...systemTools, ...accountTools];
46001
+ const TOOLS = [
46002
+ ...systemTools,
46003
+ ...accountTools,
46004
+ ...organizationTools,
46005
+ ...staffTools
46006
+ ];
45446
46007
  const TOOL_NAMES = TOOLS.map((tool) => tool.name);
45447
46008
  /**
45448
46009
  * The scope a named tool needs. `null` for a public tool, and `null` for a
@@ -45686,7 +46247,7 @@ function stdioIdentity(env = process.env, options = {}) {
45686
46247
  }
45687
46248
  //#endregion
45688
46249
  //#region package.json
45689
- var version = "3.2.0";
46250
+ var version = "4.0.0";
45690
46251
  //#endregion
45691
46252
  //#region src/deps.ts
45692
46253
  const NO_IDENTITY = async () => void 0;
@@ -45721,6 +46282,22 @@ function buildMcpServer(deps, identity) {
45721
46282
  });
45722
46283
  const scope = makeRequestScope(deps, identity);
45723
46284
  registerAllTools(server, scope);
46285
+ if (deps.posthog !== void 0) instrument(server, deps.posthog, {
46286
+ context: { description: "Explain the user goal that requires this Capxul tool call." },
46287
+ enableConversationId: true,
46288
+ enableExceptionAutocapture: false,
46289
+ identify: async () => {
46290
+ const resolved = await scope.identity();
46291
+ return resolved?.ok === true ? { distinctId: resolved.value.authUserId } : null;
46292
+ },
46293
+ eventProperties: async () => ({
46294
+ capxul_env: deps.posthogEnvironment ?? "unknown",
46295
+ producer: "mcp",
46296
+ $geoip_disable: true
46297
+ }),
46298
+ beforeSend: privacySafeMcpEvent,
46299
+ logger: (message) => console.error(`[capxul-mcp] posthog: ${message}`)
46300
+ });
45724
46301
  const previous = server.server.onclose;
45725
46302
  server.server.onclose = () => {
45726
46303
  scope.close();
@@ -45728,9 +46305,75 @@ function buildMcpServer(deps, identity) {
45728
46305
  };
45729
46306
  return server;
45730
46307
  }
46308
+ const SAFE_MCP_PROPERTIES = /* @__PURE__ */ new Set([
46309
+ "$geoip_disable",
46310
+ "$lib",
46311
+ "$lib_version",
46312
+ "$mcp_client_name",
46313
+ "$mcp_conversation_id",
46314
+ "$mcp_duration_ms",
46315
+ "$mcp_intent",
46316
+ "$mcp_intent_source",
46317
+ "$mcp_is_error",
46318
+ "$mcp_listed_tool_names",
46319
+ "$mcp_protocol_version",
46320
+ "$mcp_server_name",
46321
+ "$mcp_server_version",
46322
+ "$mcp_source",
46323
+ "$mcp_tool_description",
46324
+ "$mcp_tool_name",
46325
+ "$process_person_profile",
46326
+ "$session_id",
46327
+ "capxul_env",
46328
+ "producer"
46329
+ ]);
46330
+ const SAFE_TOOL_INTENTS = {
46331
+ [CAPXUL_OPERATIONS.system.ping]: "Verify MCP transport.",
46332
+ [CAPXUL_OPERATIONS.system.health]: "Verify MCP backend health.",
46333
+ [CAPXUL_OPERATIONS.onboarding.completePerson]: "Complete Person onboarding.",
46334
+ [CAPXUL_OPERATIONS.onboarding.completeOrganization]: "Complete Organization onboarding.",
46335
+ [CAPXUL_OPERATIONS.org.acceptInvitations]: "Accept Organization invitations.",
46336
+ [CAPXUL_OPERATIONS.org.activateMember]: "Activate an Organization member.",
46337
+ [CAPXUL_OPERATIONS.org.invite]: "Invite an Organization member.",
46338
+ [CAPXUL_OPERATIONS.org.list]: "List Organizations.",
46339
+ [CAPXUL_OPERATIONS.org.members]: "List Organization members.",
46340
+ [CAPXUL_OPERATIONS.org.roles]: "List Organization roles.",
46341
+ [CAPXUL_OPERATIONS.me.get]: "Verify authenticated Person identity.",
46342
+ [CAPXUL_OPERATIONS.account.status]: "Verify Account readiness.",
46343
+ [CAPXUL_OPERATIONS.account.balance]: "Verify Account funding."
46344
+ };
46345
+ const SAFE_MCP_TOOL_NAMES = new Set(TOOL_NAMES);
46346
+ 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;
46347
+ 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;
46348
+ function normalizeClientName(value) {
46349
+ if (typeof value !== "string") return "other";
46350
+ const name = value.trim().toLowerCase();
46351
+ if (name.startsWith("codex")) return "codex";
46352
+ if (name.startsWith("claude-code")) return "claude-code";
46353
+ if (name === "capxul-journeys") return name;
46354
+ if (name === "hermetic-client") return name;
46355
+ return "other";
46356
+ }
46357
+ /** Keep MCP analytics useful without sending tool payloads or free-form PII. */
46358
+ const privacySafeMcpEvent = (event) => {
46359
+ const properties = Object.fromEntries(Object.entries(event.properties).filter(([name]) => SAFE_MCP_PROPERTIES.has(name)));
46360
+ const toolName = properties.$mcp_tool_name;
46361
+ if (typeof toolName !== "string" || !SAFE_MCP_TOOL_NAMES.has(toolName)) delete properties.$mcp_tool_name;
46362
+ if (typeof properties.$mcp_intent === "string") properties.$mcp_intent = typeof toolName === "string" ? SAFE_TOOL_INTENTS[toolName] ?? "Use a Capxul tool." : "Use a Capxul tool.";
46363
+ properties.$mcp_client_name = normalizeClientName(properties.$mcp_client_name);
46364
+ if (typeof properties.$mcp_conversation_id !== "string" || !MCP_CONVERSATION_ID.test(properties.$mcp_conversation_id)) delete properties.$mcp_conversation_id;
46365
+ if (typeof properties.$session_id !== "string" || !MCP_SESSION_ID.test(properties.$session_id)) delete properties.$session_id;
46366
+ if (properties.$mcp_protocol_version !== "2025-06-18" && properties.$mcp_protocol_version !== "2026-07-28") delete properties.$mcp_protocol_version;
46367
+ const distinctId = properties.$process_person_profile === false ? `anon_${createHash("sha256").update(event.distinct_id).digest("hex").slice(0, 24)}` : event.distinct_id;
46368
+ return {
46369
+ ...event,
46370
+ distinct_id: distinctId,
46371
+ properties
46372
+ };
46373
+ };
45731
46374
  function createHandler(input) {
45732
46375
  return createMcpHandler(({ authInfo }) => buildMcpServer(input.deps, identityOf(input, authInfo)), {
45733
- legacy: "reject",
46376
+ legacy: "stateless",
45734
46377
  responseMode: "json",
45735
46378
  ...input.onError === void 0 ? {} : { onerror: input.onError }
45736
46379
  });
@@ -45778,7 +46421,8 @@ async function startHttpServer(input) {
45778
46421
  resource,
45779
46422
  identities,
45780
46423
  mcp,
45781
- guards
46424
+ guards,
46425
+ posthog: input.deps.posthog
45782
46426
  }).catch((cause) => {
45783
46427
  if (!res.headersSent) writeJson(res, 500, { error: "internal_error" });
45784
46428
  console.error("[capxul-mcp] request failed:", cause);
@@ -45818,6 +46462,11 @@ async function handle(input) {
45818
46462
  const token = bearerToken(headerValue(req, "authorization"));
45819
46463
  if (decision.identity !== void 0 && token !== void 0) authenticated.auth = toAuthInfo(decision.identity, token);
45820
46464
  await input.mcp(req, res, body);
46465
+ if (input.posthog !== void 0) try {
46466
+ await input.posthog.flush();
46467
+ } catch {
46468
+ console.error("[capxul-mcp] PostHog flush failed");
46469
+ }
45821
46470
  }
45822
46471
  function protectedResourceMetadata(resource) {
45823
46472
  return {
@@ -45989,9 +46638,9 @@ function formatToolCallLine(event) {
45989
46638
  //#endregion
45990
46639
  //#region src/sdk.ts
45991
46640
  /**
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.
46641
+ * One fresh client per request. Live mode derives the counterfactual Account
46642
+ * and fails closed before a signature. Dev mode has its explicit test signer,
46643
+ * so it requires a deployed Account and can exercise signed lifecycle paths.
45995
46644
  *
45996
46645
  * This code passes no `authCache`. The SDK detects one instead. A node process
45997
46646
  * has no `window`, so the SDK builds a fresh `InMemoryAuthCacheAdapter` for
@@ -46011,7 +46660,7 @@ async function createSdkClient(input, createClient = createCapxulClient) {
46011
46660
  bootstrapBaseUrl: config.bootstrapBaseUrl,
46012
46661
  origin: config.origin,
46013
46662
  authBaseUrl: config.authBaseUrl,
46014
- requirement: "counterfactual",
46663
+ requirement: signer === void 0 ? "counterfactual" : "deployed",
46015
46664
  runtime: "node",
46016
46665
  ...identity === void 0 ? {} : { authClient: identity.authClient },
46017
46666
  ...signer === void 0 ? {} : { signer }
@@ -46059,7 +46708,7 @@ async function createSdkClient(input, createClient = createCapxulClient) {
46059
46708
  email: String(result.value.profile.email),
46060
46709
  displayName: result.value.profile.displayName,
46061
46710
  country: String(result.value.profile.country),
46062
- username: result.value.profile.username
46711
+ handle: result.value.profile.handle
46063
46712
  },
46064
46713
  account: {
46065
46714
  status: "ready",
@@ -46069,6 +46718,120 @@ async function createSdkClient(input, createClient = createCapxulClient) {
46069
46718
  }
46070
46719
  };
46071
46720
  },
46721
+ completeOrganization: (organization) => client.onboarding.completeOrganization(organization),
46722
+ listOrganizations: async () => {
46723
+ const result = await client.orgs();
46724
+ if (!result.ok) return result;
46725
+ return {
46726
+ ok: true,
46727
+ value: result.value.map((organization) => ({
46728
+ organizationId: String(organization.id),
46729
+ name: organization.name,
46730
+ handle: organization.handle,
46731
+ role: organization.role
46732
+ }))
46733
+ };
46734
+ },
46735
+ listOrganizationRoles: async (orgId) => {
46736
+ const result = await client.org(orgId).roles();
46737
+ if (!result.ok) return result;
46738
+ return {
46739
+ ok: true,
46740
+ value: result.value.map((role) => ({ label: role.label }))
46741
+ };
46742
+ },
46743
+ listOrganizationMembers: async (orgId) => {
46744
+ const result = await client.org(orgId).members();
46745
+ if (!result.ok) return result;
46746
+ return {
46747
+ ok: true,
46748
+ value: result.value.map((member) => ({
46749
+ email: String(member.email),
46750
+ name: member.name,
46751
+ role: member.role,
46752
+ status: member.status
46753
+ }))
46754
+ };
46755
+ },
46756
+ inviteOrganizationMember: async (orgId, invitation) => {
46757
+ const result = await client.org(orgId).invite(invitation);
46758
+ if (!result.ok) return result;
46759
+ return {
46760
+ ok: true,
46761
+ value: {
46762
+ email: String(result.value.email),
46763
+ role: result.value.role,
46764
+ status: result.value.status
46765
+ }
46766
+ };
46767
+ },
46768
+ acceptOrganizationInvitations: async () => {
46769
+ const result = await client.orgs.detectAndAcceptPendingInvitations();
46770
+ if (!result.ok) return result;
46771
+ return {
46772
+ ok: true,
46773
+ value: { organizationIds: result.value.matched.map(String) }
46774
+ };
46775
+ },
46776
+ activateOrganizationMember: async (orgId, activation) => {
46777
+ const memberEmail = activation.email.trim().toLowerCase();
46778
+ const scoped = client.org(orgId);
46779
+ const members = await scoped.members();
46780
+ if (!members.ok) return members;
46781
+ const matches = members.value.filter((member) => String(member.email) === memberEmail);
46782
+ const member = matches.length === 1 ? matches[0] : void 0;
46783
+ if (member === void 0) return {
46784
+ ok: false,
46785
+ error: Errors.invalidInput("email", "member was not found")
46786
+ };
46787
+ if (member.status === "active") return {
46788
+ ok: true,
46789
+ value: {
46790
+ email: memberEmail,
46791
+ status: "active"
46792
+ }
46793
+ };
46794
+ if (member.status !== "pending_grant" || member.roleKey === null) return {
46795
+ ok: false,
46796
+ error: Errors.wrongState({
46797
+ method: CAPXUL_OPERATIONS.org.activateMember,
46798
+ currentState: member.status,
46799
+ validStates: ["pending_grant", "active"]
46800
+ })
46801
+ };
46802
+ const permissions = await scoped.permissions.list();
46803
+ if (!permissions.ok) return permissions;
46804
+ const matchingPermissions = permissions.value.permissions.filter((permission) => permission.type === "managePeople" && permission.state === "active" && String(permission.roleKey).toLowerCase() === String(member.roleKey).toLowerCase());
46805
+ const permission = matchingPermissions.length === 1 ? matchingPermissions[0] : void 0;
46806
+ if (permission === void 0) return {
46807
+ ok: false,
46808
+ error: Errors.wrongState({
46809
+ method: CAPXUL_OPERATIONS.org.activateMember,
46810
+ currentState: "matching-permission-missing",
46811
+ validStates: ["one-active-role-permission"]
46812
+ })
46813
+ };
46814
+ const requestKey = `mcp-staff-${createHash("sha256").update(JSON.stringify({
46815
+ orgId,
46816
+ email: memberEmail,
46817
+ accountId: activation.accountId,
46818
+ permissionId: permission.permissionId
46819
+ })).digest("hex")}`;
46820
+ const assigned = await scoped.permissions.assign({
46821
+ requestKey,
46822
+ permissionId: String(permission.permissionId),
46823
+ accountId: activation.accountId,
46824
+ expectedMemberEmail: memberEmail
46825
+ });
46826
+ if (!assigned.ok) return assigned;
46827
+ return {
46828
+ ok: true,
46829
+ value: {
46830
+ email: memberEmail,
46831
+ status: "submitted"
46832
+ }
46833
+ };
46834
+ },
46072
46835
  getLifecycle: async () => {
46073
46836
  const result = await client.account.getLifecycle();
46074
46837
  if (!result.ok) return result;
@@ -46143,6 +46906,8 @@ if (!modeConfig.ok) {
46143
46906
  }
46144
46907
  const mode = modeConfig.value;
46145
46908
  const port = cli.port;
46909
+ const analyticsConfig = readMcpAnalyticsEnvConfig();
46910
+ const posthog = analyticsConfig === void 0 ? void 0 : new PostHog(analyticsConfig.projectToken, { host: analyticsConfig.host });
46146
46911
  const deps = {
46147
46912
  createSdkClient: (identity) => createSdkClient({
46148
46913
  config: readSdkEnvConfig(),
@@ -46151,6 +46916,10 @@ const deps = {
46151
46916
  }),
46152
46917
  onToolCall: (event) => {
46153
46918
  console.error(formatToolCallLine(event));
46919
+ },
46920
+ ...posthog === void 0 ? {} : {
46921
+ posthog,
46922
+ posthogEnvironment: analyticsConfig?.environment ?? "unknown"
46154
46923
  }
46155
46924
  };
46156
46925
  if (cli.stdio) {
@@ -46164,7 +46933,7 @@ if (cli.stdio) {
46164
46933
  bearer: identity === void 0 ? "none" : "environment"
46165
46934
  }));
46166
46935
  const shutdownStdio = () => {
46167
- handle.close().finally(() => process.exit(0));
46936
+ handle.close().catch(() => void 0).then(() => posthog?.shutdown()).catch(() => void 0).finally(() => process.exit(0));
46168
46937
  };
46169
46938
  process.on("SIGINT", shutdownStdio);
46170
46939
  process.on("SIGTERM", shutdownStdio);
@@ -46183,7 +46952,7 @@ if (cli.stdio) {
46183
46952
  bearer: "oauth"
46184
46953
  }));
46185
46954
  const shutdown = () => {
46186
- running.close().finally(() => process.exit(0));
46955
+ running.close().catch(() => void 0).then(() => posthog?.shutdown()).catch(() => void 0).finally(() => process.exit(0));
46187
46956
  };
46188
46957
  process.on("SIGINT", shutdown);
46189
46958
  process.on("SIGTERM", shutdown);