@capxul/sdk 3.2.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/{OAuthBearerAuthClient-8F_kyVP5.mjs → OAuthBearerAuthClient-BHvDR8_0.mjs} +1 -1
- package/dist/{OAuthBearerAuthClient-CsOgeeZa.d.mts → OAuthBearerAuthClient-D-DLYlKj.d.mts} +1 -1
- package/dist/{clock-CWpcQlLy.mjs → clock-C2AUlq1V.mjs} +34 -1
- package/dist/{create-capxul-client-BCq08ppe.mjs → create-capxul-client-DyCEJZtD.mjs} +700 -351
- package/dist/index.d.mts +17 -20
- package/dist/index.mjs +18 -8
- package/dist/node/index.d.mts +2 -2
- package/dist/node/index.mjs +2 -2
- package/dist/{observation-B76zFxd6.d.mts → observation-DtzTdv20.d.mts} +75 -71
- package/dist/{signer-DOqb8M1Y.d.mts → signer-C0hZ6Kiy.d.mts} +9 -2
- package/dist/testing/index.d.mts +1 -1
- package/dist/testing/index.mjs +6 -6
- package/package.json +6 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as
|
|
2
|
-
import { Context, Data, Deferred, Duration, Effect, Exit, Fiber, Layer, Queue, Ref, Result, Schema, SchemaGetter, Scope } from "effect";
|
|
1
|
+
import { $ as CapxulError, A as toAuthUserId, C as WEI_RE, D as toAddress, E as toAccountId, G as toPayrollRunId, H as toOrgId, I as toEmail, M as toChainId, N as toCountryCode, P as toCurrencyCode, Q as CAPXUL_ERROR_CODES, S as SUPPORTED_CURRENCY_CODES, U as toPartyId, W as toPayrollGroupId, _ as deriveCapxulSafeAddress, at as boundedResponseHeaders, b as BYTES32_RE, ct as decodeChainCause, dt as isFailureMode, et as EXPECTED_OPERATION_OUTCOMES, ft as revertSummaryText, it as FAILURE_MODES$1, j as toBudgetId, lt as failureFingerprint, mt as redactSecrets, n as InMemoryAuthCacheAdapter, nt as isCapxulError, ot as chainCauseProperties, p as orgRoleKeyForLabel, pt as containsSensitiveMaterial, q as toRoleKey, r as BrowserAuthCacheAdapter, rt as CHAIN_UPSTREAMS, st as chainEvidenceLabel, tt as Errors, ut as isChainUpstream, v as validateHandle, w as ZERO_BYTES32, x as EVM_ADDRESS_RE$1, y as APP_ID_RE } from "./clock-C2AUlq1V.mjs";
|
|
2
|
+
import { Context, Data, Deferred, Duration, Effect, Exit, Fiber, Layer, Queue, Ref, Result, Schema, SchemaGetter, SchemaParser, Scope } from "effect";
|
|
3
3
|
import { formatUnits, keccak256, parseUnits, recoverAddress, toBytes } from "viem";
|
|
4
4
|
import { makeFunctionReference } from "convex/server";
|
|
5
5
|
//#region src/domain/identity/model.ts
|
|
@@ -494,7 +494,6 @@ const CAPXUL_OPERATIONS = {
|
|
|
494
494
|
current: "holdings.current",
|
|
495
495
|
primary: "holdings.primary"
|
|
496
496
|
},
|
|
497
|
-
handles: { resolve: "handles.resolve" },
|
|
498
497
|
identity: {
|
|
499
498
|
accountAt: "identity.AccountAt",
|
|
500
499
|
accountClaimed: "identity.AccountClaimed",
|
|
@@ -530,7 +529,7 @@ const CAPXUL_OPERATIONS = {
|
|
|
530
529
|
signOut: "identity.SignOut",
|
|
531
530
|
signOutFailed: "identity.SignOutFailed",
|
|
532
531
|
update: "identity.update",
|
|
533
|
-
|
|
532
|
+
handleAvailable: "identity.handleAvailable",
|
|
534
533
|
verified: "identity.Verified",
|
|
535
534
|
verifyFailed: "identity.VerifyFailed",
|
|
536
535
|
verifyOtp: "identity.VerifyOtp"
|
|
@@ -546,10 +545,12 @@ const CAPXUL_OPERATIONS = {
|
|
|
546
545
|
get: "me.get"
|
|
547
546
|
},
|
|
548
547
|
moneyExecution: {
|
|
548
|
+
abandonPaymentExecution: "moneyExecution.abandonPaymentExecution",
|
|
549
549
|
prepareOrganizationPaymentExecution: "moneyExecution.prepareOrganizationPaymentExecution",
|
|
550
550
|
preparePaymentExecution: "moneyExecution.preparePaymentExecution",
|
|
551
551
|
preparePaymentLifecycleExecution: "moneyExecution.preparePaymentLifecycleExecution",
|
|
552
552
|
preparePermissionExecution: "moneyExecution.preparePermissionExecution",
|
|
553
|
+
recoverSubmissionClaims: "moneyExecution.recoverSubmissionClaims",
|
|
553
554
|
submit: "moneyExecution.submit",
|
|
554
555
|
submitPaymentCommandExecution: "moneyExecution.submitPaymentCommandExecution",
|
|
555
556
|
submitPaymentExecution: "moneyExecution.submitPaymentExecution",
|
|
@@ -568,9 +569,14 @@ const CAPXUL_OPERATIONS = {
|
|
|
568
569
|
quote: "offramp.quote",
|
|
569
570
|
status: "offramp.status"
|
|
570
571
|
},
|
|
571
|
-
onboarding: {
|
|
572
|
+
onboarding: {
|
|
573
|
+
completeOrganization: "onboarding.completeOrganization",
|
|
574
|
+
completePerson: "onboarding.completePerson"
|
|
575
|
+
},
|
|
572
576
|
org: {
|
|
577
|
+
acceptInvitations: "org.acceptInvitations",
|
|
573
578
|
account: { get: "org.account.get" },
|
|
579
|
+
activateMember: "org.activateMember",
|
|
574
580
|
auditLog: "org.auditLog",
|
|
575
581
|
confirmBootstrap: "org.confirmBootstrap",
|
|
576
582
|
createOrg: "org.createOrg",
|
|
@@ -581,6 +587,7 @@ const CAPXUL_OPERATIONS = {
|
|
|
581
587
|
getProofReceipt: "org.getProofReceipt",
|
|
582
588
|
invite: "org.invite",
|
|
583
589
|
inviteMember: "org.inviteMember",
|
|
590
|
+
list: "org.list",
|
|
584
591
|
load: "org.load",
|
|
585
592
|
me: "org.me",
|
|
586
593
|
members: "org.members",
|
|
@@ -673,11 +680,7 @@ const CAPXUL_OPERATIONS = {
|
|
|
673
680
|
render: "paymentDocuments.render",
|
|
674
681
|
verify: "paymentDocuments.verify"
|
|
675
682
|
},
|
|
676
|
-
|
|
677
|
-
create: "payees.create",
|
|
678
|
-
get: "payees.get",
|
|
679
|
-
resolve: "payees.resolve"
|
|
680
|
-
},
|
|
683
|
+
recipient: { resolve: "recipient.resolve" },
|
|
681
684
|
payroll: {
|
|
682
685
|
authorizeRun: "payroll.authorizeRun",
|
|
683
686
|
groups: {
|
|
@@ -759,12 +762,6 @@ const CAPXUL_OPERATIONS = {
|
|
|
759
762
|
ping: "system.ping",
|
|
760
763
|
runtimeChain: "system.runtimeChain"
|
|
761
764
|
},
|
|
762
|
-
targets: { resolve: {
|
|
763
|
-
email: "targets.resolve.email",
|
|
764
|
-
handle: "targets.resolve.handle",
|
|
765
|
-
organization: "targets.resolve.organization",
|
|
766
|
-
payee: "targets.resolve.payee"
|
|
767
|
-
} },
|
|
768
765
|
testUsdc: { mint: "TestUSDC.mint" },
|
|
769
766
|
_internal: {
|
|
770
767
|
accounts: { fund: "_internal.accounts.fund" },
|
|
@@ -1192,32 +1189,116 @@ const OrgInviteExpiredProps = Schema.Struct({
|
|
|
1192
1189
|
role: OptionalString,
|
|
1193
1190
|
status: OptionalString
|
|
1194
1191
|
});
|
|
1192
|
+
const RecipientLocatorKindSchema = Schema.Literals([
|
|
1193
|
+
"handle",
|
|
1194
|
+
"email",
|
|
1195
|
+
"address",
|
|
1196
|
+
"party"
|
|
1197
|
+
]);
|
|
1198
|
+
const RecipientResolutionStatusSchema = Schema.Literals([
|
|
1199
|
+
"known_party",
|
|
1200
|
+
"new_email",
|
|
1201
|
+
"external_address"
|
|
1202
|
+
]);
|
|
1203
|
+
const RecipientPartyKindSchema = Schema.Literals([
|
|
1204
|
+
"person",
|
|
1205
|
+
"organization",
|
|
1206
|
+
"unresolved"
|
|
1207
|
+
]);
|
|
1208
|
+
const RecipientTelemetryProps = {
|
|
1209
|
+
recipient_locator_kind: Schema.optional(RecipientLocatorKindSchema),
|
|
1210
|
+
recipient_resolution_status: Schema.optional(RecipientResolutionStatusSchema),
|
|
1211
|
+
recipient_party_id: OptionalString,
|
|
1212
|
+
recipient_party_kind: Schema.optional(RecipientPartyKindSchema),
|
|
1213
|
+
recipient_is_capxul_account: Schema.optional(Schema.Boolean),
|
|
1214
|
+
recipient_handle: OptionalString,
|
|
1215
|
+
recipient_address: OptionalAddress,
|
|
1216
|
+
external_address_acknowledged: Schema.optional(Schema.Boolean)
|
|
1217
|
+
};
|
|
1195
1218
|
const PaymentInitiatedProps = Schema.Struct({
|
|
1219
|
+
command_id: OptionalString,
|
|
1220
|
+
execution_id: OptionalString,
|
|
1221
|
+
payment_lifecycle_id: OptionalString,
|
|
1196
1222
|
...TelemetryEnvelopeProps,
|
|
1223
|
+
...RecipientTelemetryProps,
|
|
1197
1224
|
kind: Schema.String,
|
|
1198
1225
|
payment_id: Schema.String
|
|
1199
1226
|
});
|
|
1227
|
+
const PaymentLifecycleProps = {
|
|
1228
|
+
payment_state: OptionalString,
|
|
1229
|
+
execution_state: OptionalString,
|
|
1230
|
+
occurred_at: Schema.optional(Schema.Number),
|
|
1231
|
+
causal_sequence: Schema.optional(Schema.Number),
|
|
1232
|
+
sponsorship_valid_until: Schema.optional(Schema.Number),
|
|
1233
|
+
terminal_event_id: OptionalString
|
|
1234
|
+
};
|
|
1200
1235
|
const PaymentSettledL2Props = Schema.Struct({
|
|
1236
|
+
...PaymentLifecycleProps,
|
|
1201
1237
|
...TelemetryEnvelopeProps,
|
|
1238
|
+
...RecipientTelemetryProps,
|
|
1202
1239
|
kind: Schema.String,
|
|
1203
1240
|
chain_id: Schema.Number,
|
|
1204
|
-
settlement_id: Schema.String
|
|
1241
|
+
settlement_id: Schema.String,
|
|
1242
|
+
payment_id: OptionalString,
|
|
1243
|
+
payment_ids: OptionalString,
|
|
1244
|
+
command_id: OptionalString,
|
|
1245
|
+
payment_lifecycle_id: OptionalString,
|
|
1246
|
+
execution_id: OptionalString,
|
|
1247
|
+
user_op_hash: OptionalString,
|
|
1248
|
+
transaction_hash: OptionalString
|
|
1205
1249
|
});
|
|
1206
1250
|
const PaymentFailedL2Props = Schema.Struct({
|
|
1251
|
+
...PaymentLifecycleProps,
|
|
1207
1252
|
...TelemetryEnvelopeProps,
|
|
1208
1253
|
...ChainCauseTelemetryProps,
|
|
1254
|
+
...RecipientTelemetryProps,
|
|
1209
1255
|
kind: Schema.String,
|
|
1210
1256
|
payment_id: Schema.String,
|
|
1211
|
-
|
|
1257
|
+
payment_ids: OptionalString,
|
|
1258
|
+
reason_code: Schema.String,
|
|
1259
|
+
command_id: OptionalString,
|
|
1260
|
+
payment_lifecycle_id: OptionalString,
|
|
1261
|
+
execution_id: OptionalString,
|
|
1262
|
+
user_op_hash: OptionalString
|
|
1212
1263
|
});
|
|
1213
1264
|
const PaymentVerificationRetryProps = Schema.Struct({
|
|
1265
|
+
...PaymentLifecycleProps,
|
|
1214
1266
|
...TelemetryEnvelopeProps,
|
|
1267
|
+
...RecipientTelemetryProps,
|
|
1215
1268
|
command_id: Schema.String,
|
|
1269
|
+
payment_lifecycle_id: Schema.String,
|
|
1216
1270
|
attempt: Schema.Number,
|
|
1217
1271
|
reason_code: Schema.String,
|
|
1218
1272
|
chain_id: Schema.Number,
|
|
1219
1273
|
delay_ms: DurationMsSchema$1,
|
|
1220
|
-
outcome: Schema.Literals(["scheduled", "unresolved"])
|
|
1274
|
+
outcome: Schema.Literals(["scheduled", "unresolved"]),
|
|
1275
|
+
payment_id: OptionalString,
|
|
1276
|
+
payment_ids: OptionalString,
|
|
1277
|
+
execution_id: OptionalString,
|
|
1278
|
+
user_op_hash: OptionalString
|
|
1279
|
+
});
|
|
1280
|
+
const PaymentLifecycleTransitionProps = Schema.Struct({
|
|
1281
|
+
...TelemetryEnvelopeProps,
|
|
1282
|
+
...RecipientTelemetryProps,
|
|
1283
|
+
payment_id: Schema.String,
|
|
1284
|
+
payment_lifecycle_id: Schema.String,
|
|
1285
|
+
command_id: Schema.String,
|
|
1286
|
+
payment_state: Schema.String,
|
|
1287
|
+
occurred_at: Schema.Number,
|
|
1288
|
+
causal_sequence: Schema.Number,
|
|
1289
|
+
execution_id: OptionalString,
|
|
1290
|
+
execution_state: OptionalString,
|
|
1291
|
+
user_op_hash: OptionalString,
|
|
1292
|
+
sponsorship_valid_until: Schema.optional(Schema.Number),
|
|
1293
|
+
reason_code: OptionalString
|
|
1294
|
+
});
|
|
1295
|
+
const QuickPayExternalAddressAcknowledgedProps = Schema.Struct({
|
|
1296
|
+
...TelemetryEnvelopeProps,
|
|
1297
|
+
recipient_locator_kind: Schema.Literal("address"),
|
|
1298
|
+
recipient_resolution_status: Schema.Literal("external_address"),
|
|
1299
|
+
recipient_address: AddressSchema$1,
|
|
1300
|
+
external_address_acknowledged: Schema.Literal(true),
|
|
1301
|
+
organization_id: OptionalOrgId
|
|
1221
1302
|
});
|
|
1222
1303
|
const DepositInitiatedProps = Schema.Struct({ ...TelemetryEnvelopeProps });
|
|
1223
1304
|
const DepositSettledProps = Schema.Struct({
|
|
@@ -1425,6 +1506,14 @@ Schema.Struct({
|
|
|
1425
1506
|
name: Schema.Literal("payment_verification_retry"),
|
|
1426
1507
|
props: PaymentVerificationRetryProps
|
|
1427
1508
|
});
|
|
1509
|
+
Schema.Struct({
|
|
1510
|
+
name: Schema.Literal("payment_lifecycle_transition"),
|
|
1511
|
+
props: PaymentLifecycleTransitionProps
|
|
1512
|
+
});
|
|
1513
|
+
Schema.Struct({
|
|
1514
|
+
name: Schema.Literal("quick_pay_external_address_acknowledged"),
|
|
1515
|
+
props: QuickPayExternalAddressAcknowledgedProps
|
|
1516
|
+
});
|
|
1428
1517
|
Schema.Struct({
|
|
1429
1518
|
name: Schema.Literal("deposit_initiated"),
|
|
1430
1519
|
props: DepositInitiatedProps
|
|
@@ -1774,16 +1863,13 @@ const CAPXUL_FUNCTIONS = {
|
|
|
1774
1863
|
list: "financialOps/destinations:list",
|
|
1775
1864
|
remove: "financialOps/destinations:remove"
|
|
1776
1865
|
},
|
|
1777
|
-
"financialOps/mutations": { createPayee: "financialOps/mutations:createPayee" },
|
|
1778
1866
|
"financialOps/queries": {
|
|
1779
1867
|
depositInstructions: "financialOps/queries:depositInstructions",
|
|
1780
|
-
getPayee: "financialOps/queries:getPayee",
|
|
1781
1868
|
getPayment: "financialOps/queries:getPayment",
|
|
1782
1869
|
listPayments: "financialOps/queries:listPayments",
|
|
1783
1870
|
me: "financialOps/queries:me",
|
|
1784
1871
|
renderStoredDocument: "financialOps/queries:renderStoredDocument",
|
|
1785
|
-
|
|
1786
|
-
resolvePayee: "financialOps/queries:resolvePayee",
|
|
1872
|
+
resolveRecipient: "financialOps/queries:resolveRecipient",
|
|
1787
1873
|
verifyPaymentDocument: "financialOps/queries:verifyPaymentDocument"
|
|
1788
1874
|
},
|
|
1789
1875
|
"financialOps/requestsInbox": {
|
|
@@ -1802,7 +1888,7 @@ const CAPXUL_FUNCTIONS = {
|
|
|
1802
1888
|
},
|
|
1803
1889
|
"identity/queries": {
|
|
1804
1890
|
loadByAuthUserId: "identity/queries:loadByAuthUserId",
|
|
1805
|
-
|
|
1891
|
+
handleAvailable: "identity/queries:handleAvailable"
|
|
1806
1892
|
},
|
|
1807
1893
|
"holdings/actions": { current: "holdings/actions:current" },
|
|
1808
1894
|
"movement/activity": {
|
|
@@ -1812,6 +1898,7 @@ const CAPXUL_FUNCTIONS = {
|
|
|
1812
1898
|
summary: "movement/activity:summary"
|
|
1813
1899
|
},
|
|
1814
1900
|
"moneyExecution/actions": {
|
|
1901
|
+
abandonPaymentExecution: "moneyExecution/actions:abandonPaymentExecution",
|
|
1815
1902
|
preparePermissionExecution: "moneyExecution/actions:preparePermissionExecution",
|
|
1816
1903
|
preparePaymentExecution: "moneyExecution/actions:preparePaymentExecution",
|
|
1817
1904
|
submitPermissionExecution: "moneyExecution/actions:submitPermissionExecution",
|
|
@@ -1889,6 +1976,7 @@ const CAPXUL_FUNCTIONS = {
|
|
|
1889
1976
|
const PAYMENT_STATUSES = [
|
|
1890
1977
|
"pending",
|
|
1891
1978
|
"settling",
|
|
1979
|
+
"unresolved",
|
|
1892
1980
|
"scheduled",
|
|
1893
1981
|
"streaming",
|
|
1894
1982
|
"pending_claim",
|
|
@@ -1896,6 +1984,30 @@ const PAYMENT_STATUSES = [
|
|
|
1896
1984
|
"cancelled",
|
|
1897
1985
|
"failed"
|
|
1898
1986
|
];
|
|
1987
|
+
/** The lifecycle of one signed Payment execution attempt. */
|
|
1988
|
+
const PAYMENT_EXECUTION_STATUS = {
|
|
1989
|
+
PENDING: "pending",
|
|
1990
|
+
INCLUDED: "included",
|
|
1991
|
+
DROPPED: "dropped",
|
|
1992
|
+
REPLACED: "replaced",
|
|
1993
|
+
EXPIRED: "expired",
|
|
1994
|
+
UNRESOLVED: "unresolved",
|
|
1995
|
+
SUPERSEDED: "superseded",
|
|
1996
|
+
FAILED: "failed",
|
|
1997
|
+
SETTLED: "settled"
|
|
1998
|
+
};
|
|
1999
|
+
const PAYMENT_EXECUTION_STATUSES = [
|
|
2000
|
+
PAYMENT_EXECUTION_STATUS.PENDING,
|
|
2001
|
+
PAYMENT_EXECUTION_STATUS.INCLUDED,
|
|
2002
|
+
PAYMENT_EXECUTION_STATUS.DROPPED,
|
|
2003
|
+
PAYMENT_EXECUTION_STATUS.REPLACED,
|
|
2004
|
+
PAYMENT_EXECUTION_STATUS.EXPIRED,
|
|
2005
|
+
PAYMENT_EXECUTION_STATUS.UNRESOLVED,
|
|
2006
|
+
PAYMENT_EXECUTION_STATUS.SUPERSEDED,
|
|
2007
|
+
PAYMENT_EXECUTION_STATUS.FAILED,
|
|
2008
|
+
PAYMENT_EXECUTION_STATUS.SETTLED
|
|
2009
|
+
];
|
|
2010
|
+
PAYMENT_EXECUTION_STATUS.DROPPED, PAYMENT_EXECUTION_STATUS.REPLACED, PAYMENT_EXECUTION_STATUS.EXPIRED, PAYMENT_EXECUTION_STATUS.SUPERSEDED;
|
|
1899
2011
|
/** The payment direction relative to the current actor. */
|
|
1900
2012
|
const PAYMENT_DIRECTIONS = [
|
|
1901
2013
|
"in",
|
|
@@ -1931,22 +2043,16 @@ const EVM_ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
|
|
|
1931
2043
|
*/
|
|
1932
2044
|
const PAYMENT_DOCUMENT_VERIFYING_CONTRACT = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
|
|
1933
2045
|
const PAYMENT_ID_RE = /^payment_[0-9A-Za-z]+$/;
|
|
1934
|
-
const PAYEE_ID_RE = /^payee_[0-9A-Za-z]+$/;
|
|
1935
2046
|
const ORG_ID_RE = /^org_[0-9A-Za-z]+$/;
|
|
1936
|
-
const USER_ID_RE = /^user_[0-9A-Za-z]+$/;
|
|
1937
2047
|
const PARTY_ID_RE = /^party_[0-9A-Za-z]+$/;
|
|
1938
|
-
const HANDLE_RE = /^@?[a-z0-
|
|
1939
|
-
const ORG_HANDLE_RE = /^[a-z0-9][a-z0-9-]{2,31}$/;
|
|
2048
|
+
const HANDLE_RE = /^@?[a-z0-9_-]{3,30}$/;
|
|
1940
2049
|
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1941
2050
|
const MinorUnitStringSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => MINOR_UNIT_STRING_RE.test(value), { message: "must be a non-negative integer minor-unit string" })));
|
|
1942
2051
|
const PaymentIdSchema$1 = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => PAYMENT_ID_RE.test(value), { message: "must be payment_ plus an alphanumeric id" })));
|
|
1943
|
-
const PayeeIdSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => PAYEE_ID_RE.test(value), { message: "must be payee_ plus an alphanumeric id" })));
|
|
1944
2052
|
const OrgIdSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => ORG_ID_RE.test(value), { message: "must be org_ plus an alphanumeric id" })));
|
|
1945
|
-
const UserIdSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => USER_ID_RE.test(value), { message: "must be user_ plus an alphanumeric id" })));
|
|
1946
2053
|
const PartyIdSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => PARTY_ID_RE.test(value), { message: "must be party_ plus an alphanumeric id" })));
|
|
1947
2054
|
const DecimalStringSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => DECIMAL_STRING_RE.test(value), { message: "must be a non-negative decimal string" })));
|
|
1948
2055
|
const HandleValueSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => !EVM_ADDRESS_RE.test(value) && HANDLE_RE.test(value), { message: "must be a handle; raw addresses are not accepted" })));
|
|
1949
|
-
const OrgHandleValueSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => !EVM_ADDRESS_RE.test(value) && ORG_HANDLE_RE.test(value), { message: "must be an org handle; raw addresses are not accepted" })));
|
|
1950
2056
|
const EmailValueSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => !EVM_ADDRESS_RE.test(value) && EMAIL_RE.test(value), { message: "must be an email; raw addresses are not accepted" })));
|
|
1951
2057
|
const Uint8Schema$1 = Schema.Number.pipe(Schema.check(Schema.makeFilter((value) => Number.isSafeInteger(value) && value >= 0 && value <= 255, { message: "must be a uint8" })));
|
|
1952
2058
|
const Uint64Schema = Schema.Number.pipe(Schema.check(Schema.makeFilter((value) => Number.isSafeInteger(value) && value >= 0, { message: "must be a non-negative safe integer" })));
|
|
@@ -2066,42 +2172,39 @@ const WithdrawalDocumentEnvelope = Schema.Struct({
|
|
|
2066
2172
|
primaryType: Schema.Literal("Withdrawal"),
|
|
2067
2173
|
message: WithdrawalDocument
|
|
2068
2174
|
});
|
|
2069
|
-
Schema.Union([AttachablePaymentDocumentEnvelope, WithdrawalDocumentEnvelope]);
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
]),
|
|
2078
|
-
destinationKind: Schema.Literals([
|
|
2079
|
-
"handle",
|
|
2080
|
-
"email",
|
|
2081
|
-
"saved-payee",
|
|
2082
|
-
"org"
|
|
2083
|
-
])
|
|
2084
|
-
});
|
|
2085
|
-
const PaymentRecipient = Schema.Struct({
|
|
2086
|
-
kind: Schema.Literals([
|
|
2087
|
-
"handle",
|
|
2088
|
-
"email",
|
|
2089
|
-
"payee",
|
|
2090
|
-
"capxulUserId",
|
|
2091
|
-
"me",
|
|
2092
|
-
"org",
|
|
2093
|
-
"party",
|
|
2094
|
-
"external_address"
|
|
2095
|
-
]),
|
|
2096
|
-
label: Schema.String,
|
|
2097
|
-
payeeId: Schema.optional(PayeeIdSchema)
|
|
2098
|
-
});
|
|
2175
|
+
const PaymentDocumentEnvelope = Schema.Union([AttachablePaymentDocumentEnvelope, WithdrawalDocumentEnvelope]);
|
|
2176
|
+
const ENVELOPE_PRIMARY_TYPE_TO_KIND = {
|
|
2177
|
+
Memo: "memo",
|
|
2178
|
+
Invoice: "invoice",
|
|
2179
|
+
Payslip: "payslip",
|
|
2180
|
+
Receipt: "receipt",
|
|
2181
|
+
Withdrawal: "withdrawal"
|
|
2182
|
+
};
|
|
2099
2183
|
/**
|
|
2100
|
-
*
|
|
2101
|
-
*
|
|
2102
|
-
*
|
|
2103
|
-
*
|
|
2104
|
-
*
|
|
2184
|
+
* Derive the wire `paymentType` an UNKNOWN document envelope classifies to
|
|
2185
|
+
* (payment-document-spec.md D11: memo/withdrawal → unspecified, invoice →
|
|
2186
|
+
* invoice, payslip → payroll, receipt → reimbursement), or `undefined` if the
|
|
2187
|
+
* envelope is absent / malformed — the same tolerance as
|
|
2188
|
+
* `tryHashPaymentDocument`. Callers holding an untyped envelope (e.g. the MCP
|
|
2189
|
+
* org spend port, #712) use this so the type they record agrees with the type
|
|
2190
|
+
* the backend re-derives from the same document.
|
|
2191
|
+
*/
|
|
2192
|
+
function paymentTypeForDocumentEnvelope(envelope) {
|
|
2193
|
+
if (envelope === void 0 || envelope === null) return void 0;
|
|
2194
|
+
const decoded = SchemaParser.decodeUnknownResult(PaymentDocumentEnvelope)(envelope);
|
|
2195
|
+
if (decoded._tag === "Failure") return void 0;
|
|
2196
|
+
return paymentTypeForDocumentKind(ENVELOPE_PRIMARY_TYPE_TO_KIND[decoded.success.primaryType]);
|
|
2197
|
+
}
|
|
2198
|
+
const PaymentRecipient = Schema.Union([Schema.Struct({
|
|
2199
|
+
kind: Schema.Literal("party"),
|
|
2200
|
+
partyId: PartyIdSchema,
|
|
2201
|
+
label: Schema.String
|
|
2202
|
+
}), Schema.Struct({
|
|
2203
|
+
kind: Schema.Literal("external_address"),
|
|
2204
|
+
label: Schema.String
|
|
2205
|
+
})]);
|
|
2206
|
+
/**
|
|
2207
|
+
* A raw external EVM address for a payment or withdrawal destination.
|
|
2105
2208
|
*/
|
|
2106
2209
|
const ExternalAddressSchema = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => EVM_ADDRESS_RE.test(value), { message: "must be a 0x EVM address (40 hex chars)" })));
|
|
2107
2210
|
const PaymentTiming = Schema.Union([
|
|
@@ -2127,16 +2230,8 @@ const PaymentRef = Schema.Union([
|
|
|
2127
2230
|
email: EmailValueSchema
|
|
2128
2231
|
}),
|
|
2129
2232
|
Schema.Struct({
|
|
2130
|
-
kind: Schema.Literal("
|
|
2131
|
-
|
|
2132
|
-
}),
|
|
2133
|
-
Schema.Struct({
|
|
2134
|
-
kind: Schema.Literal("capxulUserId"),
|
|
2135
|
-
capxulUserId: UserIdSchema
|
|
2136
|
-
}),
|
|
2137
|
-
Schema.Struct({
|
|
2138
|
-
kind: Schema.Literal("payeeId"),
|
|
2139
|
-
payeeId: PayeeIdSchema
|
|
2233
|
+
kind: Schema.Literal("address"),
|
|
2234
|
+
address: ExternalAddressSchema
|
|
2140
2235
|
}),
|
|
2141
2236
|
Schema.Struct({
|
|
2142
2237
|
kind: Schema.Literal("party"),
|
|
@@ -2159,6 +2254,10 @@ const Payment = Schema.Struct({
|
|
|
2159
2254
|
timing: PaymentTiming,
|
|
2160
2255
|
released: FinancialOpsMoney,
|
|
2161
2256
|
availableToClaim: FinancialOpsMoney,
|
|
2257
|
+
execution: Schema.optional(Schema.Struct({
|
|
2258
|
+
status: Schema.Literals(PAYMENT_EXECUTION_STATUSES),
|
|
2259
|
+
retryRequired: Schema.Boolean
|
|
2260
|
+
})),
|
|
2162
2261
|
createdAt: EpochMsSchema,
|
|
2163
2262
|
updatedAt: EpochMsSchema
|
|
2164
2263
|
}).pipe(Schema.check(Schema.makeFilter((payment) => payment.documents.every((document) => paymentTypeForDocumentKind(document.kind) === payment.paymentType), { message: "document kind must map to paymentType" })));
|
|
@@ -2303,11 +2402,21 @@ const MovementIdentitySchema = Schema.Struct({
|
|
|
2303
2402
|
txHash: TxHashSchema,
|
|
2304
2403
|
logIndex: LogIndexSchema
|
|
2305
2404
|
});
|
|
2306
|
-
const
|
|
2405
|
+
const MovementCanonicalStateInputSchema = Schema.Literals([
|
|
2307
2406
|
"observed",
|
|
2407
|
+
"included",
|
|
2308
2408
|
"finalized",
|
|
2309
2409
|
"removed"
|
|
2310
2410
|
]);
|
|
2411
|
+
const MovementCanonicalStateOutputSchema = Schema.Literals([
|
|
2412
|
+
"observed",
|
|
2413
|
+
"included",
|
|
2414
|
+
"removed"
|
|
2415
|
+
]);
|
|
2416
|
+
const MovementCanonicalStateSchema = MovementCanonicalStateInputSchema.pipe(Schema.decodeTo(MovementCanonicalStateOutputSchema, {
|
|
2417
|
+
decode: SchemaGetter.transform((state) => state === "finalized" ? "included" : state),
|
|
2418
|
+
encode: SchemaGetter.transform((state) => state)
|
|
2419
|
+
}));
|
|
2311
2420
|
const MovementSchema = Schema.Struct({
|
|
2312
2421
|
...MovementIdentitySchema.fields,
|
|
2313
2422
|
movementId: MovementIdSchema,
|
|
@@ -2658,7 +2767,7 @@ Schema.Struct({
|
|
|
2658
2767
|
transfers: Schema.Array(TransferEvidenceSchema),
|
|
2659
2768
|
requestCount: nonNegativeInteger("requestCount")
|
|
2660
2769
|
});
|
|
2661
|
-
const
|
|
2770
|
+
const VerifiedMoneyEvidenceCommonSchema = Schema.Struct({
|
|
2662
2771
|
chainId: BaseSepoliaChainIdSchema,
|
|
2663
2772
|
contractAddress: AddressSchema,
|
|
2664
2773
|
userOpHash: Bytes32Schema,
|
|
@@ -2668,8 +2777,8 @@ const FinalizedMoneyEvidenceCommonSchema = Schema.Struct({
|
|
|
2668
2777
|
blockTimestamp: Uint48Schema,
|
|
2669
2778
|
eventLogIndex: LogIndexSchema
|
|
2670
2779
|
});
|
|
2671
|
-
const
|
|
2672
|
-
...
|
|
2780
|
+
const VerifiedPaymentEvidenceSchema = Schema.Struct({
|
|
2781
|
+
...VerifiedMoneyEvidenceCommonSchema.fields,
|
|
2673
2782
|
operation: Schema.Literal("send"),
|
|
2674
2783
|
settlementId: SettlementIdSchema,
|
|
2675
2784
|
purposeKind: PaymentPurposeKindSchema,
|
|
@@ -2681,8 +2790,8 @@ const FinalizedPaymentEvidenceSchema = Schema.Struct({
|
|
|
2681
2790
|
destination: AddressSchema,
|
|
2682
2791
|
rawAmount: WeiAmountSchema
|
|
2683
2792
|
});
|
|
2684
|
-
const
|
|
2685
|
-
...
|
|
2793
|
+
const VerifiedCommitmentCreationEvidenceSchema = Schema.Struct({
|
|
2794
|
+
...VerifiedMoneyEvidenceCommonSchema.fields,
|
|
2686
2795
|
operation: Schema.Literal("create_commitment"),
|
|
2687
2796
|
commitmentId: Uint256StringSchema,
|
|
2688
2797
|
settlementId: SettlementIdSchema,
|
|
@@ -2698,8 +2807,8 @@ const FinalizedCommitmentCreationEvidenceSchema = Schema.Struct({
|
|
|
2698
2807
|
documentHash: NonzeroDocumentHashSchema,
|
|
2699
2808
|
transferLogIndex: LogIndexSchema
|
|
2700
2809
|
});
|
|
2701
|
-
const
|
|
2702
|
-
...
|
|
2810
|
+
const VerifiedCommitmentClaimEvidenceSchema = Schema.Struct({
|
|
2811
|
+
...VerifiedMoneyEvidenceCommonSchema.fields,
|
|
2703
2812
|
operation: Schema.Literal("claim_commitment"),
|
|
2704
2813
|
commitmentId: Uint256StringSchema,
|
|
2705
2814
|
settlementId: SettlementIdSchema,
|
|
@@ -2712,8 +2821,8 @@ const FinalizedCommitmentClaimEvidenceSchema = Schema.Struct({
|
|
|
2712
2821
|
documentHash: NonzeroDocumentHashSchema,
|
|
2713
2822
|
transferLogIndex: LogIndexSchema
|
|
2714
2823
|
});
|
|
2715
|
-
const
|
|
2716
|
-
...
|
|
2824
|
+
const VerifiedCommitmentCancelEvidenceSchema = Schema.Struct({
|
|
2825
|
+
...VerifiedMoneyEvidenceCommonSchema.fields,
|
|
2717
2826
|
operation: Schema.Literal("cancel_commitment"),
|
|
2718
2827
|
commitmentId: Uint256StringSchema,
|
|
2719
2828
|
settlementId: SettlementIdSchema,
|
|
@@ -2727,8 +2836,8 @@ const FinalizedCommitmentCancelEvidenceSchema = Schema.Struct({
|
|
|
2727
2836
|
documentHash: NonzeroDocumentHashSchema,
|
|
2728
2837
|
transfer: Schema.NullOr(TransferEvidenceSchema)
|
|
2729
2838
|
});
|
|
2730
|
-
const
|
|
2731
|
-
...
|
|
2839
|
+
const VerifiedCommitmentRedirectEvidenceSchema = Schema.Struct({
|
|
2840
|
+
...VerifiedMoneyEvidenceCommonSchema.fields,
|
|
2732
2841
|
operation: Schema.Literal("redirect_commitment"),
|
|
2733
2842
|
commitmentId: Uint256StringSchema,
|
|
2734
2843
|
settlementId: SettlementIdSchema,
|
|
@@ -2739,12 +2848,12 @@ const FinalizedCommitmentRedirectEvidenceSchema = Schema.Struct({
|
|
|
2739
2848
|
documentHash: NonzeroDocumentHashSchema,
|
|
2740
2849
|
transfer: Schema.Null
|
|
2741
2850
|
});
|
|
2742
|
-
const
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2851
|
+
const VerifiedMoneyEvidenceSchema = Schema.Union([
|
|
2852
|
+
VerifiedPaymentEvidenceSchema,
|
|
2853
|
+
VerifiedCommitmentCreationEvidenceSchema,
|
|
2854
|
+
VerifiedCommitmentClaimEvidenceSchema,
|
|
2855
|
+
VerifiedCommitmentCancelEvidenceSchema,
|
|
2856
|
+
VerifiedCommitmentRedirectEvidenceSchema
|
|
2748
2857
|
]);
|
|
2749
2858
|
Schema.Union([
|
|
2750
2859
|
Schema.Struct({
|
|
@@ -2754,7 +2863,7 @@ Schema.Union([
|
|
|
2754
2863
|
}),
|
|
2755
2864
|
Schema.Struct({
|
|
2756
2865
|
status: Schema.Literal("verified"),
|
|
2757
|
-
evidence:
|
|
2866
|
+
evidence: VerifiedMoneyEvidenceSchema
|
|
2758
2867
|
}),
|
|
2759
2868
|
Schema.Struct({
|
|
2760
2869
|
status: Schema.Literal("mismatch"),
|
|
@@ -2766,7 +2875,7 @@ Schema.Union([
|
|
|
2766
2875
|
retryable: Schema.Literal(true)
|
|
2767
2876
|
})
|
|
2768
2877
|
]);
|
|
2769
|
-
const
|
|
2878
|
+
const VerifiedAttributedInboundMovementSchema = Schema.Struct({
|
|
2770
2879
|
movement: MovementSchema,
|
|
2771
2880
|
attribution: MovementAttributionSchema
|
|
2772
2881
|
});
|
|
@@ -2792,6 +2901,25 @@ const ProtocolBirthInputSchema = Schema.Struct({
|
|
|
2792
2901
|
release: ReleaseTermsSchema,
|
|
2793
2902
|
lineage: Schema.optional(PaymentCommandLineageSchema)
|
|
2794
2903
|
}).pipe(Schema.refine((birth) => hasActorBoundPermission(birth.actor, birth.actor.kind === "organization" ? birth.actor.orgId : void 0, birth.permissionId), { message: "Organization Payment and Payout births require permissionId; personal births forbid it" }));
|
|
2904
|
+
const ApplyVerifiedEvidenceCommandSchema = Schema.Struct({
|
|
2905
|
+
kind: Schema.Literal("apply_verified_evidence"),
|
|
2906
|
+
paymentId: PaymentIdSchema,
|
|
2907
|
+
evidence: VerifiedMoneyEvidenceSchema
|
|
2908
|
+
});
|
|
2909
|
+
const ApplyFinalizedEvidenceCommandSchema = Schema.Struct({
|
|
2910
|
+
kind: Schema.Literal("apply_finalized_evidence"),
|
|
2911
|
+
paymentId: PaymentIdSchema,
|
|
2912
|
+
evidence: VerifiedMoneyEvidenceSchema
|
|
2913
|
+
}).pipe(Schema.decodeTo(ApplyVerifiedEvidenceCommandSchema, {
|
|
2914
|
+
decode: SchemaGetter.transform((value) => ({
|
|
2915
|
+
...value,
|
|
2916
|
+
kind: "apply_verified_evidence"
|
|
2917
|
+
})),
|
|
2918
|
+
encode: SchemaGetter.transform((value) => ({
|
|
2919
|
+
...value,
|
|
2920
|
+
kind: "apply_finalized_evidence"
|
|
2921
|
+
}))
|
|
2922
|
+
}));
|
|
2795
2923
|
Schema.Union([
|
|
2796
2924
|
Schema.Struct({
|
|
2797
2925
|
kind: Schema.Literal("birth"),
|
|
@@ -2799,7 +2927,7 @@ Schema.Union([
|
|
|
2799
2927
|
}),
|
|
2800
2928
|
Schema.Struct({
|
|
2801
2929
|
kind: Schema.Literal("birth_deposit"),
|
|
2802
|
-
movement:
|
|
2930
|
+
movement: VerifiedAttributedInboundMovementSchema
|
|
2803
2931
|
}),
|
|
2804
2932
|
Schema.Struct({
|
|
2805
2933
|
kind: Schema.Literal("rollback_deposit"),
|
|
@@ -2811,11 +2939,8 @@ Schema.Union([
|
|
|
2811
2939
|
paymentIds: Schema.Array(PaymentIdSchema),
|
|
2812
2940
|
userOpHash: Bytes32Schema
|
|
2813
2941
|
}),
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
paymentId: PaymentIdSchema,
|
|
2817
|
-
evidence: FinalizedMoneyEvidenceSchema
|
|
2818
|
-
}),
|
|
2942
|
+
ApplyVerifiedEvidenceCommandSchema,
|
|
2943
|
+
ApplyFinalizedEvidenceCommandSchema,
|
|
2819
2944
|
Schema.Struct({
|
|
2820
2945
|
kind: Schema.Literal("transition"),
|
|
2821
2946
|
paymentId: PaymentIdSchema,
|
|
@@ -2957,6 +3082,7 @@ const MoneyExecutionIdSchema = Schema.String.pipe(Schema.refine((value) => /^mon
|
|
|
2957
3082
|
const OwnerSignatureSchema = Schema.String.pipe(Schema.refine((value) => /^0x[0-9a-fA-F]{130}$/u.test(value), { message: "signature must be a 65-byte 0x value" }));
|
|
2958
3083
|
const PaymentExecutionIntentSchema = Schema.Struct({
|
|
2959
3084
|
to: PaymentRef,
|
|
3085
|
+
externalAddressAcknowledged: Schema.optional(Schema.Literal(true)),
|
|
2960
3086
|
amount: FinancialOpsMoney,
|
|
2961
3087
|
paymentType: Schema.optional(Schema.Literals([
|
|
2962
3088
|
"unspecified",
|
|
@@ -2973,7 +3099,31 @@ Schema.Struct({
|
|
|
2973
3099
|
signerAddress: AddressSchema,
|
|
2974
3100
|
payment: PaymentExecutionIntentSchema
|
|
2975
3101
|
});
|
|
3102
|
+
const RecipientObservationSchema = Schema.Struct({
|
|
3103
|
+
recipient_locator_kind: Schema.Literals([
|
|
3104
|
+
"handle",
|
|
3105
|
+
"email",
|
|
3106
|
+
"party",
|
|
3107
|
+
"address"
|
|
3108
|
+
]),
|
|
3109
|
+
recipient_resolution_status: Schema.Literals([
|
|
3110
|
+
"known_party",
|
|
3111
|
+
"new_email",
|
|
3112
|
+
"external_address"
|
|
3113
|
+
]),
|
|
3114
|
+
recipient_is_capxul_account: Schema.Boolean,
|
|
3115
|
+
recipient_party_id: Schema.optional(Schema.String),
|
|
3116
|
+
recipient_party_kind: Schema.optional(Schema.Literals([
|
|
3117
|
+
"person",
|
|
3118
|
+
"organization",
|
|
3119
|
+
"unresolved"
|
|
3120
|
+
])),
|
|
3121
|
+
recipient_handle: Schema.optional(Schema.String),
|
|
3122
|
+
recipient_address: AddressSchema,
|
|
3123
|
+
external_address_acknowledged: Schema.Boolean
|
|
3124
|
+
});
|
|
2976
3125
|
Schema.Struct({
|
|
3126
|
+
recipientObservation: RecipientObservationSchema,
|
|
2977
3127
|
executionId: MoneyExecutionIdSchema,
|
|
2978
3128
|
commandId: PaymentCommandIdSchema,
|
|
2979
3129
|
paymentId: PaymentIdSchema,
|
|
@@ -2990,6 +3140,14 @@ Schema.Struct({
|
|
|
2990
3140
|
executionId: MoneyExecutionIdSchema,
|
|
2991
3141
|
signature: OwnerSignatureSchema
|
|
2992
3142
|
});
|
|
3143
|
+
Schema.Struct({
|
|
3144
|
+
executionId: MoneyExecutionIdSchema,
|
|
3145
|
+
reason: Schema.Literals([
|
|
3146
|
+
"signer_rejected",
|
|
3147
|
+
"cancelled",
|
|
3148
|
+
"prepared_mismatch"
|
|
3149
|
+
])
|
|
3150
|
+
});
|
|
2993
3151
|
Schema.Struct({
|
|
2994
3152
|
executionId: MoneyExecutionIdSchema,
|
|
2995
3153
|
commandId: PaymentCommandIdSchema,
|
|
@@ -3003,6 +3161,10 @@ Schema.Struct({
|
|
|
3003
3161
|
payments: Schema.Array(Payment)
|
|
3004
3162
|
});
|
|
3005
3163
|
const PaymentLifecycleExecutionIntentSchema = Schema.Union([
|
|
3164
|
+
Schema.Struct({
|
|
3165
|
+
kind: Schema.Literal("retry"),
|
|
3166
|
+
paymentId: PaymentIdSchema
|
|
3167
|
+
}),
|
|
3006
3168
|
Schema.Struct({
|
|
3007
3169
|
kind: Schema.Literal("claim"),
|
|
3008
3170
|
paymentId: PaymentIdSchema
|
|
@@ -3023,6 +3185,7 @@ Schema.Struct({
|
|
|
3023
3185
|
});
|
|
3024
3186
|
const OrganizationPaymentExecutionItemSchema = Schema.Struct({
|
|
3025
3187
|
to: PaymentRef,
|
|
3188
|
+
externalAddressAcknowledged: Schema.optional(Schema.Literal(true)),
|
|
3026
3189
|
amount: FinancialOpsMoney,
|
|
3027
3190
|
paymentType: Schema.optional(Schema.Literals([
|
|
3028
3191
|
"unspecified",
|
|
@@ -3041,6 +3204,8 @@ Schema.Struct({
|
|
|
3041
3204
|
lineage: Schema.optional(PaymentCommandLineageSchema)
|
|
3042
3205
|
});
|
|
3043
3206
|
const PreparedPaymentCommandExecutionSchema = Schema.Struct({
|
|
3207
|
+
recipientObservations: Schema.Array(RecipientObservationSchema),
|
|
3208
|
+
emitPaymentInitiated: Schema.Boolean,
|
|
3044
3209
|
executionId: MoneyExecutionIdSchema,
|
|
3045
3210
|
commandId: PaymentCommandIdSchema,
|
|
3046
3211
|
paymentIds: Schema.Array(PaymentIdSchema),
|
|
@@ -3076,7 +3241,8 @@ const PermissionCommandSchema = Schema.Union([
|
|
|
3076
3241
|
operation: Schema.Literal("assign"),
|
|
3077
3242
|
requestKey: nonEmpty("requestKey"),
|
|
3078
3243
|
permissionId: PermissionIdSchema,
|
|
3079
|
-
accountId: nonEmpty("accountId")
|
|
3244
|
+
accountId: nonEmpty("accountId"),
|
|
3245
|
+
expectedMemberEmail: Schema.optional(nonEmpty("expectedMemberEmail"))
|
|
3080
3246
|
}),
|
|
3081
3247
|
Schema.Struct({
|
|
3082
3248
|
operation: Schema.Literal("revoke"),
|
|
@@ -4520,25 +4686,11 @@ function normalizeRefForBackend$1(ref, field) {
|
|
|
4520
4686
|
email: nonEmptyRefValue$1(ref.email, "email")
|
|
4521
4687
|
}
|
|
4522
4688
|
};
|
|
4523
|
-
case "
|
|
4689
|
+
case "address": return {
|
|
4524
4690
|
ok: true,
|
|
4525
4691
|
value: {
|
|
4526
|
-
kind: "
|
|
4527
|
-
|
|
4528
|
-
}
|
|
4529
|
-
};
|
|
4530
|
-
case "capxulUserId": return {
|
|
4531
|
-
ok: true,
|
|
4532
|
-
value: {
|
|
4533
|
-
kind: "capxulUserId",
|
|
4534
|
-
capxulUserId: nonEmptyRefValue$1(ref.capxulUserId, "capxulUserId")
|
|
4535
|
-
}
|
|
4536
|
-
};
|
|
4537
|
-
case "payeeId": return {
|
|
4538
|
-
ok: true,
|
|
4539
|
-
value: {
|
|
4540
|
-
kind: "payeeId",
|
|
4541
|
-
payeeId: nonEmptyRefValue$1(ref.payeeId, "payeeId")
|
|
4692
|
+
kind: "address",
|
|
4693
|
+
address: toAddress(ref.address)
|
|
4542
4694
|
}
|
|
4543
4695
|
};
|
|
4544
4696
|
case "party": return {
|
|
@@ -4802,10 +4954,7 @@ function makeAccountMethods(deps) {
|
|
|
4802
4954
|
const financialOpsContract = {
|
|
4803
4955
|
me: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].me),
|
|
4804
4956
|
depositInstructions: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].depositInstructions),
|
|
4805
|
-
|
|
4806
|
-
createPayee: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/mutations"].createPayee),
|
|
4807
|
-
getPayee: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].getPayee),
|
|
4808
|
-
resolvePayee: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].resolvePayee),
|
|
4957
|
+
resolveRecipient: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/queries"].resolveRecipient),
|
|
4809
4958
|
addDestination: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/destinations"].add),
|
|
4810
4959
|
listDestinations: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/destinations"].list),
|
|
4811
4960
|
removeDestination: makeFunctionReference(CAPXUL_FUNCTIONS["financialOps/destinations"].remove),
|
|
@@ -4821,6 +4970,7 @@ const financialOpsContract = {
|
|
|
4821
4970
|
//#endregion
|
|
4822
4971
|
//#region src/contract/money-execution.ts
|
|
4823
4972
|
const moneyExecutionContract = {
|
|
4973
|
+
abandonPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].abandonPaymentExecution),
|
|
4824
4974
|
preparePermissionExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].preparePermissionExecution),
|
|
4825
4975
|
preparePaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/actions"].preparePaymentExecution),
|
|
4826
4976
|
prepareOrganizationPaymentExecution: makeFunctionReference(CAPXUL_FUNCTIONS["moneyExecution/paymentCommandActions"].prepareOrganizationPaymentExecution),
|
|
@@ -4831,7 +4981,7 @@ const moneyExecutionContract = {
|
|
|
4831
4981
|
};
|
|
4832
4982
|
//#endregion
|
|
4833
4983
|
//#region package.json
|
|
4834
|
-
var version = "
|
|
4984
|
+
var version = "4.0.0";
|
|
4835
4985
|
//#endregion
|
|
4836
4986
|
//#region src/telemetry/exception-projection.ts
|
|
4837
4987
|
/** Fixed fallback for failures that have no safe message. */
|
|
@@ -5542,7 +5692,11 @@ function emitPaymentInitiated(telemetry, input) {
|
|
|
5542
5692
|
name: "payment_initiated",
|
|
5543
5693
|
props: {
|
|
5544
5694
|
kind: input.kind,
|
|
5545
|
-
payment_id: input.paymentId
|
|
5695
|
+
payment_id: input.paymentId,
|
|
5696
|
+
payment_lifecycle_id: `payment_lifecycle_${input.paymentId}`,
|
|
5697
|
+
...input.commandId === void 0 ? {} : { command_id: input.commandId },
|
|
5698
|
+
...input.executionId === void 0 ? {} : { execution_id: input.executionId },
|
|
5699
|
+
...input.recipient
|
|
5546
5700
|
}
|
|
5547
5701
|
});
|
|
5548
5702
|
}
|
|
@@ -5574,7 +5728,17 @@ async function fingerprintPaymentIntent(intent) {
|
|
|
5574
5728
|
function matchesIntent(expected) {
|
|
5575
5729
|
return async (request) => await fingerprintPaymentIntent(request) === await fingerprintPaymentIntent(expected);
|
|
5576
5730
|
}
|
|
5577
|
-
async function
|
|
5731
|
+
async function abandonPrepared$1(deps, executionId, closePayment, reason, result, onPreparedClosed) {
|
|
5732
|
+
if (!closePayment) return result;
|
|
5733
|
+
const abandoned = await runIfActive(void 0, CAPXUL_OPERATIONS.moneyExecution.abandonPaymentExecution, () => deps.convexCall.action(deps.functions.abandonPaymentExecution, { input: {
|
|
5734
|
+
executionId,
|
|
5735
|
+
reason
|
|
5736
|
+
} }));
|
|
5737
|
+
if (!abandoned.ok) return abandoned;
|
|
5738
|
+
if (abandoned.value) onPreparedClosed?.();
|
|
5739
|
+
return result;
|
|
5740
|
+
}
|
|
5741
|
+
async function executePrepared(deps, prepare, isExpectedRequest, closePaymentOnExit, onPreparedClosed, signal) {
|
|
5578
5742
|
if (isAborted$2(signal)) return {
|
|
5579
5743
|
ok: false,
|
|
5580
5744
|
error: Errors.cancelled({ operation: "payments" })
|
|
@@ -5595,32 +5759,45 @@ async function executePrepared(deps, prepare, isExpectedRequest, signal) {
|
|
|
5595
5759
|
}
|
|
5596
5760
|
const prepared = await prepare(signerAddress);
|
|
5597
5761
|
if (!prepared.ok) return prepared;
|
|
5598
|
-
if (!await isExpectedRequest(prepared.value.request)) return {
|
|
5762
|
+
if (!await isExpectedRequest(prepared.value.request)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "prepared_mismatch", {
|
|
5599
5763
|
ok: false,
|
|
5600
5764
|
error: Errors.invalidInput("payment", "prepared command mismatch")
|
|
5601
|
-
};
|
|
5765
|
+
}, onPreparedClosed);
|
|
5602
5766
|
const expectedSafe = deriveCapxulSafeAddress({ email: session.email });
|
|
5603
|
-
if (prepared.value.chainId !== deps.chainId || prepared.value.signerAddress.toLowerCase() !== signerAddress.toLowerCase() || prepared.value.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return {
|
|
5767
|
+
if (prepared.value.chainId !== deps.chainId || prepared.value.signerAddress.toLowerCase() !== signerAddress.toLowerCase() || prepared.value.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "prepared_mismatch", {
|
|
5604
5768
|
ok: false,
|
|
5605
5769
|
error: Errors.invalidInput("payment", "prepared authority mismatch")
|
|
5606
|
-
};
|
|
5607
|
-
if (isAborted$2(signal)) return {
|
|
5770
|
+
}, onPreparedClosed);
|
|
5771
|
+
if (isAborted$2(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
|
|
5608
5772
|
ok: false,
|
|
5609
5773
|
error: Errors.cancelled({ operation: "payments" })
|
|
5610
|
-
};
|
|
5774
|
+
}, onPreparedClosed);
|
|
5775
|
+
if (prepared.value.emitPaymentInitiated && "items" in prepared.value.request) for (const [index, item] of prepared.value.request.items.entries()) {
|
|
5776
|
+
const paymentId = prepared.value.paymentIds[index];
|
|
5777
|
+
const recipient = prepared.value.recipientObservations[index];
|
|
5778
|
+
if (paymentId === void 0 || recipient === void 0) continue;
|
|
5779
|
+
const paymentType = paymentTypeForDocumentEnvelope(item.document) ?? item.paymentType ?? "unspecified";
|
|
5780
|
+
await emitPaymentInitiated(deps.telemetry, {
|
|
5781
|
+
commandId: prepared.value.commandId,
|
|
5782
|
+
executionId: prepared.value.executionId,
|
|
5783
|
+
paymentId,
|
|
5784
|
+
kind: paymentType === "unspecified" ? "quick_pay" : paymentType,
|
|
5785
|
+
recipient
|
|
5786
|
+
});
|
|
5787
|
+
}
|
|
5611
5788
|
let signature;
|
|
5612
5789
|
try {
|
|
5613
5790
|
signature = await deps.signer.signUserOpHash(prepared.value.digest);
|
|
5614
5791
|
} catch (cause) {
|
|
5615
|
-
return {
|
|
5792
|
+
return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "signer_rejected", {
|
|
5616
5793
|
ok: false,
|
|
5617
5794
|
error: signerFailure(deps.signer.source, "signUserOpHash", cause)
|
|
5618
|
-
};
|
|
5795
|
+
}, onPreparedClosed);
|
|
5619
5796
|
}
|
|
5620
|
-
if (isAborted$2(signal)) return {
|
|
5797
|
+
if (isAborted$2(signal)) return abandonPrepared$1(deps, prepared.value.executionId, closePaymentOnExit, "cancelled", {
|
|
5621
5798
|
ok: false,
|
|
5622
5799
|
error: Errors.cancelled({ operation: "payments" })
|
|
5623
|
-
};
|
|
5800
|
+
}, onPreparedClosed);
|
|
5624
5801
|
return runIfActive(void 0, CAPXUL_OPERATIONS.payments.submitCommandExecution, () => deps.convexCall.action(deps.functions.submitPaymentCommandExecution, { input: {
|
|
5625
5802
|
executionId: prepared.value.executionId,
|
|
5626
5803
|
signature
|
|
@@ -5630,13 +5807,13 @@ function executePaymentLifecycle(deps, intent, signal) {
|
|
|
5630
5807
|
return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.payments.prepareLifecycleExecution, () => deps.convexCall.action(deps.functions.preparePaymentLifecycleExecution, { input: {
|
|
5631
5808
|
signerAddress,
|
|
5632
5809
|
intent
|
|
5633
|
-
} })), matchesIntent(intent), signal);
|
|
5810
|
+
} })), matchesIntent(intent), false, void 0, signal);
|
|
5634
5811
|
}
|
|
5635
|
-
function executeOrganizationPayment(deps, input, signal) {
|
|
5812
|
+
function executeOrganizationPayment(deps, input, signal, onPreparedClosed) {
|
|
5636
5813
|
return executePrepared(deps, (signerAddress) => runIfActive(signal, CAPXUL_OPERATIONS.organizationPayments.prepareExecution, () => deps.convexCall.action(deps.functions.prepareOrganizationPaymentExecution, { input: {
|
|
5637
5814
|
...input,
|
|
5638
5815
|
signerAddress
|
|
5639
|
-
} })), matchesIntent(input), signal);
|
|
5816
|
+
} })), matchesIntent(input), true, onPreparedClosed, signal);
|
|
5640
5817
|
}
|
|
5641
5818
|
//#endregion
|
|
5642
5819
|
//#region src/surface/payment-execution.ts
|
|
@@ -5668,7 +5845,16 @@ async function signerCall(source, operation, run) {
|
|
|
5668
5845
|
};
|
|
5669
5846
|
}
|
|
5670
5847
|
}
|
|
5671
|
-
async function
|
|
5848
|
+
async function abandonPrepared(deps, executionId, reason, result, onPreparedClosed) {
|
|
5849
|
+
const abandoned = await runIfActive(void 0, CAPXUL_OPERATIONS.moneyExecution.abandonPaymentExecution, () => deps.convexCall.action(deps.functions.abandonPaymentExecution, { input: {
|
|
5850
|
+
executionId,
|
|
5851
|
+
reason
|
|
5852
|
+
} }));
|
|
5853
|
+
if (!abandoned.ok) return abandoned;
|
|
5854
|
+
if (abandoned.value) onPreparedClosed?.();
|
|
5855
|
+
return result;
|
|
5856
|
+
}
|
|
5857
|
+
async function executePersonalPayment(deps, payment, signal, requestKey, onPreparedClosed) {
|
|
5672
5858
|
if (isAborted$1(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
|
|
5673
5859
|
if (deps.signer === void 0) return mismatch("signer", "payments.pay requires a configured CapxulSigner");
|
|
5674
5860
|
const session = deps.actor.authSession();
|
|
@@ -5686,18 +5872,21 @@ async function executePersonalPayment(deps, payment, signal, requestKey) {
|
|
|
5686
5872
|
payment
|
|
5687
5873
|
} }));
|
|
5688
5874
|
if (!prepared.ok) return prepared;
|
|
5689
|
-
if (prepared.value.requestKey !== resolvedRequestKey || canonicalJson(prepared.value.payment) !== canonicalJson(payment)) return mismatch("payment", "prepared Payment execution uses another request");
|
|
5690
|
-
if (prepared.value.chainId !== deps.chainId) return mismatch("chainId", "prepared Payment execution uses another chain");
|
|
5691
|
-
if (prepared.value.signerAddress.toLowerCase() !== signerAddress.value.toLowerCase()) return mismatch("signerAddress", "prepared Payment execution uses another signer");
|
|
5692
|
-
if (prepared.value.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return mismatch("userOpSenderSafe", "prepared Payment execution uses another Account Safe");
|
|
5875
|
+
if (prepared.value.requestKey !== resolvedRequestKey || canonicalJson(prepared.value.payment) !== canonicalJson(payment)) return abandonPrepared(deps, prepared.value.executionId, "prepared_mismatch", mismatch("payment", "prepared Payment execution uses another request"), onPreparedClosed);
|
|
5876
|
+
if (prepared.value.chainId !== deps.chainId) return abandonPrepared(deps, prepared.value.executionId, "prepared_mismatch", mismatch("chainId", "prepared Payment execution uses another chain"), onPreparedClosed);
|
|
5877
|
+
if (prepared.value.signerAddress.toLowerCase() !== signerAddress.value.toLowerCase()) return abandonPrepared(deps, prepared.value.executionId, "prepared_mismatch", mismatch("signerAddress", "prepared Payment execution uses another signer"), onPreparedClosed);
|
|
5878
|
+
if (prepared.value.userOpSenderSafe.toLowerCase() !== expectedSafe.toLowerCase()) return abandonPrepared(deps, prepared.value.executionId, "prepared_mismatch", mismatch("userOpSenderSafe", "prepared Payment execution uses another Account Safe"), onPreparedClosed);
|
|
5693
5879
|
if (prepared.value.emitPaymentInitiated) await emitPaymentInitiated(deps.telemetry, {
|
|
5694
5880
|
kind: prepared.value.purposeKind,
|
|
5695
|
-
paymentId: prepared.value.paymentId
|
|
5881
|
+
paymentId: prepared.value.paymentId,
|
|
5882
|
+
commandId: prepared.value.commandId,
|
|
5883
|
+
executionId: prepared.value.executionId,
|
|
5884
|
+
recipient: prepared.value.recipientObservation
|
|
5696
5885
|
});
|
|
5697
|
-
if (isAborted$1(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
|
|
5886
|
+
if (isAborted$1(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
|
|
5698
5887
|
const signature = await signerCall(deps.signer.source, "signUserOpHash", () => deps.signer.signUserOpHash(prepared.value.digest));
|
|
5699
|
-
if (!signature.ok) return signature;
|
|
5700
|
-
if (isAborted$1(signal)) return cancelled(CAPXUL_OPERATIONS.payments.pay);
|
|
5888
|
+
if (!signature.ok) return abandonPrepared(deps, prepared.value.executionId, "signer_rejected", signature, onPreparedClosed);
|
|
5889
|
+
if (isAborted$1(signal)) return abandonPrepared(deps, prepared.value.executionId, "cancelled", cancelled(CAPXUL_OPERATIONS.payments.pay), onPreparedClosed);
|
|
5701
5890
|
return runIfActive(void 0, CAPXUL_OPERATIONS.payments.submitExecution, () => deps.convexCall.action(deps.functions.submitPaymentExecution, { input: {
|
|
5702
5891
|
executionId: prepared.value.executionId,
|
|
5703
5892
|
signature: signature.value
|
|
@@ -5925,6 +6114,30 @@ async function waitForPaymentSubmission(submission, signal, operation, onCancel
|
|
|
5925
6114
|
});
|
|
5926
6115
|
});
|
|
5927
6116
|
}
|
|
6117
|
+
function normalizeActivityDetail(detail) {
|
|
6118
|
+
if (detail === null) return null;
|
|
6119
|
+
if (detail.kind === "payment") {
|
|
6120
|
+
if (detail.evidence === null) return detail;
|
|
6121
|
+
return {
|
|
6122
|
+
...detail,
|
|
6123
|
+
evidence: {
|
|
6124
|
+
...detail.evidence,
|
|
6125
|
+
inclusion: "included",
|
|
6126
|
+
verification: "verified",
|
|
6127
|
+
finality: "finalized"
|
|
6128
|
+
}
|
|
6129
|
+
};
|
|
6130
|
+
}
|
|
6131
|
+
return {
|
|
6132
|
+
...detail,
|
|
6133
|
+
evidence: {
|
|
6134
|
+
...detail.evidence,
|
|
6135
|
+
inclusion: "included",
|
|
6136
|
+
verification: "verified",
|
|
6137
|
+
canonicalState: "finalized"
|
|
6138
|
+
}
|
|
6139
|
+
};
|
|
6140
|
+
}
|
|
5928
6141
|
function paymentExecutionIntent(input) {
|
|
5929
6142
|
if (actorReferenceToBackend(input.actor)?.kind === "org") return {
|
|
5930
6143
|
ok: false,
|
|
@@ -5937,6 +6150,7 @@ function paymentExecutionIntent(input) {
|
|
|
5937
6150
|
value: {
|
|
5938
6151
|
to: to.value,
|
|
5939
6152
|
amount: input.amount,
|
|
6153
|
+
...input.externalAddressAcknowledged === void 0 ? {} : { externalAddressAcknowledged: input.externalAddressAcknowledged },
|
|
5940
6154
|
...input.paymentType === void 0 ? {} : { paymentType: input.paymentType },
|
|
5941
6155
|
...input.document === void 0 ? {} : { document: input.document },
|
|
5942
6156
|
...input.timing === void 0 ? {} : { timing: input.timing },
|
|
@@ -5974,6 +6188,7 @@ function makeFinancialOpsMethods(deps) {
|
|
|
5974
6188
|
let flight = inFlightPersonalPayments.get(sharedKey);
|
|
5975
6189
|
if (flight === void 0) {
|
|
5976
6190
|
const controller = new AbortController();
|
|
6191
|
+
const requestState = { resolved: false };
|
|
5977
6192
|
const submission = executePersonalPayment({
|
|
5978
6193
|
actor: deps.actor,
|
|
5979
6194
|
chainId: deps.chainId,
|
|
@@ -5981,10 +6196,11 @@ function makeFinancialOpsMethods(deps) {
|
|
|
5981
6196
|
functions: executionFns,
|
|
5982
6197
|
...deps.signer === void 0 ? {} : { signer: deps.signer },
|
|
5983
6198
|
...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
|
|
5984
|
-
}, payment.value, controller.signal, requestKey.key);
|
|
6199
|
+
}, payment.value, controller.signal, requestKey.key, () => requestState.resolved = true);
|
|
5985
6200
|
flight = {
|
|
5986
6201
|
controller,
|
|
5987
6202
|
promise: submission,
|
|
6203
|
+
requestState,
|
|
5988
6204
|
waiters: 0,
|
|
5989
6205
|
settled: false
|
|
5990
6206
|
};
|
|
@@ -6022,7 +6238,7 @@ function makeFinancialOpsMethods(deps) {
|
|
|
6022
6238
|
}
|
|
6023
6239
|
release(false);
|
|
6024
6240
|
try {
|
|
6025
|
-
await requestKey.finish(submitted.ok);
|
|
6241
|
+
await requestKey.finish(submitted.ok || flight.requestState.resolved);
|
|
6026
6242
|
} catch {}
|
|
6027
6243
|
return mapOk(submitted, (value) => normalizePaymentTiming(value.payment));
|
|
6028
6244
|
};
|
|
@@ -6062,61 +6278,34 @@ function makeFinancialOpsMethods(deps) {
|
|
|
6062
6278
|
};
|
|
6063
6279
|
}
|
|
6064
6280
|
};
|
|
6281
|
+
const retryPayment = async (paymentId, signal) => {
|
|
6282
|
+
const execution = lifecycleDependencies();
|
|
6283
|
+
if (!execution.ok) return execution;
|
|
6284
|
+
try {
|
|
6285
|
+
const submitted = await executePaymentLifecycle(execution.value, {
|
|
6286
|
+
kind: "retry",
|
|
6287
|
+
paymentId
|
|
6288
|
+
}, signal);
|
|
6289
|
+
return submitted.ok ? {
|
|
6290
|
+
ok: true,
|
|
6291
|
+
value: submitted.value.payments.map((payment) => normalizePaymentTiming(payment))
|
|
6292
|
+
} : submitted;
|
|
6293
|
+
} catch (cause) {
|
|
6294
|
+
return {
|
|
6295
|
+
ok: false,
|
|
6296
|
+
error: cause instanceof CapxulError ? cause : Errors.unknown(cause)
|
|
6297
|
+
};
|
|
6298
|
+
}
|
|
6299
|
+
};
|
|
6065
6300
|
return {
|
|
6066
6301
|
me: {
|
|
6067
6302
|
get: (options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.me.get, () => deps.convexCall.query(fns.me, {})),
|
|
6068
6303
|
depositInstructions: (options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.me.depositInstructions, () => deps.convexCall.query(fns.depositInstructions, {}).pipe(Effect.tap(() => Effect.promise(() => emitDepositInitiated(deps.telemetry)))))
|
|
6069
6304
|
},
|
|
6070
|
-
handles: { resolve: (handle, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.handles.resolve, () => deps.convexCall.query(fns.resolveHandle, { handle })) },
|
|
6071
|
-
payees: {
|
|
6072
|
-
create: (input, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payees.create, () => deps.convexCall.mutation(fns.createPayee, {
|
|
6073
|
-
label: input.label,
|
|
6074
|
-
recipient: input.recipient,
|
|
6075
|
-
...input.handle === void 0 ? {} : { handle: input.handle }
|
|
6076
|
-
})),
|
|
6077
|
-
get: (payeeId, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payees.get, () => deps.convexCall.query(fns.getPayee, { payeeId })),
|
|
6078
|
-
resolve: (recipient, options) => runIfActive(options?.signal, CAPXUL_OPERATIONS.payees.resolve, () => deps.convexCall.query(fns.resolvePayee, { recipient }))
|
|
6079
|
-
},
|
|
6080
6305
|
targets: { resolve: async (reference, options) => {
|
|
6081
|
-
|
|
6082
|
-
|
|
6083
|
-
|
|
6084
|
-
case "organization": {
|
|
6085
|
-
const resolved = await runIfActive(options?.signal, CAPXUL_OPERATIONS.targets.resolve.organization, () => deps.convexCall.query(fns.resolveHandle, { handle: reference.handle }));
|
|
6086
|
-
if (!resolved.ok) return {
|
|
6087
|
-
ok: false,
|
|
6088
|
-
error: resolved.error
|
|
6089
|
-
};
|
|
6090
|
-
if (resolved.value.kind !== "org") return {
|
|
6091
|
-
ok: false,
|
|
6092
|
-
error: Errors.invalidInput("reference", "organization handle could not be resolved")
|
|
6093
|
-
};
|
|
6094
|
-
return {
|
|
6095
|
-
ok: true,
|
|
6096
|
-
value: resolvedTargetFromResolution(reference, resolved.value)
|
|
6097
|
-
};
|
|
6098
|
-
}
|
|
6099
|
-
case "payee": {
|
|
6100
|
-
const payee = await runIfActive(options?.signal, CAPXUL_OPERATIONS.targets.resolve.payee, () => deps.convexCall.query(fns.getPayee, { payeeId: reference.id }));
|
|
6101
|
-
if (!payee.ok) return {
|
|
6102
|
-
ok: false,
|
|
6103
|
-
error: payee.error
|
|
6104
|
-
};
|
|
6105
|
-
if (payee.value === null) return {
|
|
6106
|
-
ok: false,
|
|
6107
|
-
error: Errors.invalidInput("reference", "payee not found")
|
|
6108
|
-
};
|
|
6109
|
-
return {
|
|
6110
|
-
ok: true,
|
|
6111
|
-
value: resolvedTargetFromPayee(reference, payee.value)
|
|
6112
|
-
};
|
|
6113
|
-
}
|
|
6114
|
-
case "party":
|
|
6115
|
-
case "destination": return Promise.resolve({
|
|
6116
|
-
ok: false,
|
|
6117
|
-
error: Errors.notImplemented("targets", `resolve.${reference.kind}`)
|
|
6118
|
-
});
|
|
6119
|
-
}
|
|
6306
|
+
const recipient = normalizeTargetForBackend(reference, "reference");
|
|
6307
|
+
if (!recipient.ok) return recipient;
|
|
6308
|
+
return mapOk(await runIfActive(options?.signal, CAPXUL_OPERATIONS.recipient.resolve, () => deps.convexCall.query(fns.resolveRecipient, { recipient: recipient.value })), resolvedTargetFromResolution);
|
|
6120
6309
|
} },
|
|
6121
6310
|
destinations: {
|
|
6122
6311
|
add: async (input, options) => {
|
|
@@ -6159,6 +6348,7 @@ function makeFinancialOpsMethods(deps) {
|
|
|
6159
6348
|
},
|
|
6160
6349
|
payments: {
|
|
6161
6350
|
pay,
|
|
6351
|
+
retry: (paymentId, options) => retryPayment(paymentId, options?.signal),
|
|
6162
6352
|
createCommitment: (input, options) => pay(input, options),
|
|
6163
6353
|
claim: (paymentId, options) => runLifecycle({
|
|
6164
6354
|
kind: "claim",
|
|
@@ -6201,7 +6391,7 @@ function makeFinancialOpsMethods(deps) {
|
|
|
6201
6391
|
...reference.kind === "payment" ? activityActorField(reference.actor) : {}
|
|
6202
6392
|
},
|
|
6203
6393
|
...actor === void 0 ? {} : { actor }
|
|
6204
|
-
}));
|
|
6394
|
+
}).pipe(Effect.map(normalizeActivityDetail)));
|
|
6205
6395
|
},
|
|
6206
6396
|
annotate: (input, options) => {
|
|
6207
6397
|
if (input.actor !== void 0 && input.reference.kind === "payment" && input.reference.actor !== void 0 && !sameActor(input.actor, input.reference.actor)) return Promise.resolve({
|
|
@@ -6288,18 +6478,11 @@ function refFromTargetReference(reference, field) {
|
|
|
6288
6478
|
email: reference.email
|
|
6289
6479
|
}
|
|
6290
6480
|
};
|
|
6291
|
-
case "
|
|
6292
|
-
ok: true,
|
|
6293
|
-
value: {
|
|
6294
|
-
kind: "orgHandle",
|
|
6295
|
-
orgHandle: reference.handle
|
|
6296
|
-
}
|
|
6297
|
-
};
|
|
6298
|
-
case "payee": return {
|
|
6481
|
+
case "address": return {
|
|
6299
6482
|
ok: true,
|
|
6300
6483
|
value: {
|
|
6301
|
-
kind: "
|
|
6302
|
-
|
|
6484
|
+
kind: "address",
|
|
6485
|
+
address: reference.address
|
|
6303
6486
|
}
|
|
6304
6487
|
};
|
|
6305
6488
|
case "party": return {
|
|
@@ -6309,10 +6492,6 @@ function refFromTargetReference(reference, field) {
|
|
|
6309
6492
|
partyId: reference.partyId
|
|
6310
6493
|
}
|
|
6311
6494
|
};
|
|
6312
|
-
case "destination": return {
|
|
6313
|
-
ok: false,
|
|
6314
|
-
error: Errors.notImplemented("targets", "reference.destination")
|
|
6315
|
-
};
|
|
6316
6495
|
default: return {
|
|
6317
6496
|
ok: false,
|
|
6318
6497
|
error: Errors.invalidInput(field, "target must be a known TargetReference variant")
|
|
@@ -6367,39 +6546,28 @@ function targetReferenceFromBackendRef(ref) {
|
|
|
6367
6546
|
kind: "email",
|
|
6368
6547
|
email: ref.email
|
|
6369
6548
|
};
|
|
6370
|
-
case "
|
|
6371
|
-
kind: "
|
|
6372
|
-
|
|
6373
|
-
};
|
|
6374
|
-
case "payeeId": return {
|
|
6375
|
-
kind: "payee",
|
|
6376
|
-
id: ref.payeeId
|
|
6549
|
+
case "address": return {
|
|
6550
|
+
kind: "address",
|
|
6551
|
+
address: ref.address
|
|
6377
6552
|
};
|
|
6378
6553
|
case "party": return {
|
|
6379
6554
|
kind: "party",
|
|
6380
6555
|
partyId: ref.partyId
|
|
6381
6556
|
};
|
|
6382
|
-
case "capxulUserId": throw Errors.notImplemented("targets", "reference.capxulUserId");
|
|
6383
6557
|
}
|
|
6384
6558
|
}
|
|
6385
|
-
function resolvedTargetFromResolution(
|
|
6386
|
-
const kind = resolution.
|
|
6559
|
+
function resolvedTargetFromResolution(resolution) {
|
|
6560
|
+
const kind = resolution.status === "known_party" ? resolution.partyKind === "org" ? "organization" : "person" : resolution.status === "external_address" ? "external_address" : "unresolved";
|
|
6387
6561
|
return {
|
|
6388
|
-
reference,
|
|
6562
|
+
reference: targetReferenceFromBackendRef(resolution.recipient),
|
|
6389
6563
|
label: resolution.label,
|
|
6564
|
+
status: resolution.status,
|
|
6390
6565
|
kind,
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
}
|
|
6396
|
-
};
|
|
6397
|
-
}
|
|
6398
|
-
function resolvedTargetFromPayee(reference, payee) {
|
|
6399
|
-
return {
|
|
6400
|
-
reference,
|
|
6401
|
-
label: payee.label,
|
|
6402
|
-
kind: "payee",
|
|
6566
|
+
safeAddress: toAddress(resolution.safeAddress),
|
|
6567
|
+
isCapxulAccount: resolution.isCapxulAccount,
|
|
6568
|
+
...resolution.partyId === void 0 ? {} : { partyId: toPartyId(resolution.partyId) },
|
|
6569
|
+
...resolution.handle === void 0 ? {} : { handle: resolution.handle },
|
|
6570
|
+
...resolution.requiresAcknowledgement === void 0 ? {} : { requiresAcknowledgement: resolution.requiresAcknowledgement },
|
|
6403
6571
|
capabilities: {
|
|
6404
6572
|
canPay: true,
|
|
6405
6573
|
canRequest: true,
|
|
@@ -6457,10 +6625,6 @@ function destinationFromBackend(destination) {
|
|
|
6457
6625
|
};
|
|
6458
6626
|
}
|
|
6459
6627
|
function normalizeDestinationRefForBackend(ref, field) {
|
|
6460
|
-
if (typeof ref === "object" && ref !== null && "kind" in ref && ref.kind === "capxulUserId") return {
|
|
6461
|
-
ok: false,
|
|
6462
|
-
error: Errors.notImplemented("targets", "reference.capxulUserId")
|
|
6463
|
-
};
|
|
6464
6628
|
return normalizeRefForBackend(ref, field);
|
|
6465
6629
|
}
|
|
6466
6630
|
function normalizeRefForBackend(ref, field) {
|
|
@@ -6488,25 +6652,11 @@ function normalizeRefForBackend(ref, field) {
|
|
|
6488
6652
|
email: nonEmptyRefValue(ref.email, "email")
|
|
6489
6653
|
}
|
|
6490
6654
|
};
|
|
6491
|
-
case "
|
|
6492
|
-
ok: true,
|
|
6493
|
-
value: {
|
|
6494
|
-
kind: "orgHandle",
|
|
6495
|
-
orgHandle: nonEmptyRefValue(ref.orgHandle, "orgHandle")
|
|
6496
|
-
}
|
|
6497
|
-
};
|
|
6498
|
-
case "capxulUserId": return {
|
|
6655
|
+
case "address": return {
|
|
6499
6656
|
ok: true,
|
|
6500
6657
|
value: {
|
|
6501
|
-
kind: "
|
|
6502
|
-
|
|
6503
|
-
}
|
|
6504
|
-
};
|
|
6505
|
-
case "payeeId": return {
|
|
6506
|
-
ok: true,
|
|
6507
|
-
value: {
|
|
6508
|
-
kind: "payeeId",
|
|
6509
|
-
payeeId: nonEmptyRefValue(ref.payeeId, "payeeId")
|
|
6658
|
+
kind: "address",
|
|
6659
|
+
address: toAddress(ref.address)
|
|
6510
6660
|
}
|
|
6511
6661
|
};
|
|
6512
6662
|
case "party": return {
|
|
@@ -7553,7 +7703,7 @@ function makeSmartAccountMethods(deps) {
|
|
|
7553
7703
|
}
|
|
7554
7704
|
//#endregion
|
|
7555
7705
|
//#region src/contract/identity.ts
|
|
7556
|
-
const
|
|
7706
|
+
const handleAvailableQuery = makeFunctionReference(CAPXUL_FUNCTIONS["identity/queries"].handleAvailable);
|
|
7557
7707
|
//#endregion
|
|
7558
7708
|
//#region src/surface/identity-deps.ts
|
|
7559
7709
|
/** The single Context tag the profile atom + `identity.loadCurrent` resolve. */
|
|
@@ -7597,19 +7747,19 @@ function makeIdentityMethods(deps) {
|
|
|
7597
7747
|
ok: false,
|
|
7598
7748
|
error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.identity.completeProfile })
|
|
7599
7749
|
};
|
|
7600
|
-
if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" || typeof profile.
|
|
7750
|
+
if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" || typeof profile.handle !== "string") return {
|
|
7601
7751
|
ok: false,
|
|
7602
7752
|
error: Errors.invalidInput("profile", "invalid profile")
|
|
7603
7753
|
};
|
|
7604
7754
|
const displayName = profile.displayName.trim();
|
|
7605
|
-
const
|
|
7755
|
+
const handle = profile.handle.trim();
|
|
7606
7756
|
if (displayName.length === 0) return {
|
|
7607
7757
|
ok: false,
|
|
7608
7758
|
error: Errors.invalidInput("displayName", "must not be empty")
|
|
7609
7759
|
};
|
|
7610
|
-
if (
|
|
7760
|
+
if (handle.length === 0) return {
|
|
7611
7761
|
ok: false,
|
|
7612
|
-
error: Errors.invalidInput("
|
|
7762
|
+
error: Errors.invalidInput("handle", "must not be empty")
|
|
7613
7763
|
};
|
|
7614
7764
|
let country;
|
|
7615
7765
|
try {
|
|
@@ -7630,98 +7780,259 @@ function makeIdentityMethods(deps) {
|
|
|
7630
7780
|
email: session.email,
|
|
7631
7781
|
displayName,
|
|
7632
7782
|
country,
|
|
7633
|
-
|
|
7783
|
+
handle
|
|
7634
7784
|
}), options, CAPXUL_OPERATIONS.identity.completeProfile);
|
|
7635
7785
|
},
|
|
7636
|
-
async
|
|
7786
|
+
async handleAvailable(handle, options) {
|
|
7637
7787
|
if (options?.signal?.aborted) return {
|
|
7638
7788
|
ok: false,
|
|
7639
|
-
error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.identity.
|
|
7789
|
+
error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.identity.handleAvailable })
|
|
7640
7790
|
};
|
|
7641
7791
|
if (convexCall === void 0) return {
|
|
7642
7792
|
ok: false,
|
|
7643
|
-
error: Errors.notImplemented("identity", "
|
|
7793
|
+
error: Errors.notImplemented("identity", "handleAvailable")
|
|
7644
7794
|
};
|
|
7645
|
-
return runPortEffect(convexCall.query(
|
|
7795
|
+
return runPortEffect(convexCall.query(handleAvailableQuery, { handle }));
|
|
7646
7796
|
}
|
|
7647
7797
|
};
|
|
7648
7798
|
}
|
|
7649
7799
|
//#endregion
|
|
7650
7800
|
//#region src/surface/onboarding.ts
|
|
7651
|
-
|
|
7652
|
-
|
|
7653
|
-
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
|
|
7657
|
-
|
|
7801
|
+
function normalizeHandleInput(input) {
|
|
7802
|
+
if (typeof input !== "string") return {
|
|
7803
|
+
ok: false,
|
|
7804
|
+
error: Errors.invalidInput("handle", "is required")
|
|
7805
|
+
};
|
|
7806
|
+
try {
|
|
7807
|
+
return {
|
|
7808
|
+
ok: true,
|
|
7809
|
+
value: validateHandle(input)
|
|
7658
7810
|
};
|
|
7659
|
-
|
|
7660
|
-
|
|
7661
|
-
if (!session.ok) return session;
|
|
7662
|
-
if (session.value === null) return {
|
|
7811
|
+
} catch (error) {
|
|
7812
|
+
if (isCapxulError(error)) return {
|
|
7663
7813
|
ok: false,
|
|
7664
|
-
error
|
|
7814
|
+
error
|
|
7665
7815
|
};
|
|
7666
|
-
|
|
7667
|
-
if (!available.ok) return available;
|
|
7668
|
-
if (!available.value.available) return {
|
|
7816
|
+
return {
|
|
7669
7817
|
ok: false,
|
|
7670
|
-
error: Errors.
|
|
7818
|
+
error: Errors.unknown(error)
|
|
7671
7819
|
};
|
|
7672
|
-
|
|
7673
|
-
|
|
7674
|
-
|
|
7675
|
-
|
|
7676
|
-
|
|
7677
|
-
|
|
7678
|
-
|
|
7679
|
-
|
|
7820
|
+
}
|
|
7821
|
+
}
|
|
7822
|
+
function normalizeOrganization(input) {
|
|
7823
|
+
if (typeof input !== "object" || input === null) return {
|
|
7824
|
+
ok: false,
|
|
7825
|
+
error: Errors.invalidInput("organization", "is required")
|
|
7826
|
+
};
|
|
7827
|
+
const name = typeof input.name === "string" ? input.name.trim() : "";
|
|
7828
|
+
if (name.length === 0) return {
|
|
7829
|
+
ok: false,
|
|
7830
|
+
error: Errors.invalidInput("name", "is required")
|
|
7831
|
+
};
|
|
7832
|
+
const handle = normalizeHandleInput(input.handle);
|
|
7833
|
+
if (!handle.ok) return handle;
|
|
7834
|
+
if (input.bio !== void 0 && typeof input.bio !== "string") return {
|
|
7835
|
+
ok: false,
|
|
7836
|
+
error: Errors.invalidInput("bio", "must be text")
|
|
7837
|
+
};
|
|
7838
|
+
if (input.size !== void 0 && typeof input.size !== "string") return {
|
|
7839
|
+
ok: false,
|
|
7840
|
+
error: Errors.invalidInput("size", "must be text")
|
|
7841
|
+
};
|
|
7842
|
+
let country;
|
|
7843
|
+
try {
|
|
7844
|
+
country = toCountryCode(input.country);
|
|
7845
|
+
} catch {
|
|
7846
|
+
return {
|
|
7680
7847
|
ok: false,
|
|
7681
|
-
error: Errors.
|
|
7848
|
+
error: Errors.invalidInput("country", "must be an ISO country code")
|
|
7682
7849
|
};
|
|
7683
|
-
|
|
7850
|
+
}
|
|
7851
|
+
const bio = input.bio?.trim() ?? "";
|
|
7852
|
+
const size = input.size?.trim() ?? "";
|
|
7853
|
+
return {
|
|
7854
|
+
ok: true,
|
|
7855
|
+
value: {
|
|
7856
|
+
name,
|
|
7857
|
+
handle: handle.value,
|
|
7858
|
+
country,
|
|
7859
|
+
...bio.length === 0 ? {} : { bio },
|
|
7860
|
+
...size.length === 0 ? {} : { size }
|
|
7861
|
+
}
|
|
7862
|
+
};
|
|
7863
|
+
}
|
|
7864
|
+
function isClaimedIdentityState(state) {
|
|
7865
|
+
return state.phase === "authenticated" && state.account.at === "claimed";
|
|
7866
|
+
}
|
|
7867
|
+
function organizationWrongState(currentState, validStates) {
|
|
7868
|
+
return {
|
|
7869
|
+
ok: false,
|
|
7870
|
+
error: Errors.wrongState({
|
|
7871
|
+
method: CAPXUL_OPERATIONS.onboarding.completeOrganization,
|
|
7872
|
+
currentState,
|
|
7873
|
+
validStates: [...validStates]
|
|
7874
|
+
})
|
|
7875
|
+
};
|
|
7876
|
+
}
|
|
7877
|
+
function requestCancelled(options) {
|
|
7878
|
+
return options?.signal?.aborted === true;
|
|
7879
|
+
}
|
|
7880
|
+
async function reachClaimedAccount(deps, options) {
|
|
7881
|
+
let state = deps.snapshotIdentity();
|
|
7882
|
+
if (state.phase !== "authenticated" || state.account.at === "unknown") {
|
|
7883
|
+
const ensured = await deps.sendIdentity({ _tag: "EnsureAccount" }, options);
|
|
7684
7884
|
if (!ensured.ok) return ensured;
|
|
7685
|
-
|
|
7686
|
-
|
|
7687
|
-
|
|
7688
|
-
|
|
7689
|
-
const
|
|
7690
|
-
|
|
7691
|
-
if (
|
|
7692
|
-
|
|
7693
|
-
|
|
7694
|
-
|
|
7695
|
-
|
|
7696
|
-
|
|
7697
|
-
|
|
7698
|
-
|
|
7699
|
-
|
|
7700
|
-
|
|
7701
|
-
|
|
7702
|
-
|
|
7703
|
-
|
|
7704
|
-
|
|
7705
|
-
|
|
7706
|
-
|
|
7707
|
-
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
|
|
7715
|
-
|
|
7716
|
-
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
}
|
|
7724
|
-
}
|
|
7885
|
+
state = ensured.value;
|
|
7886
|
+
}
|
|
7887
|
+
if (state.phase !== "authenticated") return organizationWrongState(state.phase, ["authenticated:claimed"]);
|
|
7888
|
+
if (state.account.at !== "claimed") {
|
|
7889
|
+
const event = state.account.at === "failed" ? { _tag: "RetryAccount" } : state.account.at === "counterfactual" ? { _tag: "ClaimAccount" } : { _tag: "EnsureAccount" };
|
|
7890
|
+
const claimed = await deps.sendIdentity(event, options);
|
|
7891
|
+
if (!claimed.ok) return claimed;
|
|
7892
|
+
state = claimed.value;
|
|
7893
|
+
}
|
|
7894
|
+
return isClaimedIdentityState(state) ? {
|
|
7895
|
+
ok: true,
|
|
7896
|
+
value: state
|
|
7897
|
+
} : organizationWrongState(state.phase === "authenticated" ? state.account.at : state.phase, ["claimed"]);
|
|
7898
|
+
}
|
|
7899
|
+
async function createOrResumeOrganization(deps, state, draft, options) {
|
|
7900
|
+
const active = state.account.org;
|
|
7901
|
+
if (active?.at === "ready") return {
|
|
7902
|
+
ok: true,
|
|
7903
|
+
value: { organizationId: active.orgId }
|
|
7904
|
+
};
|
|
7905
|
+
if (active?.at === "failed" && !active.retryable) return {
|
|
7906
|
+
ok: false,
|
|
7907
|
+
error: publicIdentityFailure(active.failure)
|
|
7908
|
+
};
|
|
7909
|
+
if (active?.at === "failed" && active.orgId === null) {
|
|
7910
|
+
const cleared = await deps.sendIdentity({ _tag: "LeaveOrganization" }, options);
|
|
7911
|
+
if (!cleared.ok) return cleared;
|
|
7912
|
+
}
|
|
7913
|
+
const event = active?.at === "failed" && active.orgId !== null ? { _tag: "RetryOrganization" } : {
|
|
7914
|
+
_tag: "CreateOrganization",
|
|
7915
|
+
draft
|
|
7916
|
+
};
|
|
7917
|
+
const created = await deps.sendIdentity(event, options);
|
|
7918
|
+
if (!created.ok) return created;
|
|
7919
|
+
const final = created.value;
|
|
7920
|
+
const organization = isClaimedIdentityState(final) ? final.account.org : null;
|
|
7921
|
+
return organization?.at === "ready" ? {
|
|
7922
|
+
ok: true,
|
|
7923
|
+
value: { organizationId: organization.orgId }
|
|
7924
|
+
} : organizationWrongState(organization?.at ?? "organization-missing", ["ready"]);
|
|
7925
|
+
}
|
|
7926
|
+
function makeOnboardingMethods(deps) {
|
|
7927
|
+
return {
|
|
7928
|
+
async completePerson(input, options) {
|
|
7929
|
+
const isCancelled = () => options?.signal?.aborted === true;
|
|
7930
|
+
if (typeof input !== "object" || input === null || typeof input.displayName !== "string" || typeof input.country !== "string") return {
|
|
7931
|
+
ok: false,
|
|
7932
|
+
error: Errors.invalidInput("profile", "displayName and country are required")
|
|
7933
|
+
};
|
|
7934
|
+
const handle = normalizeHandleInput(input.handle);
|
|
7935
|
+
if (!handle.ok) return handle;
|
|
7936
|
+
const session = await deps.restoreSession(options);
|
|
7937
|
+
if (!session.ok) return session;
|
|
7938
|
+
if (session.value === null) return {
|
|
7939
|
+
ok: false,
|
|
7940
|
+
error: Errors.notAuthenticated()
|
|
7941
|
+
};
|
|
7942
|
+
const available = await deps.handleAvailable(handle.value, options);
|
|
7943
|
+
if (!available.ok) return available;
|
|
7944
|
+
if (!available.value.available) return {
|
|
7945
|
+
ok: false,
|
|
7946
|
+
error: Errors.invalidInput("handle", "handle is already taken")
|
|
7947
|
+
};
|
|
7948
|
+
const completed = await deps.completeProfile({
|
|
7949
|
+
...input,
|
|
7950
|
+
handle: available.value.normalized
|
|
7951
|
+
}, options);
|
|
7952
|
+
if (!completed.ok) return completed;
|
|
7953
|
+
const refreshed = await deps.refreshIdentity(options);
|
|
7954
|
+
if (!refreshed.ok) return refreshed;
|
|
7955
|
+
if (isCancelled()) return {
|
|
7956
|
+
ok: false,
|
|
7957
|
+
error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
|
|
7958
|
+
};
|
|
7959
|
+
const ensured = await deps.ensureAccount();
|
|
7960
|
+
if (!ensured.ok) return ensured;
|
|
7961
|
+
if (isCancelled()) return {
|
|
7962
|
+
ok: false,
|
|
7963
|
+
error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
|
|
7964
|
+
};
|
|
7965
|
+
const lifecycle = await deps.getLifecycle();
|
|
7966
|
+
if (!lifecycle.ok) return lifecycle;
|
|
7967
|
+
if (isCancelled()) return {
|
|
7968
|
+
ok: false,
|
|
7969
|
+
error: Errors.cancelled({ operation: CAPXUL_OPERATIONS.onboarding.completePerson })
|
|
7970
|
+
};
|
|
7971
|
+
if (lifecycle.value.status !== "ready") return {
|
|
7972
|
+
ok: false,
|
|
7973
|
+
error: Errors.wrongState({
|
|
7974
|
+
method: CAPXUL_OPERATIONS.onboarding.completePerson,
|
|
7975
|
+
currentState: lifecycle.value.status,
|
|
7976
|
+
validStates: ["ready"]
|
|
7977
|
+
})
|
|
7978
|
+
};
|
|
7979
|
+
const profile = await deps.loadProfile(options);
|
|
7980
|
+
if (!profile.ok) return profile;
|
|
7981
|
+
if (profile.value === null || profile.value.displayName === null || profile.value.handle !== available.value.normalized) return {
|
|
7982
|
+
ok: false,
|
|
7983
|
+
error: Errors.wrongState({
|
|
7984
|
+
method: CAPXUL_OPERATIONS.onboarding.completePerson,
|
|
7985
|
+
currentState: "profile-incomplete",
|
|
7986
|
+
validStates: ["profile-complete"]
|
|
7987
|
+
})
|
|
7988
|
+
};
|
|
7989
|
+
return {
|
|
7990
|
+
ok: true,
|
|
7991
|
+
value: {
|
|
7992
|
+
profile: {
|
|
7993
|
+
...profile.value,
|
|
7994
|
+
displayName: profile.value.displayName,
|
|
7995
|
+
handle: profile.value.handle
|
|
7996
|
+
},
|
|
7997
|
+
account: lifecycle.value
|
|
7998
|
+
}
|
|
7999
|
+
};
|
|
8000
|
+
},
|
|
8001
|
+
async completeOrganization(input, options) {
|
|
8002
|
+
const operation = CAPXUL_OPERATIONS.onboarding.completeOrganization;
|
|
8003
|
+
const normalized = normalizeOrganization(input);
|
|
8004
|
+
if (!normalized.ok) return normalized;
|
|
8005
|
+
const session = await deps.restoreSession(options);
|
|
8006
|
+
if (!session.ok) return session;
|
|
8007
|
+
if (session.value === null) return {
|
|
8008
|
+
ok: false,
|
|
8009
|
+
error: Errors.notAuthenticated()
|
|
8010
|
+
};
|
|
8011
|
+
const profile = await deps.loadProfile(options);
|
|
8012
|
+
if (!profile.ok) return profile;
|
|
8013
|
+
if (profile.value === null || profile.value.displayName === null || profile.value.handle === null) return {
|
|
8014
|
+
ok: false,
|
|
8015
|
+
error: Errors.wrongState({
|
|
8016
|
+
method: operation,
|
|
8017
|
+
currentState: "profile-incomplete",
|
|
8018
|
+
validStates: ["profile-complete"]
|
|
8019
|
+
})
|
|
8020
|
+
};
|
|
8021
|
+
const refreshed = await deps.refreshIdentity(options);
|
|
8022
|
+
if (!refreshed.ok) return refreshed;
|
|
8023
|
+
if (requestCancelled(options)) return {
|
|
8024
|
+
ok: false,
|
|
8025
|
+
error: Errors.cancelled({ operation })
|
|
8026
|
+
};
|
|
8027
|
+
const claimed = await reachClaimedAccount(deps, options);
|
|
8028
|
+
if (!claimed.ok) return claimed;
|
|
8029
|
+
if (requestCancelled(options)) return {
|
|
8030
|
+
ok: false,
|
|
8031
|
+
error: Errors.cancelled({ operation })
|
|
8032
|
+
};
|
|
8033
|
+
return createOrResumeOrganization(deps, claimed.value, normalized.value, options);
|
|
8034
|
+
}
|
|
8035
|
+
};
|
|
7725
8036
|
}
|
|
7726
8037
|
//#endregion
|
|
7727
8038
|
//#region src/surface/accounts-deps.ts
|
|
@@ -8024,7 +8335,8 @@ function executionDependencies$1(input) {
|
|
|
8024
8335
|
chainId: input.chainId,
|
|
8025
8336
|
convexCall: input.convexCall,
|
|
8026
8337
|
functions: moneyExecutionContract,
|
|
8027
|
-
signer: input.signer
|
|
8338
|
+
signer: input.signer,
|
|
8339
|
+
...input.telemetry === void 0 ? {} : { telemetry: input.telemetry }
|
|
8028
8340
|
};
|
|
8029
8341
|
}
|
|
8030
8342
|
function makeOrganizationPaymentsMethods(deps, orgId) {
|
|
@@ -8056,16 +8368,18 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
|
|
|
8056
8368
|
let flight = inFlightOrganizationPayments.get(flightKey);
|
|
8057
8369
|
if (flight === void 0) {
|
|
8058
8370
|
const controller = new AbortController();
|
|
8371
|
+
const requestState = { resolved: false };
|
|
8059
8372
|
const submission = executeOrganizationPayment(execution, {
|
|
8060
8373
|
orgId,
|
|
8061
8374
|
permissionId: input.permissionId,
|
|
8062
8375
|
requestKey: requestKey.key,
|
|
8063
8376
|
items: input.items,
|
|
8064
8377
|
...input.lineage === void 0 ? {} : { lineage: input.lineage }
|
|
8065
|
-
}, controller.signal);
|
|
8378
|
+
}, controller.signal, () => requestState.resolved = true);
|
|
8066
8379
|
flight = {
|
|
8067
8380
|
controller,
|
|
8068
8381
|
promise: submission,
|
|
8382
|
+
requestState,
|
|
8069
8383
|
waiters: 0,
|
|
8070
8384
|
settled: false
|
|
8071
8385
|
};
|
|
@@ -8103,11 +8417,29 @@ function makeOrganizationPaymentsMethods(deps, orgId) {
|
|
|
8103
8417
|
}
|
|
8104
8418
|
release(false);
|
|
8105
8419
|
try {
|
|
8106
|
-
await requestKey.finish(result.ok);
|
|
8420
|
+
await requestKey.finish(result.ok || flight.requestState.resolved);
|
|
8107
8421
|
} catch {}
|
|
8108
|
-
|
|
8422
|
+
const normalized = mapOk(result, (value) => value.payments.map((payment) => normalizePaymentTiming(payment)));
|
|
8423
|
+
if (!normalized.ok) return normalized;
|
|
8424
|
+
return normalized;
|
|
8109
8425
|
};
|
|
8110
8426
|
return {
|
|
8427
|
+
retry: async (paymentId, options) => {
|
|
8428
|
+
const execution = executionDependencies$1(deps);
|
|
8429
|
+
if (execution === null) return {
|
|
8430
|
+
ok: false,
|
|
8431
|
+
error: Errors.notImplemented("organizationPayments", "executionComposition")
|
|
8432
|
+
};
|
|
8433
|
+
const result = await executePaymentLifecycle(execution, {
|
|
8434
|
+
kind: "retry",
|
|
8435
|
+
paymentId
|
|
8436
|
+
}, options?.signal);
|
|
8437
|
+
if (!result.ok) return result;
|
|
8438
|
+
return {
|
|
8439
|
+
ok: true,
|
|
8440
|
+
value: result.value.payments.map((payment) => normalizePaymentTiming(payment))
|
|
8441
|
+
};
|
|
8442
|
+
},
|
|
8111
8443
|
pay: async (input, options) => {
|
|
8112
8444
|
const { permissionId, requestKey: providedRequestKey, lineage, ...item } = input;
|
|
8113
8445
|
const result = await execute({
|
|
@@ -8239,6 +8571,7 @@ function makePayrollMethods(deps, orgId) {
|
|
|
8239
8571
|
input
|
|
8240
8572
|
}, input.requestKey);
|
|
8241
8573
|
let authorized;
|
|
8574
|
+
let preparedClosed = false;
|
|
8242
8575
|
const submitted = await executePrepared(execution, async (signerAddress) => {
|
|
8243
8576
|
const prepared = await runIfActive(signal, AUTHORIZE_RUN, () => deps.convexCall.action(payrollContract.authorizeRun, { input: {
|
|
8244
8577
|
orgId,
|
|
@@ -8260,9 +8593,9 @@ function makePayrollMethods(deps, orgId) {
|
|
|
8260
8593
|
requestKey: requestKey.key,
|
|
8261
8594
|
runId: authorized.id,
|
|
8262
8595
|
items: input.items
|
|
8263
|
-
})(request), signal);
|
|
8596
|
+
})(request), true, () => preparedClosed = true, signal);
|
|
8264
8597
|
try {
|
|
8265
|
-
await requestKey.finish(submitted.ok);
|
|
8598
|
+
await requestKey.finish(submitted.ok || preparedClosed);
|
|
8266
8599
|
} catch {}
|
|
8267
8600
|
if (!submitted.ok) return submitted;
|
|
8268
8601
|
return authorized === void 0 ? {
|
|
@@ -8883,7 +9216,8 @@ function makeOrgMethods(deps) {
|
|
|
8883
9216
|
...deps.requestKeyScope === void 0 ? {} : { requestKeyScope: deps.requestKeyScope },
|
|
8884
9217
|
...deps.actor === void 0 ? {} : { actor: deps.actor },
|
|
8885
9218
|
...deps.chainId === void 0 ? {} : { chainId: Number(deps.chainId) },
|
|
8886
|
-
...deps.signer === void 0 ? {} : { signer: deps.signer }
|
|
9219
|
+
...deps.signer === void 0 ? {} : { signer: deps.signer },
|
|
9220
|
+
...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
|
|
8887
9221
|
}, String(orgId)),
|
|
8888
9222
|
payroll: convexCall === void 0 ? makeUnavailablePayrollMethods() : makePayrollMethods({
|
|
8889
9223
|
convexCall,
|
|
@@ -8910,7 +9244,8 @@ function makeNotImplementedPermissionMethods() {
|
|
|
8910
9244
|
function makeNotImplementedOrganizationPaymentsMethods() {
|
|
8911
9245
|
return {
|
|
8912
9246
|
pay: organizationPaymentExecutionUnavailable,
|
|
8913
|
-
payBatch: organizationPaymentExecutionUnavailable
|
|
9247
|
+
payBatch: organizationPaymentExecutionUnavailable,
|
|
9248
|
+
retry: organizationPaymentExecutionUnavailable
|
|
8914
9249
|
};
|
|
8915
9250
|
}
|
|
8916
9251
|
const orgMeUnavailable = () => Promise.resolve({
|
|
@@ -9245,11 +9580,13 @@ function assembleCapxulClient(input) {
|
|
|
9245
9580
|
const onboarding = makeOnboardingMethods({
|
|
9246
9581
|
restoreSession: auth.getSession,
|
|
9247
9582
|
refreshIdentity: (options) => runCapxulEffect(askIdentity(actor, { _tag: "ReadSession" }, options).pipe(Effect.asVoid), options, CAPXUL_OPERATIONS.identity.readSession, effectRunner.runPromise),
|
|
9248
|
-
|
|
9583
|
+
handleAvailable: identity.handleAvailable,
|
|
9249
9584
|
completeProfile: identity.completeProfile,
|
|
9250
9585
|
loadProfile: identity.loadCurrent,
|
|
9251
9586
|
ensureAccount: account._internal.ensureReady,
|
|
9252
|
-
getLifecycle: account.getLifecycle
|
|
9587
|
+
getLifecycle: account.getLifecycle,
|
|
9588
|
+
snapshotIdentity: actor.snapshot,
|
|
9589
|
+
sendIdentity: (event, options) => runCapxulEffect(askIdentity(actor, event, options), options, CAPXUL_OPERATIONS._internal.identity.send, effectRunner.runPromise)
|
|
9253
9590
|
});
|
|
9254
9591
|
const system = makeSystemMethods({ convexCall: input.ports.convexCall });
|
|
9255
9592
|
const media = makeMediaMethods({ convexCall: input.ports.convexCall });
|
|
@@ -9308,7 +9645,7 @@ function assembleCapxulClient(input) {
|
|
|
9308
9645
|
}
|
|
9309
9646
|
},
|
|
9310
9647
|
async completeProfile(profile, controls) {
|
|
9311
|
-
if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" ||
|
|
9648
|
+
if (typeof profile !== "object" || profile === null || typeof profile.displayName !== "string" || typeof profile.country !== "string" || typeof profile.handle !== "string") return {
|
|
9312
9649
|
ok: false,
|
|
9313
9650
|
reason: "INVALID_INPUT"
|
|
9314
9651
|
};
|
|
@@ -9326,8 +9663,8 @@ function assembleCapxulClient(input) {
|
|
|
9326
9663
|
reason: "INVALID_INPUT"
|
|
9327
9664
|
};
|
|
9328
9665
|
}
|
|
9329
|
-
const
|
|
9330
|
-
if (
|
|
9666
|
+
const handle = profile.handle.trim();
|
|
9667
|
+
if (handle.length === 0) return {
|
|
9331
9668
|
ok: false,
|
|
9332
9669
|
reason: "INVALID_INPUT"
|
|
9333
9670
|
};
|
|
@@ -9341,7 +9678,7 @@ function assembleCapxulClient(input) {
|
|
|
9341
9678
|
email: session.email,
|
|
9342
9679
|
displayName,
|
|
9343
9680
|
country,
|
|
9344
|
-
|
|
9681
|
+
handle
|
|
9345
9682
|
}), controls, CAPXUL_OPERATIONS.identity.completeProfile, effectRunner.runPromise);
|
|
9346
9683
|
return result.ok ? { ok: true } : {
|
|
9347
9684
|
ok: false,
|
|
@@ -9360,8 +9697,6 @@ function assembleCapxulClient(input) {
|
|
|
9360
9697
|
accounts,
|
|
9361
9698
|
currentUser,
|
|
9362
9699
|
me: financialOps.me,
|
|
9363
|
-
handles: financialOps.handles,
|
|
9364
|
-
payees: financialOps.payees,
|
|
9365
9700
|
targets: financialOps.targets,
|
|
9366
9701
|
destinations: financialOps.destinations,
|
|
9367
9702
|
payments: financialOps.payments,
|
|
@@ -9380,6 +9715,20 @@ function assembleCapxulClient(input) {
|
|
|
9380
9715
|
accounts: { fund: accounts.fund },
|
|
9381
9716
|
organizationSetup: { getProofReceipt: (orgId) => runPortEffect(input.ports.convexCall.query(organizationSetupProofReceiptQuery, { orgId })) },
|
|
9382
9717
|
telemetry: input.ports.telemetry,
|
|
9718
|
+
captureExternalAddressAcknowledged: (address, organizationId) => {
|
|
9719
|
+
const telemetry = input.ports.telemetry;
|
|
9720
|
+
if (telemetry === void 0) return;
|
|
9721
|
+
Effect.runPromise(Effect.suspend(() => telemetry.emit({
|
|
9722
|
+
name: "quick_pay_external_address_acknowledged",
|
|
9723
|
+
props: {
|
|
9724
|
+
recipient_locator_kind: "address",
|
|
9725
|
+
recipient_resolution_status: "external_address",
|
|
9726
|
+
recipient_address: address,
|
|
9727
|
+
external_address_acknowledged: true,
|
|
9728
|
+
...organizationId === void 0 ? {} : { organization_id: organizationId }
|
|
9729
|
+
}
|
|
9730
|
+
})).pipe(Effect.catchCause(() => Effect.void)));
|
|
9731
|
+
},
|
|
9383
9732
|
close: stopActor
|
|
9384
9733
|
}
|
|
9385
9734
|
}, observation.failureObservation, observation.hostObservationSnapshot);
|