@capxul/sdk 4.20.0-beta.34 → 4.20.0-beta.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { Cause, Clock, Context, Data, Deferred, Effect, Exit, Fiber, Layer, Option, Predicate, Queue, Ref, Result, Schema, SchemaAST, SchemaGetter, SchemaIssue, SchemaParser } from "effect";
2
2
  import { makeFunctionReference } from "convex/server";
3
- import { bytesToHex, concat, decodeErrorResult, encodeAbiParameters, encodeFunctionData, encodePacked, formatUnits, getContractAddress, hashTypedData, isAddress, isHex, keccak256, pad, padHex, parseAbiParameters, recoverAddress, recoverTypedDataAddress, toBytes, toFunctionSignature, toHex } from "viem";
3
+ import { bytesToHex, concat, decodeErrorResult, encodeAbiParameters, encodeFunctionData, encodePacked, formatUnits, getContractAddress, hashTypedData, isAddress, isHex, keccak256, pad, padHex, parseAbiParameters, recoverAddress, recoverTypedDataAddress, sha256, toBytes, toFunctionSignature, toHex } from "viem";
4
4
  import { getUserOperationHash } from "viem/account-abstraction";
5
5
  //#region src/access/actor-references.ts
6
6
  function actorReferenceToBackend(actor) {
@@ -173,6 +173,17 @@ const Errors = {
173
173
  ...opts?.chain === void 0 ? {} : { chain: opts.chain }
174
174
  });
175
175
  },
