@capxul/sdk 4.20.0-beta.34 → 4.20.0-beta.35
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-DpPt-SvA.mjs} +869 -341
- package/dist/{index-DtFIxdqJ.d.mts → index-DOR7Fkn7.d.mts} +1556 -610
- 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-BmX52Uev.mjs} +2 -2
- package/dist/{permission-approvals-tXIk7kNA.mjs → permission-approvals-Bw9VaKay.mjs} +2 -2
- package/dist/{production-C7WbsKZl.mjs → production-DdjhwgRC.mjs} +2 -2
- package/dist/testing/index.d.mts +1 -1
- package/dist/testing/index.mjs +2 -2
- package/package.json +3 -3
|
@@ -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) {
|
|
@@ -1966,6 +1966,15 @@ const CAPXUL_ERROR_CODES = [
|
|
|
1966
1966
|
"WORK_DIED",
|
|
1967
1967
|
"ACTOR_STOPPED"
|
|
1968
1968
|
];
|
|
1969
|
+
/** The existing Organization authority refusal vocabulary. */
|
|
1970
|
+
const ROLE_PERMISSION_DENIED_REASONS = [
|
|
1971
|
+
"over_cap",
|
|
1972
|
+
"daily_cap",
|
|
1973
|
+
"not_member",
|
|
1974
|
+
"disallowed_recipient",
|
|
1975
|
+
"condition_violation",
|
|
1976
|
+
"budget_exhausted"
|
|
1977
|
+
];
|
|
1969
1978
|
/**
|
|
1970
1979
|
* The error codes that represent an expected product outcome rather than a
|
|
1971
1980
|
* defect. The SDK and backend observation boundaries both classify failures
|
|
@@ -4307,7 +4316,7 @@ function isQuantityHex(value) {
|
|
|
4307
4316
|
function isBytes32(value) {
|
|
4308
4317
|
return typeof value === "string" && BYTES32_HEX.test(value);
|
|
4309
4318
|
}
|
|
4310
|
-
function refused(field, shape, value) {
|
|
4319
|
+
function refused$1(field, shape, value) {
|
|
4311
4320
|
throw Errors.invalidInput(field, invalidValueReason(`must be ${shape}`, value));
|
|
4312
4321
|
}
|
|
4313
4322
|
/** Rebuilding the `0x` prefix keeps the result a `Hex`; lowercasing never changes the bytes. */
|
|
@@ -4316,19 +4325,19 @@ function lowered(value) {
|
|
|
4316
4325
|
}
|
|
4317
4326
|
/** Hex data exactly as given: case kept, for text another party compares or hashes as is. */
|
|
4318
4327
|
function toExactHex(value, field = "value") {
|
|
4319
|
-
return isHex$1(value) ? value : refused(field, "0x-prefixed hex", value);
|
|
4328
|
+
return isHex$1(value) ? value : refused$1(field, "0x-prefixed hex", value);
|
|
4320
4329
|
}
|
|
4321
4330
|
/** Hex data, lowercased. */
|
|
4322
4331
|
function toLowerHex(value, field = "value") {
|
|
4323
|
-
return isHex$1(value) ? lowered(value) : refused(field, "0x-prefixed hex", value);
|
|
4332
|
+
return isHex$1(value) ? lowered(value) : refused$1(field, "0x-prefixed hex", value);
|
|
4324
4333
|
}
|
|
4325
4334
|
/** A bytes32 value, lowercased. */
|
|
4326
4335
|
function toLowerBytes32(value, field = "value") {
|
|
4327
|
-
return isBytes32(value) ? lowered(value) : refused(field, "a 0x-prefixed bytes32 value", value);
|
|
4336
|
+
return isBytes32(value) ? lowered(value) : refused$1(field, "a 0x-prefixed bytes32 value", value);
|
|
4328
4337
|
}
|
|
4329
4338
|
/** An address, lowercased: the form stored rows and digests compare. */
|
|
4330
4339
|
function toLowerAddress(value, field = "address") {
|
|
4331
|
-
return isAddress$1(value) ? lowered(value) : refused(field, "an EVM address", value);
|
|
4340
|
+
return isAddress$1(value) ? lowered(value) : refused$1(field, "an EVM address", value);
|
|
4332
4341
|
}
|
|
4333
4342
|
//#endregion
|
|
4334
4343
|
//#region ../protocol/src/evm/schema.ts
|
|
@@ -4881,16 +4890,19 @@ const PaymentCommandSchema = Schema.Union([
|
|
|
4881
4890
|
PaymentBirthCommandSchema,
|
|
4882
4891
|
Schema.Struct({
|
|
4883
4892
|
kind: Schema.Literal("claim_commitment"),
|
|
4893
|
+
requestKey: Schema.optional(nonEmpty("requestKey")),
|
|
4884
4894
|
actor: AccountActorRefSchema,
|
|
4885
4895
|
paymentId: PaymentIdSchema
|
|
4886
4896
|
}),
|
|
4887
4897
|
Schema.Struct({
|
|
4888
4898
|
kind: Schema.Literal("cancel_commitment"),
|
|
4899
|
+
requestKey: Schema.optional(nonEmpty("requestKey")),
|
|
4889
4900
|
actor: ActorRefSchema,
|
|
4890
4901
|
paymentId: PaymentIdSchema
|
|
4891
4902
|
}),
|
|
4892
4903
|
Schema.Struct({
|
|
4893
4904
|
kind: Schema.Literal("redirect_commitment"),
|
|
4905
|
+
requestKey: Schema.optional(nonEmpty("requestKey")),
|
|
4894
4906
|
actor: ActorRefSchema,
|
|
4895
4907
|
paymentId: PaymentIdSchema,
|
|
4896
4908
|
recipient: ActorOrDestinationRefSchema
|
|
@@ -4915,8 +4927,10 @@ const PreparedMoneyItemSchema = Schema.Union([
|
|
|
4915
4927
|
tokenAddress: AddressSchema$1,
|
|
4916
4928
|
rawAmount: WeiAmountSchema$1,
|
|
4917
4929
|
kind: Uint16Schema,
|
|
4918
|
-
documentHash: NonzeroDocumentHashSchema
|
|
4919
|
-
|
|
4930
|
+
documentHash: NonzeroDocumentHashSchema,
|
|
4931
|
+
jobNonce: Schema.optional(Bytes32Schema),
|
|
4932
|
+
executor: Schema.optional(AddressSchema$1)
|
|
4933
|
+
}).pipe(Schema.refine((item) => item.jobNonce === void 0 === (item.executor === void 0), { message: "Prepared V3 identity requires both jobNonce and executor" })),
|
|
4920
4934
|
Schema.Struct({
|
|
4921
4935
|
operation: Schema.Literal("create_commitment"),
|
|
4922
4936
|
paymentId: PaymentIdSchema,
|
|
@@ -5018,6 +5032,12 @@ const PersonalUnsignedUserOperationSchema = Schema.Struct({
|
|
|
5018
5032
|
entryPoint: Schema.optional(Schema.Never),
|
|
5019
5033
|
safe4337ModuleAddress: Schema.optional(Schema.Never)
|
|
5020
5034
|
});
|
|
5035
|
+
const SubmittedPaymentExecutionSchema = Schema.Struct({
|
|
5036
|
+
executionId: MoneyExecutionIdSchema,
|
|
5037
|
+
commandId: PaymentCommandIdSchema,
|
|
5038
|
+
userOpHash: Bytes32Schema,
|
|
5039
|
+
payment: Payment
|
|
5040
|
+
});
|
|
5021
5041
|
const PreparedPaymentExecutionSchema = Schema.Struct({
|
|
5022
5042
|
actorAccountId: AccountIdSchema$1,
|
|
5023
5043
|
item: PreparedMoneyItemSchema,
|
|
@@ -5035,7 +5055,8 @@ const PreparedPaymentExecutionSchema = Schema.Struct({
|
|
|
5035
5055
|
chainId: BaseSepoliaChainIdSchema,
|
|
5036
5056
|
signerAddress: AddressSchema$1,
|
|
5037
5057
|
userOpSenderSafe: SafeAddressSchema,
|
|
5038
|
-
digest: Bytes32Schema
|
|
5058
|
+
digest: Bytes32Schema,
|
|
5059
|
+
settled: Schema.optional(SubmittedPaymentExecutionSchema)
|
|
5039
5060
|
});
|
|
5040
5061
|
const SubmitPaymentExecutionInputSchema = Schema.Struct({
|
|
5041
5062
|
executionId: MoneyExecutionIdSchema,
|
|
@@ -5049,12 +5070,6 @@ const AbandonPaymentExecutionInputSchema = Schema.Struct({
|
|
|
5049
5070
|
"prepared_mismatch"
|
|
5050
5071
|
])
|
|
5051
5072
|
});
|
|
5052
|
-
const SubmittedPaymentExecutionSchema = Schema.Struct({
|
|
5053
|
-
executionId: MoneyExecutionIdSchema,
|
|
5054
|
-
commandId: PaymentCommandIdSchema,
|
|
5055
|
-
userOpHash: Bytes32Schema,
|
|
5056
|
-
payment: Payment
|
|
5057
|
-
});
|
|
5058
5073
|
const SubmittedPaymentCommandExecutionSchema = Schema.Struct({
|
|
5059
5074
|
executionId: MoneyExecutionIdSchema,
|
|
5060
5075
|
commandId: PaymentCommandIdSchema,
|
|
@@ -5069,14 +5084,17 @@ const PaymentLifecycleExecutionIntentSchema = Schema.Union([
|
|
|
5069
5084
|
}),
|
|
5070
5085
|
Schema.Struct({
|
|
5071
5086
|
kind: Schema.Literal("claim"),
|
|
5072
|
-
paymentId: PaymentIdSchema
|
|
5087
|
+
paymentId: PaymentIdSchema,
|
|
5088
|
+
requestKey: Schema.optional(nonEmpty("requestKey"))
|
|
5073
5089
|
}),
|
|
5074
5090
|
Schema.Struct({
|
|
5075
5091
|
kind: Schema.Literal("cancel"),
|
|
5076
|
-
paymentId: PaymentIdSchema
|
|
5092
|
+
paymentId: PaymentIdSchema,
|
|
5093
|
+
requestKey: Schema.optional(nonEmpty("requestKey"))
|
|
5077
5094
|
}),
|
|
5078
5095
|
Schema.Struct({
|
|
5079
5096
|
kind: Schema.Literal("redirect"),
|
|
5097
|
+
requestKey: Schema.optional(nonEmpty("requestKey")),
|
|
5080
5098
|
paymentId: PaymentIdSchema,
|
|
5081
5099
|
recipient: RedirectPaymentRef
|
|
5082
5100
|
})
|
|
@@ -5135,10 +5153,12 @@ const RequestPaymentConfirmationFields = {
|
|
|
5135
5153
|
const RequestPaymentTermsSchema = Schema.Struct(RequestPaymentConfirmationFields);
|
|
5136
5154
|
const RequestPaymentConfirmationSchema = Schema.Union([Schema.Struct({
|
|
5137
5155
|
...RequestPaymentConfirmationFields,
|
|
5156
|
+
requestKey: Schema.optional(nonEmpty("requestKey")),
|
|
5138
5157
|
payer: Schema.Struct({ kind: Schema.Literal("account") }),
|
|
5139
5158
|
permissionId: Schema.optional(Schema.Never)
|
|
5140
5159
|
}), Schema.Struct({
|
|
5141
5160
|
...RequestPaymentConfirmationFields,
|
|
5161
|
+
requestKey: Schema.optional(nonEmpty("requestKey")),
|
|
5142
5162
|
payer: OrganizationActorRefSchema,
|
|
5143
5163
|
permissionId: PermissionIdSchema
|
|
5144
5164
|
})]);
|
|
@@ -5198,13 +5218,14 @@ const PreparedPaymentCommandExecutionSchema = Schema.Struct({
|
|
|
5198
5218
|
commitmentId: Uint256StringSchema,
|
|
5199
5219
|
documentHash: NonzeroDocumentHashSchema
|
|
5200
5220
|
})),
|
|
5201
|
-
documentBundles: Schema.optional(Schema.Array(PaymentDocumentBundleV3Schema))
|
|
5221
|
+
documentBundles: Schema.optional(Schema.Array(PaymentDocumentBundleV3Schema)),
|
|
5222
|
+
settled: Schema.optional(SubmittedPaymentCommandExecutionSchema)
|
|
5202
5223
|
}).check(Schema.makeFilter((execution) => {
|
|
5203
5224
|
if (!("kind" in execution.request) || execution.request.kind !== "payment_request") return true;
|
|
5204
5225
|
const source = execution.sourceCommand;
|
|
5205
5226
|
const prepared = execution.preparedCommand;
|
|
5206
5227
|
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;
|
|
5228
|
+
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
5229
|
if ([
|
|
5209
5230
|
source.items.length,
|
|
5210
5231
|
execution.request.items.length,
|
|
@@ -5217,7 +5238,7 @@ const PreparedPaymentCommandExecutionSchema = Schema.Struct({
|
|
|
5217
5238
|
prepared.instructionDocuments?.length
|
|
5218
5239
|
].some((length) => length !== 1)) return false;
|
|
5219
5240
|
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
|
|
5241
|
+
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
5242
|
}));
|
|
5222
5243
|
//#endregion
|
|
5223
5244
|
//#region ../protocol/src/accounts/approval-schema.ts
|
|
@@ -5285,6 +5306,7 @@ const ApprovalSummarySchema = Schema.Struct({
|
|
|
5285
5306
|
/** The exact operation the signature covers: the digest is the one thing the key signs. */
|
|
5286
5307
|
const ApprovalOperationSchema = Schema.Struct({
|
|
5287
5308
|
executionId: MoneyExecutionIdSchema,
|
|
5309
|
+
commandId: Schema.optional(nonEmpty("commandId")),
|
|
5288
5310
|
digest: Bytes32Schema,
|
|
5289
5311
|
userOperation: PersonalUnsignedUserOperationSchema,
|
|
5290
5312
|
paymentIds: Schema.Array(PaymentIdSchema)
|
|
@@ -5477,6 +5499,21 @@ const approvals = {
|
|
|
5477
5499
|
...APPROVAL
|
|
5478
5500
|
]
|
|
5479
5501
|
}),
|
|
5502
|
+
/** Read the signed operation's progress. Consumption alone does not prove completion. */
|
|
5503
|
+
observe: Operation.query("accounts.approvals.observe", {
|
|
5504
|
+
input: Schema.Struct({ approvalId: ApprovalIdSchema }),
|
|
5505
|
+
output: Schema.Struct({
|
|
5506
|
+
approval: ApprovalSchema,
|
|
5507
|
+
completed: Schema.Boolean
|
|
5508
|
+
}),
|
|
5509
|
+
errors: [
|
|
5510
|
+
...CALL$10,
|
|
5511
|
+
...DEFECTS,
|
|
5512
|
+
...APPROVAL,
|
|
5513
|
+
"SUPERSEDED",
|
|
5514
|
+
"TRANSACTION_FAILED"
|
|
5515
|
+
]
|
|
5516
|
+
}),
|
|
5480
5517
|
/** The person opened the approval page: stamp the first review of a pending approval. */
|
|
5481
5518
|
review: Operation.mutation("accounts.approvals.review", {
|
|
5482
5519
|
input: Schema.Struct({ approvalId: ApprovalIdSchema }),
|
|
@@ -6819,6 +6856,12 @@ function failureFingerprint(code, mode, operation) {
|
|
|
6819
6856
|
//#endregion
|
|
6820
6857
|
//#region ../protocol/src/errors/schema.ts
|
|
6821
6858
|
const FailureModeSchema$1 = Schema.Literals(FAILURE_MODES$1);
|
|
6859
|
+
Schema.Struct({
|
|
6860
|
+
reason: Schema.Literals(ROLE_PERMISSION_DENIED_REASONS),
|
|
6861
|
+
operation: Schema.optionalKey(Schema.String),
|
|
6862
|
+
remaining: Schema.optionalKey(AssetAmountSchema),
|
|
6863
|
+
required: Schema.optionalKey(AssetAmountSchema)
|
|
6864
|
+
});
|
|
6822
6865
|
const ChainUpstreamSchema$1 = Schema.Literals(CHAIN_UPSTREAMS);
|
|
6823
6866
|
const ChainCauseSchema = Schema.Struct({
|
|
6824
6867
|
mode: FailureModeSchema$1,
|
|
@@ -9440,6 +9483,7 @@ const inboxes = {
|
|
|
9440
9483
|
input: Schema.Struct({
|
|
9441
9484
|
actor,
|
|
9442
9485
|
paymentRequestId: Schema.String,
|
|
9486
|
+
requestKey: Schema.optionalKey(nonEmpty("requestKey")),
|
|
9443
9487
|
timing: Schema.optionalKey(PaymentTiming),
|
|
9444
9488
|
permissionId: Schema.optionalKey(Schema.String)
|
|
9445
9489
|
}),
|
|
@@ -9816,7 +9860,8 @@ const PEOPLE_OPERATIONS = {
|
|
|
9816
9860
|
expire: "accounts.approvals.expire",
|
|
9817
9861
|
recordApproval: "accounts.approvals.recordApproval",
|
|
9818
9862
|
recordExpiry: "accounts.approvals.recordExpiry",
|
|
9819
|
-
sendApproved: "accounts.approvals.sendApproved"
|
|
9863
|
+
sendApproved: "accounts.approvals.sendApproved",
|
|
9864
|
+
rescheduleApproved: "accounts.approvals.rescheduleApproved"
|
|
9820
9865
|
},
|
|
9821
9866
|
balances: { readBinding: "accounts.balances.readBinding" },
|
|
9822
9867
|
claims: {
|
|
@@ -13703,7 +13748,7 @@ function mapAccountLifecycle(input) {
|
|
|
13703
13748
|
}
|
|
13704
13749
|
//#endregion
|
|
13705
13750
|
//#region package.json
|
|
13706
|
-
var version = "4.20.0-beta.
|
|
13751
|
+
var version = "4.20.0-beta.35";
|
|
13707
13752
|
//#endregion
|
|
13708
13753
|
//#region src/observability/telemetry/exception-projection.ts
|
|
13709
13754
|
/** Fixed fallback for failures that have no safe message. */
|
|
@@ -14476,6 +14521,127 @@ function mapOk(result, f) {
|
|
|
14476
14521
|
}
|
|
14477
14522
|
}
|
|
14478
14523
|
//#endregion
|
|
14524
|
+
//#region ../protocol/src/evm/test-assets.ts
|
|
14525
|
+
const SYNTHETIC_TEST_ASSET_SOURCE = "synthetic-test-liquidity";
|
|
14526
|
+
/**
|
|
14527
|
+
* Owned test assets, with metadata read from each creation receipt and contract.
|
|
14528
|
+
* Settlement admission lives in assets.ts. The fixed test exchange uses the
|
|
14529
|
+
* original five assets; bank EURC has its own deployment.
|
|
14530
|
+
*
|
|
14531
|
+
* `symbol` is the display string the owned contract returns. A
|
|
14532
|
+
* provider-supported USDC would be a different contract at a different
|
|
14533
|
+
* address returning the same symbol, which is why the resolvers below key on
|
|
14534
|
+
* `assetId`, or on chain plus address, and never on a symbol.
|
|
14535
|
+
*/
|
|
14536
|
+
const SYNTHETIC_TEST_ASSET_FIXTURES = {
|
|
14537
|
+
usdc: {
|
|
14538
|
+
assetId: assetIdFor(84532, "0x06ba8b863ca77490b0e7008427562bdbfcff730e"),
|
|
14539
|
+
chainId: toChainId(84532),
|
|
14540
|
+
tokenAddress: "0x06ba8b863ca77490b0e7008427562bdbfcff730e",
|
|
14541
|
+
symbol: "USDC",
|
|
14542
|
+
decimals: 6,
|
|
14543
|
+
peg: toCurrencyCode("USD"),
|
|
14544
|
+
deploymentStartBlock: 46690061,
|
|
14545
|
+
deploymentTransaction: "0x2661b7af5f62b9e31c707a59746cda65b90ba4448852317ac1968162fb94ff52",
|
|
14546
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
14547
|
+
},
|
|
14548
|
+
usdt: {
|
|
14549
|
+
assetId: assetIdFor(84532, "0xcb5f361ae070e75d573941b8cd54995fa3876d75"),
|
|
14550
|
+
chainId: toChainId(84532),
|
|
14551
|
+
tokenAddress: "0xcb5f361ae070e75d573941b8cd54995fa3876d75",
|
|
14552
|
+
symbol: "USDT",
|
|
14553
|
+
decimals: 6,
|
|
14554
|
+
peg: toCurrencyCode("USD"),
|
|
14555
|
+
deploymentStartBlock: 46690061,
|
|
14556
|
+
deploymentTransaction: "0x98e5303f97974a31eddb61ad030072d900ce7283ce8080bfe0b9e5ea6f297749",
|
|
14557
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
14558
|
+
},
|
|
14559
|
+
weth: {
|
|
14560
|
+
assetId: assetIdFor(84532, "0x85b7bd39ce3df9a85135e1e307225dd435f67e47"),
|
|
14561
|
+
chainId: toChainId(84532),
|
|
14562
|
+
tokenAddress: "0x85b7bd39ce3df9a85135e1e307225dd435f67e47",
|
|
14563
|
+
symbol: "WETH",
|
|
14564
|
+
decimals: 18,
|
|
14565
|
+
peg: null,
|
|
14566
|
+
deploymentStartBlock: 46690061,
|
|
14567
|
+
deploymentTransaction: "0x48dfacc01c15adc34f6c629aec5c9ff7bb84176d448017da0d0d4fdaf8b5a68a",
|
|
14568
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
14569
|
+
},
|
|
14570
|
+
wbtc: {
|
|
14571
|
+
assetId: assetIdFor(84532, "0xcf433a81f507dcc88c2c404650ffafb40750b451"),
|
|
14572
|
+
chainId: toChainId(84532),
|
|
14573
|
+
tokenAddress: "0xcf433a81f507dcc88c2c404650ffafb40750b451",
|
|
14574
|
+
symbol: "WBTC",
|
|
14575
|
+
decimals: 8,
|
|
14576
|
+
peg: null,
|
|
14577
|
+
deploymentStartBlock: 46690061,
|
|
14578
|
+
deploymentTransaction: "0xa975fcda0a67509742243bbfc386032d2e0d6ca78404c255fae2e4ffae1c7f4d",
|
|
14579
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
14580
|
+
},
|
|
14581
|
+
cngn: {
|
|
14582
|
+
assetId: assetIdFor(84532, "0xda515a7267e190710f0003f951c62bcfd70d6b2a"),
|
|
14583
|
+
chainId: toChainId(84532),
|
|
14584
|
+
tokenAddress: "0xda515a7267e190710f0003f951c62bcfd70d6b2a",
|
|
14585
|
+
symbol: "cNGN",
|
|
14586
|
+
decimals: 6,
|
|
14587
|
+
peg: toCurrencyCode("NGN"),
|
|
14588
|
+
deploymentStartBlock: 46690061,
|
|
14589
|
+
deploymentTransaction: "0x6f6b0302448c7cd7db5c118a8250e548c6e72821df373e5a27550e5cdfa635a1",
|
|
14590
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
14591
|
+
},
|
|
14592
|
+
eurc: {
|
|
14593
|
+
assetId: assetIdFor(84532, "0x15055b4ed1d248c169b92705757cd9c3d985ad5f"),
|
|
14594
|
+
chainId: toChainId(84532),
|
|
14595
|
+
tokenAddress: "0x15055b4ed1d248c169b92705757cd9c3d985ad5f",
|
|
14596
|
+
symbol: "EURC",
|
|
14597
|
+
decimals: 6,
|
|
14598
|
+
peg: toCurrencyCode("EUR"),
|
|
14599
|
+
deploymentStartBlock: 47893251,
|
|
14600
|
+
deploymentTransaction: "0x4e0ab412d980a672336487afd10da007d51f34f17876b19b13732c8125be90ca",
|
|
14601
|
+
source: SYNTHETIC_TEST_ASSET_SOURCE
|
|
14602
|
+
}
|
|
14603
|
+
};
|
|
14604
|
+
/** EURC is minted for bank deposits and has no admission to the fixed test exchange. */
|
|
14605
|
+
const SYNTHETIC_TEST_ASSETS = [...[
|
|
14606
|
+
SYNTHETIC_TEST_ASSET_FIXTURES.usdc,
|
|
14607
|
+
SYNTHETIC_TEST_ASSET_FIXTURES.usdt,
|
|
14608
|
+
SYNTHETIC_TEST_ASSET_FIXTURES.weth,
|
|
14609
|
+
SYNTHETIC_TEST_ASSET_FIXTURES.wbtc,
|
|
14610
|
+
SYNTHETIC_TEST_ASSET_FIXTURES.cngn
|
|
14611
|
+
], SYNTHETIC_TEST_ASSET_FIXTURES.eurc];
|
|
14612
|
+
toChainId(84532);
|
|
14613
|
+
/**
|
|
14614
|
+
* The settlement tier: the owned test assets admitted to the exact-transfer
|
|
14615
|
+
* path and to the treasury reads. USDC, USDT, WETH and EURC are admitted assets.
|
|
14616
|
+
* There is no default token.
|
|
14617
|
+
*/
|
|
14618
|
+
const SETTLEMENT_ASSETS_BASE_SEPOLIA = Object.freeze({
|
|
14619
|
+
CAPXUL_TEST_USDC: SYNTHETIC_TEST_ASSET_FIXTURES.usdc,
|
|
14620
|
+
CAPXUL_TEST_USDT: SYNTHETIC_TEST_ASSET_FIXTURES.usdt,
|
|
14621
|
+
CAPXUL_TEST_WETH: SYNTHETIC_TEST_ASSET_FIXTURES.weth,
|
|
14622
|
+
CAPXUL_TEST_EURC: SYNTHETIC_TEST_ASSET_FIXTURES.eurc
|
|
14623
|
+
});
|
|
14624
|
+
const CONFIGURED_MONEY_ASSETS = Object.freeze(Object.values(SETTLEMENT_ASSETS_BASE_SEPOLIA));
|
|
14625
|
+
/** Public AssetIds for the admitted Base Sepolia test assets. */
|
|
14626
|
+
const TOKENS = Object.freeze({ BASE_SEPOLIA: Object.freeze({
|
|
14627
|
+
CAPXUL_TEST_USDC: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_USDC.assetId,
|
|
14628
|
+
CAPXUL_TEST_USDT: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_USDT.assetId,
|
|
14629
|
+
CAPXUL_TEST_WETH: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_WETH.assetId,
|
|
14630
|
+
CAPXUL_TEST_EURC: SETTLEMENT_ASSETS_BASE_SEPOLIA.CAPXUL_TEST_EURC.assetId
|
|
14631
|
+
}) });
|
|
14632
|
+
/**
|
|
14633
|
+
* Every known asset in ONE identity space. The tiers above declare admission;
|
|
14634
|
+
* this is the only list an identity resolves against, so an asset is never
|
|
14635
|
+
* two different things depending on which list a caller happened to read.
|
|
14636
|
+
*/
|
|
14637
|
+
const MONEY_ASSET_REGISTRY = [...SYNTHETIC_TEST_ASSETS];
|
|
14638
|
+
CONFIGURED_MONEY_ASSETS.map((asset) => asset.tokenAddress.toLowerCase());
|
|
14639
|
+
/** The registry row for `assetId` across every tier, or `null`. */
|
|
14640
|
+
function configuredMoneyAssetById(assetId) {
|
|
14641
|
+
const canonical = toAssetId(assetId);
|
|
14642
|
+
return MONEY_ASSET_REGISTRY.find((asset) => asset.assetId === canonical) ?? null;
|
|
14643
|
+
}
|
|
14644
|
+
//#endregion
|
|
14479
14645
|
//#region src/platform/transport/call-operation.ts
|
|
14480
14646
|
function callOperation(port, row, args, options) {
|
|
14481
14647
|
const op = row;
|
|
@@ -15649,6 +15815,23 @@ async function verifyPaymentDocumentSignatureV3(input) {
|
|
|
15649
15815
|
})).toLowerCase() === envelope.signature.signer;
|
|
15650
15816
|
}
|
|
15651
15817
|
//#endregion
|
|
15818
|
+
//#region ../protocol/src/documents/identities.ts
|
|
15819
|
+
/** A caller handed this module a value its own types rule out: a defect, named. */
|
|
15820
|
+
function defect$1(step, message) {
|
|
15821
|
+
return new CapxulError("UNKNOWN", message, { details: { step } });
|
|
15822
|
+
}
|
|
15823
|
+
function hashDocumentOriginIdV3(input) {
|
|
15824
|
+
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");
|
|
15825
|
+
return keccak256(encodeAbiParameters(parseAbiParameters("string namespace, uint256 chainId, string actorKind, string actorId, string requestKey, uint256 itemIndex"), [
|
|
15826
|
+
"capxul.document-origin.v3",
|
|
15827
|
+
BigInt(input.chainId),
|
|
15828
|
+
input.actorKind,
|
|
15829
|
+
input.actorId,
|
|
15830
|
+
input.requestKey,
|
|
15831
|
+
BigInt(input.itemIndex)
|
|
15832
|
+
]));
|
|
15833
|
+
}
|
|
15834
|
+
//#endregion
|
|
15652
15835
|
//#region src/documents/birth-context.ts
|
|
15653
15836
|
function sourcePurpose(source) {
|
|
15654
15837
|
if ("purposeKind" in source) return source.purposeKind;
|
|
@@ -15663,13 +15846,20 @@ function isBirthItem(item) {
|
|
|
15663
15846
|
function requestRetryInstruction(input) {
|
|
15664
15847
|
const request = input.evidence.request;
|
|
15665
15848
|
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" ||
|
|
15849
|
+
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
15850
|
const document = original.items[input.index]?.document;
|
|
15668
15851
|
if (document?.kind !== "envelope") return void 0;
|
|
15669
15852
|
const bytes = decodeCanonicalBase64V3(document.bytesBase64);
|
|
15670
15853
|
const envelope = decodeSupportedPaymentDocumentEnvelope(bytes);
|
|
15671
15854
|
if (envelope.primaryType !== "Memo" && envelope.primaryType !== "Invoice") return void 0;
|
|
15672
15855
|
if (envelope.version === 5) return void 0;
|
|
15856
|
+
if (original.lineage.requestId !== original.requestKey && (original.lineage.kind !== "payment_request" || envelope.primaryType !== "Invoice" || envelope.message.originId !== hashDocumentOriginIdV3({
|
|
15857
|
+
chainId: input.evidence.chainId,
|
|
15858
|
+
actorKind: original.actor.kind,
|
|
15859
|
+
actorId: original.actor.kind === "account" ? original.actor.accountId : original.actor.orgId,
|
|
15860
|
+
requestKey: original.lineage.requestId,
|
|
15861
|
+
itemIndex: input.index
|
|
15862
|
+
}))) return void 0;
|
|
15673
15863
|
return {
|
|
15674
15864
|
documentHash: hashSupportedPaymentDocument(envelope),
|
|
15675
15865
|
contentHash: hashPaymentDocumentContentV3(bytes),
|
|
@@ -15698,11 +15888,7 @@ function requestBirthContext(evidence) {
|
|
|
15698
15888
|
].some((items) => items?.length !== 1)) return null;
|
|
15699
15889
|
const item = command.items[0];
|
|
15700
15890
|
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;
|
|
15891
|
+
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
15892
|
return {
|
|
15707
15893
|
source: source.items,
|
|
15708
15894
|
actorKind: source.actor.kind,
|
|
@@ -15728,127 +15914,6 @@ function retryBirthContext(evidence) {
|
|
|
15728
15914
|
};
|
|
15729
15915
|
}
|
|
15730
15916
|
//#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
15917
|
//#region ../protocol/src/documents/receipts.ts
|
|
15853
15918
|
async function parseSupportingReceiptV3(input) {
|
|
15854
15919
|
const supporting = SchemaParser.decodeUnknownSync(SupportingReceiptInputSchema, { onExcessProperty: "error" })(input);
|
|
@@ -15879,23 +15944,6 @@ async function parseSupportingReceiptV3(input) {
|
|
|
15879
15944
|
};
|
|
15880
15945
|
}
|
|
15881
15946
|
//#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
15947
|
//#region ../protocol/src/documents/context.ts
|
|
15900
15948
|
function sameAmount(left, right) {
|
|
15901
15949
|
return left.asset === right.asset && left.minorUnits === right.minorUnits && left.decimals === right.decimals;
|
|
@@ -16176,6 +16224,25 @@ function verifiesInvoiceCheckoutBirthEvidence(evidence, invoice, chainId, source
|
|
|
16176
16224
|
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
16225
|
}
|
|
16178
16226
|
//#endregion
|
|
16227
|
+
//#region ../protocol/src/payments/execution-identity.ts
|
|
16228
|
+
/** A command and its exact signed operation have one durable execution identity. */
|
|
16229
|
+
function moneyExecutionId(commandId, digest) {
|
|
16230
|
+
return `money_execution_${keccak256(encodeAbiParameters([
|
|
16231
|
+
{ type: "string" },
|
|
16232
|
+
{ type: "string" },
|
|
16233
|
+
{ type: "bytes32" }
|
|
16234
|
+
], [
|
|
16235
|
+
"capxul.money-execution.v1",
|
|
16236
|
+
commandId,
|
|
16237
|
+
toLowerBytes32(digest)
|
|
16238
|
+
])).slice(2)}`;
|
|
16239
|
+
}
|
|
16240
|
+
/** Existing stored executions keep their digest-derived identity. */
|
|
16241
|
+
function matchesMoneyExecutionId(executionId, digest, commandId) {
|
|
16242
|
+
const exactDigest = toLowerBytes32(digest);
|
|
16243
|
+
return executionId === `money_execution_${exactDigest.slice(2)}` || commandId !== void 0 && executionId === moneyExecutionId(commandId, exactDigest);
|
|
16244
|
+
}
|
|
16245
|
+
//#endregion
|
|
16179
16246
|
//#region ../protocol/src/evm/payments-abi.ts
|
|
16180
16247
|
/** The exact compiled CapxulPaymentsV2 ABI. */
|
|
16181
16248
|
const CAPXUL_PAYMENTS_V2_ABI = [
|
|
@@ -16822,6 +16889,313 @@ const CAPXUL_PAYMENTS_V2_ABI = [
|
|
|
16822
16889
|
/** Immutable CapxulPaymentsV2 deployment on Base Sepolia. */
|
|
16823
16890
|
const CAPXUL_PAYMENTS_V2_ADDRESS = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
|
|
16824
16891
|
//#endregion
|
|
16892
|
+
//#region ../protocol/src/evm/payments-v3.ts
|
|
16893
|
+
const PAYMENT_ITEM_COMPONENTS = [
|
|
16894
|
+
{
|
|
16895
|
+
name: "settlementId",
|
|
16896
|
+
type: "bytes32",
|
|
16897
|
+
internalType: "bytes32"
|
|
16898
|
+
},
|
|
16899
|
+
{
|
|
16900
|
+
name: "recipient",
|
|
16901
|
+
type: "address",
|
|
16902
|
+
internalType: "address"
|
|
16903
|
+
},
|
|
16904
|
+
{
|
|
16905
|
+
name: "token",
|
|
16906
|
+
type: "address",
|
|
16907
|
+
internalType: "address"
|
|
16908
|
+
},
|
|
16909
|
+
{
|
|
16910
|
+
name: "amount",
|
|
16911
|
+
type: "uint256",
|
|
16912
|
+
internalType: "uint256"
|
|
16913
|
+
},
|
|
16914
|
+
{
|
|
16915
|
+
name: "kind",
|
|
16916
|
+
type: "uint16",
|
|
16917
|
+
internalType: "uint16"
|
|
16918
|
+
},
|
|
16919
|
+
{
|
|
16920
|
+
name: "documentHash",
|
|
16921
|
+
type: "bytes32",
|
|
16922
|
+
internalType: "bytes32"
|
|
16923
|
+
},
|
|
16924
|
+
{
|
|
16925
|
+
name: "jobNonce",
|
|
16926
|
+
type: "bytes32",
|
|
16927
|
+
internalType: "bytes32"
|
|
16928
|
+
},
|
|
16929
|
+
{
|
|
16930
|
+
name: "executor",
|
|
16931
|
+
type: "address",
|
|
16932
|
+
internalType: "address"
|
|
16933
|
+
}
|
|
16934
|
+
];
|
|
16935
|
+
const PAYMENT_ITEM_INPUT = {
|
|
16936
|
+
name: "item",
|
|
16937
|
+
type: "tuple",
|
|
16938
|
+
internalType: "struct CapxulPaymentsV3.PaymentItem",
|
|
16939
|
+
components: PAYMENT_ITEM_COMPONENTS
|
|
16940
|
+
};
|
|
16941
|
+
/** The exact compiled CapxulPaymentsV3 ABI. */
|
|
16942
|
+
const CAPXUL_PAYMENTS_V3_ABI = [
|
|
16943
|
+
{
|
|
16944
|
+
type: "function",
|
|
16945
|
+
name: "paymentId",
|
|
16946
|
+
inputs: [PAYMENT_ITEM_INPUT],
|
|
16947
|
+
outputs: [{
|
|
16948
|
+
name: "",
|
|
16949
|
+
type: "bytes32",
|
|
16950
|
+
internalType: "bytes32"
|
|
16951
|
+
}],
|
|
16952
|
+
stateMutability: "view"
|
|
16953
|
+
},
|
|
16954
|
+
{
|
|
16955
|
+
type: "function",
|
|
16956
|
+
name: "send",
|
|
16957
|
+
inputs: [PAYMENT_ITEM_INPUT],
|
|
16958
|
+
outputs: [],
|
|
16959
|
+
stateMutability: "nonpayable"
|
|
16960
|
+
},
|
|
16961
|
+
{
|
|
16962
|
+
type: "function",
|
|
16963
|
+
name: "sendBatch",
|
|
16964
|
+
inputs: [{
|
|
16965
|
+
name: "items",
|
|
16966
|
+
type: "tuple[]",
|
|
16967
|
+
internalType: "struct CapxulPaymentsV3.PaymentItem[]",
|
|
16968
|
+
components: PAYMENT_ITEM_COMPONENTS
|
|
16969
|
+
}],
|
|
16970
|
+
outputs: [],
|
|
16971
|
+
stateMutability: "nonpayable"
|
|
16972
|
+
},
|
|
16973
|
+
{
|
|
16974
|
+
type: "function",
|
|
16975
|
+
name: "settled",
|
|
16976
|
+
inputs: [{
|
|
16977
|
+
name: "",
|
|
16978
|
+
type: "bytes32",
|
|
16979
|
+
internalType: "bytes32"
|
|
16980
|
+
}],
|
|
16981
|
+
outputs: [{
|
|
16982
|
+
name: "",
|
|
16983
|
+
type: "bool",
|
|
16984
|
+
internalType: "bool"
|
|
16985
|
+
}],
|
|
16986
|
+
stateMutability: "view"
|
|
16987
|
+
},
|
|
16988
|
+
{
|
|
16989
|
+
type: "event",
|
|
16990
|
+
name: "PaymentSent",
|
|
16991
|
+
inputs: [
|
|
16992
|
+
{
|
|
16993
|
+
name: "settlementId",
|
|
16994
|
+
type: "bytes32",
|
|
16995
|
+
indexed: true,
|
|
16996
|
+
internalType: "bytes32"
|
|
16997
|
+
},
|
|
16998
|
+
{
|
|
16999
|
+
name: "sender",
|
|
17000
|
+
type: "address",
|
|
17001
|
+
indexed: true,
|
|
17002
|
+
internalType: "address"
|
|
17003
|
+
},
|
|
17004
|
+
{
|
|
17005
|
+
name: "recipient",
|
|
17006
|
+
type: "address",
|
|
17007
|
+
indexed: true,
|
|
17008
|
+
internalType: "address"
|
|
17009
|
+
},
|
|
17010
|
+
{
|
|
17011
|
+
name: "token",
|
|
17012
|
+
type: "address",
|
|
17013
|
+
indexed: false,
|
|
17014
|
+
internalType: "address"
|
|
17015
|
+
},
|
|
17016
|
+
{
|
|
17017
|
+
name: "amount",
|
|
17018
|
+
type: "uint256",
|
|
17019
|
+
indexed: false,
|
|
17020
|
+
internalType: "uint256"
|
|
17021
|
+
},
|
|
17022
|
+
{
|
|
17023
|
+
name: "kind",
|
|
17024
|
+
type: "uint16",
|
|
17025
|
+
indexed: false,
|
|
17026
|
+
internalType: "uint16"
|
|
17027
|
+
},
|
|
17028
|
+
{
|
|
17029
|
+
name: "documentHash",
|
|
17030
|
+
type: "bytes32",
|
|
17031
|
+
indexed: false,
|
|
17032
|
+
internalType: "bytes32"
|
|
17033
|
+
}
|
|
17034
|
+
],
|
|
17035
|
+
anonymous: false
|
|
17036
|
+
},
|
|
17037
|
+
{
|
|
17038
|
+
type: "error",
|
|
17039
|
+
name: "InexactTransfer",
|
|
17040
|
+
inputs: [
|
|
17041
|
+
{
|
|
17042
|
+
name: "token",
|
|
17043
|
+
type: "address",
|
|
17044
|
+
internalType: "address"
|
|
17045
|
+
},
|
|
17046
|
+
{
|
|
17047
|
+
name: "expected",
|
|
17048
|
+
type: "uint256",
|
|
17049
|
+
internalType: "uint256"
|
|
17050
|
+
},
|
|
17051
|
+
{
|
|
17052
|
+
name: "received",
|
|
17053
|
+
type: "uint256",
|
|
17054
|
+
internalType: "uint256"
|
|
17055
|
+
}
|
|
17056
|
+
]
|
|
17057
|
+
},
|
|
17058
|
+
{
|
|
17059
|
+
type: "error",
|
|
17060
|
+
name: "InvalidExecutor",
|
|
17061
|
+
inputs: [{
|
|
17062
|
+
name: "expected",
|
|
17063
|
+
type: "address",
|
|
17064
|
+
internalType: "address"
|
|
17065
|
+
}, {
|
|
17066
|
+
name: "supplied",
|
|
17067
|
+
type: "address",
|
|
17068
|
+
internalType: "address"
|
|
17069
|
+
}]
|
|
17070
|
+
},
|
|
17071
|
+
{
|
|
17072
|
+
type: "error",
|
|
17073
|
+
name: "PaymentIdMismatch",
|
|
17074
|
+
inputs: [{
|
|
17075
|
+
name: "expected",
|
|
17076
|
+
type: "bytes32",
|
|
17077
|
+
internalType: "bytes32"
|
|
17078
|
+
}, {
|
|
17079
|
+
name: "supplied",
|
|
17080
|
+
type: "bytes32",
|
|
17081
|
+
internalType: "bytes32"
|
|
17082
|
+
}]
|
|
17083
|
+
},
|
|
17084
|
+
{
|
|
17085
|
+
type: "error",
|
|
17086
|
+
name: "ReentrantCall",
|
|
17087
|
+
inputs: []
|
|
17088
|
+
},
|
|
17089
|
+
{
|
|
17090
|
+
type: "error",
|
|
17091
|
+
name: "SettlementIdConsumed",
|
|
17092
|
+
inputs: [{
|
|
17093
|
+
name: "settlementId",
|
|
17094
|
+
type: "bytes32",
|
|
17095
|
+
internalType: "bytes32"
|
|
17096
|
+
}]
|
|
17097
|
+
},
|
|
17098
|
+
{
|
|
17099
|
+
type: "error",
|
|
17100
|
+
name: "TokenCallReturnedFalse",
|
|
17101
|
+
inputs: [{
|
|
17102
|
+
name: "token",
|
|
17103
|
+
type: "address",
|
|
17104
|
+
internalType: "address"
|
|
17105
|
+
}]
|
|
17106
|
+
},
|
|
17107
|
+
{
|
|
17108
|
+
type: "error",
|
|
17109
|
+
name: "TokenHasNoCode",
|
|
17110
|
+
inputs: [{
|
|
17111
|
+
name: "token",
|
|
17112
|
+
type: "address",
|
|
17113
|
+
internalType: "address"
|
|
17114
|
+
}]
|
|
17115
|
+
},
|
|
17116
|
+
{
|
|
17117
|
+
type: "error",
|
|
17118
|
+
name: "ZeroAddress",
|
|
17119
|
+
inputs: []
|
|
17120
|
+
},
|
|
17121
|
+
{
|
|
17122
|
+
type: "error",
|
|
17123
|
+
name: "ZeroAmount",
|
|
17124
|
+
inputs: []
|
|
17125
|
+
},
|
|
17126
|
+
{
|
|
17127
|
+
type: "error",
|
|
17128
|
+
name: "ZeroDocumentHash",
|
|
17129
|
+
inputs: []
|
|
17130
|
+
},
|
|
17131
|
+
{
|
|
17132
|
+
type: "error",
|
|
17133
|
+
name: "ZeroJobNonce",
|
|
17134
|
+
inputs: []
|
|
17135
|
+
},
|
|
17136
|
+
{
|
|
17137
|
+
type: "error",
|
|
17138
|
+
name: "ZeroSettlementId",
|
|
17139
|
+
inputs: []
|
|
17140
|
+
}
|
|
17141
|
+
];
|
|
17142
|
+
/** The fixed CREATE2 deployment on every admitted chain. */
|
|
17143
|
+
const CAPXUL_PAYMENTS_V3_ADDRESS = "0x46b28f455c8de7c1505e3185A3f8f87B07eaE1aE";
|
|
17144
|
+
//#endregion
|
|
17145
|
+
//#region ../protocol/src/evm/payments/encoding.ts
|
|
17146
|
+
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)"));
|
|
17147
|
+
function paymentJobNonce(commandId, itemIndex) {
|
|
17148
|
+
if (!Number.isSafeInteger(itemIndex) || itemIndex < 0) throw Errors.invalidInput("itemIndex", "must be a non-negative safe integer");
|
|
17149
|
+
return sha256(toBytes(`{"commandId":${JSON.stringify(commandId)},"index":${itemIndex},"version":1}`));
|
|
17150
|
+
}
|
|
17151
|
+
function capxulPaymentsV3PaymentId(chainId, router, item) {
|
|
17152
|
+
return keccak256(encodeAbiParameters(parseAbiParameters("bytes32,uint256,address,bytes32,address,address,address,uint256,uint16,bytes32"), [
|
|
17153
|
+
CAPXUL_PAYMENT_V3_TYPEHASH,
|
|
17154
|
+
BigInt(chainId),
|
|
17155
|
+
router,
|
|
17156
|
+
item.jobNonce,
|
|
17157
|
+
item.executor,
|
|
17158
|
+
item.recipient,
|
|
17159
|
+
item.token,
|
|
17160
|
+
item.amount,
|
|
17161
|
+
item.kind,
|
|
17162
|
+
item.documentHash
|
|
17163
|
+
]));
|
|
17164
|
+
}
|
|
17165
|
+
function encodeCapxulPaymentsV3Send(item) {
|
|
17166
|
+
return encodeFunctionData({
|
|
17167
|
+
abi: CAPXUL_PAYMENTS_V3_ABI,
|
|
17168
|
+
functionName: "send",
|
|
17169
|
+
args: [item]
|
|
17170
|
+
});
|
|
17171
|
+
}
|
|
17172
|
+
function encodeCapxulPaymentsV3SendBatch(items) {
|
|
17173
|
+
return encodeFunctionData({
|
|
17174
|
+
abi: CAPXUL_PAYMENTS_V3_ABI,
|
|
17175
|
+
functionName: "sendBatch",
|
|
17176
|
+
args: [items]
|
|
17177
|
+
});
|
|
17178
|
+
}
|
|
17179
|
+
function v3Item(command, item, itemIndex) {
|
|
17180
|
+
const { commandId, chainId, senderSafe } = command;
|
|
17181
|
+
if (commandId === void 0 || chainId === void 0 || senderSafe === void 0) throw Errors.invalidInput("command", "CapxulPaymentsV3 requires its command identity");
|
|
17182
|
+
const terms = {
|
|
17183
|
+
recipient: item.recipientSafe,
|
|
17184
|
+
token: item.tokenAddress,
|
|
17185
|
+
amount: BigInt(item.rawAmount),
|
|
17186
|
+
kind: item.kind,
|
|
17187
|
+
documentHash: item.documentHash,
|
|
17188
|
+
jobNonce: item.jobNonce ?? paymentJobNonce(commandId, itemIndex),
|
|
17189
|
+
executor: item.executor ?? senderSafe
|
|
17190
|
+
};
|
|
17191
|
+
const settlementId = capxulPaymentsV3PaymentId(chainId, command.contractAddress, terms);
|
|
17192
|
+
if (settlementId.toLowerCase() !== item.settlementId.toLowerCase()) throw Errors.invalidInput("settlementId", "does not match CapxulPaymentsV3 terms");
|
|
17193
|
+
return {
|
|
17194
|
+
settlementId,
|
|
17195
|
+
...terms
|
|
17196
|
+
};
|
|
17197
|
+
}
|
|
17198
|
+
//#endregion
|
|
16825
17199
|
//#region ../protocol/src/evm/zodiac-abi.ts
|
|
16826
17200
|
const MODULE_PROXY_FACTORY_ABI = [{
|
|
16827
17201
|
type: "function",
|
|
@@ -17185,7 +17559,8 @@ function requiredByPaymentToken(items) {
|
|
|
17185
17559
|
}
|
|
17186
17560
|
return totals;
|
|
17187
17561
|
}
|
|
17188
|
-
function birthCall(
|
|
17562
|
+
function birthCall(command, item, itemIndex) {
|
|
17563
|
+
const contract = command.contractAddress;
|
|
17189
17564
|
const common = {
|
|
17190
17565
|
settlementId: item.settlementId,
|
|
17191
17566
|
recipient: item.recipientSafe,
|
|
@@ -17196,7 +17571,7 @@ function birthCall(contract, item) {
|
|
|
17196
17571
|
return {
|
|
17197
17572
|
to: contract,
|
|
17198
17573
|
value: 0n,
|
|
17199
|
-
data: item.operation === "send" ? encodeCapxulPaymentsV2Send({
|
|
17574
|
+
data: item.operation === "send" ? contract.toLowerCase() === "0x46b28f455c8de7c1505e3185A3f8f87B07eaE1aE".toLowerCase() ? encodeCapxulPaymentsV3Send(v3Item(command, item, itemIndex)) : encodeCapxulPaymentsV2Send({
|
|
17200
17575
|
...common,
|
|
17201
17576
|
amount: BigInt(item.rawAmount)
|
|
17202
17577
|
}) : encodeCapxulPaymentsV2CreateCommitment({
|
|
@@ -17208,7 +17583,8 @@ function birthCall(contract, item) {
|
|
|
17208
17583
|
})
|
|
17209
17584
|
};
|
|
17210
17585
|
}
|
|
17211
|
-
function birthCalls(
|
|
17586
|
+
function birthCalls(command, items) {
|
|
17587
|
+
const contract = command.contractAddress;
|
|
17212
17588
|
const approvals = [...requiredByPaymentToken(items).values()].map(({ token, total }) => ({
|
|
17213
17589
|
to: token,
|
|
17214
17590
|
value: 0n,
|
|
@@ -17222,7 +17598,7 @@ function birthCalls(contract, items) {
|
|
|
17222
17598
|
if (items.length > 1 && sends.length === items.length) return [...approvals, {
|
|
17223
17599
|
to: contract,
|
|
17224
17600
|
value: 0n,
|
|
17225
|
-
data: encodeCapxulPaymentsV2SendBatch(sends.map((item) => ({
|
|
17601
|
+
data: contract.toLowerCase() === "0x46b28f455c8de7c1505e3185A3f8f87B07eaE1aE".toLowerCase() ? encodeCapxulPaymentsV3SendBatch(sends.map((item, index) => v3Item(command, item, index))) : encodeCapxulPaymentsV2SendBatch(sends.map((item) => ({
|
|
17226
17602
|
settlementId: item.settlementId,
|
|
17227
17603
|
recipient: item.recipientSafe,
|
|
17228
17604
|
token: item.tokenAddress,
|
|
@@ -17231,7 +17607,7 @@ function birthCalls(contract, items) {
|
|
|
17231
17607
|
documentHash: item.documentHash
|
|
17232
17608
|
})))
|
|
17233
17609
|
}];
|
|
17234
|
-
return [...approvals, ...items.map((item) => birthCall(
|
|
17610
|
+
return [...approvals, ...items.map((item, index) => birthCall(command, item, index))];
|
|
17235
17611
|
}
|
|
17236
17612
|
function lifecycleData(item) {
|
|
17237
17613
|
switch (item.operation) {
|
|
@@ -17246,7 +17622,7 @@ function encodePreparedPaymentCallData(command) {
|
|
|
17246
17622
|
if (command.items.length === 0) throw Errors.invalidInput("items", "must not be empty");
|
|
17247
17623
|
const births = command.items.filter(isBirth);
|
|
17248
17624
|
if (births.length === command.items.length) {
|
|
17249
|
-
const calls = birthCalls(command
|
|
17625
|
+
const calls = birthCalls(command, births);
|
|
17250
17626
|
return command.executionRoute.kind === "direct" ? safe4337MultiSendUserOpCallData({ calls }) : buildOrgRoleSpendPersonalCallData(buildOrgRoleMultiCall({
|
|
17251
17627
|
rolesModuleAddress: command.executionRoute.rolesModule,
|
|
17252
17628
|
roleKey: command.executionRoute.roleKey,
|
|
@@ -17309,15 +17685,16 @@ function verifiesMoneyOperation(evidence, expectedSafe, chainId, permissionId) {
|
|
|
17309
17685
|
try {
|
|
17310
17686
|
const command = evidence.preparedCommand;
|
|
17311
17687
|
const operation = evidence.userOperation;
|
|
17312
|
-
if (command === void 0 || operation === void 0
|
|
17313
|
-
|
|
17688
|
+
if (command === void 0 || operation === void 0) return false;
|
|
17689
|
+
const knownRouter = command.contractAddress.toLowerCase() === "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4".toLowerCase() || command.contractAddress.toLowerCase() === "0x46b28f455c8de7c1505e3185A3f8f87B07eaE1aE".toLowerCase();
|
|
17690
|
+
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
17691
|
const route = command.executionRoute;
|
|
17315
17692
|
if (route.kind === "direct") {
|
|
17316
17693
|
if (permissionId !== void 0 || command.senderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return false;
|
|
17317
17694
|
} else if ((permissionId === void 0 ? !isOwnerLifecycle(command) : route.roleKey.toLowerCase() !== roleKeyForPermission(permissionId).toLowerCase()) || command.senderSafe.toLowerCase() !== route.organizationSafe.toLowerCase()) return false;
|
|
17318
17695
|
if (operation.callData.toLowerCase() !== encodePreparedPaymentCallData(command).toLowerCase()) return false;
|
|
17319
17696
|
const digest = moneySafeOpDigest(operation, chainId);
|
|
17320
|
-
return evidence.digest.toLowerCase() === digest.toLowerCase() && evidence.executionId
|
|
17697
|
+
return evidence.digest.toLowerCase() === digest.toLowerCase() && matchesMoneyExecutionId(evidence.executionId, digest, evidence.commandId);
|
|
17321
17698
|
} catch {
|
|
17322
17699
|
return false;
|
|
17323
17700
|
}
|
|
@@ -17524,6 +17901,29 @@ function reportMoneyTelemetryFailure(kind, name, cause) {
|
|
|
17524
17901
|
}));
|
|
17525
17902
|
}
|
|
17526
17903
|
//#endregion
|
|
17904
|
+
//#region ../protocol/src/payments/request-finality.ts
|
|
17905
|
+
/** Add a proved request outcome without changing the original failure. */
|
|
17906
|
+
function withPaymentRequestFinality(error, paymentRequestFinality) {
|
|
17907
|
+
const marked = new CapxulError(error.code, error.message, {
|
|
17908
|
+
cause: error.cause,
|
|
17909
|
+
details: {
|
|
17910
|
+
...error.details,
|
|
17911
|
+
paymentRequestFinality
|
|
17912
|
+
},
|
|
17913
|
+
...error.correlationId === void 0 ? {} : { correlationId: error.correlationId },
|
|
17914
|
+
...error.layer === void 0 ? {} : { layer: error.layer },
|
|
17915
|
+
...error.mode === void 0 ? {} : { mode: error.mode },
|
|
17916
|
+
...error.chain === void 0 ? {} : { chain: error.chain }
|
|
17917
|
+
});
|
|
17918
|
+
marked.name = error.name;
|
|
17919
|
+
if (error.stack !== void 0) marked.stack = error.stack;
|
|
17920
|
+
return marked;
|
|
17921
|
+
}
|
|
17922
|
+
/** Only an authoritative failed-key response or confirmed durable closure resolves a key. */
|
|
17923
|
+
function isFinalPaymentRequestError(error) {
|
|
17924
|
+
return error.details?.paymentRequestFinality === "closed" || error.code === "INVALID_INPUT" && error.details?.field === "requestKey" && error.details.paymentRequestFinality === "failed";
|
|
17925
|
+
}
|
|
17926
|
+
//#endregion
|
|
17527
17927
|
//#region src/payments/prepared-execution.ts
|
|
17528
17928
|
async function abandonPrepared(deps, executionId, reason, result, onPreparedClosed) {
|
|
17529
17929
|
const abandoned = await runIfActive(void 0, executions.abandon.name, () => callOperation(deps.convexCall, executions.abandon, {
|
|
@@ -17531,8 +17931,12 @@ async function abandonPrepared(deps, executionId, reason, result, onPreparedClos
|
|
|
17531
17931
|
reason
|
|
17532
17932
|
}).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
|
|
17533
17933
|
if (!abandoned.ok) return abandoned;
|
|
17534
|
-
if (abandoned.value)
|
|
17535
|
-
|
|
17934
|
+
if (!abandoned.value) return result;
|
|
17935
|
+
onPreparedClosed?.();
|
|
17936
|
+
return result.ok ? result : {
|
|
17937
|
+
ok: false,
|
|
17938
|
+
error: withPaymentRequestFinality(result.error, "closed")
|
|
17939
|
+
};
|
|
17536
17940
|
}
|
|
17537
17941
|
async function notifyVerifiedPaymentPrepared(onPrepared, paymentId) {
|
|
17538
17942
|
if (onPrepared === void 0) return {
|
|
@@ -17576,14 +17980,31 @@ async function abandonPreparedCommand(deps, executionId, closePayment, reason, r
|
|
|
17576
17980
|
reason
|
|
17577
17981
|
})).pipe(Effect.mapError((publicError) => ({ publicError })))), controls), deps.runPromise);
|
|
17578
17982
|
if (!abandoned.ok) return abandoned;
|
|
17579
|
-
if (abandoned.value)
|
|
17580
|
-
|
|
17983
|
+
if (!abandoned.value) return result;
|
|
17984
|
+
onPreparedClosed?.();
|
|
17985
|
+
return result.ok ? result : {
|
|
17986
|
+
ok: false,
|
|
17987
|
+
error: withPaymentRequestFinality(result.error, "closed")
|
|
17988
|
+
};
|
|
17581
17989
|
}
|
|
17582
17990
|
//#endregion
|
|
17583
17991
|
//#region src/payments/command-execution.ts
|
|
17584
17992
|
function isAborted$1(signal) {
|
|
17585
17993
|
return signal?.aborted === true;
|
|
17586
17994
|
}
|
|
17995
|
+
function settledPaymentsMatch(evidence) {
|
|
17996
|
+
try {
|
|
17997
|
+
return evidence.settled?.payments.every((payment, index) => {
|
|
17998
|
+
const item = evidence.preparedCommand?.items[index];
|
|
17999
|
+
const instructions = payment.documents.filter((document) => document.role === "instruction");
|
|
18000
|
+
const amount = toExactAssetAmount(payment.amount, CONFIGURED_MONEY_ASSETS);
|
|
18001
|
+
const asset = CONFIGURED_MONEY_ASSETS.find((row) => row.assetId === amount.asset);
|
|
18002
|
+
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]);
|
|
18003
|
+
}) === true;
|
|
18004
|
+
} catch {
|
|
18005
|
+
return false;
|
|
18006
|
+
}
|
|
18007
|
+
}
|
|
17587
18008
|
async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnExit, onPreparedClosed, signal, controls, onPrepared, readAcceptedReplay, checkout, sourceWallet) {
|
|
17588
18009
|
if (isAborted$1(signal)) return {
|
|
17589
18010
|
ok: false,
|
|
@@ -17616,7 +18037,7 @@ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnE
|
|
|
17616
18037
|
const prepared = await prepare(signerAddress);
|
|
17617
18038
|
if (!current()) return cancelled;
|
|
17618
18039
|
if (!prepared.ok) return prepared;
|
|
17619
|
-
const accepted = readAcceptedReplay?.();
|
|
18040
|
+
const accepted = readAcceptedReplay?.() ?? prepared.value.settled;
|
|
17620
18041
|
const closePrepared = closePaymentOnExit && accepted === void 0;
|
|
17621
18042
|
const executionId = Schema.decodeUnknownResult(MoneyExecutionIdSchema)(readField(prepared.value, "executionId"));
|
|
17622
18043
|
if (executionId._tag === "Failure") return {
|
|
@@ -17642,12 +18063,12 @@ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnE
|
|
|
17642
18063
|
if (!verified) return abandon("prepared_mismatch", Errors.invalidInput("execution", "prepared Money operation mismatch"));
|
|
17643
18064
|
if (accepted !== void 0) {
|
|
17644
18065
|
const decodedSubmission = Schema.decodeResult(SubmittedPaymentCommandExecutionSchema, { onExcessProperty: "error" })(accepted);
|
|
17645
|
-
if (decodedSubmission._tag === "Failure" || !acceptedSubmissionMatches(evidence, decodedSubmission.success)) return {
|
|
18066
|
+
if (decodedSubmission._tag === "Failure" || !acceptedSubmissionMatches(evidence, decodedSubmission.success) || evidence.settled !== void 0 && !settledPaymentsMatch(evidence)) return {
|
|
17646
18067
|
ok: false,
|
|
17647
|
-
error: Errors.invalidInput("execution", "accepted
|
|
18068
|
+
error: Errors.invalidInput("execution", "accepted Money replay evidence mismatch")
|
|
17648
18069
|
};
|
|
17649
18070
|
if (!current() || isAborted$1(signal)) return cancelled;
|
|
17650
|
-
return {
|
|
18071
|
+
if (evidence.settled === void 0) return {
|
|
17651
18072
|
ok: true,
|
|
17652
18073
|
value: decodedSubmission.success
|
|
17653
18074
|
};
|
|
@@ -17664,6 +18085,10 @@ async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnE
|
|
|
17664
18085
|
}
|
|
17665
18086
|
if (!current()) return cancelled;
|
|
17666
18087
|
if (isAborted$1(signal)) return abandon("cancelled", Errors.cancelled({ operation: "payments" }));
|
|
18088
|
+
if (evidence.settled !== void 0) return {
|
|
18089
|
+
ok: true,
|
|
18090
|
+
value: evidence.settled
|
|
18091
|
+
};
|
|
17667
18092
|
await emitPreparedInitiation(deps, evidence);
|
|
17668
18093
|
if (!current()) return cancelled;
|
|
17669
18094
|
if (isAborted$1(signal)) return abandon("cancelled", Errors.cancelled({ operation: "payments" }));
|
|
@@ -17714,10 +18139,10 @@ function itemMatches(prepared, amount) {
|
|
|
17714
18139
|
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
18140
|
}
|
|
17716
18141
|
/** The callData a personal Payment birth item must carry: approve, then send or commit. */
|
|
17717
|
-
function expectedPersonalCallData(prepared) {
|
|
18142
|
+
function expectedPersonalCallData(prepared, expectedSafe, chainId) {
|
|
17718
18143
|
const item = prepared.item;
|
|
17719
18144
|
if (item.operation !== "send" && item.operation !== "create_commitment") throw new Error("Expected personal Payment birth item");
|
|
17720
|
-
const contract = CAPXUL_PAYMENTS_V2_ADDRESS;
|
|
18145
|
+
const contract = toAddress(CAPXUL_PAYMENTS_V2_ADDRESS);
|
|
17721
18146
|
const { settlementId, recipientSafe, tokenAddress, documentHash } = item;
|
|
17722
18147
|
const amount = BigInt(item.operation === "send" ? item.rawAmount : item.totalAmount);
|
|
17723
18148
|
const paymentData = item.operation === "send" ? encodeCapxulPaymentsV2Send({
|
|
@@ -17738,26 +18163,61 @@ function expectedPersonalCallData(prepared) {
|
|
|
17738
18163
|
kind: item.kind,
|
|
17739
18164
|
documentHash
|
|
17740
18165
|
});
|
|
17741
|
-
|
|
18166
|
+
const calls = (router, encodedPaymentData) => safe4337MultiSendUserOpCallData({ calls: [{
|
|
17742
18167
|
to: tokenAddress,
|
|
17743
18168
|
value: 0n,
|
|
17744
18169
|
data: encodeFunctionData({
|
|
17745
18170
|
abi: ERC20_APPROVE_ABI,
|
|
17746
18171
|
functionName: "approve",
|
|
17747
|
-
args: [
|
|
18172
|
+
args: [router, amount]
|
|
17748
18173
|
})
|
|
17749
18174
|
}, {
|
|
17750
|
-
to:
|
|
18175
|
+
to: router,
|
|
17751
18176
|
value: 0n,
|
|
17752
|
-
data:
|
|
18177
|
+
data: encodedPaymentData
|
|
17753
18178
|
}] });
|
|
18179
|
+
const v2 = calls(contract, paymentData);
|
|
18180
|
+
if (item.operation !== "send") return [v2];
|
|
18181
|
+
const terms = {
|
|
18182
|
+
recipient: item.recipientSafe,
|
|
18183
|
+
token: item.tokenAddress,
|
|
18184
|
+
amount,
|
|
18185
|
+
kind: item.kind,
|
|
18186
|
+
documentHash,
|
|
18187
|
+
jobNonce: paymentJobNonce(prepared.commandId, 0),
|
|
18188
|
+
executor: toAddress(expectedSafe)
|
|
18189
|
+
};
|
|
18190
|
+
const v3Contract = toAddress(CAPXUL_PAYMENTS_V3_ADDRESS);
|
|
18191
|
+
const v3SettlementId = capxulPaymentsV3PaymentId(chainId, v3Contract, terms);
|
|
18192
|
+
if (v3SettlementId.toLowerCase() !== settlementId.toLowerCase()) return [v2];
|
|
18193
|
+
return [calls(v3Contract, encodeCapxulPaymentsV3Send({
|
|
18194
|
+
settlementId: v3SettlementId,
|
|
18195
|
+
...terms
|
|
18196
|
+
}))];
|
|
17754
18197
|
}
|
|
17755
18198
|
function verifiesPersonalOperation(prepared, expectedSafe, chainId) {
|
|
17756
18199
|
try {
|
|
17757
18200
|
const operation = prepared.userOperation;
|
|
17758
|
-
if (operation.sender.toLowerCase() !== expectedSafe.toLowerCase() || operation.callData.toLowerCase()
|
|
18201
|
+
if (operation.sender.toLowerCase() !== expectedSafe.toLowerCase() || !expectedPersonalCallData(prepared, expectedSafe, chainId).some((callData) => operation.callData.toLowerCase() === callData.toLowerCase())) return false;
|
|
17759
18202
|
const digest = moneySafeOpDigest(operation, chainId);
|
|
17760
|
-
return prepared.digest.toLowerCase() === digest.toLowerCase() && prepared.executionId
|
|
18203
|
+
return prepared.digest.toLowerCase() === digest.toLowerCase() && matchesMoneyExecutionId(prepared.executionId, digest, prepared.commandId);
|
|
18204
|
+
} catch {
|
|
18205
|
+
return false;
|
|
18206
|
+
}
|
|
18207
|
+
}
|
|
18208
|
+
/** A settled reply retains the verified operation, quantity, instruction and receipt. */
|
|
18209
|
+
function verifiesSettledPersonalReplay(evidence) {
|
|
18210
|
+
const settled = evidence.settled;
|
|
18211
|
+
if (settled === void 0) return true;
|
|
18212
|
+
try {
|
|
18213
|
+
const instructions = settled.payment.documents.filter((document) => document.role === "instruction");
|
|
18214
|
+
return acceptedSubmissionMatches({
|
|
18215
|
+
...evidence,
|
|
18216
|
+
paymentIds: [evidence.paymentId]
|
|
18217
|
+
}, {
|
|
18218
|
+
...settled,
|
|
18219
|
+
payments: [settled.payment]
|
|
18220
|
+
}) && 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
18221
|
} catch {
|
|
17762
18222
|
return false;
|
|
17763
18223
|
}
|
|
@@ -17871,6 +18331,7 @@ async function preparedMismatch(chainId, evidence, payment, expected) {
|
|
|
17871
18331
|
if (evidence.userOpSenderSafe.toLowerCase() !== expected.expectedSafe.toLowerCase()) return mismatch("userOpSenderSafe", "prepared Payment execution uses another Account Safe");
|
|
17872
18332
|
if (!await verifiesPersonalDocument(evidence)) return mismatch("document", "prepared Payment document does not match the request");
|
|
17873
18333
|
if (!verifiesPersonalOperation(evidence, expected.expectedSafe, chainId)) return mismatch("execution", "prepared Payment operation does not match the request");
|
|
18334
|
+
if (!verifiesSettledPersonalReplay(evidence)) return mismatch("execution", "settled Payment replay evidence mismatch");
|
|
17874
18335
|
}
|
|
17875
18336
|
/**
|
|
17876
18337
|
* Prepare one personal Payment for this signer and check what the backend
|
|
@@ -17921,19 +18382,27 @@ async function emitPreparedPaymentInitiated(deps, evidence) {
|
|
|
17921
18382
|
async function executePersonalPayment(deps, payment, signal, requestKey, onPreparedClosed, onPrepared) {
|
|
17922
18383
|
if (isAborted(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
|
|
17923
18384
|
if (deps.signer === void 0) return mismatch("signer", "payments.pay requires a configured CapxulSigner");
|
|
17924
|
-
|
|
18385
|
+
const session = deps.actor.authSession();
|
|
18386
|
+
if (session === null) return {
|
|
17925
18387
|
ok: false,
|
|
17926
18388
|
error: Errors.notAuthenticated()
|
|
17927
18389
|
};
|
|
18390
|
+
const lifetime = deps.actor.authLifetime();
|
|
18391
|
+
const current = () => deps.actor.matchesAuthLifetime(lifetime, session.authUserId);
|
|
17928
18392
|
const signerAddress = await signerCall(deps.signer.source, "getAddress", () => deps.signer.getAddress());
|
|
17929
18393
|
if (!signerAddress.ok) return signerAddress;
|
|
17930
18394
|
const prepared = await prepareVerifiedPersonalPayment(deps, payment, signerAddress.value, requestKey ?? `pay_${crypto.randomUUID()}`, signal, onPreparedClosed);
|
|
17931
18395
|
if (!prepared.ok) return prepared;
|
|
17932
18396
|
const evidence = prepared.value;
|
|
18397
|
+
if (evidence.settled !== void 0 && !current()) return cancelled(CAPXUL_OPERATIONS.payments.pay);
|
|
17933
18398
|
const digest = evidence.digest;
|
|
17934
18399
|
if (isAborted(signal)) return abandonPrepared(deps, evidence.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
|
|
17935
18400
|
const delivered = await notifyVerifiedPaymentPrepared(onPrepared, evidence.paymentId);
|
|
17936
18401
|
if (!delivered.ok) return delivered;
|
|
18402
|
+
if (evidence.settled !== void 0) return current() ? {
|
|
18403
|
+
ok: true,
|
|
18404
|
+
value: evidence.settled
|
|
18405
|
+
} : cancelled(CAPXUL_OPERATIONS.payments.pay);
|
|
17937
18406
|
if (isAborted(signal)) return abandonPrepared(deps, evidence.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
|
|
17938
18407
|
await emitPreparedPaymentInitiated(deps, evidence);
|
|
17939
18408
|
if (isAborted(signal)) return abandonPrepared(deps, evidence.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
|
|
@@ -18467,6 +18936,41 @@ function isCheckoutSettlementConsumed(error, settlementId) {
|
|
|
18467
18936
|
return false;
|
|
18468
18937
|
}
|
|
18469
18938
|
//#endregion
|
|
18939
|
+
//#region src/requests/request-keys.ts
|
|
18940
|
+
/** Keep an Invoice attempt through uncertainty; renew an old failed default only before preparation. */
|
|
18941
|
+
async function withInvoiceRequestKey(actorId, intent, provided, run) {
|
|
18942
|
+
let key;
|
|
18943
|
+
let prepared = false;
|
|
18944
|
+
try {
|
|
18945
|
+
key = await paymentRequestKeyLifecycle(`invoice-request:${actorId}`, intent, provided);
|
|
18946
|
+
let result = await run(key.key, () => {
|
|
18947
|
+
prepared = true;
|
|
18948
|
+
});
|
|
18949
|
+
const renew = provided === void 0 && !prepared && !result.ok && isFinalPaymentRequestError(result.error) && result.error.details?.paymentRequestFinality === "failed";
|
|
18950
|
+
let finished = true;
|
|
18951
|
+
try {
|
|
18952
|
+
await key.finish(!result.ok && isFinalPaymentRequestError(result.error));
|
|
18953
|
+
} catch {
|
|
18954
|
+
finished = false;
|
|
18955
|
+
}
|
|
18956
|
+
if (renew && finished) {
|
|
18957
|
+
key = await paymentRequestKeyLifecycle(`invoice-request:${actorId}`, intent);
|
|
18958
|
+
result = await run(key.key, () => {
|
|
18959
|
+
prepared = true;
|
|
18960
|
+
});
|
|
18961
|
+
await key.finish(!result.ok && isFinalPaymentRequestError(result.error)).catch(() => void 0);
|
|
18962
|
+
}
|
|
18963
|
+
return result;
|
|
18964
|
+
} catch (cause) {
|
|
18965
|
+
return {
|
|
18966
|
+
ok: false,
|
|
18967
|
+
error: asCapxulError(cause)
|
|
18968
|
+
};
|
|
18969
|
+
} finally {
|
|
18970
|
+
await key?.finish(false).catch(() => void 0);
|
|
18971
|
+
}
|
|
18972
|
+
}
|
|
18973
|
+
//#endregion
|
|
18470
18974
|
//#region src/requests/checkout-payments.ts
|
|
18471
18975
|
const missing$1 = async () => ({
|
|
18472
18976
|
ok: false,
|
|
@@ -18656,72 +19160,96 @@ function makeCheckoutMethods(deps) {
|
|
|
18656
19160
|
}
|
|
18657
19161
|
//#endregion
|
|
18658
19162
|
//#region src/requests/inbox-payments.ts
|
|
18659
|
-
|
|
19163
|
+
const refused = () => ({
|
|
19164
|
+
ok: false,
|
|
19165
|
+
error: Errors.providerError("convex", inboxes.approve.name, "approved Payment read does not match its command")
|
|
19166
|
+
});
|
|
19167
|
+
/** Read the approved command's actual Payment under the payer's existing scope. */
|
|
19168
|
+
async function readApprovedInboxPayment(calls, command, controls, current) {
|
|
18660
19169
|
const item = command.items[0];
|
|
18661
|
-
|
|
19170
|
+
const cancelled = {
|
|
18662
19171
|
ok: false,
|
|
18663
|
-
error: Errors.
|
|
19172
|
+
error: Errors.cancelled({ operation: inboxes.approve.name })
|
|
18664
19173
|
};
|
|
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
|
-
}
|
|
19174
|
+
if (command.items.length !== 1 || item === void 0 || item.operation !== "send" && item.operation !== "create_commitment") return refused();
|
|
19175
|
+
if (!current()) return cancelled;
|
|
19176
|
+
const check = (payment) => {
|
|
19177
|
+
if (!current()) return cancelled;
|
|
19178
|
+
if (payment === null || payment.id !== item.paymentId || payment.direction !== "out") return refused();
|
|
19179
|
+
try {
|
|
19180
|
+
const amount = toExactAssetAmount(payment.amount, CONFIGURED_MONEY_ASSETS);
|
|
19181
|
+
const asset = CONFIGURED_MONEY_ASSETS.find((row) => row.assetId === amount.asset);
|
|
19182
|
+
const instruction = payment.documents.find((document) => document.role === "instruction");
|
|
19183
|
+
const expected = command.instructionDocuments?.[0];
|
|
19184
|
+
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();
|
|
19185
|
+
return {
|
|
19186
|
+
ok: true,
|
|
19187
|
+
value: normalizePaymentTiming(payment)
|
|
19188
|
+
};
|
|
19189
|
+
} catch (cause) {
|
|
19190
|
+
return {
|
|
19191
|
+
ok: false,
|
|
19192
|
+
error: Errors.unknown(cause)
|
|
19193
|
+
};
|
|
19194
|
+
}
|
|
19195
|
+
};
|
|
19196
|
+
const actor = calls.actor;
|
|
19197
|
+
const result = actor.kind === "account" ? await calls.bookChecked(records.get, { paymentId: item.paymentId }, controls, check) : await calls.bookChecked(records.getForOrganization, {
|
|
19198
|
+
orgId: actor.orgId,
|
|
19199
|
+
paymentId: item.paymentId
|
|
19200
|
+
}, controls, (response) => response.orgId === actor.orgId ? check(response.payment) : refused());
|
|
19201
|
+
return current() ? result : cancelled;
|
|
18708
19202
|
}
|
|
18709
19203
|
//#endregion
|
|
18710
19204
|
//#region src/requests/inboxes.ts
|
|
18711
19205
|
function makeInboxMethods(calls) {
|
|
18712
|
-
const { actor, convexCall, deps, observeContactScope, book
|
|
19206
|
+
const { actor, convexCall, deps, observeContactScope, book } = calls;
|
|
18713
19207
|
return {
|
|
18714
19208
|
paymentTerms: (requestId, options) => book(inboxes.paymentTerms, {
|
|
18715
19209
|
actor,
|
|
18716
19210
|
paymentRequestId: requestId
|
|
18717
19211
|
}, options, (terms) => terms),
|
|
18718
19212
|
list: (options) => book(inboxes.listCurrent, { actor }, options, (items) => mapPage(items, mapInboxItem)),
|
|
18719
|
-
approve: (
|
|
18720
|
-
|
|
18721
|
-
|
|
18722
|
-
|
|
18723
|
-
|
|
18724
|
-
|
|
19213
|
+
approve: async (providedInput, options) => {
|
|
19214
|
+
const input = structuredClone(providedInput);
|
|
19215
|
+
const identity = deps.identityActor;
|
|
19216
|
+
const lifetime = identity?.authLifetime();
|
|
19217
|
+
const current = () => identity === void 0 || lifetime !== void 0 && identity.matchesAuthLifetime(lifetime, lifetime.authUserId);
|
|
19218
|
+
const cancelled = {
|
|
19219
|
+
ok: false,
|
|
19220
|
+
error: Errors.cancelled({ operation: inboxes.approve.name })
|
|
19221
|
+
};
|
|
19222
|
+
const controls = deps.invocationControls?.(options) ?? options;
|
|
19223
|
+
const approve = async (requestKey) => {
|
|
19224
|
+
if (!current()) return cancelled;
|
|
19225
|
+
const prepared = await book(inboxes.approve, {
|
|
19226
|
+
actor,
|
|
19227
|
+
paymentRequestId: input.requestId,
|
|
19228
|
+
...requestKey === void 0 ? {} : { requestKey },
|
|
19229
|
+
...input.timing === void 0 ? {} : { timing: input.timing },
|
|
19230
|
+
...input.permissionId === void 0 ? {} : { permissionId: input.permissionId }
|
|
19231
|
+
}, controls, (value) => value);
|
|
19232
|
+
if (!current()) return cancelled;
|
|
19233
|
+
if (!prepared.ok) return prepared;
|
|
19234
|
+
return readApprovedInboxPayment(calls, prepared.value, controls, current);
|
|
19235
|
+
};
|
|
19236
|
+
const terms = await book(inboxes.paymentTerms, {
|
|
19237
|
+
actor,
|
|
19238
|
+
paymentRequestId: input.requestId
|
|
19239
|
+
}, controls, (value) => value);
|
|
19240
|
+
if (!current()) return cancelled;
|
|
19241
|
+
if (!terms.ok) return terms;
|
|
19242
|
+
if (terms.value.instruction.kind !== "invoice") return approve(input.requestKey);
|
|
19243
|
+
return withInvoiceRequestKey(lifetime?.authUserId ?? "signed-out", {
|
|
19244
|
+
...terms.value,
|
|
19245
|
+
payer: actor.kind === "account" ? { kind: "account" } : {
|
|
19246
|
+
kind: "organization",
|
|
19247
|
+
orgId: actor.orgId
|
|
19248
|
+
},
|
|
19249
|
+
permissionId: input.permissionId,
|
|
19250
|
+
release: input.timing ?? { kind: "instant" }
|
|
19251
|
+
}, input.requestKey, (key) => approve(key));
|
|
19252
|
+
},
|
|
18725
19253
|
fulfill: (input, options) => {
|
|
18726
19254
|
const onPrepared = options?.onPrepared;
|
|
18727
19255
|
const decoded = Schema.decodeResult(RequestPaymentConfirmationSchema, { onExcessProperty: "error" })(input);
|
|
@@ -18744,20 +19272,26 @@ function makeInboxMethods(calls) {
|
|
|
18744
19272
|
const controls = deps.invocationControls?.(options) ?? options;
|
|
18745
19273
|
return runCapxulEffect(Effect.gen(function* () {
|
|
18746
19274
|
const parent = yield* Effect.currentSpan.pipe(Effect.orDie);
|
|
18747
|
-
|
|
19275
|
+
const run = (named, prepared) => executeRequestPayment({
|
|
18748
19276
|
actor: identityActor,
|
|
18749
19277
|
chainId,
|
|
18750
19278
|
signer,
|
|
18751
19279
|
convexCall,
|
|
18752
19280
|
runPromise: deps.runPromise,
|
|
18753
19281
|
...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
|
|
18754
|
-
},
|
|
18755
|
-
|
|
19282
|
+
}, named, carryInvocationParentSpan(controls, parent), async (paymentIds) => {
|
|
19283
|
+
prepared();
|
|
19284
|
+
await onPrepared?.({ paymentIds });
|
|
18756
19285
|
return {
|
|
18757
19286
|
ok: true,
|
|
18758
19287
|
value: void 0
|
|
18759
19288
|
};
|
|
18760
|
-
})
|
|
19289
|
+
});
|
|
19290
|
+
const { requestKey, ...intent } = confirmation;
|
|
19291
|
+
return yield* awaitCapxulResult(() => confirmation.instruction.kind !== "invoice" ? run(confirmation, () => void 0) : withInvoiceRequestKey(identityActor.authSession()?.authUserId ?? "signed-out", intent, requestKey, (key, prepared) => run({
|
|
19292
|
+
...confirmation,
|
|
19293
|
+
requestKey: key
|
|
19294
|
+
}, prepared)));
|
|
18761
19295
|
}).pipe(Effect.tap(() => observeContactScope)), controls, CAPXUL_OPERATIONS.inbox.fulfill, deps.runPromise);
|
|
18762
19296
|
},
|
|
18763
19297
|
decline: (requestId, options) => book(inboxes.decline, {
|
|
@@ -19683,7 +20217,7 @@ function makePersonalPay(deps) {
|
|
|
19683
20217
|
};
|
|
19684
20218
|
}
|
|
19685
20219
|
release(false);
|
|
19686
|
-
await finishQuietly(requestKey, submitted.ok || flight.requestState.resolved);
|
|
20220
|
+
await finishQuietly(requestKey, submitted.ok || flight.requestState.resolved || isFinalPaymentRequestError(submitted.error));
|
|
19687
20221
|
return mapOk(submitted, (value) => normalizePaymentTiming(value.payment));
|
|
19688
20222
|
};
|
|
19689
20223
|
}
|
|
@@ -19760,6 +20294,7 @@ function makePaymentsMethods(deps) {
|
|
|
19760
20294
|
createCommitment: (input, options) => pay(input, options),
|
|
19761
20295
|
claim: (paymentId, options) => runLifecycle({
|
|
19762
20296
|
kind: "claim",
|
|
20297
|
+
requestKey: options?.requestKey ?? `pay_${crypto.randomUUID()}`,
|
|
19763
20298
|
paymentId
|
|
19764
20299
|
}, deps.invocationControls?.(options) ?? options, CAPXUL_OPERATIONS.payments.claim),
|
|
19765
20300
|
list: (options) => {
|
|
@@ -19772,6 +20307,7 @@ function makePaymentsMethods(deps) {
|
|
|
19772
20307
|
},
|
|
19773
20308
|
cancel: (paymentId, options) => runLifecycle({
|
|
19774
20309
|
kind: "cancel",
|
|
20310
|
+
requestKey: options?.requestKey ?? `pay_${crypto.randomUUID()}`,
|
|
19775
20311
|
paymentId
|
|
19776
20312
|
}, deps.invocationControls?.(options) ?? options, CAPXUL_OPERATIONS.payments.cancel),
|
|
19777
20313
|
redirect: async (input, options) => {
|
|
@@ -19780,6 +20316,7 @@ function makePaymentsMethods(deps) {
|
|
|
19780
20316
|
if (!recipient.ok) return runCapxulEffect(Effect.fail(recipient.error), observationOnlyControls(controls), CAPXUL_OPERATIONS.payments.redirect, deps.runPromise);
|
|
19781
20317
|
return runLifecycle({
|
|
19782
20318
|
kind: "redirect",
|
|
20319
|
+
requestKey: options?.requestKey ?? `pay_${crypto.randomUUID()}`,
|
|
19783
20320
|
paymentId: input.paymentId,
|
|
19784
20321
|
recipient: recipient.value
|
|
19785
20322
|
}, controls, CAPXUL_OPERATIONS.payments.redirect);
|
|
@@ -20033,7 +20570,7 @@ async function executeOrganizationBatch(scope, input, signal, operation, control
|
|
|
20033
20570
|
}
|
|
20034
20571
|
release(false);
|
|
20035
20572
|
try {
|
|
20036
|
-
await requestKey.finish(result.ok || flight.requestState.resolved);
|
|
20573
|
+
await requestKey.finish(result.ok || flight.requestState.resolved || isFinalPaymentRequestError(result.error));
|
|
20037
20574
|
} catch {}
|
|
20038
20575
|
const normalized = mapOk(result, (value) => value.payments.map((payment) => normalizePaymentTiming(payment)));
|
|
20039
20576
|
if (!normalized.ok) return normalized;
|
|
@@ -20134,7 +20671,8 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
|
|
|
20134
20671
|
},
|
|
20135
20672
|
cancel: (paymentId, options) => ownerLifecycle({
|
|
20136
20673
|
kind: "cancel",
|
|
20137
|
-
paymentId
|
|
20674
|
+
paymentId,
|
|
20675
|
+
requestKey: options?.requestKey ?? `pay_${crypto.randomUUID()}`
|
|
20138
20676
|
}, deps.invocationControls?.(options) ?? options, CAPXUL_OPERATIONS.organizationPayments.cancel),
|
|
20139
20677
|
redirect: (input, options) => {
|
|
20140
20678
|
const controls = deps.invocationControls?.(options) ?? options;
|
|
@@ -20142,7 +20680,8 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
|
|
|
20142
20680
|
return recipient.ok ? ownerLifecycle({
|
|
20143
20681
|
kind: "redirect",
|
|
20144
20682
|
paymentId: input.paymentId,
|
|
20145
|
-
recipient: recipient.value
|
|
20683
|
+
recipient: recipient.value,
|
|
20684
|
+
requestKey: options?.requestKey ?? `pay_${crypto.randomUUID()}`
|
|
20146
20685
|
}, controls, CAPXUL_OPERATIONS.organizationPayments.redirect) : runCapxulEffect(Effect.fail(recipient.error), observationOnlyControls(controls), CAPXUL_OPERATIONS.organizationPayments.redirect, deps.runPromise);
|
|
20147
20686
|
},
|
|
20148
20687
|
payBatch: (input, options) => {
|
|
@@ -20762,6 +21301,46 @@ function makeAccountMethods(deps) {
|
|
|
20762
21301
|
};
|
|
20763
21302
|
}
|
|
20764
21303
|
//#endregion
|
|
21304
|
+
//#region src/accounts/approval-rules.ts
|
|
21305
|
+
const IN_FLIGHT = /* @__PURE__ */ new Set([
|
|
21306
|
+
"pending",
|
|
21307
|
+
"settling",
|
|
21308
|
+
"in_transit"
|
|
21309
|
+
]);
|
|
21310
|
+
/** A Payment the chain has not decided yet. */
|
|
21311
|
+
function inFlight(payment) {
|
|
21312
|
+
return IN_FLIGHT.has(payment.status);
|
|
21313
|
+
}
|
|
21314
|
+
/**
|
|
21315
|
+
* The operation the approval describes is the one its digest signs: the
|
|
21316
|
+
* SafeOp digest of its UserOperation on this client's chain, and the
|
|
21317
|
+
* execution that digest names. Anything else is refused before the key signs.
|
|
21318
|
+
*/
|
|
21319
|
+
function describedOperation(approval, chainId) {
|
|
21320
|
+
const { operation, summary } = approval;
|
|
21321
|
+
if (chainId !== void 0 && summary.network.chainId !== chainId) return Errors.invalidInput("approval", "the approval is for another chain");
|
|
21322
|
+
try {
|
|
21323
|
+
const digest = moneySafeOpDigest(operation.userOperation, summary.network.chainId);
|
|
21324
|
+
if (digest.toLowerCase() === operation.digest.toLowerCase() && matchesMoneyExecutionId(operation.executionId, digest, operation.commandId)) return void 0;
|
|
21325
|
+
} catch {}
|
|
21326
|
+
return Errors.invalidInput("approval", "the operation does not match the digest it asks to sign");
|
|
21327
|
+
}
|
|
21328
|
+
/** Wait, unless the caller gives up first. False when aborted. */
|
|
21329
|
+
function sleep(ms, signal) {
|
|
21330
|
+
if (signal?.aborted === true) return Promise.resolve(false);
|
|
21331
|
+
return new Promise((resolve) => {
|
|
21332
|
+
const timer = setTimeout(() => {
|
|
21333
|
+
signal?.removeEventListener("abort", onAbort);
|
|
21334
|
+
resolve(true);
|
|
21335
|
+
}, ms);
|
|
21336
|
+
const onAbort = () => {
|
|
21337
|
+
clearTimeout(timer);
|
|
21338
|
+
resolve(false);
|
|
21339
|
+
};
|
|
21340
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
21341
|
+
});
|
|
21342
|
+
}
|
|
21343
|
+
//#endregion
|
|
20765
21344
|
//#region src/accounts/organization-approvals.ts
|
|
20766
21345
|
/** The Organization Payment prepared for `signerAddress` and checked, before any approval. */
|
|
20767
21346
|
async function prepareVerifiedOrganizationPayment(deps, input, signerAddress, signal) {
|
|
@@ -20854,58 +21433,6 @@ async function checkedBankApproval(deps, input, opened) {
|
|
|
20854
21433
|
});
|
|
20855
21434
|
}
|
|
20856
21435
|
//#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
21436
|
//#region ../protocol/src/payroll/model.ts
|
|
20910
21437
|
function toPayrollRunId(raw) {
|
|
20911
21438
|
return toNonEmptyStringBrand(raw, "payrollRunId", (value) => isNonEmptyString(value));
|
|
@@ -21367,7 +21894,8 @@ function lifecycleIntent(input) {
|
|
|
21367
21894
|
ok: true,
|
|
21368
21895
|
value: {
|
|
21369
21896
|
kind: "cancel",
|
|
21370
|
-
paymentId: input.cancel
|
|
21897
|
+
paymentId: input.cancel,
|
|
21898
|
+
requestKey: input.requestKey ?? `pay_${crypto.randomUUID()}`
|
|
21371
21899
|
}
|
|
21372
21900
|
};
|
|
21373
21901
|
const recipient = normalizeTargetForBackend(input.to, "to");
|
|
@@ -21376,7 +21904,8 @@ function lifecycleIntent(input) {
|
|
|
21376
21904
|
value: {
|
|
21377
21905
|
kind: "redirect",
|
|
21378
21906
|
paymentId: input.redirect,
|
|
21379
|
-
recipient: recipient.value
|
|
21907
|
+
recipient: recipient.value,
|
|
21908
|
+
requestKey: input.requestKey ?? `pay_${crypto.randomUUID()}`
|
|
21380
21909
|
}
|
|
21381
21910
|
} : recipient;
|
|
21382
21911
|
}
|
|
@@ -21408,10 +21937,19 @@ async function prepareVerifiedRequestPayment(deps, input, signerAddress, signal)
|
|
|
21408
21937
|
error: Errors.invalidInput("confirmation", "invalid request confirmation")
|
|
21409
21938
|
};
|
|
21410
21939
|
const confirmation = decoded.success;
|
|
21411
|
-
|
|
21412
|
-
|
|
21413
|
-
|
|
21414
|
-
|
|
21940
|
+
const run = async (named, prepared) => {
|
|
21941
|
+
const result = await runIfActive(signal, commands$1.prepareRequest.name, () => callOperation(deps.convexCall, commands$1.prepareRequest, {
|
|
21942
|
+
confirmation: named,
|
|
21943
|
+
signerAddress
|
|
21944
|
+
}).pipe(Effect.mapError((publicError) => ({ publicError }))), deps.runPromise);
|
|
21945
|
+
if (result.ok) prepared();
|
|
21946
|
+
return checked(deps, signerAddress, result, requestPaymentCheck(named), false);
|
|
21947
|
+
};
|
|
21948
|
+
const { requestKey, ...intent } = confirmation;
|
|
21949
|
+
return confirmation.instruction.kind !== "invoice" ? run(confirmation, () => void 0) : withInvoiceRequestKey(deps.actor?.authSession()?.authUserId ?? "signed-out", intent, requestKey, (key, prepared) => run({
|
|
21950
|
+
...confirmation,
|
|
21951
|
+
requestKey: key
|
|
21952
|
+
}, prepared));
|
|
21415
21953
|
}
|
|
21416
21954
|
/** One payroll run: the run the backend writes and the batch that pays it, checked together. */
|
|
21417
21955
|
async function prepareVerifiedPayrollRun(deps, input, signerAddress, signal) {
|
|
@@ -21506,7 +22044,7 @@ function makeApprovalsMethods(deps) {
|
|
|
21506
22044
|
const signal = options?.signal;
|
|
21507
22045
|
if (isCommandApproval(input)) return openApproval(signal, (signerAddress) => prepareVerifiedCommand(deps, input, signerAddress, signal));
|
|
21508
22046
|
if (isPermissionChange(input)) return openApproval(signal, async (signerAddress) => {
|
|
21509
|
-
const { prepareVerifiedPermissionChange } = await import("./permission-approvals-
|
|
22047
|
+
const { prepareVerifiedPermissionChange } = await import("./permission-approvals-Bw9VaKay.mjs");
|
|
21510
22048
|
return prepareVerifiedPermissionChange(deps, input, signerAddress, signal);
|
|
21511
22049
|
});
|
|
21512
22050
|
if ("organizationId" in input) return checkedBankApproval(deps, input, await openApproval(signal, (signerAddress) => prepareVerifiedOrganizationPayment(deps, input, signerAddress, signal)));
|
|
@@ -21603,43 +22141,33 @@ function makeApprovalsMethods(deps) {
|
|
|
21603
22141
|
};
|
|
21604
22142
|
/**
|
|
21605
22143
|
* 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.
|
|
22144
|
+
* again. This path only reads. The backend owns submission and recovery.
|
|
21608
22145
|
*/
|
|
21609
22146
|
const step = async (approvalId, signal, organizationId) => {
|
|
21610
|
-
const read = await call(approvals.
|
|
22147
|
+
const read = await call(approvals.observe.name, approvals.observe, { approvalId }, signal);
|
|
21611
22148
|
if (!read.ok) return read;
|
|
21612
|
-
const approval = read.value;
|
|
22149
|
+
const { approval, completed } = read.value;
|
|
21613
22150
|
if (approval.state === "pending") return {
|
|
21614
22151
|
ok: true,
|
|
21615
22152
|
value: null
|
|
21616
22153
|
};
|
|
21617
|
-
|
|
21618
|
-
|
|
21619
|
-
|
|
21620
|
-
|
|
21621
|
-
|
|
21622
|
-
|
|
21623
|
-
|
|
21624
|
-
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
|
|
21629
|
-
};
|
|
21630
|
-
}
|
|
22154
|
+
const closed = approval.state === "rejected" || approval.state === "expired";
|
|
22155
|
+
if (!closed && !completed) return {
|
|
22156
|
+
ok: true,
|
|
22157
|
+
value: null
|
|
22158
|
+
};
|
|
22159
|
+
if (!movesMoney(approval)) return {
|
|
22160
|
+
ok: true,
|
|
22161
|
+
value: {
|
|
22162
|
+
approval,
|
|
22163
|
+
payments: []
|
|
22164
|
+
}
|
|
22165
|
+
};
|
|
21631
22166
|
const payments = await readApprovalPayments(deps, approval.operation.paymentIds, organizationId ?? (approval.actor.kind === "organization" ? approval.actor.orgId : void 0), signal);
|
|
21632
22167
|
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
22168
|
return {
|
|
21641
22169
|
ok: true,
|
|
21642
|
-
value:
|
|
22170
|
+
value: closed || endsOnceSent(approval) || !payments.value.some(inFlight) ? {
|
|
21643
22171
|
approval,
|
|
21644
22172
|
payments: payments.value
|
|
21645
22173
|
} : null
|
|
@@ -22317,7 +22845,7 @@ function decodeStatus(body) {
|
|
|
22317
22845
|
*/
|
|
22318
22846
|
const HEADS = {
|
|
22319
22847
|
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",
|
|
22848
|
+
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
22849
|
balance: "select \"chain_id\", \"asset_id\", \"to\", \"amount\" from \"balance\" where \"balance\".\"to\" = $1"
|
|
22322
22850
|
};
|
|
22323
22851
|
/** How many times the statement binds the Safe address. */
|
|
@@ -22360,7 +22888,7 @@ function ponderQuery(table, input) {
|
|
|
22360
22888
|
input.limit
|
|
22361
22889
|
];
|
|
22362
22890
|
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}`,
|
|
22891
|
+
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
22892
|
params,
|
|
22365
22893
|
typings: params.map(() => "none")
|
|
22366
22894
|
};
|
|
@@ -24558,4 +25086,4 @@ function executeIdentityProductObservation(telemetry, record, state) {
|
|
|
24558
25086
|
return ignoreTransportFailure(() => invocationTelemetry.emit(mapped), "emit", mapped.name).pipe(Effect.andThen(ignoreTransportFailure(after, mapped.name === "auth_signed_out" ? "reset" : "identify", mapped.name)));
|
|
24559
25087
|
}
|
|
24560
25088
|
//#endregion
|
|
24561
|
-
export { parseAssetAmount as $,
|
|
25089
|
+
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 };
|