@capxul/cli 4.20.0-beta.20 → 4.20.0-beta.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.mjs CHANGED
@@ -1343,6 +1343,11 @@ const CAPXUL_OPERATIONS = {
1343
1343
  deactivate: "offers.deactivate"
1344
1344
  },
1345
1345
  checkouts: {
1346
+ request: "checkouts.request",
1347
+ prepareRequest: "checkouts.prepareRequest",
1348
+ requestState: "checkouts.requestState",
1349
+ reconcileRequest: "checkouts.reconcileRequest",
1350
+ prepareRequestRegistered: "checkouts.prepareRequestRegistered",
1346
1351
  invoice: "checkouts.invoice",
1347
1352
  prepareInvoice: "checkouts.prepareInvoice",
1348
1353
  invoiceState: "checkouts.invoiceState",
@@ -14926,6 +14931,7 @@ const PreparedOfferCheckoutExecutionSchema = Schema.Struct({
14926
14931
  });
14927
14932
  /** Link holders receive payment terms, not the private Invoice document. */
14928
14933
  const InvoiceCheckoutSummarySchema = Schema.Struct({
14934
+ documentKind: Schema.optional(Schema.Literals(["memo", "invoice"])),
14929
14935
  linkToken: text$3(128),
14930
14936
  issuerLabel: text$3(256),
14931
14937
  dueAt: InvoiceDraftSchema.fields.dueAt,
@@ -14987,6 +14993,44 @@ const PreparedInvoiceCheckoutExecutionSchema = Schema.Struct({
14987
14993
  ...registeredCheckoutExecutionFields,
14988
14994
  invoice: InvoiceCheckoutSummarySchema
14989
14995
  });
14996
+ /** Generic request checkout uses the same fixed obligation and receipt contract. */
14997
+ const RequestCheckoutSummarySchema = Schema.Struct({
14998
+ ...InvoiceCheckoutSummarySchema.fields,
14999
+ documentKind: Schema.Literals(["memo", "invoice"])
15000
+ });
15001
+ const RequestCheckoutPreparationSchema = Schema.Struct({
15002
+ request: RequestCheckoutSummarySchema,
15003
+ sourceWallet: InvoiceCheckoutPreparationSchema.fields.sourceWallet,
15004
+ allowance: InvoiceCheckoutPreparationSchema.fields.allowance,
15005
+ approval: InvoiceCheckoutPreparationSchema.fields.approval,
15006
+ payment: InvoiceCheckoutPreparationSchema.fields.payment
15007
+ });
15008
+ const RequestCheckoutStateSchema = Schema.Struct({
15009
+ request: RequestCheckoutSummarySchema,
15010
+ verification: InvoiceCheckoutStateSchema.fields.verification,
15011
+ receipt: InvoiceCheckoutStateSchema.fields.receipt,
15012
+ latePayment: InvoiceCheckoutStateSchema.fields.latePayment
15013
+ });
15014
+ const RequestCheckoutReconciliationSchema = Schema.Union([
15015
+ Schema.Struct({
15016
+ status: Schema.Literal("verified"),
15017
+ receipt: CheckoutReceiptSchema,
15018
+ state: RequestCheckoutStateSchema
15019
+ }),
15020
+ Schema.Struct({
15021
+ status: Schema.Literals(["pending", "provider_failure"]),
15022
+ state: RequestCheckoutStateSchema
15023
+ }),
15024
+ Schema.Struct({
15025
+ status: Schema.Literal("mismatch"),
15026
+ code: Schema.String,
15027
+ state: RequestCheckoutStateSchema
15028
+ })
15029
+ ]);
15030
+ const PreparedRequestCheckoutExecutionSchema = Schema.Struct({
15031
+ ...registeredCheckoutExecutionFields,
15032
+ request: RequestCheckoutSummarySchema
15033
+ });
14990
15034
  /** Build a reference URL. The consumer still reads authoritative terms from the backend. */
14991
15035
  function checkoutUrl(frontendOrigin, reference) {
14992
15036
  const origin = new URL(frontendOrigin);
@@ -14998,7 +15042,7 @@ function checkoutUrl(frontendOrigin, reference) {
14998
15042
  if (origin.protocol !== "https:" && !(origin.protocol === "http:" && loopback) || origin.username !== "" || origin.password !== "" || origin.pathname !== "/" || origin.search !== "" || origin.hash !== "") throw new TypeError("Provide an approved frontend origin");
14999
15043
  const id = reference.kind === "offer" ? reference.offerId : reference.linkToken;
15000
15044
  if (!/^[A-Za-z0-9_-]{1,128}$/u.test(id)) throw new TypeError("Invalid checkout reference");
15001
- const route = reference.kind === "offer" ? "offers" : "invoices";
15045
+ const route = reference.kind === "offer" ? "offers" : reference.kind === "request" ? "requests" : "invoices";
15002
15046
  const result = new URL(`/checkout/${route}/${encodeURIComponent(id)}`, origin);
15003
15047
  if (reference.kind === "offer" && reference.quantity !== void 0) {
15004
15048
  if (!Number.isSafeInteger(reference.quantity) || reference.quantity < 1) throw new TypeError("Invalid checkout quantity");
@@ -15124,6 +15168,13 @@ const CAPXUL_FUNCTIONS = {
15124
15168
  state: "financialOps/offerCheckoutSettlement:state",
15125
15169
  reconcile: "financialOps/offerCheckoutSettlement:reconcile"
15126
15170
  },
15171
+ "financialOps/requestCheckouts": {
15172
+ summary: "financialOps/requestCheckouts:summary",
15173
+ prepare: "financialOps/requestCheckouts:prepare",
15174
+ state: "financialOps/requestCheckouts:state",
15175
+ reconcile: "financialOps/requestCheckouts:reconcile",
15176
+ prepareRegistered: "financialOps/requestCheckouts:prepareRegistered"
15177
+ },
15127
15178
  "financialOps/invoiceCheckouts": {
15128
15179
  summary: "financialOps/invoiceCheckouts:summary",
15129
15180
  prepare: "financialOps/invoiceCheckouts:prepare",
@@ -16629,7 +16680,7 @@ function signerFailure(source, operation, cause) {
16629
16680
  }
16630
16681
  //#endregion
16631
16682
  //#region ../../packages/sdk/package.json
16632
- var version$3 = "4.20.0-beta.20";
16683
+ var version$3 = "4.20.0-beta.22";
16633
16684
  //#endregion
16634
16685
  //#region ../../packages/sdk/src/telemetry/exception-projection.ts
16635
16686
  /** Fixed fallback for failures that have no safe message. */
@@ -18900,19 +18951,41 @@ function itemFactsMatch(source, item, observation) {
18900
18951
  if (exact.denomination !== 1 || item.tokenAddress.toLowerCase() !== asset?.tokenAddress.toLowerCase() || (item.operation === "send" ? item.rawAmount : item.totalAmount) !== exact.minorUnits || !operationMatches(source, item) || observation !== void 0 && "to" in source && !recipientMatches$1(source, observation, item.recipientSafe.toLowerCase())) return null;
18901
18952
  return exact;
18902
18953
  }
18954
+ /** Retry keeps the original request instruction. Ordinary Payment retries keep actor context. */
18955
+ function requestRetryInstruction(input) {
18956
+ const request = input.evidence.request;
18957
+ const original = input.evidence.sourceCommand;
18958
+ 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;
18959
+ const document = original.items[input.index]?.document;
18960
+ if (document?.kind !== "envelope") return void 0;
18961
+ const bytes = decodeCanonicalBase64V3(document.bytesBase64);
18962
+ const envelope = decodeSupportedPaymentDocumentEnvelope(bytes);
18963
+ if (envelope.primaryType !== "Memo" && envelope.primaryType !== "Invoice") return void 0;
18964
+ return {
18965
+ documentHash: hashSupportedPaymentDocument(envelope),
18966
+ contentHash: hashPaymentDocumentContentV3(bytes),
18967
+ role: "instruction",
18968
+ kind: envelope.primaryType === "Memo" ? "memo" : "invoice",
18969
+ format: envelope.version === 4 ? "envelope-v4" : "envelope-v3",
18970
+ issuedAt: envelope.message.issuedAt
18971
+ };
18972
+ }
18903
18973
  async function documentContextMatches(input, command, item, bundle, ref, exact) {
18904
18974
  const envelope = bundle.envelope;
18905
- const originId = hashDocumentOriginIdV3({
18975
+ const request = input.evidence.request;
18976
+ const confirmedInstruction = "kind" in request && request.kind === "payment_request" ? request.confirmation.instruction : requestRetryInstruction(input);
18977
+ const originId = confirmedInstruction === void 0 ? hashDocumentOriginIdV3({
18906
18978
  chainId: input.evidence.chainId,
18907
18979
  actorKind: input.actorKind,
18908
18980
  actorId: input.actorId,
18909
18981
  requestKey: input.requestKey,
18910
18982
  itemIndex: input.index
18911
- });
18912
- return bundle.originId === originId && verifySupportedPaymentDocumentContext(envelope, {
18983
+ }) : envelope.message.originId;
18984
+ const source = confirmedInstruction !== void 0 && envelope.primaryType === "Memo" ? envelope.message.source : command.senderSafe.toLowerCase();
18985
+ return (confirmedInstruction === void 0 || documentJson$1(ref) === documentJson$1(confirmedInstruction)) && bundle.originId === originId && verifySupportedPaymentDocumentContext(envelope, {
18913
18986
  chainId: input.evidence.chainId,
18914
18987
  originId,
18915
- source: command.senderSafe.toLowerCase(),
18988
+ source,
18916
18989
  target: item.recipientSafe.toLowerCase(),
18917
18990
  amount: {
18918
18991
  asset: exact.asset,
@@ -19092,7 +19165,7 @@ function verifiesOfferCheckoutBirthEvidence(evidence, checkout, chainId) {
19092
19165
  /** Invoice checkout binds public fixed terms and the caller-selected funding Safe. */
19093
19166
  function verifiesInvoiceCheckoutBirthEvidence(evidence, invoice, chainId, sourceWallet) {
19094
19167
  const item = evidence.preparedCommand?.items[0];
19095
- 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 === 1 && invoice.chainId === chainId;
19168
+ 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;
19096
19169
  }
19097
19170
  //#endregion
19098
19171
  //#region ../../packages/sdk/src/surface/payment-command-execution.ts
@@ -66163,8 +66236,14 @@ function makeOnboardingMethods(deps) {
66163
66236
  //#region ../../packages/sdk/src/contract/checkouts.ts
66164
66237
  const fns = CAPXUL_FUNCTIONS["financialOps/offerCheckouts"];
66165
66238
  const settlement = CAPXUL_FUNCTIONS["financialOps/offerCheckoutSettlement"];
66239
+ const requests = CAPXUL_FUNCTIONS["financialOps/requestCheckouts"];
66166
66240
  const invoices = CAPXUL_FUNCTIONS["financialOps/invoiceCheckouts"];
66167
66241
  const checkoutContract = {
66242
+ request: makeFunctionReference(requests.summary),
66243
+ prepareRequest: makeFunctionReference(requests.prepare),
66244
+ requestState: makeFunctionReference(requests.state),
66245
+ reconcileRequest: makeFunctionReference(requests.reconcile),
66246
+ prepareRequestRegistered: makeFunctionReference(requests.prepareRegistered),
66168
66247
  invoice: makeFunctionReference(invoices.summary),
66169
66248
  prepareInvoice: makeFunctionReference(invoices.prepare),
66170
66249
  invoiceState: makeFunctionReference(invoices.state),
@@ -66184,9 +66263,96 @@ const missing$2 = async () => ({
66184
66263
  ok: false,
66185
66264
  error: Errors.notImplemented("checkouts", "convex")
66186
66265
  });
66266
+ const decodeCheckoutResponse = (read) => Effect.try({
66267
+ try: read,
66268
+ catch: (cause) => ({ publicError: isCapxulError(cause) ? cause : Errors.unknown(cause) })
66269
+ });
66270
+ function decodeObligationSummary(value, generic) {
66271
+ if (generic) return Schema.decodeUnknownSync(RequestCheckoutSummarySchema)(value);
66272
+ const invoice = Schema.decodeUnknownSync(InvoiceCheckoutSummarySchema)(value);
66273
+ if (invoice.documentKind === "memo") throw Errors.invalidInput("invoice", "Invoice checkout cannot use a Memo");
66274
+ return invoice;
66275
+ }
66276
+ function decodeRegisteredObligation(value, generic) {
66277
+ if (generic) {
66278
+ const { request, ...evidence } = Schema.decodeUnknownSync(PreparedRequestCheckoutExecutionSchema, { onExcessProperty: "error" })(value);
66279
+ return {
66280
+ snapshot: request,
66281
+ evidence
66282
+ };
66283
+ }
66284
+ const { invoice, ...evidence } = Schema.decodeUnknownSync(PreparedInvoiceCheckoutExecutionSchema, { onExcessProperty: "error" })(value);
66285
+ if (invoice.documentKind === "memo") throw Errors.invalidInput("invoice", "Invoice checkout cannot use a Memo");
66286
+ return {
66287
+ snapshot: invoice,
66288
+ evidence
66289
+ };
66290
+ }
66291
+ async function payObligationRegistered(deps, input, options, generic) {
66292
+ const port = deps.convexCall;
66293
+ if (port === void 0 || deps.execution === void 0) return missing$2();
66294
+ const lifetime = deps.execution.actor.authLifetime();
66295
+ const authUserId = deps.execution.actor.authSession()?.authUserId;
66296
+ if (authUserId === void 0) return {
66297
+ ok: false,
66298
+ error: Errors.notAuthenticated()
66299
+ };
66300
+ const controls = deps.invocationControls?.(options) ?? options;
66301
+ const sourceWallet = Schema.decodeUnknownResult(AddressSchema)(input.sourceWallet);
66302
+ if (sourceWallet._tag === "Failure") return {
66303
+ ok: false,
66304
+ error: Errors.invalidInput("sourceWallet", "selected funding wallet is invalid")
66305
+ };
66306
+ const frozen = await runPortEffect(port.query(generic ? checkoutContract.request : checkoutContract.invoice, copyInvocationObservation(controls, { linkToken: input.linkToken })).pipe(Effect.flatMap((value) => decodeCheckoutResponse(() => value === null ? null : decodeObligationSummary(value, generic)))), controls, generic ? CAPXUL_OPERATIONS.checkouts.request : CAPXUL_OPERATIONS.checkouts.invoice, deps.runPromise);
66307
+ if (!deps.execution.actor.matchesAuthLifetime(lifetime, authUserId)) return {
66308
+ ok: false,
66309
+ error: Errors.cancelled({ operation: "checkouts" })
66310
+ };
66311
+ if (!frozen.ok) return frozen;
66312
+ if (frozen.value === null || frozen.value.linkToken !== input.linkToken) return {
66313
+ ok: false,
66314
+ error: Errors.invalidInput(generic ? "request" : "invoice", generic ? "Request is unavailable" : "Invoice is unavailable")
66315
+ };
66316
+ const snapshot = frozen.value;
66317
+ const { sourceWallet: _sourceWallet, ...wireInput } = input;
66318
+ const request = {
66319
+ kind: "invoice_checkout",
66320
+ linkToken: input.linkToken,
66321
+ payer: input.payer,
66322
+ ...input.permissionId === void 0 ? {} : { permissionId: input.permissionId }
66323
+ };
66324
+ return executePrepared(deps.execution, async (signerAddress) => {
66325
+ const prepared = await runPortEffect(generic ? port.action(checkoutContract.prepareRequestRegistered, copyInvocationObservation(controls, { input: {
66326
+ ...wireInput,
66327
+ signerAddress
66328
+ } })).pipe(Effect.flatMap((value) => decodeCheckoutResponse(() => decodeRegisteredObligation(value, true)))) : port.action(checkoutContract.prepareInvoiceRegistered, copyInvocationObservation(controls, { input: {
66329
+ ...wireInput,
66330
+ signerAddress
66331
+ } })).pipe(Effect.flatMap((value) => decodeCheckoutResponse(() => decodeRegisteredObligation(value, false)))), controls, generic ? CAPXUL_OPERATIONS.checkouts.prepareRequestRegistered : CAPXUL_OPERATIONS.moneyExecution.prepareInvoiceCheckoutExecution, deps.runPromise);
66332
+ if (!prepared.ok) return prepared;
66333
+ if (canonicalJson(prepared.value.snapshot) !== canonicalJson(snapshot)) return {
66334
+ ok: false,
66335
+ error: Errors.invalidInput(generic ? "request" : "invoice", "prepared checkout differs from frozen terms")
66336
+ };
66337
+ return {
66338
+ ok: true,
66339
+ value: {
66340
+ ...prepared.value.evidence,
66341
+ request,
66342
+ emitPaymentInitiated: false,
66343
+ recipientObservations: []
66344
+ }
66345
+ };
66346
+ }, async (actual) => canonicalJson(actual) === canonicalJson(request), false, void 0, controls?.signal, controls, void 0, void 0, snapshot, sourceWallet.success);
66347
+ }
66187
66348
  function makeCheckoutMethods(deps) {
66188
66349
  const port = deps.convexCall;
66189
66350
  if (port === void 0) return {
66351
+ request: missing$2,
66352
+ prepareRequest: missing$2,
66353
+ requestState: missing$2,
66354
+ reconcileRequest: missing$2,
66355
+ payRequestRegistered: missing$2,
66190
66356
  invoice: missing$2,
66191
66357
  prepareInvoice: missing$2,
66192
66358
  invoiceState: missing$2,
@@ -66203,82 +66369,65 @@ function makeCheckoutMethods(deps) {
66203
66369
  const offer = Schema.decodeUnknownSync(FixedOfferSchema);
66204
66370
  const checkout = Schema.decodeUnknownSync(OfferCheckoutSchema);
66205
66371
  return {
66372
+ request: (linkToken, options) => {
66373
+ const controls = deps.invocationControls?.(options) ?? options;
66374
+ return runPortEffect(port.query(checkoutContract.request, copyInvocationObservation(controls, { linkToken })).pipe(Effect.map((value) => value === null ? null : Schema.decodeUnknownSync(RequestCheckoutSummarySchema)(value))), controls, CAPXUL_OPERATIONS.checkouts.request, deps.runPromise);
66375
+ },
66376
+ prepareRequest: (input, options) => {
66377
+ const controls = deps.invocationControls?.(options) ?? options;
66378
+ return runPortEffect(port.mutation(checkoutContract.prepareRequest, copyInvocationObservation(controls, {
66379
+ linkToken: input.linkToken,
66380
+ sourceWallet: input.sourceWallet
66381
+ })).pipe(Effect.map((value) => Schema.decodeUnknownSync(RequestCheckoutPreparationSchema)(value))), controls, CAPXUL_OPERATIONS.checkouts.prepareRequest, deps.runPromise);
66382
+ },
66383
+ requestState: (linkToken, options) => {
66384
+ const controls = deps.invocationControls?.(options) ?? options;
66385
+ return runPortEffect(port.action(checkoutContract.requestState, copyInvocationObservation(controls, { linkToken })).pipe(Effect.map((value) => value === null ? null : Schema.decodeUnknownSync(RequestCheckoutStateSchema)(value))), controls, CAPXUL_OPERATIONS.checkouts.requestState, deps.runPromise);
66386
+ },
66387
+ reconcileRequest: (input, options) => {
66388
+ const controls = deps.invocationControls?.(options) ?? options;
66389
+ return runPortEffect(port.action(checkoutContract.reconcileRequest, copyInvocationObservation(controls, {
66390
+ linkToken: input.linkToken,
66391
+ transactionHash: input.transactionHash
66392
+ })).pipe(Effect.map((value) => Schema.decodeUnknownSync(RequestCheckoutReconciliationSchema)(value))), controls, CAPXUL_OPERATIONS.checkouts.reconcileRequest, deps.runPromise);
66393
+ },
66206
66394
  invoice: (linkToken, options) => {
66207
66395
  const controls = deps.invocationControls?.(options) ?? options;
66208
- return runPortEffect(port.query(checkoutContract.invoice, copyInvocationObservation(controls, { linkToken })).pipe(Effect.map((value) => value === null ? null : Schema.decodeUnknownSync(InvoiceCheckoutSummarySchema)(value))), controls, CAPXUL_OPERATIONS.checkouts.invoice, deps.runPromise);
66396
+ return runPortEffect(port.query(checkoutContract.invoice, copyInvocationObservation(controls, { linkToken })).pipe(Effect.flatMap((value) => decodeCheckoutResponse(() => value === null ? null : decodeObligationSummary(value, false)))), controls, CAPXUL_OPERATIONS.checkouts.invoice, deps.runPromise);
66209
66397
  },
66210
66398
  prepareInvoice: (input, options) => {
66211
66399
  const controls = deps.invocationControls?.(options) ?? options;
66212
66400
  return runPortEffect(port.query(checkoutContract.prepareInvoice, copyInvocationObservation(controls, {
66213
66401
  linkToken: input.linkToken,
66214
66402
  sourceWallet: input.sourceWallet
66215
- })).pipe(Effect.map((value) => Schema.decodeUnknownSync(InvoiceCheckoutPreparationSchema)(value))), controls, CAPXUL_OPERATIONS.checkouts.prepareInvoice, deps.runPromise);
66403
+ })).pipe(Effect.flatMap((value) => decodeCheckoutResponse(() => {
66404
+ const decoded = Schema.decodeUnknownSync(InvoiceCheckoutPreparationSchema)(value);
66405
+ decodeObligationSummary(decoded.invoice, false);
66406
+ return decoded;
66407
+ }))), controls, CAPXUL_OPERATIONS.checkouts.prepareInvoice, deps.runPromise);
66216
66408
  },
66217
66409
  invoiceState: (linkToken, options) => {
66218
66410
  const controls = deps.invocationControls?.(options) ?? options;
66219
- return runPortEffect(port.action(checkoutContract.invoiceState, copyInvocationObservation(controls, { linkToken })).pipe(Effect.map((value) => value === null ? null : Schema.decodeUnknownSync(InvoiceCheckoutStateSchema)(value))), controls, CAPXUL_OPERATIONS.checkouts.invoiceState, deps.runPromise);
66411
+ return runPortEffect(port.action(checkoutContract.invoiceState, copyInvocationObservation(controls, { linkToken })).pipe(Effect.flatMap((value) => decodeCheckoutResponse(() => {
66412
+ if (value === null) return null;
66413
+ const decoded = Schema.decodeUnknownSync(InvoiceCheckoutStateSchema)(value);
66414
+ decodeObligationSummary(decoded.invoice, false);
66415
+ return decoded;
66416
+ }))), controls, CAPXUL_OPERATIONS.checkouts.invoiceState, deps.runPromise);
66220
66417
  },
66221
66418
  reconcileInvoice: (input, options) => {
66222
66419
  const controls = deps.invocationControls?.(options) ?? options;
66223
66420
  return runPortEffect(port.action(checkoutContract.reconcileInvoice, copyInvocationObservation(controls, {
66224
66421
  linkToken: input.linkToken,
66225
66422
  transactionHash: input.transactionHash
66226
- })).pipe(Effect.map((value) => Schema.decodeUnknownSync(InvoiceCheckoutReconciliationSchema)(value))), controls, CAPXUL_OPERATIONS.checkouts.reconcileInvoice, deps.runPromise);
66227
- },
66228
- payInvoiceRegistered: async (input, options) => {
66229
- if (deps.execution === void 0) return missing$2();
66230
- const lifetime = deps.execution.actor.authLifetime();
66231
- const authUserId = deps.execution.actor.authSession()?.authUserId;
66232
- if (authUserId === void 0) return {
66233
- ok: false,
66234
- error: Errors.notAuthenticated()
66235
- };
66236
- const controls = deps.invocationControls?.(options) ?? options;
66237
- const sourceWallet = Schema.decodeUnknownResult(AddressSchema)(input.sourceWallet);
66238
- if (sourceWallet._tag === "Failure") return {
66239
- ok: false,
66240
- error: Errors.invalidInput("sourceWallet", "selected funding wallet is invalid")
66241
- };
66242
- const frozen = await runPortEffect(port.query(checkoutContract.invoice, copyInvocationObservation(controls, { linkToken: input.linkToken })).pipe(Effect.map((value) => value === null ? null : Schema.decodeUnknownSync(InvoiceCheckoutSummarySchema)(value))), controls, CAPXUL_OPERATIONS.checkouts.invoice, deps.runPromise);
66243
- if (!deps.execution.actor.matchesAuthLifetime(lifetime, authUserId)) return {
66244
- ok: false,
66245
- error: Errors.cancelled({ operation: "checkouts" })
66246
- };
66247
- if (!frozen.ok) return frozen;
66248
- if (frozen.value === null || frozen.value.linkToken !== input.linkToken) return {
66249
- ok: false,
66250
- error: Errors.invalidInput("invoice", "Invoice is unavailable")
66251
- };
66252
- const snapshot = frozen.value;
66253
- const { sourceWallet: _sourceWallet, ...wireInput } = input;
66254
- const request = {
66255
- kind: "invoice_checkout",
66256
- linkToken: input.linkToken,
66257
- payer: input.payer,
66258
- ...input.permissionId === void 0 ? {} : { permissionId: input.permissionId }
66259
- };
66260
- return executePrepared(deps.execution, async (signerAddress) => {
66261
- const prepared = await runPortEffect(port.action(checkoutContract.prepareInvoiceRegistered, copyInvocationObservation(controls, { input: {
66262
- ...wireInput,
66263
- signerAddress
66264
- } })).pipe(Effect.map((value) => Schema.decodeUnknownSync(PreparedInvoiceCheckoutExecutionSchema, { onExcessProperty: "error" })(value))), controls, CAPXUL_OPERATIONS.moneyExecution.prepareInvoiceCheckoutExecution, deps.runPromise);
66265
- if (!prepared.ok) return prepared;
66266
- if (canonicalJson(prepared.value.invoice) !== canonicalJson(snapshot)) return {
66267
- ok: false,
66268
- error: Errors.invalidInput("invoice", "prepared Invoice differs from frozen terms")
66269
- };
66270
- const { invoice: _invoice, ...evidence } = prepared.value;
66271
- return {
66272
- ok: true,
66273
- value: {
66274
- ...evidence,
66275
- request,
66276
- emitPaymentInitiated: false,
66277
- recipientObservations: []
66278
- }
66279
- };
66280
- }, async (actual) => canonicalJson(actual) === canonicalJson(request), false, void 0, controls?.signal, controls, void 0, void 0, snapshot, sourceWallet.success);
66423
+ })).pipe(Effect.flatMap((value) => decodeCheckoutResponse(() => {
66424
+ const decoded = Schema.decodeUnknownSync(InvoiceCheckoutReconciliationSchema)(value);
66425
+ decodeObligationSummary(decoded.state.invoice, false);
66426
+ return decoded;
66427
+ }))), controls, CAPXUL_OPERATIONS.checkouts.reconcileInvoice, deps.runPromise);
66281
66428
  },
66429
+ payInvoiceRegistered: (input, options) => payObligationRegistered(deps, input, options, false),
66430
+ payRequestRegistered: (input, options) => payObligationRegistered(deps, input, options, true),
66282
66431
  payRegistered: async (input, options) => {
66283
66432
  if (deps.execution === void 0) return missing$2();
66284
66433
  const lifetime = deps.execution.actor.authLifetime();
@@ -69817,8 +69966,8 @@ function captureException(telemetry, error, context) {
69817
69966
  }
69818
69967
  //#endregion
69819
69968
  //#region src/runtime/version.ts
69820
- const cliVersion = "4.20.0-beta.20";
69821
- const sdkVersion = "4.20.0-beta.20";
69969
+ const cliVersion = "4.20.0-beta.22";
69970
+ const sdkVersion = "4.20.0-beta.22";
69822
69971
  const ReleaseVersion = Schema.String.check(Schema.isMaxLength(256), Schema.isPattern(/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+[0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*)?$/u)).pipe(Schema.brand("CliReleaseVersion"));
69823
69972
  const parts = (version) => {
69824
69973
  const [core = "", ...prerelease] = version.split("+")[0].split("-");
@@ -75111,13 +75260,16 @@ const referenceLabel = (ref) => {
75111
75260
  case "handle": return ref.handle;
75112
75261
  }
75113
75262
  };
75114
- const requestCheckout = (item, origin) => ({
75115
- ...item,
75116
- ..."linkToken" in item && item.linkToken !== void 0 && item.documents.some((document) => document.kind === "invoice" && document.role === "instruction") ? { checkoutUrl: checkoutUrl(origin, {
75117
- kind: "invoice",
75118
- linkToken: item.linkToken
75119
- }) } : {}
75120
- });
75263
+ const requestCheckout = (item, origin) => {
75264
+ const instruction = item.documents.find((document) => document.role === "instruction" && (document.kind === "invoice" || document.kind === "memo"));
75265
+ return {
75266
+ ...item,
75267
+ ..."linkToken" in item && item.linkToken !== void 0 && instruction !== void 0 ? { checkoutUrl: checkoutUrl(origin, {
75268
+ kind: instruction.kind === "invoice" ? "invoice" : "request",
75269
+ linkToken: item.linkToken
75270
+ }) } : {}
75271
+ };
75272
+ };
75121
75273
  const requestLines = (item, email, orgId = null) => [
75122
75274
  `Request ${terminalText(item.id)}`,
75123
75275
  ...item.checkoutUrl === void 0 ? [] : [` Checkout: ${terminalText(item.checkoutUrl)}`],
@@ -75638,7 +75790,20 @@ const readPaymentInput = (source) => Effect.gen(function* () {
75638
75790
  }).pipe(Effect.mapError((error) => error instanceof UpdateUnavailable ? inputRequired("Payment input exceeds 64 KiB.") : error));
75639
75791
  //#endregion
75640
75792
  //#region src/commands/request/internal/issue-input.ts
75641
- const invalid$4 = () => inputRequired("Provide one Invoice request JSON object with payer, amount, and invoice.");
75793
+ const invalid$4 = () => inputRequired("Provide one request JSON object with payer, amount, and reference or invoice.");
75794
+ const readRequestMetadata = (value, invoiceNumber) => Effect.gen(function* () {
75795
+ const reference = "reference" in value ? value.reference : invoiceNumber;
75796
+ if (typeof reference !== "string" || reference.trim().length === 0 || reference.trim().length > 120) return yield* invalid$4();
75797
+ const memo = "memo" in value ? value.memo : void 0;
75798
+ if (memo !== void 0 && (typeof memo !== "string" || memo.trim().length > 280)) return yield* invalid$4();
75799
+ const expiresAt = "expiresAt" in value ? value.expiresAt : void 0;
75800
+ if (expiresAt !== void 0 && (typeof expiresAt !== "number" || !Number.isSafeInteger(expiresAt) || expiresAt <= Date.now())) return yield* inputRequired("Provide expiresAt as a future epoch time in milliseconds.");
75801
+ return {
75802
+ reference: reference.trim(),
75803
+ ...memo === void 0 || memo.trim() === "" ? {} : { memo: memo.trim() },
75804
+ ...expiresAt === void 0 ? {} : { expiresAt }
75805
+ };
75806
+ });
75642
75807
  const parseIssueInput = (value) => Effect.gen(function* () {
75643
75808
  if (!record$1(value)) return yield* invalid$4();
75644
75809
  if (!Object.keys(value).every((key) => [
@@ -75649,27 +75814,22 @@ const parseIssueInput = (value) => Effect.gen(function* () {
75649
75814
  "memo",
75650
75815
  "expiresAt"
75651
75816
  ].includes(key))) return yield* invalid$4();
75652
- if (!("payer" in value) || !("amount" in value) || !("invoice" in value)) return yield* invalid$4();
75817
+ if (!("payer" in value) || !("amount" in value)) return yield* invalid$4();
75653
75818
  const payment = yield* parsePaymentInput({
75654
75819
  to: value.payer,
75655
75820
  amount: value.amount,
75656
- document: value.invoice
75821
+ ..."invoice" in value ? { document: value.invoice } : {}
75657
75822
  });
75658
- if (payment.document?.kind !== "invoice") return yield* invalid$4();
75659
- if (!Number.isFinite(new Date(payment.document.dueAt).getTime())) return yield* inputRequired("Provide an Invoice dueAt that is a valid UTC date in epoch milliseconds.");
75660
- const reference = "reference" in value ? value.reference : payment.document.invoiceNumber;
75661
- if (typeof reference !== "string" || reference.trim().length === 0 || reference.trim().length > 120) return yield* invalid$4();
75662
- const memo = "memo" in value ? value.memo : void 0;
75663
- if (memo !== void 0 && (typeof memo !== "string" || memo.trim().length > 280)) return yield* invalid$4();
75664
- const expiresAt = "expiresAt" in value ? value.expiresAt : void 0;
75665
- if (expiresAt !== void 0 && (typeof expiresAt !== "number" || !Number.isSafeInteger(expiresAt) || expiresAt <= Date.now())) return yield* inputRequired("Provide expiresAt as a future epoch time in milliseconds.");
75823
+ const invoice = payment.document;
75824
+ if ("invoice" in value && invoice?.kind !== "invoice") return yield* invalid$4();
75825
+ if (invoice !== void 0 && invoice.kind !== "invoice") return yield* invalid$4();
75826
+ if (invoice !== void 0 && !Number.isFinite(new Date(invoice.dueAt).getTime())) return yield* inputRequired("Provide an Invoice dueAt that is a valid UTC date in epoch milliseconds.");
75827
+ const metadata = yield* readRequestMetadata(value, invoice?.invoiceNumber);
75666
75828
  return {
75667
75829
  payer: payment.to,
75668
75830
  amount: payment.amount,
75669
- invoice: payment.document,
75670
- reference: reference.trim(),
75671
- ...memo === void 0 || memo.trim() === "" ? {} : { memo: memo.trim() },
75672
- ...expiresAt === void 0 ? {} : { expiresAt }
75831
+ ...invoice === void 0 ? {} : { invoice },
75832
+ ...metadata
75673
75833
  };
75674
75834
  });
75675
75835
  const readIssueInput = (source) => Effect.gen(function* () {
@@ -75681,7 +75841,7 @@ const readIssueInput = (source) => Effect.gen(function* () {
75681
75841
  catch: invalid$4
75682
75842
  });
75683
75843
  return yield* parseIssueInput(value);
75684
- }).pipe(Effect.mapError((error) => error instanceof UpdateUnavailable ? inputRequired("Invoice input exceeds 64 KiB.") : error));
75844
+ }).pipe(Effect.mapError((error) => error instanceof UpdateUnavailable ? inputRequired("Request input exceeds 64 KiB.") : error));
75685
75845
  const issuePreview = (draft) => {
75686
75846
  const decimals = requireAsset(draft.amount.asset).decimals;
75687
75847
  const minor = (raw) => {
@@ -75692,28 +75852,32 @@ const issuePreview = (draft) => {
75692
75852
  value
75693
75853
  });
75694
75854
  };
75855
+ const invoice = draft.invoice;
75695
75856
  return [
75696
- `Invoice: ${terminalText(draft.invoice.invoiceNumber)}`,
75857
+ ...invoice === void 0 ? [] : [`Invoice: ${terminalText(invoice.invoiceNumber)}`],
75697
75858
  `Payer: ${terminalText(referenceLabel(draft.payer))}`,
75698
75859
  `Reference: ${terminalText(draft.reference)}`,
75699
75860
  `Total: ${terminalText(formatAssetAmount(draft.amount))}`,
75700
- `Due: ${draft.invoice.dueAt === 0 ? "No due date" : terminalText(new Date(draft.invoice.dueAt).toUTCString())}`,
75701
- ...draft.invoice.lineItems.map((item) => ` ${terminalText(item.description)}: ${item.quantity} x ${terminalText(minor(item.unitMinor))}`),
75702
- `Discount: ${terminalText(minor(draft.invoice.discountMinor ?? "0"))}`,
75703
- ...draft.invoice.note === void 0 ? [] : [`Notes: ${terminalText(draft.invoice.note)}`]
75861
+ ...draft.memo === void 0 ? [] : [`Memo: ${terminalText(draft.memo)}`],
75862
+ ...invoice === void 0 ? [] : [
75863
+ `Due: ${invoice.dueAt === 0 ? "No due date" : terminalText(new Date(invoice.dueAt).toUTCString())}`,
75864
+ ...invoice.lineItems.map((item) => ` ${terminalText(item.description)}: ${item.quantity} x ${terminalText(minor(item.unitMinor))}`),
75865
+ `Discount: ${terminalText(minor(invoice.discountMinor ?? "0"))}`,
75866
+ ...invoice.note === void 0 ? [] : [`Notes: ${terminalText(invoice.note)}`]
75867
+ ]
75704
75868
  ];
75705
75869
  };
75706
75870
  //#endregion
75707
75871
  //#region src/commands/request/subcommands/issue/execute.ts
75708
75872
  const execute$59 = (config, input) => Effect.gen(function* () {
75709
75873
  const orgId = yield* readScope(input);
75710
- if (input.direction !== "issued") return yield* inputRequired("Use request issue for an issued Invoice.");
75874
+ if (input.direction !== "issued") return yield* inputRequired("Use request issue for an issued payment request.");
75711
75875
  const draft = yield* readIssueInput(input.source);
75712
75876
  const interactive = yield* requireWriteConfirmation(input.confirm);
75713
75877
  const { client, session } = yield* restoreAuthenticatedClient(config, input.email);
75714
75878
  if (interactive) yield* confirmWrite({
75715
75879
  lines: [`Scope: ${orgId === null ? "Personal" : `Organization ${terminalText(orgId)}`}`, ...issuePreview(draft)],
75716
- question: "Issue this Invoice request?"
75880
+ question: "Issue this payment request?"
75717
75881
  });
75718
75882
  const actor = orgId === null ? client.account : client.org(orgId);
75719
75883
  const stored = yield* Effect.promise((signal) => actor.requests.issue(draft, { signal })).pipe(Effect.flatMap(resultValue), Effect.mapError((error) => requestWriteFailure(error, orgId, "issued", null, session.email)));
@@ -75746,7 +75910,7 @@ const command$62 = (context) => Command.make("issue", {
75746
75910
  email: Option.getOrUndefined(email),
75747
75911
  outputDirectory: Option.getOrUndefined(outputDirectory),
75748
75912
  orgs: "orgs" in scope ? scope.orgs : []
75749
- }, execute$59)).pipe(context.annotate("issue"), Command.withDescription("Issue an Invoice request and save its PDF"));
75913
+ }, execute$59)).pipe(context.annotate("issue"), Command.withDescription("Issue a payment request and save its available PDFs"));
75750
75914
  //#endregion
75751
75915
  //#region src/commands/request/subcommands/pay/execute.ts
75752
75916
  const command$61 = (args) => args.map(shellArgument).join(" ");