176
+ /**
177
+ * The provider answered, but its answer cannot be used: `field` names the
178
+ * part that is missing or malformed and `reason` says what is wrong with it.
179
+ * Distinct from `PROVIDER_ERROR`, where the call itself failed or was refused.
180
+ */
181
+ providerResponseInvalid: (provider, operation, field, reason) => new CapxulError("PROVIDER_RESPONSE_INVALID", `${provider} ${operation} answered with an unusable ${field}: ${reason}`, { details: {
182
+ provider,
183
+ operation,
184
+ field,
185
+ reason
186
+ } }),
176
187
  capabilityUnavailable: (provider, operation) => new CapxulError("CAPABILITY_UNAVAILABLE", "Provider capability is unavailable", { details: {
177
188
  provider,
178
189
  operation
@@ -1945,6 +1956,7 @@ const CAPXUL_ERROR_CODES = [
1945
1956
  "ACCOUNT_NOT_FOUND",
1946
1957
  "ACCOUNT_CLAIMED_BY_OTHER_SIGNER",
1947
1958
  "PROVIDER_ERROR",
1959
+ "PROVIDER_RESPONSE_INVALID",
1948
1960
  "CAPABILITY_UNAVAILABLE",
1949
1961
  "INVALID_INPUT",
1950
1962
  "ENV_MISSING",
@@ -1966,6 +1978,15 @@ const CAPXUL_ERROR_CODES = [
1966
1978
  "WORK_DIED",
1967
1979
  "ACTOR_STOPPED"
1968
1980
  ];
1981
+ /** The existing Organization authority refusal vocabulary. */
1982
+ const ROLE_PERMISSION_DENIED_REASONS = [
1983
+ "over_cap",
1984
+ "daily_cap",
1985
+ "not_member",
1986
+ "disallowed_recipient",
1987
+ "condition_violation",
1988
+ "budget_exhausted"
1989
+ ];
1969
1990
  /**
1970
1991
  * The error codes that represent an expected product outcome rather than a
1971
1992
  * defect. The SDK and backend observation boundaries both classify failures
@@ -4307,7 +4328,7 @@ function isQuantityHex(value) {
4307
4328
  function isBytes32(value) {
4308
4329
  return typeof value === "string" && BYTES32_HEX.test(value);
4309
4330
  }
4310
- function refused(field, shape, value) {
4331
+ function refused$1(field, shape, value) {
4311
4332
  throw Errors.invalidInput(field, invalidValueReason(`must be ${shape}`, value));
4312
4333
  }
4313
4334
  /** Rebuilding the `0x` prefix keeps the result a `Hex`; lowercasing never changes the bytes. */
@@ -4316,19 +4337,19 @@ function lowered(value) {
4316
4337
  }
4317
4338
  /** Hex data exactly as given: case kept, for text another party compares or hashes as is. */
4318
4339
  function toExactHex(value, field = "value") {
4319
- return isHex$1(value) ? value : refused(field, "0x-prefixed hex", value);
4340
+ return isHex$1(value) ? value : refused$1(field, "0x-prefixed hex", value);
4320
4341
  }
4321
4342
  /** Hex data, lowercased. */
4322
4343
  function toLowerHex(value, field = "value") {
4323
- return isHex$1(value) ? lowered(value) : refused(field, "0x-prefixed hex", value);
4344
+ return isHex$1(value) ? lowered(value) : refused$1(field, "0x-prefixed hex", value);
4324
4345
  }
4325
4346
  /** A bytes32 value, lowercased. */
4326
4347
  function toLowerBytes32(value, field = "value") {
4327
- return isBytes32(value) ? lowered(value) : refused(field, "a 0x-prefixed bytes32 value", value);
4348
+ return isBytes32(value) ? lowered(value) : refused$1(field, "a 0x-prefixed bytes32 value", value);
4328
4349
  }
4329
4350
  /** An address, lowercased: the form stored rows and digests compare. */
4330
4351
  function toLowerAddress(value, field = "address") {
4331
- return isAddress$1(value) ? lowered(value) : refused(field, "an EVM address", value);
4352
+ return isAddress$1(value) ? lowered(value) : refused$1(field, "an EVM address", value);
4332
4353
  }
4333
4354
  //#endregion
4334
4355
  //#region ../protocol/src/evm/schema.ts
@@ -4881,16 +4902,19 @@ const PaymentCommandSchema = Schema.Union([
4881
4902
  PaymentBirthCommandSchema,
4882
4903
  Schema.Struct({
4883
4904
  kind: Schema.Literal("claim_commitment"),
4905
+ requestKey: Schema.optional(nonEmpty("requestKey")),
4884
4906
  actor: AccountActorRefSchema,
4885
4907
  paymentId: PaymentIdSchema
4886
4908
  }),
4887
4909
  Schema.Struct({
4888
4910
  kind: Schema.Literal("cancel_commitment"),
4911
+ requestKey: Schema.optional(nonEmpty("requestKey")),
4889
4912
  actor: ActorRefSchema,
4890
4913
  paymentId: PaymentIdSchema
4891
4914
  }),
4892
4915
  Schema.Struct({
4893
4916
  kind: Schema.Literal("redirect_commitment"),
4917
+ requestKey: Schema.optional(nonEmpty("requestKey")),
4894
4918
  actor: ActorRefSchema,
4895
4919
  paymentId: PaymentIdSchema,
4896
4920
  recipient: ActorOrDestinationRefSchema
@@ -4915,8 +4939,10 @@ const PreparedMoneyItemSchema = Schema.Union([
4915
4939
  tokenAddress: AddressSchema$1,
4916
4940
  rawAmount: WeiAmountSchema$1,
4917
4941
  kind: Uint16Schema,
4918
- documentHash: NonzeroDocumentHashSchema
4919
- }),
4942
+ documentHash: NonzeroDocumentHashSchema,
4943
+ jobNonce: Schema.optional(Bytes32Schema),
4944
+ executor: Schema.optional(AddressSchema$1)
4945
+ }).pipe(Schema.refine((item) => item.jobNonce === void 0 === (item.executor === void 0), { message: "Prepared V3 identity requires both jobNonce and executor" })),
4920
4946
  Schema.Struct({
4921
4947
  operation: Schema.Literal("create_commitment"),
4922
4948
  paymentId: PaymentIdSchema,
@@ -5018,6 +5044,12 @@ const PersonalUnsignedUserOperationSchema = Schema.Struct({
5018
5044
  entryPoint: Schema.optional(Schema.Never),
5019
5045
  safe4337ModuleAddress: Schema.optional(Schema.Never)
5020
5046
  });
5047
+ const SubmittedPaymentExecutionSchema = Schema.Struct({
5048
+ executionId: MoneyExecutionIdSchema,
5049
+ commandId: PaymentCommandIdSchema,
5050
+ userOpHash: Bytes32Schema,
5051
+ payment: Payment
5052
+ });
5021
5053
  const PreparedPaymentExecutionSchema = Schema.Struct({
5022
5054
  actorAccountId: AccountIdSchema$1,
5023
5055
  item: PreparedMoneyItemSchema,
@@ -5035,7 +5067,8 @@ const PreparedPaymentExecutionSchema = Schema.Struct({
5035
5067
  chainId: BaseSepoliaChainIdSchema,
5036
5068
  signerAddress: AddressSchema$1,
5037
5069
  userOpSenderSafe: SafeAddressSchema,
5038
- digest: Bytes32Schema
5070
+ digest: Bytes32Schema,
5071
+ settled: Schema.optional(SubmittedPaymentExecutionSchema)
5039
5072
  });
5040
5073
  const SubmitPaymentExecutionInputSchema = Schema.Struct({
5041
5074
  executionId: MoneyExecutionIdSchema,
@@ -5049,12 +5082,6 @@ const AbandonPaymentExecutionInputSchema = Schema.Struct({
5049
5082
  "prepared_mismatch"
5050
5083
  ])
5051
5084
  });
5052
- const SubmittedPaymentExecutionSchema = Schema.Struct({
5053
- executionId: MoneyExecutionIdSchema,
5054
- commandId: PaymentCommandIdSchema,
5055
- userOpHash: Bytes32Schema,
5056
- payment: Payment
5057
- });
5058
5085
  const SubmittedPaymentCommandExecutionSchema = Schema.Struct({
5059
5086
  executionId: MoneyExecutionIdSchema,
5060
5087
  commandId: PaymentCommandIdSchema,
@@ -5069,14 +5096,17 @@ const PaymentLifecycleExecutionIntentSchema = Schema.Union([
5069
5096
  }),
5070
5097
  Schema.Struct({
5071
5098
  kind: Schema.Literal("claim"),
5072
- paymentId: PaymentIdSchema
5099
+ paymentId: PaymentIdSchema,
5100
+ requestKey: Schema.optional(nonEmpty("requestKey"))
5073
5101
  }),
5074
5102
  Schema.Struct({
5075
5103
  kind: Schema.Literal("cancel"),
5076
- paymentId: PaymentIdSchema
5104
+ paymentId: PaymentIdSchema,
5105
+ requestKey: Schema.optional(nonEmpty("requestKey"))
5077
5106
  }),
5078
5107
  Schema.Struct({
5079
5108
  kind: Schema.Literal("redirect"),
5109
+ requestKey: Schema.optional(nonEmpty("requestKey")),
5080
5110
  paymentId: PaymentIdSchema,
5081
5111
  recipient: RedirectPaymentRef
5082
5112
  })
@@ -5135,10 +5165,12 @@ const RequestPaymentConfirmationFields = {
5135
5165
  const RequestPaymentTermsSchema = Schema.Struct(RequestPaymentConfirmationFields);
5136
5166
  const RequestPaymentConfirmationSchema = Schema.Union([Schema.Struct({
5137
5167
  ...RequestPaymentConfirmationFields,
5168
+ requestKey: Schema.optional(nonEmpty("requestKey")),
5138
5169
  payer: Schema.Struct({ kind: Schema.Literal("account") }),
5139
5170
  permissionId: Schema.optional(Schema.Never)
5140
5171
  }), Schema.Struct({
5141
5172
  ...RequestPaymentConfirmationFields,
5173
+ requestKey: Schema.optional(nonEmpty("requestKey")),
5142
5174
  payer: OrganizationActorRefSchema,
5143
5175
  permissionId: PermissionIdSchema
5144
5176
  })]);
@@ -5198,13 +5230,14 @@ const PreparedPaymentCommandExecutionSchema = Schema.Struct({
5198
5230
  commitmentId: Uint256StringSchema,
5199
5231
  documentHash: NonzeroDocumentHashSchema
5200
5232
  })),
5201
- documentBundles: Schema.optional(Schema.Array(PaymentDocumentBundleV3Schema))
5233
+ documentBundles: Schema.optional(Schema.Array(PaymentDocumentBundleV3Schema)),
5234
+ settled: Schema.optional(SubmittedPaymentCommandExecutionSchema)
5202
5235
  }).check(Schema.makeFilter((execution) => {
5203
5236
  if (!("kind" in execution.request) || execution.request.kind !== "payment_request") return true;
5204
5237
  const source = execution.sourceCommand;
5205
5238
  const prepared = execution.preparedCommand;
5206
5239
  if (source?.kind !== "birth" || prepared === void 0 || source.lineage?.kind !== "payment_request") return false;
5207
- if (source.lineage.requestId !== execution.request.confirmation.requestId || source.requestKey !== execution.request.requestKey || source.requestKey !== execution.request.confirmation.requestId || execution.userOperation === void 0) return false;
5240
+ if (source.lineage.requestId !== execution.request.confirmation.requestId || source.requestKey !== execution.request.requestKey || source.requestKey !== (execution.request.confirmation.requestKey ?? execution.request.confirmation.requestId) || execution.userOperation === void 0) return false;
5208
5241
  if ([
5209
5242
  source.items.length,
5210
5243
  execution.request.items.length,
@@ -5217,7 +5250,7 @@ const PreparedPaymentCommandExecutionSchema = Schema.Struct({
5217
5250
  prepared.instructionDocuments?.length
5218
5251
  ].some((length) => length !== 1)) return false;
5219
5252
  const item = prepared.items[0];
5220
- return "recipientSafe" in item && item.operation === source.items[0].operation && item.operation === execution.request.items[0].operation && item.paymentId === execution.paymentIds[0] && item.paymentId === execution.sourcePaymentIds?.[0] && item.recipientSafe === execution.sourceRecipientSafes?.[0];
5253
+ return "recipientSafe" in item && item.operation === source.items[0].operation && item.operation === execution.request.items[0].operation && [item.paymentId, execution.sourcePaymentIds?.[0]].every((id) => id === execution.paymentIds[0]) && item.recipientSafe === execution.sourceRecipientSafes?.[0];
5221
5254
  }));
5222
5255
  //#endregion
5223
5256
  //#region ../protocol/src/accounts/approval-schema.ts
@@ -5285,6 +5318,7 @@ const ApprovalSummarySchema = Schema.Struct({
5285
5318
  /** The exact operation the signature covers: the digest is the one thing the key signs. */
5286
5319
  const ApprovalOperationSchema = Schema.Struct({
5287
5320
  executionId: MoneyExecutionIdSchema,
5321
+ commandId: Schema.optional(nonEmpty("commandId")),
5288
5322
  digest: Bytes32Schema,
5289
5323
  userOperation: PersonalUnsignedUserOperationSchema,
5290
5324
  paymentIds: Schema.Array(PaymentIdSchema)
@@ -5477,6 +5511,21 @@ const approvals = {
5477
5511
  ...APPROVAL
5478
5512
  ]
5479
5513
  }),
5514
+ /** Read the signed operation's progress. Consumption alone does not prove completion. */
5515
+ observe: Operation.query("accounts.approvals.observe", {
5516
+ input: Schema.Struct({ approvalId: ApprovalIdSchema }),
5517
+ output: Schema.Struct({
5518
+ approval: ApprovalSchema,
5519
+ completed: Schema.Boolean
5520
+ }),
5521
+ errors: [
5522
+ ...CALL$10,
5523
+ ...DEFECTS,
5524
+ ...APPROVAL,
5525
+ "SUPERSEDED",
5526
+ "TRANSACTION_FAILED"
5527
+ ]
5528
+ }),
5480
5529
  /** The person opened the approval page: stamp the first review of a pending approval. */
5481
5530
  review: Operation.mutation("accounts.approvals.review", {
5482
5531
  input: Schema.Struct({ approvalId: ApprovalIdSchema }),
@@ -5683,6 +5732,8 @@ const errors = [
5683
5732
  ...DEFECTS
5684
5733
  ];
5685
5734
  const writeErrors = [...errors, "WRONG_STATE"];
5735
+ /** Bank-details writes also read Bridge's answer back, which can be unusable. */
5736
+ const bridgeWriteErrors = [...writeErrors, "PROVIDER_RESPONSE_INVALID"];
5686
5737
  const bankDetails = {
5687
5738
  list: Operation.query("banking.bankDetails.list", {
5688
5739
  input: Schema.Struct({ actor: actor$3 }),
@@ -5697,7 +5748,7 @@ const bankDetails = {
5697
5748
  open: Operation.action("banking.bankDetails.open", {
5698
5749
  input: Schema.Struct(target),
5699
5750
  output: BankDetailsSchema,
5700
- errors: writeErrors
5751
+ errors: bridgeWriteErrors
5701
5752
  }),
5702
5753
  settle: Operation.action("banking.bankDetails.settle", {
5703
5754
  input: Schema.Struct({
@@ -5705,17 +5756,17 @@ const bankDetails = {
5705
5756
  token: SettlementTokenSchema
5706
5757
  }),
5707
5758
  output: BankDetailsSchema,
5708
- errors: writeErrors
5759
+ errors: bridgeWriteErrors
5709
5760
  }),
5710
5761
  deactivate: Operation.action("banking.bankDetails.deactivate", {
5711
5762
  input: Schema.Struct(target),
5712
5763
  output: BankDetailsSchema,
5713
- errors: writeErrors
5764
+ errors: bridgeWriteErrors
5714
5765
  }),
5715
5766
  reactivate: Operation.action("banking.bankDetails.reactivate", {
5716
5767
  input: Schema.Struct(target),
5717
5768
  output: BankDetailsSchema,
5718
- errors: writeErrors
5769
+ errors: bridgeWriteErrors
5719
5770
  })
5720
5771
  };
5721
5772
  const deposits = {
@@ -6819,6 +6870,12 @@ function failureFingerprint(code, mode, operation) {
6819
6870
  //#endregion
6820
6871
  //#region ../protocol/src/errors/schema.ts
6821
6872
  const FailureModeSchema$1 = Schema.Literals(FAILURE_MODES$1);
6873
+ Schema.Struct({
6874
+ reason: Schema.Literals(ROLE_PERMISSION_DENIED_REASONS),
6875
+ operation: Schema.optionalKey(Schema.String),
6876
+ remaining: Schema.optionalKey(AssetAmountSchema),
6877
+ required: Schema.optionalKey(AssetAmountSchema)
6878
+ });
6822
6879
  const ChainUpstreamSchema$1 = Schema.Literals(CHAIN_UPSTREAMS);
6823
6880
  const ChainCauseSchema = Schema.Struct({
6824
6881
  mode: FailureModeSchema$1,
@@ -9440,6 +9497,7 @@ const inboxes = {
9440
9497
  input: Schema.Struct({
9441
9498
  actor,
9442
9499
  paymentRequestId: Schema.String,
9500
+ requestKey: Schema.optionalKey(nonEmpty("requestKey")),
9443
9501
  timing: Schema.optionalKey(PaymentTiming),
9444
9502
  permissionId: Schema.optionalKey(Schema.String)
9445
9503
  }),
@@ -9816,7 +9874,8 @@ const PEOPLE_OPERATIONS = {
9816
9874
  expire: "accounts.approvals.expire",
9817
9875
  recordApproval: "accounts.approvals.recordApproval",
9818
9876
  recordExpiry: "accounts.approvals.recordExpiry",
9819
- sendApproved: "accounts.approvals.sendApproved"
9877
+ sendApproved: "accounts.approvals.sendApproved",
9878
+ rescheduleApproved: "accounts.approvals.rescheduleApproved"
9820
9879
  },
9821
9880
  balances: { readBinding: "accounts.balances.readBinding" },
9822
9881
  claims: {
@@ -13703,7 +13762,7 @@ function mapAccountLifecycle(input) {
13703
13762
  }
13704
13763
  //#endregion
13705
13764
  //#region package.json
13706
- var version = "4.20.0-beta.34";
13765
+ var version = "4.20.0-beta.36";
13707
13766
  //#endregion
13708
13767
  //#region src/observability/telemetry/exception-projection.ts
13709
13768
  /** Fixed fallback for failures that have no safe message. */
@@ -14476,6 +14535,127 @@ function mapOk(result, f) {
14476
14535
  }
14477
14536
  }
14478
14537
  //#endregion
14538
+ //#region ../protocol/src/evm/test-assets.ts
14539
+ const SYNTHETIC_TEST_ASSET_SOURCE = "synthetic-test-liquidity";
14540
+ /**
14541
+ * Owned test assets, with metadata read from each creation receipt and contract.
14542
+ * Settlement admission lives in assets.ts. The fixed test exchange uses the
14543
+ * original five assets; bank EURC has its own deployment.
14544
+ *
14545
+ * `symbol` is the display string the owned contract returns. A
14546
+ * provider-supported USDC would be a different contract at a different
14547
+ * address returning the same symbol, which is why the resolvers below key on
14548
+ * `assetId`, or on chain plus address, and never on a symbol.
14549
+ */
14550
+ const SYNTHETIC_TEST_ASSET_FIXTURES = {
14551
+ usdc: {
14552
+ assetId: assetIdFor(84532, "0x06ba8b863ca77490b0e7008427562bdbfcff730e"),
14553
+ chainId: toChainId(84532),
14554
+ tokenAddress: "0x06ba8b863ca77490b0e7008427562bdbfcff730e",
14555
+ symbol: "USDC",
14556
+ decimals: 6,
14557
+ peg: toCurrencyCode("USD"),
14558
+ deploymentStartBlock: 46690061,
14559
+ deploymentTransaction: "0x2661b7af5f62b9e31c707a59746cda65b90ba4448852317ac1968162fb94ff52",
14560
+ source: SYNTHETIC_TEST_ASSET_SOURCE
14561
+ },
14562
+ usdt: {
14563
+ assetId: assetIdFor(84532, "0xcb5f361ae070e75d573941b8cd54995fa3876d75"),
14564
+ chainId: toChainId(84532),
14565
+ tokenAddress: "0xcb5f361ae070e75d573941b8cd54995fa3876d75",
14566
+ symbol: "USDT",
14567
+ decimals: 6,
14568
+ peg: toCurrencyCode("USD"),
14569
+ deploymentStartBlock: 46690061,
14570
+ deploymentTransaction: "0x98e5303f97974a31eddb61ad030072d900ce7283ce8080bfe0b9e5ea6f297749",
14571
+ source: SYNTHETIC_TEST_ASSET_SOURCE
14572
+ },
14573
+ weth: {
14574
+ assetId: assetIdFor(84532, "0x85b7bd39ce3df9a85135e1e307225dd435f67e47"),
14575
+ chainId: toChainId(84532),
14576
+ tokenAddress: "0x85b7bd39ce3df9a85135e1e307225dd435f67e47",
14577
+ symbol: "WETH",
14578
+ decimals: 18,
14579
+ peg: null,
14580
+ deploymentStartBlock: 46690061,
14581
+ deploymentTransaction: "0x48dfacc01c15adc34f6c629aec5c9ff7bb84176d448017da0d0d4fdaf8b5a68a",
14582
+ source: SYNTHETIC_TEST_ASSET_SOURCE
14583
+ },
14584
+ wbtc: {
14585
+ assetId: assetIdFor(84532, "0xcf433a81f507dcc88c2c404650ffafb40750b451"),
14586
+ chainId: toChainId(84532),
14587
+ tokenAddress: "0xcf433a81f507dcc88c2c404650ffafb40750b451",
14588
+ symbol: "WBTC",
14589
+ decimals: 8,
14590
+ peg: null,
14591
+ deploymentStartBlock: 46690061,
14592
+ deploymentTransaction: "0xa975fcda0a67509742243bbfc386032d2e0d6ca78404c255fae2e4ffae1c7f4d",
14593
+ source: SYNTHETIC_TEST_ASSET_SOURCE
14594
+ },
14595
+ cngn: {
14596
+ assetId: assetIdFor(84532, "0xda515a7267e190710f0003f951c62bcfd70d6b2a"),
14597
+ chainId: toChainId(84532),
14598
+ tokenAddress: "0xda515a7267e190710f0003f951c62bcfd70d6b2a",
14599
+ symbol: "cNGN",
14600
+ decimals: 6,
14601
+ peg: toCurrencyCode("NGN"),
14602
+ deploymentStartBlock: 46690061,
14603
+ deploymentTransaction: "0x6f6b0302448c7cd7db5c118a8250e548c6e72821df373e5a27550e5cdfa635a1",
14604
+ source: SYNTHETIC_TEST_ASSET_SOURCE
14605
+ },
14606
+ eurc: {
14607
+ assetId: assetIdFor(84532, "0x15055b4ed1d248c169b92705757cd9c3d985ad5f"),
14608
+ chainId: toChainId(84532),
14609
+ tokenAddress: "0x15055b4ed1d248c169b92705757cd9c3d985ad5f",
14610
+ symbol: "EURC",
14611
+ decimals: 6,
14612
+ peg: toCurrencyCode("EUR"),
14613
+ deploymentStartBlock: 47893251,
14614
+ deploymentTransaction: "0x4e0ab412d980a672336487afd10da007d51f34f17876b19b13732c8125be90ca",
14615
+ source: SYNTHETIC_TEST_ASSET_SOURCE
14616
+ }
14617
+ };
14618
+ /** EURC is minted for bank deposits and has no admission to the fixed test exchange. */
14619
+ const SYNTHETIC_TEST_ASSETS = [...[
14620
+ SYNTHETIC_TEST_ASSET_FIXTURES.usdc,
14621
+ SYNTHETIC_TEST_ASSET_FIXTURES.usdt,
14622
+ SYNTHETIC_TEST_ASSET_FIXTURES.weth,
14623
+ SYNTHETIC_TEST_ASSET_FIXTURES.wbtc,
14624
+ SYNTHETIC_TEST_ASSET_FIXTURES.cngn
14625
+ ], SYNTHETIC_TEST_ASSET_FIXTURES.eurc];
14626
+ toChainId(84532);
14627
+ /**
14628
+ * The settlement tier: the owned test assets admitted to the exact-transfer
14629
+ * path and to the treasury reads. USDC, USDT, WETH and EURC are admitted assets.
14630
+ * There is no default token.
14631
+ */
14632
+ const SETTLEMENT_ASSETS_BASE_SEPOLIA = Object.freeze({
14633
+ CAPXUL_TEST_USDC: SYNTHETIC_TEST_ASSET_FIXTURES.usdc,
14634
+ CAPXUL_TEST_USDT: SYNTHETIC_TEST_ASSET_FIXTURES.usdt,
14635
+ CAPXUL_TEST_WETH: SYNTHETIC_TEST_ASSET_FIXTURES.weth,
14636
+ CAPXUL_TEST_EURC: SYNTHETIC_TEST_ASSET_FIXTURES.eurc
14637
+ });
14638
+ const CONFIGURED_MONEY_ASSETS = Object.freeze(Object.values(SETTLEMENT_ASSETS_BASE_SEPOLIA));
14639
+ /** Public AssetIds for the admitted Base Sepolia test assets. */
14640
+ const TOKENS = Object.freeze({ BASE_SEPOLIA: Object.freeze({
14641
+ CAPXUL_TEST_USDC: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_USDC.assetId,
14642
+ CAPXUL_TEST_USDT: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_USDT.assetId,
14643
+ CAPXUL_TEST_WETH: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_WETH.assetId,
14644
+ CAPXUL_TEST_EURC: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_EURC.assetId
14645
+ }) });
14646
+ /**
14647
+ * Every known asset in ONE identity space. The tiers above declare admission;
14648
+ * this is the only list an identity resolves against, so an asset is never
14649
+ * two different things depending on which list a caller happened to read.
14650
+ */
14651
+ const MONEY_ASSET_REGISTRY = [...SYNTHETIC_TEST_ASSETS];
14652
+ CONFIGURED_MONEY_ASSETS.map((asset) => asset.tokenAddress.toLowerCase());
14653
+ /** The registry row for `assetId` across every tier, or `null`. */
14654
+ function configuredMoneyAssetById(assetId) {
14655
+ const canonical = toAssetId(assetId);
14656
+ return MONEY_ASSET_REGISTRY.find((asset) => asset.assetId === canonical) ?? null;
14657
+ }
14658
+ //#endregion
14479
14659
  //#region src/platform/transport/call-operation.ts
14480
14660
  function callOperation(port, row, args, options) {
14481
14661
  const op = row;
@@ -15649,6 +15829,23 @@ async function verifyPaymentDocumentSignatureV3(input) {
15649
15829
  })).toLowerCase() === envelope.signature.signer;
15650
15830
  }
15651
15831
  //#endregion
15832
+ //#region ../protocol/src/documents/identities.ts
15833
+ /** A caller handed this module a value its own types rule out: a defect, named. */
15834
+ function defect$1(step, message) {
15835
+ return new CapxulError("UNKNOWN", message, { details: { step } });
15836
+ }
15837
+ function hashDocumentOriginIdV3(input) {
15838
+ if (!Number.isSafeInteger(input.chainId) || input.chainId <= 0 || !Number.isSafeInteger(input.itemIndex) || input.itemIndex < 0 || input.actorKind !== "account" && input.actorKind !== "organization" || input.actorId.length === 0 || input.requestKey.length === 0) throw defect$1("hashDocumentOriginIdV3", "Invalid document origin input");
15839
+ return keccak256(encodeAbiParameters(parseAbiParameters("string namespace, uint256 chainId, string actorKind, string actorId, string requestKey, uint256 itemIndex"), [
15840
+ "capxul.document-origin.v3",
15841
+ BigInt(input.chainId),
15842
+ input.actorKind,
15843
+ input.actorId,
15844
+ input.requestKey,
15845
+ BigInt(input.itemIndex)
15846
+ ]));
15847
+ }
15848
+ //#endregion
15652
15849
  //#region src/documents/birth-context.ts
15653
15850
  function sourcePurpose(source) {
15654
15851
  if ("purposeKind" in source) return source.purposeKind;
@@ -15663,13 +15860,20 @@ function isBirthItem(item) {
15663
15860
  function requestRetryInstruction(input) {
15664
15861
  const request = input.evidence.request;
15665
15862
  const original = input.evidence.sourceCommand;
15666
- if (!("kind" in request) || request.kind !== "retry" || original?.kind !== "birth" || original.lineage?.kind !== "payment_request" && original.lineage?.kind !== "invoice_checkout" || original.lineage.requestId !== original.requestKey || !input.evidence.sourcePaymentIds?.includes(request.paymentId)) return void 0;
15863
+ if (!("kind" in request) || request.kind !== "retry" || original?.kind !== "birth" || original.lineage?.kind !== "payment_request" && original.lineage?.kind !== "invoice_checkout" || !input.evidence.sourcePaymentIds?.includes(request.paymentId)) return void 0;
15667
15864
  const document = original.items[input.index]?.document;
15668
15865
  if (document?.kind !== "envelope") return void 0;
15669
15866
  const bytes = decodeCanonicalBase64V3(document.bytesBase64);
15670
15867
  const envelope = decodeSupportedPaymentDocumentEnvelope(bytes);
15671
15868
  if (envelope.primaryType !== "Memo" && envelope.primaryType !== "Invoice") return void 0;
15672
15869
  if (envelope.version === 5) return void 0;
15870
+ if (original.lineage.requestId !== original.requestKey && (original.lineage.kind !== "payment_request" || envelope.primaryType !== "Invoice" || envelope.message.originId !== hashDocumentOriginIdV3({
15871
+ chainId: input.evidence.chainId,
15872
+ actorKind: original.actor.kind,
15873
+ actorId: original.actor.kind === "account" ? original.actor.accountId : original.actor.orgId,
15874
+ requestKey: original.lineage.requestId,
15875
+ itemIndex: input.index
15876
+ }))) return void 0;
15673
15877
  return {
15674
15878
  documentHash: hashSupportedPaymentDocument(envelope),
15675
15879
  contentHash: hashPaymentDocumentContentV3(bytes),
@@ -15698,11 +15902,7 @@ function requestBirthContext(evidence) {
15698
15902
  ].some((items) => items?.length !== 1)) return null;
15699
15903
  const item = command.items[0];
15700
15904
  const instruction = command.instructionDocuments?.[0];
15701
- if (!isBirthItem(item) || instruction === void 0 || source.lineage?.kind !== "payment_request" || [
15702
- source.lineage.requestId,
15703
- source.requestKey,
15704
- request.requestKey
15705
- ].some((key) => key !== request.confirmation.requestId) || documentJson(request.actor) !== documentJson(source.actor) || documentJson(request.items) !== documentJson(source.items) || evidence.sourcePaymentIds?.[0] !== evidence.paymentIds[0] || evidence.sourceRecipientSafes?.[0]?.toLowerCase() !== request.confirmation.issuerSafe.toLowerCase() || documentJson(evidence.documentBundles) !== documentJson(command.documentBundles) || !confirmedRequestFactsMatch(request.confirmation, source, item, instruction)) return null;
15905
+ if (!isBirthItem(item) || instruction === void 0 || source.lineage?.kind !== "payment_request" || source.lineage.requestId !== request.confirmation.requestId || [source.requestKey, request.requestKey].some((key) => key !== (request.confirmation.requestKey ?? request.confirmation.requestId)) || documentJson(request.actor) !== documentJson(source.actor) || documentJson(request.items) !== documentJson(source.items) || evidence.sourcePaymentIds?.[0] !== evidence.paymentIds[0] || evidence.sourceRecipientSafes?.[0]?.toLowerCase() !== request.confirmation.issuerSafe.toLowerCase() || documentJson(evidence.documentBundles) !== documentJson(command.documentBundles) || !confirmedRequestFactsMatch(request.confirmation, source, item, instruction)) return null;
15706
15906
  return {
15707
15907
  source: source.items,
15708
15908
  actorKind: source.actor.kind,
@@ -15728,127 +15928,6 @@ function retryBirthContext(evidence) {
15728
15928
  };
15729
15929
  }
15730
15930
  //#endregion
15731
- //#region ../protocol/src/evm/test-assets.ts
15732
- const SYNTHETIC_TEST_ASSET_SOURCE = "synthetic-test-liquidity";
15733
- /**
15734
- * Owned test assets, with metadata read from each creation receipt and contract.
15735
- * Settlement admission lives in assets.ts. The fixed test exchange uses the
15736
- * original five assets; bank EURC has its own deployment.
15737
- *
15738
- * `symbol` is the display string the owned contract returns. A
15739
- * provider-supported USDC would be a different contract at a different
15740
- * address returning the same symbol, which is why the resolvers below key on
15741
- * `assetId`, or on chain plus address, and never on a symbol.
15742
- */
15743
- const SYNTHETIC_TEST_ASSET_FIXTURES = {
15744
- usdc: {
15745
- assetId: assetIdFor(84532, "0x06ba8b863ca77490b0e7008427562bdbfcff730e"),
15746
- chainId: toChainId(84532),
15747
- tokenAddress: "0x06ba8b863ca77490b0e7008427562bdbfcff730e",
15748
- symbol: "USDC",
15749
- decimals: 6,
15750
- peg: toCurrencyCode("USD"),
15751
- deploymentStartBlock: 46690061,
15752
- deploymentTransaction: "0x2661b7af5f62b9e31c707a59746cda65b90ba4448852317ac1968162fb94ff52",
15753
- source: SYNTHETIC_TEST_ASSET_SOURCE
15754
- },
15755
- usdt: {
15756
- assetId: assetIdFor(84532, "0xcb5f361ae070e75d573941b8cd54995fa3876d75"),
15757
- chainId: toChainId(84532),
15758
- tokenAddress: "0xcb5f361ae070e75d573941b8cd54995fa3876d75",
15759
- symbol: "USDT",
15760
- decimals: 6,
15761
- peg: toCurrencyCode("USD"),
15762
- deploymentStartBlock: 46690061,
15763
- deploymentTransaction: "0x98e5303f97974a31eddb61ad030072d900ce7283ce8080bfe0b9e5ea6f297749",
15764
- source: SYNTHETIC_TEST_ASSET_SOURCE
15765
- },
15766
- weth: {
15767
- assetId: assetIdFor(84532, "0x85b7bd39ce3df9a85135e1e307225dd435f67e47"),
15768
- chainId: toChainId(84532),
15769
- tokenAddress: "0x85b7bd39ce3df9a85135e1e307225dd435f67e47",
15770
- symbol: "WETH",
15771
- decimals: 18,
15772
- peg: null,
15773
- deploymentStartBlock: 46690061,
15774
- deploymentTransaction: "0x48dfacc01c15adc34f6c629aec5c9ff7bb84176d448017da0d0d4fdaf8b5a68a",
15775
- source: SYNTHETIC_TEST_ASSET_SOURCE
15776
- },
15777
- wbtc: {
15778
- assetId: assetIdFor(84532, "0xcf433a81f507dcc88c2c404650ffafb40750b451"),
15779
- chainId: toChainId(84532),
15780
- tokenAddress: "0xcf433a81f507dcc88c2c404650ffafb40750b451",
15781
- symbol: "WBTC",
15782
- decimals: 8,
15783
- peg: null,
15784
- deploymentStartBlock: 46690061,
15785
- deploymentTransaction: "0xa975fcda0a67509742243bbfc386032d2e0d6ca78404c255fae2e4ffae1c7f4d",
15786
- source: SYNTHETIC_TEST_ASSET_SOURCE
15787
- },
15788
- cngn: {
15789
- assetId: assetIdFor(84532, "0xda515a7267e190710f0003f951c62bcfd70d6b2a"),
15790
- chainId: toChainId(84532),
15791
- tokenAddress: "0xda515a7267e190710f0003f951c62bcfd70d6b2a",
15792
- symbol: "cNGN",
15793
- decimals: 6,
15794
- peg: toCurrencyCode("NGN"),
15795
- deploymentStartBlock: 46690061,
15796
- deploymentTransaction: "0x6f6b0302448c7cd7db5c118a8250e548c6e72821df373e5a27550e5cdfa635a1",
15797
- source: SYNTHETIC_TEST_ASSET_SOURCE
15798
- },
15799
- eurc: {
15800
- assetId: assetIdFor(84532, "0x15055b4ed1d248c169b92705757cd9c3d985ad5f"),
15801
- chainId: toChainId(84532),
15802
- tokenAddress: "0x15055b4ed1d248c169b92705757cd9c3d985ad5f",
15803
- symbol: "EURC",
15804
- decimals: 6,
15805
- peg: toCurrencyCode("EUR"),
15806
- deploymentStartBlock: 47893251,
15807
- deploymentTransaction: "0x4e0ab412d980a672336487afd10da007d51f34f17876b19b13732c8125be90ca",
15808
- source: SYNTHETIC_TEST_ASSET_SOURCE
15809
- }
15810
- };
15811
- /** EURC is minted for bank deposits and has no admission to the fixed test exchange. */
15812
- const SYNTHETIC_TEST_ASSETS = [...[
15813
- SYNTHETIC_TEST_ASSET_FIXTURES.usdc,
15814
- SYNTHETIC_TEST_ASSET_FIXTURES.usdt,
15815
- SYNTHETIC_TEST_ASSET_FIXTURES.weth,
15816
- SYNTHETIC_TEST_ASSET_FIXTURES.wbtc,
15817
- SYNTHETIC_TEST_ASSET_FIXTURES.cngn
15818
- ], SYNTHETIC_TEST_ASSET_FIXTURES.eurc];
15819
- toChainId(84532);
15820
- /**
15821
- * The settlement tier: the owned test assets admitted to the exact-transfer
15822
- * path and to the treasury reads. USDC, USDT, WETH and EURC are admitted assets.
15823
- * There is no default token.
15824
- */
15825
- const SETTLEMENT_ASSETS_BASE_SEPOLIA = Object.freeze({
15826
- CAPXUL_TEST_USDC: SYNTHETIC_TEST_ASSET_FIXTURES.usdc,
15827
- CAPXUL_TEST_USDT: SYNTHETIC_TEST_ASSET_FIXTURES.usdt,
15828
- CAPXUL_TEST_WETH: SYNTHETIC_TEST_ASSET_FIXTURES.weth,
15829
- CAPXUL_TEST_EURC: SYNTHETIC_TEST_ASSET_FIXTURES.eurc
15830
- });
15831
- const CONFIGURED_MONEY_ASSETS = Object.freeze(Object.values(SETTLEMENT_ASSETS_BASE_SEPOLIA));
15832
- /** Public AssetIds for the admitted Base Sepolia test assets. */
15833
- const TOKENS = Object.freeze({ BASE_SEPOLIA: Object.freeze({
15834
- CAPXUL_TEST_USDC: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_USDC.assetId,
15835
- CAPXUL_TEST_USDT: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_USDT.assetId,
15836
- CAPXUL_TEST_WETH: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_WETH.assetId,
15837
- CAPXUL_TEST_EURC: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_EURC.assetId
15838
- }) });
15839
- /**
15840
- * Every known asset in ONE identity space. The tiers above declare admission;
15841
- * this is the only list an identity resolves against, so an asset is never
15842
- * two different things depending on which list a caller happened to read.
15843
- */
15844
- const MONEY_ASSET_REGISTRY = [...SYNTHETIC_TEST_ASSETS];
15845
- CONFIGURED_MONEY_ASSETS.map((asset) => asset.tokenAddress.toLowerCase());
15846
- /** The registry row for `assetId` across every tier, or `null`. */
15847
- function configuredMoneyAssetById(assetId) {
15848
- const canonical = toAssetId(assetId);
15849
- return MONEY_ASSET_REGISTRY.find((asset) => asset.assetId === canonical) ?? null;
15850
- }
15851
- //#endregion
15852
15931
  //#region ../protocol/src/documents/receipts.ts
15853
15932
  async function parseSupportingReceiptV3(input) {
15854
15933
  const supporting = SchemaParser.decodeUnknownSync(SupportingReceiptInputSchema, { onExcessProperty: "error" })(input);
@@ -15879,23 +15958,6 @@ async function parseSupportingReceiptV3(input) {
15879
15958
  };
15880
15959
  }
15881
15960
  //#endregion
15882
- //#region ../protocol/src/documents/identities.ts
15883
- /** A caller handed this module a value its own types rule out: a defect, named. */
15884
- function defect$1(step, message) {
15885
- return new CapxulError("UNKNOWN", message, { details: { step } });
15886
- }
15887
- function hashDocumentOriginIdV3(input) {
15888
- if (!Number.isSafeInteger(input.chainId) || input.chainId <= 0 || !Number.isSafeInteger(input.itemIndex) || input.itemIndex < 0 || input.actorKind !== "account" && input.actorKind !== "organization" || input.actorId.length === 0 || input.requestKey.length === 0) throw defect$1("hashDocumentOriginIdV3", "Invalid document origin input");
15889
- return keccak256(encodeAbiParameters(parseAbiParameters("string namespace, uint256 chainId, string actorKind, string actorId, string requestKey, uint256 itemIndex"), [
15890
- "capxul.document-origin.v3",
15891
- BigInt(input.chainId),
15892
- input.actorKind,
15893
- input.actorId,
15894
- input.requestKey,
15895
- BigInt(input.itemIndex)
15896
- ]));
15897
- }
15898
- //#endregion
15899
15961
  //#region ../protocol/src/documents/context.ts
15900
15962
  function sameAmount(left, right) {
15901
15963
  return left.asset === right.asset && left.minorUnits === right.minorUnits && left.decimals === right.decimals;
@@ -16176,6 +16238,25 @@ function verifiesInvoiceCheckoutBirthEvidence(evidence, invoice, chainId, source
16176
16238
  return "kind" in evidence.request && evidence.request.kind === "invoice_checkout" && evidence.request.linkToken === invoice.linkToken && evidence.preparedCommand?.items.length === 1 && item?.operation === "send" && evidence.preparedCommand.senderSafe.toLowerCase() === sourceWallet.toLowerCase() && evidence.preparedCommand.contractAddress.toLowerCase() === invoice.contractAddress.toLowerCase() && item.settlementId === invoice.settlementId && item.documentHash === invoice.documentHash && item.recipientSafe.toLowerCase() === invoice.recipientSafe.toLowerCase() && item.tokenAddress.toLowerCase() === invoice.tokenAddress.toLowerCase() && item.rawAmount === invoice.rawAmount && item.kind === (invoice.documentKind === "memo" ? 0 : 1) && invoice.chainId === chainId;
16177
16239
  }
16178
16240
  //#endregion
16241
+ //#region ../protocol/src/payments/execution-identity.ts
16242
+ /** A command and its exact signed operation have one durable execution identity. */
16243
+ function moneyExecutionId(commandId, digest) {
16244
+ return `money_execution_${keccak256(encodeAbiParameters([
16245
+ { type: "string" },
16246
+ { type: "string" },
16247
+ { type: "bytes32" }
16248
+ ], [
16249
+ "capxul.money-execution.v1",
16250
+ commandId,
16251
+ toLowerBytes32(digest)
16252
+ ])).slice(2)}`;
16253
+ }
16254
+ /** Existing stored executions keep their digest-derived identity. */
16255
+ function matchesMoneyExecutionId(executionId, digest, commandId) {
16256
+ const exactDigest = toLowerBytes32(digest);
16257
+ return executionId === `money_execution_${exactDigest.slice(2)}` || commandId !== void 0 && executionId === moneyExecutionId(commandId, exactDigest);
16258
+ }
16259
+ //#endregion
16179
16260
  //#region ../protocol/src/evm/payments-abi.ts
16180
16261
  /** The exact compiled CapxulPaymentsV2 ABI. */
16181
16262
  const CAPXUL_PAYMENTS_V2_ABI = [
@@ -16753,22 +16834,270 @@ const CAPXUL_PAYMENTS_V2_ABI = [
16753
16834
  },
16754
16835
  {
16755
16836
  type: "error",
16756
- name: "InvalidTimeParams",
16757
- inputs: []
16758
- },
16759
- {
16760
- type: "error",
16761
- name: "NotCreator",
16762
- inputs: []
16763
- },
16764
- {
16765
- type: "error",
16766
- name: "NotRecipient",
16767
- inputs: []
16768
- },
16769
- {
16770
- type: "error",
16771
- name: "NothingToClaim",
16837
+ name: "InvalidTimeParams",
16838
+ inputs: []
16839
+ },
16840
+ {
16841
+ type: "error",
16842
+ name: "NotCreator",
16843
+ inputs: []
16844
+ },
16845
+ {
16846
+ type: "error",
16847
+ name: "NotRecipient",
16848
+ inputs: []
16849
+ },
16850
+ {
16851
+ type: "error",
16852
+ name: "NothingToClaim",
16853
+ inputs: []
16854
+ },
16855
+ {
16856
+ type: "error",
16857
+ name: "SettlementIdConsumed",
16858
+ inputs: [{
16859
+ name: "settlementId",
16860
+ type: "bytes32",
16861
+ internalType: "bytes32"
16862
+ }]
16863
+ },
16864
+ {
16865
+ type: "error",
16866
+ name: "TokenCallReturnedFalse",
16867
+ inputs: [{
16868
+ name: "token",
16869
+ type: "address",
16870
+ internalType: "address"
16871
+ }]
16872
+ },
16873
+ {
16874
+ type: "error",
16875
+ name: "TokenHasNoCode",
16876
+ inputs: [{
16877
+ name: "token",
16878
+ type: "address",
16879
+ internalType: "address"
16880
+ }]
16881
+ },
16882
+ {
16883
+ type: "error",
16884
+ name: "ZeroAddress",
16885
+ inputs: []
16886
+ },
16887
+ {
16888
+ type: "error",
16889
+ name: "ZeroAmount",
16890
+ inputs: []
16891
+ },
16892
+ {
16893
+ type: "error",
16894
+ name: "ZeroDocumentHash",
16895
+ inputs: []
16896
+ },
16897
+ {
16898
+ type: "error",
16899
+ name: "ZeroSettlementId",
16900
+ inputs: []
16901
+ }
16902
+ ];
16903
+ /** Immutable CapxulPaymentsV2 deployment on Base Sepolia. */
16904
+ const CAPXUL_PAYMENTS_V2_ADDRESS = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
16905
+ //#endregion
16906
+ //#region ../protocol/src/evm/payments-v3.ts
16907
+ const PAYMENT_ITEM_COMPONENTS = [
16908
+ {
16909
+ name: "settlementId",
16910
+ type: "bytes32",
16911
+ internalType: "bytes32"
16912
+ },
16913
+ {
16914
+ name: "recipient",
16915
+ type: "address",
16916
+ internalType: "address"
16917
+ },
16918
+ {
16919
+ name: "token",
16920
+ type: "address",
16921
+ internalType: "address"
16922
+ },
16923
+ {
16924
+ name: "amount",
16925
+ type: "uint256",
16926
+ internalType: "uint256"
16927
+ },
16928
+ {
16929
+ name: "kind",
16930
+ type: "uint16",
16931
+ internalType: "uint16"
16932
+ },
16933
+ {
16934
+ name: "documentHash",
16935
+ type: "bytes32",
16936
+ internalType: "bytes32"
16937
+ },
16938
+ {
16939
+ name: "jobNonce",
16940
+ type: "bytes32",
16941
+ internalType: "bytes32"
16942
+ },
16943
+ {
16944
+ name: "executor",
16945
+ type: "address",
16946
+ internalType: "address"
16947
+ }
16948
+ ];
16949
+ const PAYMENT_ITEM_INPUT = {
16950
+ name: "item",
16951
+ type: "tuple",
16952
+ internalType: "struct CapxulPaymentsV3.PaymentItem",
16953
+ components: PAYMENT_ITEM_COMPONENTS
16954
+ };
16955
+ /** The exact compiled CapxulPaymentsV3 ABI. */
16956
+ const CAPXUL_PAYMENTS_V3_ABI = [
16957
+ {
16958
+ type: "function",
16959
+ name: "paymentId",
16960
+ inputs: [PAYMENT_ITEM_INPUT],
16961
+ outputs: [{
16962
+ name: "",
16963
+ type: "bytes32",
16964
+ internalType: "bytes32"
16965
+ }],
16966
+ stateMutability: "view"
16967
+ },
16968
+ {
16969
+ type: "function",
16970
+ name: "send",
16971
+ inputs: [PAYMENT_ITEM_INPUT],
16972
+ outputs: [],
16973
+ stateMutability: "nonpayable"
16974
+ },
16975
+ {
16976
+ type: "function",
16977
+ name: "sendBatch",
16978
+ inputs: [{
16979
+ name: "items",
16980
+ type: "tuple[]",
16981
+ internalType: "struct CapxulPaymentsV3.PaymentItem[]",
16982
+ components: PAYMENT_ITEM_COMPONENTS
16983
+ }],
16984
+ outputs: [],
16985
+ stateMutability: "nonpayable"
16986
+ },
16987
+ {
16988
+ type: "function",
16989
+ name: "settled",
16990
+ inputs: [{
16991
+ name: "",
16992
+ type: "bytes32",
16993
+ internalType: "bytes32"
16994
+ }],
16995
+ outputs: [{
16996
+ name: "",
16997
+ type: "bool",
16998
+ internalType: "bool"
16999
+ }],
17000
+ stateMutability: "view"
17001
+ },
17002
+ {
17003
+ type: "event",
17004
+ name: "PaymentSent",
17005
+ inputs: [
17006
+ {
17007
+ name: "settlementId",
17008
+ type: "bytes32",
17009
+ indexed: true,
17010
+ internalType: "bytes32"
17011
+ },
17012
+ {
17013
+ name: "sender",
17014
+ type: "address",
17015
+ indexed: true,
17016
+ internalType: "address"
17017
+ },
17018
+ {
17019
+ name: "recipient",
17020
+ type: "address",
17021
+ indexed: true,
17022
+ internalType: "address"
17023
+ },
17024
+ {
17025
+ name: "token",
17026
+ type: "address",
17027
+ indexed: false,
17028
+ internalType: "address"
17029
+ },
17030
+ {
17031
+ name: "amount",
17032
+ type: "uint256",
17033
+ indexed: false,
17034
+ internalType: "uint256"
17035
+ },
17036
+ {
17037
+ name: "kind",
17038
+ type: "uint16",
17039
+ indexed: false,
17040
+ internalType: "uint16"
17041
+ },
17042
+ {
17043
+ name: "documentHash",
17044
+ type: "bytes32",
17045
+ indexed: false,
17046
+ internalType: "bytes32"
17047
+ }
17048
+ ],
17049
+ anonymous: false
17050
+ },
17051
+ {
17052
+ type: "error",
17053
+ name: "InexactTransfer",
17054
+ inputs: [
17055
+ {
17056
+ name: "token",
17057
+ type: "address",
17058
+ internalType: "address"
17059
+ },
17060
+ {
17061
+ name: "expected",
17062
+ type: "uint256",
17063
+ internalType: "uint256"
17064
+ },
17065
+ {
17066
+ name: "received",
17067
+ type: "uint256",
17068
+ internalType: "uint256"
17069
+ }
17070
+ ]
17071
+ },
17072
+ {
17073
+ type: "error",
17074
+ name: "InvalidExecutor",
17075
+ inputs: [{
17076
+ name: "expected",
17077
+ type: "address",
17078
+ internalType: "address"
17079
+ }, {
17080
+ name: "supplied",
17081
+ type: "address",
17082
+ internalType: "address"
17083
+ }]
17084
+ },
17085
+ {
17086
+ type: "error",
17087
+ name: "PaymentIdMismatch",
17088
+ inputs: [{
17089
+ name: "expected",
17090
+ type: "bytes32",
17091
+ internalType: "bytes32"
17092
+ }, {
17093
+ name: "supplied",
17094
+ type: "bytes32",
17095
+ internalType: "bytes32"
17096
+ }]
17097
+ },
17098
+ {
17099
+ type: "error",
17100
+ name: "ReentrantCall",
16772
17101
  inputs: []
16773
17102
  },
16774
17103
  {
@@ -16813,14 +17142,73 @@ const CAPXUL_PAYMENTS_V2_ABI = [
16813
17142
  name: "ZeroDocumentHash",
16814
17143
  inputs: []
16815
17144
  },
17145
+ {
17146
+ type: "error",
17147
+ name: "ZeroJobNonce",
17148
+ inputs: []
17149
+ },
16816
17150
  {
16817
17151
  type: "error",
16818
17152
  name: "ZeroSettlementId",
16819
17153
  inputs: []
16820
17154
  }
16821
17155
  ];
16822
- /** Immutable CapxulPaymentsV2 deployment on Base Sepolia. */
16823
- const CAPXUL_PAYMENTS_V2_ADDRESS = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
17156
+ /** The fixed CREATE2 deployment on every admitted chain. */
17157
+ const CAPXUL_PAYMENTS_V3_ADDRESS = "0x46b28f455c8de7c1505e3185A3f8f87B07eaE1aE";
17158
+ //#endregion
17159
+ //#region ../protocol/src/evm/payments/encoding.ts
17160
+ const CAPXUL_PAYMENT_V3_TYPEHASH = keccak256(toBytes("CapxulPayment(uint256 chainId,address router,bytes32 jobNonce,address executor,address recipient,address token,uint256 amount,uint16 kind,bytes32 documentHash)"));
17161
+ function paymentJobNonce(commandId, itemIndex) {
17162
+ if (!Number.isSafeInteger(itemIndex) || itemIndex < 0) throw Errors.invalidInput("itemIndex", "must be a non-negative safe integer");
17163
+ return sha256(toBytes(`{"commandId":${JSON.stringify(commandId)},"index":${itemIndex},"version":1}`));
17164
+ }
17165
+ function capxulPaymentsV3PaymentId(chainId, router, item) {
17166
+ return keccak256(encodeAbiParameters(parseAbiParameters("bytes32,uint256,address,bytes32,address,address,address,uint256,uint16,bytes32"), [
17167
+ CAPXUL_PAYMENT_V3_TYPEHASH,
17168
+ BigInt(chainId),
17169
+ router,
17170
+ item.jobNonce,
17171
+ item.executor,
17172
+ item.recipient,
17173
+ item.token,
17174
+ item.amount,
17175
+ item.kind,
17176
+ item.documentHash
17177
+ ]));
17178
+ }
17179
+ function encodeCapxulPaymentsV3Send(item) {
17180
+ return encodeFunctionData({
17181
+ abi: CAPXUL_PAYMENTS_V3_ABI,
17182
+ functionName: "send",
17183
+ args: [item]
17184
+ });
17185
+ }
17186
+ function encodeCapxulPaymentsV3SendBatch(items) {
17187
+ return encodeFunctionData({
17188
+ abi: CAPXUL_PAYMENTS_V3_ABI,
17189
+ functionName: "sendBatch",
17190
+ args: [items]
17191
+ });
17192
+ }
17193
+ function v3Item(command, item, itemIndex) {
17194
+ const { commandId, chainId, senderSafe } = command;
17195
+ if (commandId === void 0 || chainId === void 0 || senderSafe === void 0) throw Errors.invalidInput("command", "CapxulPaymentsV3 requires its command identity");
17196
+ const terms = {
17197
+ recipient: item.recipientSafe,
17198
+ token: item.tokenAddress,
17199
+ amount: BigInt(item.rawAmount),
17200
+ kind: item.kind,
17201
+ documentHash: item.documentHash,
17202
+ jobNonce: item.jobNonce ?? paymentJobNonce(commandId, itemIndex),
17203
+ executor: item.executor ?? senderSafe
17204
+ };
17205
+ const settlementId = capxulPaymentsV3PaymentId(chainId, command.contractAddress, terms);
17206
+ if (settlementId.toLowerCase() !== item.settlementId.toLowerCase()) throw Errors.invalidInput("settlementId", "does not match CapxulPaymentsV3 terms");
17207
+ return {
17208
+ settlementId,
17209
+ ...terms
17210
+ };
17211
+ }
16824
17212
  //#endregion
16825
17213
  //#region ../protocol/src/evm/zodiac-abi.ts
16826
17214
  const MODULE_PROXY_FACTORY_ABI = [{
@@ -17185,7 +17573,8 @@ function requiredByPaymentToken(items) {
17185
17573
  }
17186
17574
  return totals;
17187
17575
  }
17188
- function birthCall(contract, item) {
17576
+ function birthCall(command, item, itemIndex) {
17577
+ const contract = command.contractAddress;
17189
17578
  const common = {
17190
17579
  settlementId: item.settlementId,
17191
17580
  recipient: item.recipientSafe,
@@ -17196,7 +17585,7 @@ function birthCall(contract, item) {
17196
17585
  return {
17197
17586
  to: contract,
17198
17587
  value: 0n,
17199
- data: item.operation === "send" ? encodeCapxulPaymentsV2Send({
17588
+ data: item.operation === "send" ? contract.toLowerCase() === "0x46b28f455c8de7c1505e3185A3f8f87B07eaE1aE".toLowerCase() ? encodeCapxulPaymentsV3Send(v3Item(command, item, itemIndex)) : encodeCapxulPaymentsV2Send({
17200
17589
  ...common,
17201
17590
  amount: BigInt(item.rawAmount)
17202
17591
  }) : encodeCapxulPaymentsV2CreateCommitment({
@@ -17208,7 +17597,8 @@ function birthCall(contract, item) {
17208
17597
  })
17209
17598
  };
17210
17599
  }
17211
- function birthCalls(contract, items) {
17600
+ function birthCalls(command, items) {
17601
+ const contract = command.contractAddress;
17212
17602
  const approvals = [...requiredByPaymentToken(items).values()].map(({ token, total }) => ({
17213
17603
  to: token,
17214
17604
  value: 0n,
@@ -17222,7 +17612,7 @@ function birthCalls(contract, items) {
17222
17612
  if (items.length > 1 && sends.length === items.length) return [...approvals, {
17223
17613
  to: contract,
17224
17614
  value: 0n,
17225
- data: encodeCapxulPaymentsV2SendBatch(sends.map((item) => ({
17615
+ data: contract.toLowerCase() === "0x46b28f455c8de7c1505e3185A3f8f87B07eaE1aE".toLowerCase() ? encodeCapxulPaymentsV3SendBatch(sends.map((item, index) => v3Item(command, item, index))) : encodeCapxulPaymentsV2SendBatch(sends.map((item) => ({
17226
17616
  settlementId: item.settlementId,
17227
17617
  recipient: item.recipientSafe,
17228
17618
  token: item.tokenAddress,
@@ -17231,7 +17621,7 @@ function birthCalls(contract, items) {
17231
17621
  documentHash: item.documentHash
17232
17622
  })))
17233
17623
  }];
17234
- return [...approvals, ...items.map((item) => birthCall(contract, item))];
17624
+ return [...approvals, ...items.map((item, index) => birthCall(command, item, index))];
17235
17625
  }
17236
17626
  function lifecycleData(item) {
17237
17627
  switch (item.operation) {
@@ -17246,7 +17636,7 @@ function encodePreparedPaymentCallData(command) {
17246
17636
  if (command.items.length === 0) throw Errors.invalidInput("items", "must not be empty");
17247
17637
  const births = command.items.filter(isBirth);
17248
17638
  if (births.length === command.items.length) {
17249
- const calls = birthCalls(command.contractAddress, births);
17639
+ const calls = birthCalls(command, births);
17250
17640
  return command.executionRoute.kind === "direct" ? safe4337MultiSendUserOpCallData({ calls }) : buildOrgRoleSpendPersonalCallData(buildOrgRoleMultiCall({
17251
17641
  rolesModuleAddress: command.executionRoute.rolesModule,
17252
17642
  roleKey: command.executionRoute.roleKey,
@@ -17309,15 +17699,16 @@ function verifiesMoneyOperation(evidence, expectedSafe, chainId, permissionId) {
17309
17699
  try {
17310
17700
  const command = evidence.preparedCommand;
17311
17701
  const operation = evidence.userOperation;
17312
- if (command === void 0 || operation === void 0 || false) return false;
17313
- if (command.commandId !== evidence.commandId || command.chainId !== chainId || evidence.chainId !== chainId || command.contractAddress.toLowerCase() !== "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4".toLowerCase() || command.items.length !== evidence.paymentIds.length || command.items.some((item, index) => item.paymentId !== evidence.paymentIds[index]) || evidence.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase() || command.executionRoute.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase() || operation.sender.toLowerCase() !== expectedSafe.toLowerCase()) return false;
17702
+ if (command === void 0 || operation === void 0) return false;
17703
+ const knownRouter = command.contractAddress.toLowerCase() === "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4".toLowerCase() || command.contractAddress.toLowerCase() === "0x46b28f455c8de7c1505e3185A3f8f87B07eaE1aE".toLowerCase();
17704
+ if (command.commandId !== evidence.commandId || command.chainId !== chainId || evidence.chainId !== chainId || !knownRouter || command.items.length !== evidence.paymentIds.length || command.items.some((item, index) => item.paymentId !== evidence.paymentIds[index]) || evidence.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase() || command.executionRoute.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase() || operation.sender.toLowerCase() !== expectedSafe.toLowerCase()) return false;
17314
17705
  const route = command.executionRoute;
17315
17706
  if (route.kind === "direct") {
17316
17707
  if (permissionId !== void 0 || command.senderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return false;
17317
17708
  } else if ((permissionId === void 0 ? !isOwnerLifecycle(command) : route.roleKey.toLowerCase() !== roleKeyForPermission(permissionId).toLowerCase()) || command.senderSafe.toLowerCase() !== route.organizationSafe.toLowerCase()) return false;
17318
17709
  if (operation.callData.toLowerCase() !== encodePreparedPaymentCallData(command).toLowerCase()) return false;
17319
17710
  const digest = moneySafeOpDigest(operation, chainId);
17320
- return evidence.digest.toLowerCase() === digest.toLowerCase() && evidence.executionId === `money_execution_${digest.slice(2).toLowerCase()}`;
17711
+ return evidence.digest.toLowerCase() === digest.toLowerCase() && matchesMoneyExecutionId(evidence.executionId, digest, evidence.commandId);
17321
17712
  } catch {
17322
17713
  return false;
17323
17714
  }
@@ -17524,6 +17915,29 @@ function reportMoneyTelemetryFailure(kind, name, cause) {
17524
17915
  }));
17525
17916
  }
17526
17917
  //#endregion
17918
+ //#region ../protocol/src/payments/request-finality.ts
17919
+ /** Add a proved request outcome without changing the original failure. */
17920
+ function withPaymentRequestFinality(error, paymentRequestFinality) {
17921
+ const marked = new CapxulError(error.code, error.message, {
17922
+ cause: error.cause,
17923
+ details: {
17924
+ ...error.details,
17925
+ paymentRequestFinality
17926
+ },
17927
+ ...error.correlationId === void 0 ? {} : { correlationId: error.correlationId },
17928
+ ...error.layer === void 0 ? {} : { layer: error.layer },
17929
+ ...error.mode === void 0 ? {} : { mode: error.mode },
17930
+ ...error.chain === void 0 ? {} : { chain: error.chain }
17931
+ });
17932
+ marked.name = error.name;
17933
+ if (error.stack !== void 0) marked.stack = error.stack;
17934
+ return marked;
17935
+ }
17936
+ /** Only an authoritative failed-key response or confirmed durable closure resolves a key. */
17937
+ function isFinalPaymentRequestError(error) {
17938
+ return error.details?.paymentRequestFinality === "closed" || error.code === "INVALID_INPUT" && error.details?.field === "requestKey" && error.details.paymentRequestFinality === "failed";
17939
+ }
17940
+ //#endregion
17527
17941
  //#region src/payments/prepared-execution.ts
17528
17942
  async function abandonPrepared(deps, executionId, reason, result, onPreparedClosed) {
17529
17943
  const abandoned = await runIfActive(void 0, executions.abandon.name, () => callOperation(deps.convexCall, executions.abandon, {
@@ -17531,8 +17945,12 @@ async function abandonPrepared(deps, executionId, reason, result, onPreparedClos
17531
17945
  reason
17532
17946
  }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
17533
17947
  if (!abandoned.ok) return abandoned;
17534
- if (abandoned.value) onPreparedClosed?.();
17535
- return result;
17948
+ if (!abandoned.value) return result;
17949
+ onPreparedClosed?.();
17950
+ return result.ok ? result : {
17951
+ ok: false,
17952
+ error: withPaymentRequestFinality(result.error, "closed")
17953
+ };
17536
17954
  }
17537
17955
  async function notifyVerifiedPaymentPrepared(onPrepared, paymentId) {
17538
17956
  if (onPrepared === void 0) return {
@@ -17576,14 +17994,31 @@ async function abandonPreparedCommand(deps, executionId, closePayment, reason, r
17576
17994
  reason
17577
17995
  })).pipe(Effect.mapError((publicError) => ({ publicError })))), controls), deps.runPromise);
17578
17996
  if (!abandoned.ok) return abandoned;
17579
- if (abandoned.value) onPreparedClosed?.();
17580
- return result;
17997
+ if (!abandoned.value) return result;
17998
+ onPreparedClosed?.();
17999
+ return result.ok ? result : {
18000
+ ok: false,
18001
+ error: withPaymentRequestFinality(result.error, "closed")
18002
+ };
17581
18003
  }
17582
18004
  //#endregion
17583
18005
  //#region src/payments/command-execution.ts
17584
18006
  function isAborted$1(signal) {
17585
18007
  return signal?.aborted === true;
17586
18008
  }
18009
+ function settledPaymentsMatch(evidence) {
18010
+ try {
18011
+ return evidence.settled?.payments.every((payment, index) => {
18012
+ const item = evidence.preparedCommand?.items[index];
18013
+ const instructions = payment.documents.filter((document) => document.role === "instruction");
18014
+ const amount = toExactAssetAmount(payment.amount, CONFIGURED_MONEY_ASSETS);
18015
+ const asset = CONFIGURED_MONEY_ASSETS.find((row) => row.assetId === amount.asset);
18016
+ return item?.operation === "send" && payment.status === "settled" && payment.direction === "out" && payment.receipt?.chainId === evidence.chainId && item.tokenAddress.toLowerCase() === asset?.tokenAddress.toLowerCase() && item.rawAmount === amount.minorUnits && instructions.length === 1 && canonicalJson(instructions[0]) === canonicalJson(evidence.preparedCommand?.instructionDocuments?.[index]);
18017
+ }) === true;
18018
+ } catch {
18019
+ return false;
18020
+ }
18021
+ }
17587
18022
  async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnExit, onPreparedClosed, signal, controls, onPrepared, readAcceptedReplay, checkout, sourceWallet) {
17588
18023
  if (isAborted$1(signal)) return {
17589
18024
  ok: false,
@@ -17616,7 +18051,7 @@ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnE
17616
18051
  const prepared = await prepare(signerAddress);
17617
18052
  if (!current()) return cancelled;
17618
18053
  if (!prepared.ok) return prepared;
17619
- const accepted = readAcceptedReplay?.();
18054
+ const accepted = readAcceptedReplay?.() ?? prepared.value.settled;
17620
18055
  const closePrepared = closePaymentOnExit && accepted === void 0;
17621
18056
  const executionId = Schema.decodeUnknownResult(MoneyExecutionIdSchema)(readField(prepared.value, "executionId"));
17622
18057
  if (executionId._tag === "Failure") return {
@@ -17642,12 +18077,12 @@ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnE
17642
18077
  if (!verified) return abandon("prepared_mismatch", Errors.invalidInput("execution", "prepared Money operation mismatch"));
17643
18078
  if (accepted !== void 0) {
17644
18079
  const decodedSubmission = Schema.decodeResult(SubmittedPaymentCommandExecutionSchema, { onExcessProperty: "error" })(accepted);
17645
- if (decodedSubmission._tag === "Failure" || !acceptedSubmissionMatches(evidence, decodedSubmission.success)) return {
18080
+ if (decodedSubmission._tag === "Failure" || !acceptedSubmissionMatches(evidence, decodedSubmission.success) || evidence.settled !== void 0 && !settledPaymentsMatch(evidence)) return {
17646
18081
  ok: false,
17647
- error: Errors.invalidInput("execution", "accepted Payroll replay evidence mismatch")
18082
+ error: Errors.invalidInput("execution", "accepted Money replay evidence mismatch")
17648
18083
  };
17649
18084
  if (!current() || isAborted$1(signal)) return cancelled;
17650
- return {
18085
+ if (evidence.settled === void 0) return {
17651
18086
  ok: true,
17652
18087
  value: decodedSubmission.success
17653
18088
  };
@@ -17664,6 +18099,10 @@ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnE
17664
18099
  }
17665
18100
  if (!current()) return cancelled;
17666
18101
  if (isAborted$1(signal)) return abandon("cancelled", Errors.cancelled({ operation: "payments" }));
18102
+ if (evidence.settled !== void 0) return {
18103
+ ok: true,
18104
+ value: evidence.settled
18105
+ };
17667
18106
  await emitPreparedInitiation(deps, evidence);
17668
18107
  if (!current()) return cancelled;
17669
18108
  if (isAborted$1(signal)) return abandon("cancelled", Errors.cancelled({ operation: "payments" }));
@@ -17714,10 +18153,10 @@ function itemMatches(prepared, amount) {
17714
18153
  return item.paymentId === prepared.paymentId && Object.entries(PAYMENT_PURPOSE_KIND_CODES).some(([name, code]) => name === prepared.purposeKind && code === item.kind) && expectedPurpose === prepared.purposeKind && documentKind === "invoice" === (purpose === "invoice") && purpose !== "payroll" && item.tokenAddress.toLowerCase() === asset?.tokenAddress.toLowerCase() && (item.operation === "send" ? item.rawAmount : item.totalAmount) === amount.minorUnits && plannedCommitmentMatches(prepared) && recipientMatches(prepared, item.recipientSafe.toLowerCase());
17715
18154
  }
17716
18155
  /** The callData a personal Payment birth item must carry: approve, then send or commit. */
17717
- function expectedPersonalCallData(prepared) {
18156
+ function expectedPersonalCallData(prepared, expectedSafe, chainId) {
17718
18157
  const item = prepared.item;
17719
18158
  if (item.operation !== "send" && item.operation !== "create_commitment") throw new Error("Expected personal Payment birth item");
17720
- const contract = CAPXUL_PAYMENTS_V2_ADDRESS;
18159
+ const contract = toAddress(CAPXUL_PAYMENTS_V2_ADDRESS);
17721
18160
  const { settlementId, recipientSafe, tokenAddress, documentHash } = item;
17722
18161
  const amount = BigInt(item.operation === "send" ? item.rawAmount : item.totalAmount);
17723
18162
  const paymentData = item.operation === "send" ? encodeCapxulPaymentsV2Send({
@@ -17738,26 +18177,61 @@ function expectedPersonalCallData(prepared) {
17738
18177
  kind: item.kind,
17739
18178
  documentHash
17740
18179
  });
17741
- return safe4337MultiSendUserOpCallData({ calls: [{
18180
+ const calls = (router, encodedPaymentData) => safe4337MultiSendUserOpCallData({ calls: [{
17742
18181
  to: tokenAddress,
17743
18182
  value: 0n,
17744
18183
  data: encodeFunctionData({
17745
18184
  abi: ERC20_APPROVE_ABI,
17746
18185
  functionName: "approve",
17747
- args: [contract, amount]
18186
+ args: [router, amount]
17748
18187
  })
17749
18188
  }, {
17750
- to: contract,
18189
+ to: router,
17751
18190
  value: 0n,
17752
- data: paymentData
18191
+ data: encodedPaymentData
17753
18192
  }] });
18193
+ const v2 = calls(contract, paymentData);
18194
+ if (item.operation !== "send") return [v2];
18195
+ const terms = {
18196
+ recipient: item.recipientSafe,
18197
+ token: item.tokenAddress,
18198
+ amount,
18199
+ kind: item.kind,
18200
+ documentHash,
18201
+ jobNonce: paymentJobNonce(prepared.commandId, 0),
18202
+ executor: toAddress(expectedSafe)
18203
+ };
18204
+ const v3Contract = toAddress(CAPXUL_PAYMENTS_V3_ADDRESS);
18205
+ const v3SettlementId = capxulPaymentsV3PaymentId(chainId, v3Contract, terms);
18206
+ if (v3SettlementId.toLowerCase() !== settlementId.toLowerCase()) return [v2];
18207
+ return [calls(v3Contract, encodeCapxulPaymentsV3Send({
18208
+ settlementId: v3SettlementId,
18209
+ ...terms
18210
+ }))];
17754
18211
  }
17755
18212
  function verifiesPersonalOperation(prepared, expectedSafe, chainId) {
17756
18213
  try {
17757
18214
  const operation = prepared.userOperation;
17758
- if (operation.sender.toLowerCase() !== expectedSafe.toLowerCase() || operation.callData.toLowerCase() !== expectedPersonalCallData(prepared).toLowerCase()) return false;
18215
+ if (operation.sender.toLowerCase() !== expectedSafe.toLowerCase() || !expectedPersonalCallData(prepared, expectedSafe, chainId).some((callData) => operation.callData.toLowerCase() === callData.toLowerCase())) return false;
17759
18216
  const digest = moneySafeOpDigest(operation, chainId);
17760
- return prepared.digest.toLowerCase() === digest.toLowerCase() && prepared.executionId === `money_execution_${digest.slice(2).toLowerCase()}`;
18217
+ return prepared.digest.toLowerCase() === digest.toLowerCase() && matchesMoneyExecutionId(prepared.executionId, digest, prepared.commandId);
18218
+ } catch {
18219
+ return false;
18220
+ }
18221
+ }
18222
+ /** A settled reply retains the verified operation, quantity, instruction and receipt. */
18223
+ function verifiesSettledPersonalReplay(evidence) {
18224
+ const settled = evidence.settled;
18225
+ if (settled === void 0) return true;
18226
+ try {
18227
+ const instructions = settled.payment.documents.filter((document) => document.role === "instruction");
18228
+ return acceptedSubmissionMatches({
18229
+ ...evidence,
18230
+ paymentIds: [evidence.paymentId]
18231
+ }, {
18232
+ ...settled,
18233
+ payments: [settled.payment]
18234
+ }) && settled.payment.status === "settled" && settled.payment.direction === "out" && settled.payment.receipt?.chainId === evidence.chainId && itemMatches(evidence, toExactAssetAmount(settled.payment.amount, CONFIGURED_MONEY_ASSETS)) && instructions.length === 1 && canonicalJson(instructions[0]) === canonicalJson(evidence.instructionDocument);
17761
18235
  } catch {
17762
18236
  return false;
17763
18237
  }
@@ -17871,6 +18345,7 @@ async function preparedMismatch(chainId, evidence, payment, expected) {
17871
18345
  if (evidence.userOpSenderSafe.toLowerCase() !== expected.expectedSafe.toLowerCase()) return mismatch("userOpSenderSafe", "prepared Payment execution uses another Account Safe");
17872
18346
  if (!await verifiesPersonalDocument(evidence)) return mismatch("document", "prepared Payment document does not match the request");
17873
18347
  if (!verifiesPersonalOperation(evidence, expected.expectedSafe, chainId)) return mismatch("execution", "prepared Payment operation does not match the request");
18348
+ if (!verifiesSettledPersonalReplay(evidence)) return mismatch("execution", "settled Payment replay evidence mismatch");
17874
18349
  }
17875
18350
  /**
17876
18351
  * Prepare one personal Payment for this signer and check what the backend
@@ -17921,19 +18396,27 @@ async function emitPreparedPaymentInitiated(deps, evidence) {
17921
18396
  async function executePersonalPayment(deps, payment, signal, requestKey, onPreparedClosed, onPrepared) {
17922
18397
  if (isAborted(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
17923
18398
  if (deps.signer === void 0) return mismatch("signer", "payments.pay requires a configured CapxulSigner");
17924
- if (deps.actor.authSession() === null) return {
18399
+ const session = deps.actor.authSession();
18400
+ if (session === null) return {
17925
18401
  ok: false,
17926
18402
  error: Errors.notAuthenticated()
17927
18403
  };
18404
+ const lifetime = deps.actor.authLifetime();
18405
+ const current = () => deps.actor.matchesAuthLifetime(lifetime, session.authUserId);
17928
18406
  const signerAddress = await signerCall(deps.signer.source, "getAddress", () => deps.signer.getAddress());
17929
18407
  if (!signerAddress.ok) return signerAddress;
17930
18408
  const prepared = await prepareVerifiedPersonalPayment(deps, payment, signerAddress.value, requestKey ?? `pay_${crypto.randomUUID()}`, signal, onPreparedClosed);
17931
18409
  if (!prepared.ok) return prepared;
17932
18410
  const evidence = prepared.value;
18411
+ if (evidence.settled !== void 0 && !current()) return cancelled(CAPXUL_OPERATIONS.payments.pay);
17933
18412
  const digest = evidence.digest;
17934
18413
  if (isAborted(signal)) return abandonPrepared(deps, evidence.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
17935
18414
  const delivered = await notifyVerifiedPaymentPrepared(onPrepared, evidence.paymentId);
17936
18415
  if (!delivered.ok) return delivered;
18416
+ if (evidence.settled !== void 0) return current() ? {
18417
+ ok: true,
18418
+ value: evidence.settled
18419
+ } : cancelled(CAPXUL_OPERATIONS.payments.pay);
17937
18420
  if (isAborted(signal)) return abandonPrepared(deps, evidence.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
17938
18421
  await emitPreparedPaymentInitiated(deps, evidence);
17939
18422
  if (isAborted(signal)) return abandonPrepared(deps, evidence.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
@@ -18467,6 +18950,41 @@ function isCheckoutSettlementConsumed(error, settlementId) {
18467
18950
  return false;
18468
18951
  }
18469
18952
  //#endregion
18953
+ //#region src/requests/request-keys.ts
18954
+ /** Keep an Invoice attempt through uncertainty; renew an old failed default only before preparation. */
18955
+ async function withInvoiceRequestKey(actorId, intent, provided, run) {
18956
+ let key;
18957
+ let prepared = false;
18958
+ try {
18959
+ key = await paymentRequestKeyLifecycle(`invoice-request:${actorId}`, intent, provided);
18960
+ let result = await run(key.key, () => {
18961
+ prepared = true;
18962
+ });
18963
+ const renew = provided === void 0 && !prepared && !result.ok && isFinalPaymentRequestError(result.error) && result.error.details?.paymentRequestFinality === "failed";
18964
+ let finished = true;
18965
+ try {
18966
+ await key.finish(!result.ok && isFinalPaymentRequestError(result.error));
18967
+ } catch {
18968
+ finished = false;
18969
+ }
18970
+ if (renew && finished) {
18971
+ key = await paymentRequestKeyLifecycle(`invoice-request:${actorId}`, intent);
18972
+ result = await run(key.key, () => {
18973
+ prepared = true;
18974
+ });
18975
+ await key.finish(!result.ok && isFinalPaymentRequestError(result.error)).catch(() => void 0);
18976
+ }
18977
+ return result;
18978
+ } catch (cause) {
18979
+ return {
18980
+ ok: false,
18981
+ error: asCapxulError(cause)
18982
+ };
18983
+ } finally {
18984
+ await key?.finish(false).catch(() => void 0);
18985
+ }
18986
+ }
18987
+ //#endregion
18470
18988
  //#region src/requests/checkout-payments.ts
18471
18989
  const missing$1 = async () => ({
18472
18990
  ok: false,
@@ -18656,72 +19174,96 @@ function makeCheckoutMethods(deps) {
18656
19174
  }
18657
19175
  //#endregion
18658
19176
  //#region src/requests/inbox-payments.ts
18659
- function mapApprovedInboxPayment(command, input) {
19177
+ const refused = () => ({
19178
+ ok: false,
19179
+ error: Errors.providerError("convex", inboxes.approve.name, "approved Payment read does not match its command")
19180
+ });
19181
+ /** Read the approved command's actual Payment under the payer's existing scope. */
19182
+ async function readApprovedInboxPayment(calls, command, controls, current) {
18660
19183
  const item = command.items[0];
18661
- if (item === void 0 || item.operation !== "send" && item.operation !== "create_commitment") return {
19184
+ const cancelled = {
18662
19185
  ok: false,
18663
- error: Errors.providerError("convex", inboxes.approve.name, "reply has no payment birth item")
19186
+ error: Errors.cancelled({ operation: inboxes.approve.name })
18664
19187
  };
18665
- try {
18666
- const asset = CONFIGURED_MONEY_ASSETS.find((candidate) => candidate.tokenAddress.toLowerCase() === item.tokenAddress.toLowerCase());
18667
- if (asset === void 0) return {
18668
- ok: false,
18669
- error: Errors.providerError("convex", inboxes.approve.name, "prepared payment asset is not configured")
18670
- };
18671
- const amount = {
18672
- asset: asset.assetId,
18673
- value: formatUnits(BigInt(item.operation === "send" ? item.rawAmount : item.totalAmount), asset.decimals)
18674
- };
18675
- const zero = {
18676
- ...amount,
18677
- value: "0"
18678
- };
18679
- const timing = input.timing ?? { kind: "instant" };
18680
- return {
18681
- ok: true,
18682
- value: {
18683
- id: item.paymentId,
18684
- status: timing.kind === "instant" ? "pending" : timing.kind === "scheduled" ? "scheduled" : "streaming",
18685
- amount,
18686
- paymentType: "invoice",
18687
- direction: "out",
18688
- counterpartyLabel: item.recipientSafe,
18689
- receipt: null,
18690
- recipient: {
18691
- kind: "external_address",
18692
- label: item.recipientSafe
18693
- },
18694
- documents: [],
18695
- timing,
18696
- released: zero,
18697
- availableToClaim: zero,
18698
- createdAt: 0,
18699
- updatedAt: 0
18700
- }
18701
- };
18702
- } catch (cause) {
18703
- return {
18704
- ok: false,
18705
- error: Errors.unknown(cause)
18706
- };
18707
- }
19188
+ if (command.items.length !== 1 || item === void 0 || item.operation !== "send" && item.operation !== "create_commitment") return refused();
19189
+ if (!current()) return cancelled;
19190
+ const check = (payment) => {
19191
+ if (!current()) return cancelled;
19192
+ if (payment === null || payment.id !== item.paymentId || payment.direction !== "out") return refused();
19193
+ try {
19194
+ const amount = toExactAssetAmount(payment.amount, CONFIGURED_MONEY_ASSETS);
19195
+ const asset = CONFIGURED_MONEY_ASSETS.find((row) => row.assetId === amount.asset);
19196
+ const instruction = payment.documents.find((document) => document.role === "instruction");
19197
+ const expected = command.instructionDocuments?.[0];
19198
+ if (asset?.tokenAddress.toLowerCase() !== item.tokenAddress.toLowerCase() || amount.minorUnits !== (item.operation === "send" ? item.rawAmount : item.totalAmount) || instruction?.documentHash !== item.documentHash || expected !== void 0 && (instruction.contentHash !== expected.contentHash || instruction.format !== expected.format) || payment.status === "settled" && payment.receipt?.chainId !== command.chainId) return refused();
19199
+ return {
19200
+ ok: true,
19201
+ value: normalizePaymentTiming(payment)
19202
+ };
19203
+ } catch (cause) {
19204
+ return {
19205
+ ok: false,
19206
+ error: Errors.unknown(cause)
19207
+ };
19208
+ }
19209
+ };
19210
+ const actor = calls.actor;
19211
+ const result = actor.kind === "account" ? await calls.bookChecked(records.get, { paymentId: item.paymentId }, controls, check) : await calls.bookChecked(records.getForOrganization, {
19212
+ orgId: actor.orgId,
19213
+ paymentId: item.paymentId
19214
+ }, controls, (response) => response.orgId === actor.orgId ? check(response.payment) : refused());
19215
+ return current() ? result : cancelled;
18708
19216
  }
18709
19217
  //#endregion
18710
19218
  //#region src/requests/inboxes.ts
18711
19219
  function makeInboxMethods(calls) {
18712
- const { actor, convexCall, deps, observeContactScope, book, bookChecked } = calls;
19220
+ const { actor, convexCall, deps, observeContactScope, book } = calls;
18713
19221
  return {
18714
19222
  paymentTerms: (requestId, options) => book(inboxes.paymentTerms, {
18715
19223
  actor,
18716
19224
  paymentRequestId: requestId
18717
19225
  }, options, (terms) => terms),
18718
19226
  list: (options) => book(inboxes.listCurrent, { actor }, options, (items) => mapPage(items, mapInboxItem)),
18719
- approve: (input, options) => bookChecked(inboxes.approve, {
18720
- actor,
18721
- paymentRequestId: input.requestId,
18722
- ...input.timing === void 0 ? {} : { timing: input.timing },
18723
- ...input.permissionId === void 0 ? {} : { permissionId: input.permissionId }
18724
- }, options, (prepared) => mapApprovedInboxPayment(prepared, input)),
19227
+ approve: async (providedInput, options) => {
19228
+ const input = structuredClone(providedInput);
19229
+ const identity = deps.identityActor;
19230
+ const lifetime = identity?.authLifetime();
19231
+ const current = () => identity === void 0 || lifetime !== void 0 && identity.matchesAuthLifetime(lifetime, lifetime.authUserId);
19232
+ const cancelled = {
19233
+ ok: false,
19234
+ error: Errors.cancelled({ operation: inboxes.approve.name })
19235
+ };
19236
+ const controls = deps.invocationControls?.(options) ?? options;
19237
+ const approve = async (requestKey) => {
19238
+ if (!current()) return cancelled;
19239
+ const prepared = await book(inboxes.approve, {
19240
+ actor,
19241
+ paymentRequestId: input.requestId,
19242
+ ...requestKey === void 0 ? {} : { requestKey },
19243
+ ...input.timing === void 0 ? {} : { timing: input.timing },
19244
+ ...input.permissionId === void 0 ? {} : { permissionId: input.permissionId }
19245
+ }, controls, (value) => value);
19246
+ if (!current()) return cancelled;
19247
+ if (!prepared.ok) return prepared;
19248
+ return readApprovedInboxPayment(calls, prepared.value, controls, current);
19249
+ };
19250
+ const terms = await book(inboxes.paymentTerms, {
19251
+ actor,
19252
+ paymentRequestId: input.requestId
19253
+ }, controls, (value) => value);
19254
+ if (!current()) return cancelled;
19255
+ if (!terms.ok) return terms;
19256
+ if (terms.value.instruction.kind !== "invoice") return approve(input.requestKey);
19257
+ return withInvoiceRequestKey(lifetime?.authUserId ?? "signed-out", {
19258
+ ...terms.value,
19259
+ payer: actor.kind === "account" ? { kind: "account" } : {
19260
+ kind: "organization",
19261
+ orgId: actor.orgId
19262
+ },
19263
+ permissionId: input.permissionId,
19264
+ release: input.timing ?? { kind: "instant" }
19265
+ }, input.requestKey, (key) => approve(key));
19266
+ },
18725
19267
  fulfill: (input, options) => {
18726
19268
  const onPrepared = options?.onPrepared;
18727
19269
  const decoded = Schema.decodeResult(RequestPaymentConfirmationSchema, { onExcessProperty: "error" })(input);
@@ -18744,20 +19286,26 @@ function makeInboxMethods(calls) {
18744
19286
  const controls = deps.invocationControls?.(options) ?? options;
18745
19287
  return runCapxulEffect(Effect.gen(function* () {
18746
19288
  const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
18747
- return yield* awaitCapxulResult(() => executeRequestPayment({
19289
+ const run = (named, prepared) => executeRequestPayment({
18748
19290
  actor: identityActor,
18749
19291
  chainId,
18750
19292
  signer,
18751
19293
  convexCall,
18752
19294
  runPromise: deps.runPromise,
18753
19295
  ...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
18754
- }, confirmation, carryInvocationParentSpan(controls, parent), onPrepared === void 0 ? void 0 : async (paymentIds) => {
18755
- await onPrepared({ paymentIds });
19296
+ }, named, carryInvocationParentSpan(controls, parent), async (paymentIds) => {
19297
+ prepared();
19298
+ await onPrepared?.({ paymentIds });
18756
19299
  return {
18757
19300
  ok: true,
18758
19301
  value: void 0
18759
19302
  };
18760
- }));
19303
+ });
19304
+ const { requestKey, ...intent } = confirmation;
19305
+ return yield* awaitCapxulResult(() => confirmation.instruction.kind !== "invoice" ? run(confirmation, () => void 0) : withInvoiceRequestKey(identityActor.authSession()?.authUserId ?? "signed-out", intent, requestKey, (key, prepared) => run({
19306
+ ...confirmation,
19307
+ requestKey: key
19308
+ }, prepared)));
18761
19309
  }).pipe(Effect.tap(() => observeContactScope)), controls, CAPXUL_OPERATIONS.inbox.fulfill, deps.runPromise);
18762
19310
  },
18763
19311
  decline: (requestId, options) => book(inboxes.decline, {
@@ -19683,7 +20231,7 @@ function makePersonalPay(deps) {
19683
20231
  };
19684
20232
  }
19685
20233
  release(false);
19686
- await finishQuietly(requestKey, submitted.ok || flight.requestState.resolved);
20234
+ await finishQuietly(requestKey, submitted.ok || flight.requestState.resolved || isFinalPaymentRequestError(submitted.error));
19687
20235
  return mapOk(submitted, (value) => normalizePaymentTiming(value.payment));
19688
20236
  };
19689
20237
  }
@@ -19760,6 +20308,7 @@ function makePaymentsMethods(deps) {
19760
20308
  createCommitment: (input, options) => pay(input, options),
19761
20309
  claim: (paymentId, options) => runLifecycle({
19762
20310
  kind: "claim",
20311
+ requestKey: options?.requestKey ?? `pay_${crypto.randomUUID()}`,
19763
20312
  paymentId
19764
20313
  }, deps.invocationControls?.(options) ?? options, CAPXUL_OPERATIONS.payments.claim),
19765
20314
  list: (options) => {
@@ -19772,6 +20321,7 @@ function makePaymentsMethods(deps) {
19772
20321
  },
19773
20322
  cancel: (paymentId, options) => runLifecycle({
19774
20323
  kind: "cancel",
20324
+ requestKey: options?.requestKey ?? `pay_${crypto.randomUUID()}`,
19775
20325
  paymentId
19776
20326
  }, deps.invocationControls?.(options) ?? options, CAPXUL_OPERATIONS.payments.cancel),
19777
20327
  redirect: async (input, options) => {
@@ -19780,6 +20330,7 @@ function makePaymentsMethods(deps) {
19780
20330
  if (!recipient.ok) return runCapxulEffect(Effect.fail(recipient.error), observationOnlyControls(controls), CAPXUL_OPERATIONS.payments.redirect, deps.runPromise);
19781
20331
  return runLifecycle({
19782
20332
  kind: "redirect",
20333
+ requestKey: options?.requestKey ?? `pay_${crypto.randomUUID()}`,
19783
20334
  paymentId: input.paymentId,
19784
20335
  recipient: recipient.value
19785
20336
  }, controls, CAPXUL_OPERATIONS.payments.redirect);
@@ -20033,7 +20584,7 @@ async function executeOrganizationBatch(scope, input, signal, operation, control
20033
20584
  }
20034
20585
  release(false);
20035
20586
  try {
20036
- await requestKey.finish(result.ok || flight.requestState.resolved);
20587
+ await requestKey.finish(result.ok || flight.requestState.resolved || isFinalPaymentRequestError(result.error));
20037
20588
  } catch {}
20038
20589
  const normalized = mapOk(result, (value) => value.payments.map((payment) => normalizePaymentTiming(payment)));
20039
20590
  if (!normalized.ok) return normalized;
@@ -20134,7 +20685,8 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
20134
20685
  },
20135
20686
  cancel: (paymentId, options) => ownerLifecycle({
20136
20687
  kind: "cancel",
20137
- paymentId
20688
+ paymentId,
20689
+ requestKey: options?.requestKey ?? `pay_${crypto.randomUUID()}`
20138
20690
  }, deps.invocationControls?.(options) ?? options, CAPXUL_OPERATIONS.organizationPayments.cancel),
20139
20691
  redirect: (input, options) => {
20140
20692
  const controls = deps.invocationControls?.(options) ?? options;
@@ -20142,7 +20694,8 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
20142
20694
  return recipient.ok ? ownerLifecycle({
20143
20695
  kind: "redirect",
20144
20696
  paymentId: input.paymentId,
20145
- recipient: recipient.value
20697
+ recipient: recipient.value,
20698
+ requestKey: options?.requestKey ?? `pay_${crypto.randomUUID()}`
20146
20699
  }, controls, CAPXUL_OPERATIONS.organizationPayments.redirect) : runCapxulEffect(Effect.fail(recipient.error), observationOnlyControls(controls), CAPXUL_OPERATIONS.organizationPayments.redirect, deps.runPromise);
20147
20700
  },
20148
20701
  payBatch: (input, options) => {
@@ -20762,6 +21315,46 @@ function makeAccountMethods(deps) {
20762
21315
  };
20763
21316
  }
20764
21317
  //#endregion
21318
+ //#region src/accounts/approval-rules.ts
21319
+ const IN_FLIGHT = /* @__PURE__ */ new Set([
21320
+ "pending",
21321
+ "settling",
21322
+ "in_transit"
21323
+ ]);
21324
+ /** A Payment the chain has not decided yet. */
21325
+ function inFlight(payment) {
21326
+ return IN_FLIGHT.has(payment.status);
21327
+ }
21328
+ /**
21329
+ * The operation the approval describes is the one its digest signs: the
21330
+ * SafeOp digest of its UserOperation on this client's chain, and the
21331
+ * execution that digest names. Anything else is refused before the key signs.
21332
+ */
21333
+ function describedOperation(approval, chainId) {
21334
+ const { operation, summary } = approval;
21335
+ if (chainId !== void 0 && summary.network.chainId !== chainId) return Errors.invalidInput("approval", "the approval is for another chain");
21336
+ try {
21337
+ const digest = moneySafeOpDigest(operation.userOperation, summary.network.chainId);
21338
+ if (digest.toLowerCase() === operation.digest.toLowerCase() && matchesMoneyExecutionId(operation.executionId, digest, operation.commandId)) return void 0;
21339
+ } catch {}
21340
+ return Errors.invalidInput("approval", "the operation does not match the digest it asks to sign");
21341
+ }
21342
+ /** Wait, unless the caller gives up first. False when aborted. */
21343
+ function sleep(ms, signal) {
21344
+ if (signal?.aborted === true) return Promise.resolve(false);
21345
+ return new Promise((resolve) => {
21346
+ const timer = setTimeout(() => {
21347
+ signal?.removeEventListener("abort", onAbort);
21348
+ resolve(true);
21349
+ }, ms);
21350
+ const onAbort = () => {
21351
+ clearTimeout(timer);
21352
+ resolve(false);
21353
+ };
21354
+ signal?.addEventListener("abort", onAbort, { once: true });
21355
+ });
21356
+ }
21357
+ //#endregion
20765
21358
  //#region src/accounts/organization-approvals.ts
20766
21359
  /** The Organization Payment prepared for `signerAddress` and checked, before any approval. */
20767
21360
  async function prepareVerifiedOrganizationPayment(deps, input, signerAddress, signal) {
@@ -20854,58 +21447,6 @@ async function checkedBankApproval(deps, input, opened) {
20854
21447
  });
20855
21448
  }
20856
21449
  //#endregion
20857
- //#region src/accounts/approval-rules.ts
20858
- const IN_FLIGHT = /* @__PURE__ */ new Set([
20859
- "pending",
20860
- "settling",
20861
- "in_transit"
20862
- ]);
20863
- /** A Payment the chain has not decided yet. */
20864
- function inFlight(payment) {
20865
- return IN_FLIGHT.has(payment.status);
20866
- }
20867
- /**
20868
- * The approved operation is not sent yet: the approval is approved, or it was
20869
- * consumed but a Payment is still `pending` (a recorded send moves it to
20870
- * `settling`), so the send did not land.
20871
- */
20872
- function unsent(approval, payments) {
20873
- return approval.state === "approved" || approval.state === "consumed" && payments.some((payment) => payment.status === "pending");
20874
- }
20875
- /** The send was refused because another send of the same operation holds its claim. */
20876
- function anotherSendInFlight(error) {
20877
- return error.code === "SUPERSEDED" && error.details?.reason === "unobservable-claim";
20878
- }
20879
- /**
20880
- * The operation the approval describes is the one its digest signs: the
20881
- * SafeOp digest of its UserOperation on this client's chain, and the
20882
- * execution that digest names. Anything else is refused before the key signs.
20883
- */
20884
- function describedOperation(approval, chainId) {
20885
- const { operation, summary } = approval;
20886
- if (chainId !== void 0 && summary.network.chainId !== chainId) return Errors.invalidInput("approval", "the approval is for another chain");
20887
- try {
20888
- const digest = moneySafeOpDigest(operation.userOperation, summary.network.chainId);
20889
- if (digest.toLowerCase() === operation.digest.toLowerCase() && operation.executionId === `money_execution_${digest.slice(2).toLowerCase()}`) return void 0;
20890
- } catch {}
20891
- return Errors.invalidInput("approval", "the operation does not match the digest it asks to sign");
20892
- }
20893
- /** Wait, unless the caller gives up first. False when aborted. */
20894
- function sleep(ms, signal) {
20895
- if (signal?.aborted === true) return Promise.resolve(false);
20896
- return new Promise((resolve) => {
20897
- const timer = setTimeout(() => {
20898
- signal?.removeEventListener("abort", onAbort);
20899
- resolve(true);
20900
- }, ms);
20901
- const onAbort = () => {
20902
- clearTimeout(timer);
20903
- resolve(false);
20904
- };
20905
- signal?.addEventListener("abort", onAbort, { once: true });
20906
- });
20907
- }
20908
- //#endregion
20909
21450
  //#region ../protocol/src/payroll/model.ts
20910
21451
  function toPayrollRunId(raw) {
20911
21452
  return toNonEmptyStringBrand(raw, "payrollRunId", (value) => isNonEmptyString(value));
@@ -21367,7 +21908,8 @@ function lifecycleIntent(input) {
21367
21908
  ok: true,
21368
21909
  value: {
21369
21910
  kind: "cancel",
21370
- paymentId: input.cancel
21911
+ paymentId: input.cancel,
21912
+ requestKey: input.requestKey ?? `pay_${crypto.randomUUID()}`
21371
21913
  }
21372
21914
  };
21373
21915
  const recipient = normalizeTargetForBackend(input.to, "to");
@@ -21376,7 +21918,8 @@ function lifecycleIntent(input) {
21376
21918
  value: {
21377
21919
  kind: "redirect",
21378
21920
  paymentId: input.redirect,
21379
- recipient: recipient.value
21921
+ recipient: recipient.value,
21922
+ requestKey: input.requestKey ?? `pay_${crypto.randomUUID()}`
21380
21923
  }
21381
21924
  } : recipient;
21382
21925
  }
@@ -21408,10 +21951,19 @@ async function prepareVerifiedRequestPayment(deps, input, signerAddress, signal)
21408
21951
  error: Errors.invalidInput("confirmation", "invalid request confirmation")
21409
21952
  };
21410
21953
  const confirmation = decoded.success;
21411
- return checked(deps, signerAddress, await runIfActive(signal, commands$1.prepareRequest.name, () => callOperation(deps.convexCall, commands$1.prepareRequest, {
21412
- confirmation,
21413
- signerAddress
21414
- }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise), requestPaymentCheck(confirmation), false);
21954
+ const run = async (named, prepared) => {
21955
+ const result = await runIfActive(signal, commands$1.prepareRequest.name, () => callOperation(deps.convexCall, commands$1.prepareRequest, {
21956
+ confirmation: named,
21957
+ signerAddress
21958
+ }).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
21959
+ if (result.ok) prepared();
21960
+ return checked(deps, signerAddress, result, requestPaymentCheck(named), false);
21961
+ };
21962
+ const { requestKey, ...intent } = confirmation;
21963
+ return confirmation.instruction.kind !== "invoice" ? run(confirmation, () => void 0) : withInvoiceRequestKey(deps.actor?.authSession()?.authUserId ?? "signed-out", intent, requestKey, (key, prepared) => run({
21964
+ ...confirmation,
21965
+ requestKey: key
21966
+ }, prepared));
21415
21967
  }
21416
21968
  /** One payroll run: the run the backend writes and the batch that pays it, checked together. */
21417
21969
  async function prepareVerifiedPayrollRun(deps, input, signerAddress, signal) {
@@ -21506,7 +22058,7 @@ function makeApprovalsMethods(deps) {
21506
22058
  const signal = options?.signal;
21507
22059
  if (isCommandApproval(input)) return openApproval(signal, (signerAddress) => prepareVerifiedCommand(deps, input, signerAddress, signal));
21508
22060
  if (isPermissionChange(input)) return openApproval(signal, async (signerAddress) => {
21509
- const { prepareVerifiedPermissionChange } = await import("./permission-approvals-tXIk7kNA.mjs");
22061
+ const { prepareVerifiedPermissionChange } = await import("./permission-approvals-B2LrXyRx.mjs");
21510
22062
  return prepareVerifiedPermissionChange(deps, input, signerAddress, signal);
21511
22063
  });
21512
22064
  if ("organizationId" in input) return checkedBankApproval(deps, input, await openApproval(signal, (signerAddress) => prepareVerifiedOrganizationPayment(deps, input, signerAddress, signal)));
@@ -21603,43 +22155,33 @@ function makeApprovalsMethods(deps) {
21603
22155
  };
21604
22156
  /**
21605
22157
  * One read of the approval: its outcome when it has ended, or null to read
21606
- * again. The Payments are read before anything is sent, so a send is never
21607
- * made for Payments this caller cannot follow.
22158
+ * again. This path only reads. The backend owns submission and recovery.
21608
22159
  */
21609
22160
  const step = async (approvalId, signal, organizationId) => {
21610
- const read = await call(approvals.get.name, approvals.get, { approvalId }, signal);
22161
+ const read = await call(approvals.observe.name, approvals.observe, { approvalId }, signal);
21611
22162
  if (!read.ok) return read;
21612
- const approval = read.value;
22163
+ const { approval, completed } = read.value;
21613
22164
  if (approval.state === "pending") return {
21614
22165
  ok: true,
21615
22166
  value: null
21616
22167
  };
21617
- if (endsOnceSent(approval)) {
21618
- if (approval.state !== "approved" && approval.state !== "consumed") return {
21619
- ok: true,
21620
- value: {
21621
- approval,
21622
- payments: []
21623
- }
21624
- };
21625
- const sent = await submit(approvalId);
21626
- return sent.ok || !anotherSendInFlight(sent.error) ? sent : {
21627
- ok: true,
21628
- value: null
21629
- };
21630
- }
22168
+ const closed = approval.state === "rejected" || approval.state === "expired";
22169
+ if (!closed && !completed) return {
22170
+ ok: true,
22171
+ value: null
22172
+ };
22173
+ if (!movesMoney(approval)) return {
22174
+ ok: true,
22175
+ value: {
22176
+ approval,
22177
+ payments: []
22178
+ }
22179
+ };
21631
22180
  const payments = await readApprovalPayments(deps, approval.operation.paymentIds, organizationId ?? (approval.actor.kind === "organization" ? approval.actor.orgId : void 0), signal);
21632
22181
  if (!payments.ok) return payments;
21633
- if (unsent(approval, payments.value)) {
21634
- const sent = await submit(approvalId);
21635
- return sent.ok || anotherSendInFlight(sent.error) ? {
21636
- ok: true,
21637
- value: null
21638
- } : sent;
21639
- }
21640
22182
  return {
21641
22183
  ok: true,
21642
- value: approval.state !== "consumed" || !payments.value.some(inFlight) ? {
22184
+ value: closed || endsOnceSent(approval) || !payments.value.some(inFlight) ? {
21643
22185
  approval,
21644
22186
  payments: payments.value
21645
22187
  } : null
@@ -22317,7 +22859,7 @@ function decodeStatus(body) {
22317
22859
  */
22318
22860
  const HEADS = {
22319
22861
  transfer: "select \"id\", \"chain_id\", \"tx_hash\", \"transaction_log_ordinal\", \"log_index\", \"block_number\", \"block_hash\", \"timestamp\", \"asset_id\", \"token\", \"from\", \"to\", \"amount\" from \"transfer\" where (\"transfer\".\"from\" = $1 or \"transfer\".\"to\" = $2) order by \"transfer\".\"block_number\" desc, \"transfer\".\"id\" desc",
22320
- payment: "select \"id\", \"chain_id\", \"tx_hash\", \"transaction_log_ordinal\", \"log_index\", \"block_number\", \"block_hash\", \"timestamp\", \"contract\", \"settlement_id\", \"sender\", \"recipient\", \"asset_id\", \"token\", \"amount\", \"kind\", \"document_hash\" from \"payment\" where (\"payment\".\"sender\" = $1 or \"payment\".\"recipient\" = $2) order by \"payment\".\"block_number\" desc, \"payment\".\"id\" desc",
22862
+ payment: "select \"id\", \"chain_id\", \"tx_hash\", \"transaction_log_ordinal\", \"log_index\", \"block_number\", \"block_hash\", \"timestamp\", \"contract\", \"settlement_id\", \"sender\", \"recipient\", \"asset_id\", \"token\", \"amount\", \"kind\", \"document_hash\", \"job_nonce\", \"executor\" from \"payment\" where (\"payment\".\"sender\" = $1 or \"payment\".\"recipient\" = $2) order by \"payment\".\"block_number\" desc, \"payment\".\"id\" desc",
22321
22863
  balance: "select \"chain_id\", \"asset_id\", \"to\", \"amount\" from \"balance\" where \"balance\".\"to\" = $1"
22322
22864
  };
22323
22865
  /** How many times the statement binds the Safe address. */
@@ -22360,7 +22902,7 @@ function ponderQuery(table, input) {
22360
22902
  input.limit
22361
22903
  ];
22362
22904
  return {
22363
- sql: `${HEADS.payment.slice(0, HEADS.payment.indexOf("where "))}where (("payment"."sender" = $1 or "payment"."recipient" = $2) and "payment"."settlement_id" in (${input.settlements.map((_, i) => `$${i + 3}`).join(", ")})) limit $${params.length}`,
22905
+ sql: `${HEADS.payment.slice(0, HEADS.payment.indexOf("where ")).replace(" from \"payment\"", ", \"contract\" as \"router\" from \"payment\"")}where (("payment"."sender" = $1 or "payment"."recipient" = $2) and "payment"."settlement_id" in (${input.settlements.map((_, i) => `$${i + 3}`).join(", ")})) limit $${params.length}`,
22364
22906
  params,
22365
22907
  typings: params.map(() => "none")
22366
22908
  };
@@ -24558,4 +25100,4 @@ function executeIdentityProductObservation(telemetry, record, state) {
24558
25100
  return ignoreTransportFailure(() => invocationTelemetry.emit(mapped), "emit", mapped.name).pipe(Effect.andThen(ignoreTransportFailure(after, mapped.name === "auth_signed_out" ? "reset" : "identify", mapped.name)));
24559
25101
  }
24560
25102
  //#endregion
24561
- export { parseAssetAmount as $, hashPermissionReplacementPreview as $n, EXPECTED_OPERATION_OUTCOMES as $r, isSettingUpLifecycle as $t, registerProductTelemetryInvocation as A, toDurationMs as Ai, onboardings as An, toExactAssetAmount as Ar, safe4337MultiSendUserOpCallData as At, makePaymentsMethods as B, FAILURE_MODES$1 as Bi, invitations as Bn, publicIdentityFailure as Br, CAPXUL_SDK_EXPECTED_OUTCOME_EVENT as Bt, AccountReadPortTag as C, AuthClientPortTag as Ci, EXCEPTION_EVENT_NAME as Cn, toPermissionAssignmentId as Cr, SEND_SIGNATURE as Ct, convexCallErrorFromCapxul as D, BrowserAuthCacheAdapter as Di, normalizeCapxulOperation as Dn, currencySymbolFor as Dr, deriveCapxulSafeAddress as Dt, ConvexCallPortTag as E, InMemoryAuthCacheAdapter as Ei, isCapxulOperation as En, ChainIdSchema$1 as Er, TOKENS as Et, decodePayrollRunInput as F, toJwtToken as Fi, PreparedPermissionExecutionSchema as Fn, toWeiAmount as Fr, callOperation as Ft, isCheckoutSettlementConsumed as G, AuthCachePortTag as Gi, workspaces as Gn, runCapxulEffect as Gr, withCapturedAttemptContext as Gt, makeDestinationsMethods as H, isRecord as Hi, roles as Hn, runPortEffect as Hr, observeFailedResult as Ht, toPayrollGroupId as I, toSessionToken as Ii, PermissionCommandViewSchema as In, absurd as Ir, asCapxulError as It, subscribeFreshQuery as J, ORGANIZATION_SETUP_STATUSES as Jn, defectAsCapxulError as Jr, normalizeExceptionErrorKind as Jt, makeTargetsMethods as K, OrganizationSetupSchema as Kn, withVerifiedOrganizationScope as Kr, EXCEPTION_MESSAGE as Kt, makeAccountMethods as L, Errors as Li, PayrollGroupIdSchema as Ln, reference as Lr, toPublicError$1 as Lt, makeApprovalsMethods as M, toEpochSeconds as Mi, commands as Mn, isEvmAddress as Mr, BASE_SEPOLIA_CHAIN_ID as Mt, makePayrollMethods as N, toAuthUserId as Ni, configurations as Nn, toAddress as Nr, MULTI_SEND_CALL_ONLY as Nt, retryIdempotentRead as O, parseAuthSession as Oi, OPERATIONS as On, toAssetId as Or, normalizeSafeSaltEmail as Ot, makeUnavailablePayrollMethods as P, toEmail as Pi, replacements as Pn, toChainId as Pr, SAFE_SENTINEL_OWNERS as Pt, formatAssetAmount as Q, InvitationViewSchema as Qn, CAPXUL_ERROR_CODES as Qr, version as Qt, annotateDepositInstructions as R, CapxulError as Ri, PayrollGroupInputSchema as Rn, makeAuthMethods as Rr, failureDetail as Rt, valueIn as S, AuthClientError as Si, CLI_INVOCATION_KINDS as Sn, toBudgetId as Sr, SEND_BATCH_SIGNATURE as St, TelemetryPortTag as T, globalLocalStorage as Ti, CAPXUL_OPERATIONS as Tn, toRoleKey as Tr, CONFIGURED_MONEY_ASSETS as Tt, makeActorRelationshipMethods as U, readField as Ui, setups as Un, sessionFromActor as Ur, observeSdkClient as Ut, waitForPaymentSubmission as V, isFailureMode as Vi, members as Vn, runIdentityFacade as Vr, postHogFailureObservation as Vt, makeCheckoutMethods as W, AuthCacheError as Wi, treasuries as Wn, observationOnlyControls as Wr, observationContextProps as Wt, assetAmountFromRaw as X, decodeChainCause as Xn, toCapxulResult as Xr, projectSdkException as Xt, abandonPrepared as Y, CHAIN_UPSTREAMS as Yn, runIfActive as Yr, normalizeExceptionOperation as Yt, assetSymbolFor as Z, toOrgId as Zn, formatTraceparent as Zr, safeExceptionLabel as Zt, accountFromAccountPositions as _, isCredentialField as _i, validateHandle as _n, toLowerHex as _r, ROLES_SET_ALLOWANCE_ABI as _t, paymentPhase as a, ClockError as ai, openfortSignerNotReadyCode as an, roleKeyForPermission as ar, fingerprintPaymentIntent as at, MONEY_READ_RATES as b, toPublishableKey as bi, CLI_CAPABILITIES as bn, DurationMsSchema$1 as br, ROLE_MANAGEMENT_SIGNATURES as bt, makePaymentDocumentsMethods as c, BetterAuthNodeLayer as ci, resolveFailureMode as cn, images as cr, resolveOrgPermissionIdentity as ct, SmartAccountPortTag as d, attachInvocationObservation as di, toCountryCode as dn, toAccountId as dr, MULTI_SEND_SELECTOR as dt, ActorFailure as ei, UNOBSERVABLE_SIGNER_STATUS as en, decodePermissionIntent as er, requireAsset as et, smartAccountErrorFromCapxul as f, copyInvocationObservation as fi, toKycTier as fn, PaymentDocumentOptionsSchema as fr, OPERATOR as ft, ConvexAccountLayer as g, redactUrlSecrets as gi, toPartyId as gn, toLowerBytes32 as gr, ROLES_EXEC_TRANSACTION_WITH_ROLE_ABI as gt, makeAccountsMethods as h, redactSecrets as hi, toHandle as hn, toLowerAddress as hr, ROLES_ASSIGN_ROLES_ABI as ht, inboxPhase as i, SystemClockLayer as ii, isSignerNotReadySignal as in, ORG_BUDGET_ACTIONS as ir, canonicalJson as it, wireChainId as j, toEpochMs as ji, authorities as jn, EVM_ADDRESS_RE$1 as jr, buildSafeMultiSendExecTransactionCall as jt, bindProductTelemetryInvocation as k, parseCachedJwt as ki, details as kn, toCurrencyCode as kr, safe4337ExecuteUserOpCallData as kt, makeSmartAccountMethods as l, BetterAuthBrowserLayer as li, makeCurrentUserMethods as ln, bankDetails as lr, CREATE_COMMITMENT_SIGNATURE as lt, PonderIndexerAdapter as m, sanitizeObservationContext as mi, HANDLE_RE as mn, toExactHex as mr, PARAMETER_TYPE as mt, bootIdentityFlow as n, withInvocationParentSpan as ni, injectedWalletSigner as nn, CurrentPolicySchema as nr, isMoneyParseError as nt, requestPhase as o, ClockPortTag as oi, recoverRawDigestSigner as on, diagnostics as or, moneySafeOpDigest as ot, makeHoldingsMethods as p, readInvocationObservation as pi, toTesterKind as pn, isBytes32 as pr, OWNER_COMMITMENT_SIGNATURES as pt, makeVerificationMethods as q, ORGANIZATION_SETUP_REASONS as qn, awaitCapxulResult as qr, SDK_VERSION as qt, makeMeMethods as r, oauthBearerAuthClient as ri, isEcdsaSignatureHex as rn, MONTHLY_REFILL_PERIOD_SECONDS as rr, parseMoney as rt, makeActivityMethods as s, readClockNow as si, signerFailure as sn, AppIdSchema$1 as sr, ZODIAC_MODULE_PROXY_FACTORY as st, executeIdentityProductObservation as t, carryInvocationParentSpan as ti, causeChain as tn, keepRefillOnChange as tr, toRaw as tt, ConvexSmartAccountLayer as u, observationRequestHeaders as ui, makeClientRequestMethods as un, deposits as ur, MODULE_PROXY_FACTORY_ABI as ut, accountPositionsFromWire as v, toAllowedOrigin as vi, redactTelemetryEvent as vn, PAYMENT_DIRECTIONS as vr, ROLES_SET_TRANSACTION_UNWRAPPER_ABI as vt, accountReadErrorFromCapxul as w, detectAuthCacheAdapter as wi, stampTelemetryEnvelope as wn, toPermissionId as wr, CAPXUL_PAYMENTS_V2_ADDRESS as wt, valueActivitySummary as x, authClientPortFromPromiseAdapter as xi, CLI_COMMAND_NAMES as xn, EpochMsSchema$1 as xr, SAFE_ENABLE_MODULE_ABI as xt, positionPeg as y, toAppId as yi, redactTelemetryProps as yn, PAYMENT_STATUSES as yr, ROLES_SET_UP_ABI as yt, makeOrganizationPaymentsMethods as z, isCapxulError as zi, FixedOfferDraftSchema as zn, askIdentity as zr, failureEvidenceProps as zt };
25103
+ export { parseAssetAmount as $, InvitationViewSchema as $n, CAPXUL_ERROR_CODES as $r, version as $t, registerProductTelemetryInvocation as A, parseCachedJwt as Ai, details as An, toCurrencyCode as Ar, buildSafeMultiSendExecTransactionCall as At, makePaymentsMethods as B, isCapxulError as Bi, FixedOfferDraftSchema as Bn, askIdentity as Br, failureEvidenceProps as Bt, AccountReadPortTag as C, AuthClientError as Ci, CLI_INVOCATION_KINDS as Cn, toBudgetId as Cr, SEND_SIGNATURE as Ct, convexCallErrorFromCapxul as D, InMemoryAuthCacheAdapter as Di, isCapxulOperation as Dn, ChainIdSchema$1 as Dr, normalizeSafeSaltEmail as Dt, ConvexCallPortTag as E, globalLocalStorage as Ei, CAPXUL_OPERATIONS as En, toRoleKey as Er, deriveCapxulSafeAddress as Et, decodePayrollRunInput as F, toEmail as Fi, replacements as Fn, toChainId as Fr, CONFIGURED_MONEY_ASSETS as Ft, isCheckoutSettlementConsumed as G, AuthCacheError as Gi, treasuries as Gn, observationOnlyControls as Gr, observationContextProps as Gt, makeDestinationsMethods as H, isFailureMode as Hi, members as Hn, runIdentityFacade as Hr, postHogFailureObservation as Ht, toPayrollGroupId as I, toJwtToken as Ii, PreparedPermissionExecutionSchema as In, toWeiAmount as Ir, TOKENS as It, subscribeFreshQuery as J, ORGANIZATION_SETUP_REASONS as Jn, awaitCapxulResult as Jr, SDK_VERSION as Jt, makeTargetsMethods as K, AuthCachePortTag as Ki, workspaces as Kn, runCapxulEffect as Kr, withCapturedAttemptContext as Kt, makeAccountMethods as L, toSessionToken as Li, PermissionCommandViewSchema as Ln, absurd as Lr, asCapxulError as Lt, makeApprovalsMethods as M, toEpochMs as Mi, authorities as Mn, EVM_ADDRESS_RE$1 as Mr, MULTI_SEND_CALL_ONLY as Mt, makePayrollMethods as N, toEpochSeconds as Ni, commands as Nn, isEvmAddress as Nr, SAFE_SENTINEL_OWNERS as Nt, retryIdempotentRead as O, BrowserAuthCacheAdapter as Oi, normalizeCapxulOperation as On, currencySymbolFor as Or, safe4337ExecuteUserOpCallData as Ot, makeUnavailablePayrollMethods as P, toAuthUserId as Pi, configurations as Pn, toAddress as Pr, callOperation as Pt, formatAssetAmount as Q, toOrgId as Qn, formatTraceparent as Qr, safeExceptionLabel as Qt, annotateDepositInstructions as R, Errors as Ri, PayrollGroupIdSchema as Rn, reference as Rr, toPublicError$1 as Rt, valueIn as S, authClientPortFromPromiseAdapter as Si, CLI_COMMAND_NAMES as Sn, EpochMsSchema$1 as Sr, SEND_BATCH_SIGNATURE as St, TelemetryPortTag as T, detectAuthCacheAdapter as Ti, stampTelemetryEnvelope as Tn, toPermissionId as Tr, matchesMoneyExecutionId as Tt, makeActorRelationshipMethods as U, isRecord as Ui, roles as Un, runPortEffect as Ur, observeFailedResult as Ut, waitForPaymentSubmission as V, FAILURE_MODES$1 as Vi, invitations as Vn, publicIdentityFailure as Vr, CAPXUL_SDK_EXPECTED_OUTCOME_EVENT as Vt, makeCheckoutMethods as W, readField as Wi, setups as Wn, sessionFromActor as Wr, observeSdkClient as Wt, assetAmountFromRaw as X, CHAIN_UPSTREAMS as Xn, runIfActive as Xr, normalizeExceptionOperation as Xt, abandonPrepared as Y, ORGANIZATION_SETUP_STATUSES as Yn, defectAsCapxulError as Yr, normalizeExceptionErrorKind as Yt, assetSymbolFor as Z, decodeChainCause as Zn, toCapxulResult as Zr, projectSdkException as Zt, accountFromAccountPositions as _, redactUrlSecrets as _i, toPartyId as _n, toLowerBytes32 as _r, ROLES_SET_ALLOWANCE_ABI as _t, paymentPhase as a, SystemClockLayer as ai, isSignerNotReadySignal as an, ORG_BUDGET_ACTIONS as ar, fingerprintPaymentIntent as at, MONEY_READ_RATES as b, toAppId as bi, redactTelemetryProps as bn, PAYMENT_STATUSES as br, ROLE_MANAGEMENT_SIGNATURES as bt, makePaymentDocumentsMethods as c, readClockNow as ci, signerFailure as cn, AppIdSchema$1 as cr, resolveOrgPermissionIdentity as ct, SmartAccountPortTag as d, observationRequestHeaders as di, makeClientRequestMethods as dn, deposits as dr, MULTI_SEND_SELECTOR as dt, EXPECTED_OPERATION_OUTCOMES as ei, isSettingUpLifecycle as en, hashPermissionReplacementPreview as er, requireAsset as et, smartAccountErrorFromCapxul as f, attachInvocationObservation as fi, toCountryCode as fn, toAccountId as fr, OPERATOR as ft, ConvexAccountLayer as g, redactSecrets as gi, toHandle as gn, toLowerAddress as gr, ROLES_EXEC_TRANSACTION_WITH_ROLE_ABI as gt, makeAccountsMethods as h, sanitizeObservationContext as hi, HANDLE_RE as hn, toExactHex as hr, ROLES_ASSIGN_ROLES_ABI as ht, inboxPhase as i, oauthBearerAuthClient as ii, isEcdsaSignatureHex as in, MONTHLY_REFILL_PERIOD_SECONDS as ir, canonicalJson as it, wireChainId as j, toDurationMs as ji, onboardings as jn, toExactAssetAmount as jr, BASE_SEPOLIA_CHAIN_ID as jt, bindProductTelemetryInvocation as k, parseAuthSession as ki, OPERATIONS as kn, toAssetId as kr, safe4337MultiSendUserOpCallData as kt, makeSmartAccountMethods as l, BetterAuthNodeLayer as li, resolveFailureMode as ln, images as lr, CREATE_COMMITMENT_SIGNATURE as lt, PonderIndexerAdapter as m, readInvocationObservation as mi, toTesterKind as mn, isBytes32 as mr, PARAMETER_TYPE as mt, bootIdentityFlow as n, carryInvocationParentSpan as ni, causeChain as nn, keepRefillOnChange as nr, isMoneyParseError as nt, requestPhase as o, ClockError as oi, openfortSignerNotReadyCode as on, roleKeyForPermission as or, moneySafeOpDigest as ot, makeHoldingsMethods as p, copyInvocationObservation as pi, toKycTier as pn, PaymentDocumentOptionsSchema as pr, OWNER_COMMITMENT_SIGNATURES as pt, makeVerificationMethods as q, OrganizationSetupSchema as qn, withVerifiedOrganizationScope as qr, EXCEPTION_MESSAGE as qt, makeMeMethods as r, withInvocationParentSpan as ri, injectedWalletSigner as rn, CurrentPolicySchema as rr, parseMoney as rt, makeActivityMethods as s, ClockPortTag as si, recoverRawDigestSigner as sn, diagnostics as sr, ZODIAC_MODULE_PROXY_FACTORY as st, executeIdentityProductObservation as t, ActorFailure as ti, UNOBSERVABLE_SIGNER_STATUS as tn, decodePermissionIntent as tr, toRaw as tt, ConvexSmartAccountLayer as u, BetterAuthBrowserLayer as ui, makeCurrentUserMethods as un, bankDetails as ur, MODULE_PROXY_FACTORY_ABI as ut, accountPositionsFromWire as v, isCredentialField as vi, validateHandle as vn, toLowerHex as vr, ROLES_SET_TRANSACTION_UNWRAPPER_ABI as vt, accountReadErrorFromCapxul as w, AuthClientPortTag as wi, EXCEPTION_EVENT_NAME as wn, toPermissionAssignmentId as wr, CAPXUL_PAYMENTS_V2_ADDRESS as wt, valueActivitySummary as x, toPublishableKey as xi, CLI_CAPABILITIES as xn, DurationMsSchema$1 as xr, SAFE_ENABLE_MODULE_ABI as xt, positionPeg as y, toAllowedOrigin as yi, redactTelemetryEvent as yn, PAYMENT_DIRECTIONS as yr, ROLES_SET_UP_ABI as yt, makeOrganizationPaymentsMethods as z, CapxulError as zi, PayrollGroupInputSchema as zn, makeAuthMethods as zr, failureDetail as zt };