@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.
- package/dist/{access-DUmQPXVl.mjs → access-D5D77YLI.mjs} +905 -363
- package/dist/{index-DtFIxdqJ.d.mts → index-9tVY0-g7.d.mts} +1354 -402
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +3 -3
- package/dist/node/index.d.mts +1 -1
- package/dist/node/index.mjs +1 -1
- package/dist/{organizations-BhSPqVR5.mjs → organizations-BKiw2PjB.mjs} +2 -2
- package/dist/{permission-approvals-tXIk7kNA.mjs → permission-approvals-B2LrXyRx.mjs} +2 -2
- package/dist/{production-C7WbsKZl.mjs → production-CLAx7XAB.mjs} +2 -2
- package/dist/testing/index.d.mts +1 -1
- package/dist/testing/index.mjs +2 -2
- package/package.json +4 -4
|
@@ -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
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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.
|
|
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" ||
|
|
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
|
-
/**
|
|
16823
|
-
const
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
17313
|
-
|
|
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
|
|
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)
|
|
17535
|
-
|
|
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)
|
|
17580
|
-
|
|
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
|
|
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
|
-
|
|
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: [
|
|
18186
|
+
args: [router, amount]
|
|
17748
18187
|
})
|
|
17749
18188
|
}, {
|
|
17750
|
-
to:
|
|
18189
|
+
to: router,
|
|
17751
18190
|
value: 0n,
|
|
17752
|
-
data:
|
|
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()
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
19184
|
+
const cancelled = {
|
|
18662
19185
|
ok: false,
|
|
18663
|
-
error: Errors.
|
|
19186
|
+
error: Errors.cancelled({ operation: inboxes.approve.name })
|
|
18664
19187
|
};
|
|
18665
|
-
|
|
18666
|
-
|
|
18667
|
-
|
|
18668
|
-
|
|
18669
|
-
|
|
18670
|
-
|
|
18671
|
-
|
|
18672
|
-
asset
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
|
|
18676
|
-
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18680
|
-
|
|
18681
|
-
|
|
18682
|
-
|
|
18683
|
-
|
|
18684
|
-
|
|
18685
|
-
|
|
18686
|
-
|
|
18687
|
-
|
|
18688
|
-
|
|
18689
|
-
|
|
18690
|
-
|
|
18691
|
-
|
|
18692
|
-
|
|
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
|
|
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: (
|
|
18720
|
-
|
|
18721
|
-
|
|
18722
|
-
|
|
18723
|
-
|
|
18724
|
-
|
|
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
|
-
|
|
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
|
-
},
|
|
18755
|
-
|
|
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
|
-
|
|
21412
|
-
|
|
21413
|
-
|
|
21414
|
-
|
|
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-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
21618
|
-
|
|
21619
|
-
|
|
21620
|
-
|
|
21621
|
-
|
|
21622
|
-
|
|
21623
|
-
|
|
21624
|
-
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
|
|
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:
|
|
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 $,
|
|
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 };
|