@capxul/sdk 2.8.2 → 3.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.
@@ -1,4 +1,5 @@
1
- import { Context, Data, Effect, Layer } from "effect";
1
+ import { concat, encodeAbiParameters, encodeFunctionData, encodePacked, getContractAddress, keccak256, padHex, stringToHex, toBytes, toEventSelector, toFunctionSelector, toFunctionSignature } from "viem";
2
+ import { Context, Data, Effect, Layer, Result } from "effect";
2
3
  //#region ../errors/src/chain-cause.ts
3
4
  /**
4
5
  * Why an operation failed — the one flat vocabulary. The first four are the
@@ -652,6 +653,978 @@ function invalidValueReason(prefix, raw) {
652
653
  return `${prefix}: ${String(raw)}`;
653
654
  }
654
655
  //#endregion
656
+ //#region ../config/src/tokens.ts
657
+ /** `TestUSDC` ("USDX") — Base Sepolia, 6 decimals, open `mint`. (Canon §1.) */
658
+ const USDX_ADDRESS_BASE_SEPOLIA = "0xf09fcbb6df9f8f918e58f9c8ab15a76ade862b77";
659
+ USDX_ADDRESS_BASE_SEPOLIA.toLowerCase();
660
+ //#endregion
661
+ //#region ../config/src/org-payments.ts
662
+ /** Zodiac MultiSendCallOnly module on Base Sepolia. */
663
+ const MULTI_SEND_CALL_ONLY = "0x9641d764fc13c8b624c04430c7356c1c7c8102e2";
664
+ //#endregion
665
+ //#region ../config/src/safe.ts
666
+ const BASE_SEPOLIA_CHAIN_ID = 84532;
667
+ const SAFE_PROXY_FACTORY = "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67";
668
+ const SAFE_L2_SINGLETON = "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762";
669
+ const SAFE_MODULE_SETUP = "0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47";
670
+ const SAFE_4337_MODULE = "0x75cf11467937ce3F2f357CE24ffc3DBF8fD5c226";
671
+ const MULTI_SEND = "0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526";
672
+ /**
673
+ * The Capxul bootstrap owner — the sole `setup()` owner of every unclaimed
674
+ * personal Safe under derivation v2. This address is part of the CREATE2
675
+ * preimage of EVERY personal Safe address: treat it exactly like
676
+ * `SAFE_PROXY_FACTORY` (changing it is a derivation-version event → v3).
677
+ * The private key lives backend-only (`CAPXUL_BOOTSTRAP_OWNER_PRIVATE_KEY`)
678
+ * and signs exactly one kind of operation: the claim userOp that deploys the
679
+ * Safe and swaps this owner out for the user's signer (PRD #462). The earlier
680
+ * ClaimGuard derivation-v3 placeholder (#461) is closed; future mainnet-scale
681
+ * hardening should be filed against the current payments/claim architecture.
682
+ */
683
+ const CAPXUL_BOOTSTRAP_OWNER = "0x425fca96f4a3e18fb80974e38096b5da460f2704";
684
+ const SAFE_PROXY_CREATION_CODE = "0x608060405234801561001057600080fd5b506040516101e63803806101e68339818101604052602081101561003357600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156100ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101c46022913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505060ab806101196000396000f3fe608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea264697066735822122003d1488ee65e08fa41e58e888a9865554c535f2c77126a82cb4c0f917f31441364736f6c63430007060033496e76616c69642073696e676c65746f6e20616464726573732070726f7669646564";
685
+ /**
686
+ * Normalize an email for use as a Capxul Safe salt input.
687
+ *
688
+ * Trims surrounding whitespace and lowercases the address so that
689
+ * `" User+Demo@Example.COM "` and `"user+demo@example.com"` derive
690
+ * the same `safeAddress`. This is the canonical normalization rule —
691
+ * any future change here would shift every existing user's Safe
692
+ * address, so the rule is pinned by the fixture matrix in
693
+ * `packages/config/tests/safe-address-conformance.test.ts`.
694
+ *
695
+ * @param email - The raw email address to normalize
696
+ * @returns The trimmed, lowercased email
697
+ */
698
+ function normalizeSafeSaltEmail(email) {
699
+ return email.trim().toLowerCase();
700
+ }
701
+ /**
702
+ * Compute the deterministic Safe salt nonce for a `(namespace, email)`
703
+ * pair. The salt nonce is the `bigint` reading of
704
+ * `keccak256(namespace + ":" + normalizeSafeSaltEmail(email))`.
705
+ *
706
+ * Namespace defaults to `CAPXUL_SAFE_SALT_NAMESPACE`
707
+ * (`"capxul:staging:email:v1"`) — the current Capxul scheme. Pass a
708
+ * different namespace only for pinned pre-v2 artifacts
709
+ * (`CAPXUL_SAFE_SALT_NAMESPACE_V1`, faucet Safe) or when bumping the scheme.
710
+ *
711
+ * @param input.email - The email to derive the salt nonce from
712
+ * @param input.namespace - Optional namespace override (defaults to `CAPXUL_SAFE_SALT_NAMESPACE`)
713
+ * @returns The Capxul-namespaced salt nonce as a `bigint`
714
+ */
715
+ function computeCapxulSafeSaltNonce(input) {
716
+ const namespace = input.namespace ?? "capxul:staging:email:v1";
717
+ const normalizedEmail = normalizeSafeSaltEmail(input.email);
718
+ return BigInt(keccak256(toBytes(`${namespace}:${normalizedEmail}`)));
719
+ }
720
+ const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
721
+ const safeSetupAbi = [{
722
+ type: "function",
723
+ name: "setup",
724
+ stateMutability: "nonpayable",
725
+ inputs: [
726
+ {
727
+ name: "_owners",
728
+ type: "address[]"
729
+ },
730
+ {
731
+ name: "_threshold",
732
+ type: "uint256"
733
+ },
734
+ {
735
+ name: "to",
736
+ type: "address"
737
+ },
738
+ {
739
+ name: "data",
740
+ type: "bytes"
741
+ },
742
+ {
743
+ name: "fallbackHandler",
744
+ type: "address"
745
+ },
746
+ {
747
+ name: "paymentToken",
748
+ type: "address"
749
+ },
750
+ {
751
+ name: "payment",
752
+ type: "uint256"
753
+ },
754
+ {
755
+ name: "paymentReceiver",
756
+ type: "address"
757
+ }
758
+ ],
759
+ outputs: []
760
+ }];
761
+ const enableModulesAbi = [{
762
+ type: "function",
763
+ name: "enableModules",
764
+ stateMutability: "nonpayable",
765
+ inputs: [{
766
+ name: "modules",
767
+ type: "address[]"
768
+ }],
769
+ outputs: []
770
+ }];
771
+ const multiSendAbi = [{
772
+ type: "function",
773
+ name: "multiSend",
774
+ stateMutability: "payable",
775
+ inputs: [{
776
+ name: "transactions",
777
+ type: "bytes"
778
+ }],
779
+ outputs: []
780
+ }];
781
+ function buildCapxulSafeInitializer(owner) {
782
+ const enableModulesCall = encodeFunctionData({
783
+ abi: enableModulesAbi,
784
+ functionName: "enableModules",
785
+ args: [[SAFE_4337_MODULE]]
786
+ });
787
+ const enableModulesByteLen = BigInt((enableModulesCall.length - 2) / 2);
788
+ const multiSendPayload = encodePacked([
789
+ "uint8",
790
+ "address",
791
+ "uint256",
792
+ "uint256",
793
+ "bytes"
794
+ ], [
795
+ 1,
796
+ SAFE_MODULE_SETUP,
797
+ 0n,
798
+ enableModulesByteLen,
799
+ enableModulesCall
800
+ ]);
801
+ const setupData = encodeFunctionData({
802
+ abi: multiSendAbi,
803
+ functionName: "multiSend",
804
+ args: [multiSendPayload]
805
+ });
806
+ return encodeFunctionData({
807
+ abi: safeSetupAbi,
808
+ functionName: "setup",
809
+ args: [
810
+ [owner],
811
+ 1n,
812
+ MULTI_SEND,
813
+ setupData,
814
+ SAFE_4337_MODULE,
815
+ ZERO_ADDRESS,
816
+ 0n,
817
+ ZERO_ADDRESS
818
+ ]
819
+ });
820
+ }
821
+ const ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;
822
+ function validateAndNormalizeAddress(field, value) {
823
+ const address = value.toLowerCase();
824
+ if (!ADDRESS_REGEX.test(address)) throw Errors.invalidInput(field, `must be 0x + 40 hex chars, got ${value}`);
825
+ return address;
826
+ }
827
+ /**
828
+ * Pure derivation of the Capxul personal Safe address — **v2: email only**
829
+ * (PRD #462). The Safe v1.4.1 (SafeL2) + 4337-module initializer's sole owner
830
+ * is the fixed `CAPXUL_BOOTSTRAP_OWNER`, so the address is a pure function of
831
+ * the (normalized) email and exists before any user signer does. The user's
832
+ * signer is installed at claim time via `swapOwner` — signer rotation can
833
+ * never move the address (org-domain rule D7, now system-wide).
834
+ *
835
+ * Returns the lowercased `0x` + 40 hex string (raw — no brand applied so this
836
+ * function is callable from both `@capxul/config` consumers that don't have
837
+ * `@capxul/types` available, and from packages that re-brand at their own
838
+ * boundary).
839
+ *
840
+ * Algorithm: exactly mirrors `permissionless.toSafeSmartAccount({ version:
841
+ * "1.4.1", safeSingletonAddress: SAFE_L2_SINGLETON, owners: [BOOTSTRAP] })`
842
+ * + the Capxul-canonical module setup (delegatecall into
843
+ * `SafeModuleSetup.enableModules([SAFE_4337_MODULE])` via the MultiSend lane
844
+ * during proxy setup). The proxy creation code is pinned at
845
+ * `SAFE_PROXY_CREATION_CODE`; the salt is Capxul-namespaced (v2) via
846
+ * `computeCapxulSafeSaltNonce({ email })`.
847
+ *
848
+ * Canonical: SDK deployment adapters and
849
+ * `packages/backend/convex/smartAccount/mutations.ts:provision` import this
850
+ * function; the conformance test at
851
+ * `packages/config/tests/safe-address-conformance.test.ts` pins the matrix.
852
+ */
853
+ function deriveCapxulSafeAddress(input) {
854
+ return deriveCapxulSafeAddressForOwner({
855
+ ownerAddress: CAPXUL_BOOTSTRAP_OWNER,
856
+ email: input.email
857
+ });
858
+ }
859
+ /**
860
+ * Owner-parametrized derivation core. Two callers only:
861
+ * 1. `deriveCapxulSafeAddress` (canonical v2: owner = bootstrap, namespace v2);
862
+ * 2. the backend faucet Safe (`testUsdcMint.ts`: owner = deployer EOA,
863
+ * namespace pinned to `CAPXUL_SAFE_SALT_NAMESPACE_V1` so its deployed
864
+ * address never moves).
865
+ * Do NOT introduce new owner-parametrized lanes — per-user owners in the
866
+ * derivation is exactly the v1 mistake v2 removes.
867
+ */
868
+ function deriveCapxulSafeAddressForOwner(input) {
869
+ const initializer = buildCapxulSafeInitializer(validateAndNormalizeAddress("ownerAddress", input.ownerAddress));
870
+ const saltNonce = computeCapxulSafeSaltNonce(input.namespace === void 0 ? { email: input.email } : {
871
+ email: input.email,
872
+ namespace: input.namespace
873
+ });
874
+ const salt = keccak256(encodePacked(["bytes32", "uint256"], [keccak256(initializer), saltNonce]));
875
+ const deploymentCode = concat([SAFE_PROXY_CREATION_CODE, encodeAbiParameters([{ type: "uint256" }], [BigInt(SAFE_L2_SINGLETON)])]);
876
+ return getContractAddress({
877
+ opcode: "CREATE2",
878
+ from: SAFE_PROXY_FACTORY,
879
+ salt,
880
+ bytecodeHash: keccak256(deploymentCode)
881
+ }).toLowerCase();
882
+ }
883
+ /**
884
+ * Normalize a raw email for binding id + Safe salt derivation.
885
+ * Delegates to {@link normalizeSafeSaltEmail} so binding resolution and
886
+ * `deriveCapxulSafeAddress` never drift apart.
887
+ */
888
+ function normalizeBindingEmail(email) {
889
+ return normalizeSafeSaltEmail(email);
890
+ }
891
+ //#endregion
892
+ //#region ../config/src/capxul-payments-v2.ts
893
+ /** The exact compiled CapxulPaymentsV2 ABI. */
894
+ const CAPXUL_PAYMENTS_V2_ABI = [
895
+ {
896
+ type: "function",
897
+ name: "cancel",
898
+ inputs: [{
899
+ name: "commitmentId",
900
+ type: "uint256",
901
+ internalType: "uint256"
902
+ }, {
903
+ name: "documentHash",
904
+ type: "bytes32",
905
+ internalType: "bytes32"
906
+ }],
907
+ outputs: [],
908
+ stateMutability: "nonpayable"
909
+ },
910
+ {
911
+ type: "function",
912
+ name: "claim",
913
+ inputs: [{
914
+ name: "commitmentId",
915
+ type: "uint256",
916
+ internalType: "uint256"
917
+ }],
918
+ outputs: [],
919
+ stateMutability: "nonpayable"
920
+ },
921
+ {
922
+ type: "function",
923
+ name: "claimableAmount",
924
+ inputs: [{
925
+ name: "commitmentId",
926
+ type: "uint256",
927
+ internalType: "uint256"
928
+ }],
929
+ outputs: [{
930
+ name: "",
931
+ type: "uint256",
932
+ internalType: "uint256"
933
+ }],
934
+ stateMutability: "view"
935
+ },
936
+ {
937
+ type: "function",
938
+ name: "commitments",
939
+ inputs: [{
940
+ name: "",
941
+ type: "uint256",
942
+ internalType: "uint256"
943
+ }],
944
+ outputs: [
945
+ {
946
+ name: "settlementId",
947
+ type: "bytes32",
948
+ internalType: "bytes32"
949
+ },
950
+ {
951
+ name: "creator",
952
+ type: "address",
953
+ internalType: "address"
954
+ },
955
+ {
956
+ name: "recipient",
957
+ type: "address",
958
+ internalType: "address"
959
+ },
960
+ {
961
+ name: "token",
962
+ type: "address",
963
+ internalType: "address"
964
+ },
965
+ {
966
+ name: "totalAmount",
967
+ type: "uint256",
968
+ internalType: "uint256"
969
+ },
970
+ {
971
+ name: "claimed",
972
+ type: "uint256",
973
+ internalType: "uint256"
974
+ },
975
+ {
976
+ name: "startTime",
977
+ type: "uint48",
978
+ internalType: "uint48"
979
+ },
980
+ {
981
+ name: "cliffTime",
982
+ type: "uint48",
983
+ internalType: "uint48"
984
+ },
985
+ {
986
+ name: "endTime",
987
+ type: "uint48",
988
+ internalType: "uint48"
989
+ },
990
+ {
991
+ name: "kind",
992
+ type: "uint16",
993
+ internalType: "uint16"
994
+ },
995
+ {
996
+ name: "documentHash",
997
+ type: "bytes32",
998
+ internalType: "bytes32"
999
+ },
1000
+ {
1001
+ name: "cancelled",
1002
+ type: "bool",
1003
+ internalType: "bool"
1004
+ }
1005
+ ],
1006
+ stateMutability: "view"
1007
+ },
1008
+ {
1009
+ type: "function",
1010
+ name: "createCommitment",
1011
+ inputs: [{
1012
+ name: "input",
1013
+ type: "tuple",
1014
+ internalType: "struct CapxulPaymentsV2.CommitmentInput",
1015
+ components: [
1016
+ {
1017
+ name: "settlementId",
1018
+ type: "bytes32",
1019
+ internalType: "bytes32"
1020
+ },
1021
+ {
1022
+ name: "recipient",
1023
+ type: "address",
1024
+ internalType: "address"
1025
+ },
1026
+ {
1027
+ name: "token",
1028
+ type: "address",
1029
+ internalType: "address"
1030
+ },
1031
+ {
1032
+ name: "totalAmount",
1033
+ type: "uint256",
1034
+ internalType: "uint256"
1035
+ },
1036
+ {
1037
+ name: "startTime",
1038
+ type: "uint48",
1039
+ internalType: "uint48"
1040
+ },
1041
+ {
1042
+ name: "cliffTime",
1043
+ type: "uint48",
1044
+ internalType: "uint48"
1045
+ },
1046
+ {
1047
+ name: "endTime",
1048
+ type: "uint48",
1049
+ internalType: "uint48"
1050
+ },
1051
+ {
1052
+ name: "kind",
1053
+ type: "uint16",
1054
+ internalType: "uint16"
1055
+ },
1056
+ {
1057
+ name: "documentHash",
1058
+ type: "bytes32",
1059
+ internalType: "bytes32"
1060
+ }
1061
+ ]
1062
+ }],
1063
+ outputs: [{
1064
+ name: "commitmentId",
1065
+ type: "uint256",
1066
+ internalType: "uint256"
1067
+ }],
1068
+ stateMutability: "nonpayable"
1069
+ },
1070
+ {
1071
+ type: "function",
1072
+ name: "nextCommitmentId",
1073
+ inputs: [],
1074
+ outputs: [{
1075
+ name: "",
1076
+ type: "uint256",
1077
+ internalType: "uint256"
1078
+ }],
1079
+ stateMutability: "view"
1080
+ },
1081
+ {
1082
+ type: "function",
1083
+ name: "redirect",
1084
+ inputs: [
1085
+ {
1086
+ name: "commitmentId",
1087
+ type: "uint256",
1088
+ internalType: "uint256"
1089
+ },
1090
+ {
1091
+ name: "recipient",
1092
+ type: "address",
1093
+ internalType: "address"
1094
+ },
1095
+ {
1096
+ name: "documentHash",
1097
+ type: "bytes32",
1098
+ internalType: "bytes32"
1099
+ }
1100
+ ],
1101
+ outputs: [],
1102
+ stateMutability: "nonpayable"
1103
+ },
1104
+ {
1105
+ type: "function",
1106
+ name: "send",
1107
+ inputs: [{
1108
+ name: "item",
1109
+ type: "tuple",
1110
+ internalType: "struct CapxulPaymentsV2.PaymentItem",
1111
+ components: [
1112
+ {
1113
+ name: "settlementId",
1114
+ type: "bytes32",
1115
+ internalType: "bytes32"
1116
+ },
1117
+ {
1118
+ name: "recipient",
1119
+ type: "address",
1120
+ internalType: "address"
1121
+ },
1122
+ {
1123
+ name: "token",
1124
+ type: "address",
1125
+ internalType: "address"
1126
+ },
1127
+ {
1128
+ name: "amount",
1129
+ type: "uint256",
1130
+ internalType: "uint256"
1131
+ },
1132
+ {
1133
+ name: "kind",
1134
+ type: "uint16",
1135
+ internalType: "uint16"
1136
+ },
1137
+ {
1138
+ name: "documentHash",
1139
+ type: "bytes32",
1140
+ internalType: "bytes32"
1141
+ }
1142
+ ]
1143
+ }],
1144
+ outputs: [],
1145
+ stateMutability: "nonpayable"
1146
+ },
1147
+ {
1148
+ type: "function",
1149
+ name: "sendBatch",
1150
+ inputs: [{
1151
+ name: "items",
1152
+ type: "tuple[]",
1153
+ internalType: "struct CapxulPaymentsV2.PaymentItem[]",
1154
+ components: [
1155
+ {
1156
+ name: "settlementId",
1157
+ type: "bytes32",
1158
+ internalType: "bytes32"
1159
+ },
1160
+ {
1161
+ name: "recipient",
1162
+ type: "address",
1163
+ internalType: "address"
1164
+ },
1165
+ {
1166
+ name: "token",
1167
+ type: "address",
1168
+ internalType: "address"
1169
+ },
1170
+ {
1171
+ name: "amount",
1172
+ type: "uint256",
1173
+ internalType: "uint256"
1174
+ },
1175
+ {
1176
+ name: "kind",
1177
+ type: "uint16",
1178
+ internalType: "uint16"
1179
+ },
1180
+ {
1181
+ name: "documentHash",
1182
+ type: "bytes32",
1183
+ internalType: "bytes32"
1184
+ }
1185
+ ]
1186
+ }],
1187
+ outputs: [],
1188
+ stateMutability: "nonpayable"
1189
+ },
1190
+ {
1191
+ type: "function",
1192
+ name: "vestedAmount",
1193
+ inputs: [{
1194
+ name: "commitmentId",
1195
+ type: "uint256",
1196
+ internalType: "uint256"
1197
+ }],
1198
+ outputs: [{
1199
+ name: "",
1200
+ type: "uint256",
1201
+ internalType: "uint256"
1202
+ }],
1203
+ stateMutability: "view"
1204
+ },
1205
+ {
1206
+ type: "event",
1207
+ name: "CommitmentCancelled",
1208
+ inputs: [
1209
+ {
1210
+ name: "commitmentId",
1211
+ type: "uint256",
1212
+ indexed: true,
1213
+ internalType: "uint256"
1214
+ },
1215
+ {
1216
+ name: "settlementId",
1217
+ type: "bytes32",
1218
+ indexed: true,
1219
+ internalType: "bytes32"
1220
+ },
1221
+ {
1222
+ name: "creator",
1223
+ type: "address",
1224
+ indexed: true,
1225
+ internalType: "address"
1226
+ },
1227
+ {
1228
+ name: "vestedUnclaimed",
1229
+ type: "uint256",
1230
+ indexed: false,
1231
+ internalType: "uint256"
1232
+ },
1233
+ {
1234
+ name: "unvestedReturned",
1235
+ type: "uint256",
1236
+ indexed: false,
1237
+ internalType: "uint256"
1238
+ },
1239
+ {
1240
+ name: "documentHash",
1241
+ type: "bytes32",
1242
+ indexed: false,
1243
+ internalType: "bytes32"
1244
+ }
1245
+ ],
1246
+ anonymous: false
1247
+ },
1248
+ {
1249
+ type: "event",
1250
+ name: "CommitmentCreated",
1251
+ inputs: [
1252
+ {
1253
+ name: "commitmentId",
1254
+ type: "uint256",
1255
+ indexed: true,
1256
+ internalType: "uint256"
1257
+ },
1258
+ {
1259
+ name: "settlementId",
1260
+ type: "bytes32",
1261
+ indexed: true,
1262
+ internalType: "bytes32"
1263
+ },
1264
+ {
1265
+ name: "creator",
1266
+ type: "address",
1267
+ indexed: true,
1268
+ internalType: "address"
1269
+ },
1270
+ {
1271
+ name: "recipient",
1272
+ type: "address",
1273
+ indexed: false,
1274
+ internalType: "address"
1275
+ },
1276
+ {
1277
+ name: "token",
1278
+ type: "address",
1279
+ indexed: false,
1280
+ internalType: "address"
1281
+ },
1282
+ {
1283
+ name: "totalAmount",
1284
+ type: "uint256",
1285
+ indexed: false,
1286
+ internalType: "uint256"
1287
+ },
1288
+ {
1289
+ name: "startTime",
1290
+ type: "uint48",
1291
+ indexed: false,
1292
+ internalType: "uint48"
1293
+ },
1294
+ {
1295
+ name: "cliffTime",
1296
+ type: "uint48",
1297
+ indexed: false,
1298
+ internalType: "uint48"
1299
+ },
1300
+ {
1301
+ name: "endTime",
1302
+ type: "uint48",
1303
+ indexed: false,
1304
+ internalType: "uint48"
1305
+ },
1306
+ {
1307
+ name: "kind",
1308
+ type: "uint16",
1309
+ indexed: false,
1310
+ internalType: "uint16"
1311
+ },
1312
+ {
1313
+ name: "documentHash",
1314
+ type: "bytes32",
1315
+ indexed: false,
1316
+ internalType: "bytes32"
1317
+ }
1318
+ ],
1319
+ anonymous: false
1320
+ },
1321
+ {
1322
+ type: "event",
1323
+ name: "CommitmentRedirected",
1324
+ inputs: [
1325
+ {
1326
+ name: "commitmentId",
1327
+ type: "uint256",
1328
+ indexed: true,
1329
+ internalType: "uint256"
1330
+ },
1331
+ {
1332
+ name: "settlementId",
1333
+ type: "bytes32",
1334
+ indexed: true,
1335
+ internalType: "bytes32"
1336
+ },
1337
+ {
1338
+ name: "oldRecipient",
1339
+ type: "address",
1340
+ indexed: true,
1341
+ internalType: "address"
1342
+ },
1343
+ {
1344
+ name: "newRecipient",
1345
+ type: "address",
1346
+ indexed: false,
1347
+ internalType: "address"
1348
+ },
1349
+ {
1350
+ name: "documentHash",
1351
+ type: "bytes32",
1352
+ indexed: false,
1353
+ internalType: "bytes32"
1354
+ }
1355
+ ],
1356
+ anonymous: false
1357
+ },
1358
+ {
1359
+ type: "event",
1360
+ name: "FundsClaimed",
1361
+ inputs: [
1362
+ {
1363
+ name: "commitmentId",
1364
+ type: "uint256",
1365
+ indexed: true,
1366
+ internalType: "uint256"
1367
+ },
1368
+ {
1369
+ name: "settlementId",
1370
+ type: "bytes32",
1371
+ indexed: true,
1372
+ internalType: "bytes32"
1373
+ },
1374
+ {
1375
+ name: "recipient",
1376
+ type: "address",
1377
+ indexed: true,
1378
+ internalType: "address"
1379
+ },
1380
+ {
1381
+ name: "amount",
1382
+ type: "uint256",
1383
+ indexed: false,
1384
+ internalType: "uint256"
1385
+ },
1386
+ {
1387
+ name: "documentHash",
1388
+ type: "bytes32",
1389
+ indexed: false,
1390
+ internalType: "bytes32"
1391
+ }
1392
+ ],
1393
+ anonymous: false
1394
+ },
1395
+ {
1396
+ type: "event",
1397
+ name: "PaymentSent",
1398
+ inputs: [
1399
+ {
1400
+ name: "settlementId",
1401
+ type: "bytes32",
1402
+ indexed: true,
1403
+ internalType: "bytes32"
1404
+ },
1405
+ {
1406
+ name: "sender",
1407
+ type: "address",
1408
+ indexed: true,
1409
+ internalType: "address"
1410
+ },
1411
+ {
1412
+ name: "recipient",
1413
+ type: "address",
1414
+ indexed: true,
1415
+ internalType: "address"
1416
+ },
1417
+ {
1418
+ name: "token",
1419
+ type: "address",
1420
+ indexed: false,
1421
+ internalType: "address"
1422
+ },
1423
+ {
1424
+ name: "amount",
1425
+ type: "uint256",
1426
+ indexed: false,
1427
+ internalType: "uint256"
1428
+ },
1429
+ {
1430
+ name: "kind",
1431
+ type: "uint16",
1432
+ indexed: false,
1433
+ internalType: "uint16"
1434
+ },
1435
+ {
1436
+ name: "documentHash",
1437
+ type: "bytes32",
1438
+ indexed: false,
1439
+ internalType: "bytes32"
1440
+ }
1441
+ ],
1442
+ anonymous: false
1443
+ },
1444
+ {
1445
+ type: "error",
1446
+ name: "AlreadyCancelled",
1447
+ inputs: []
1448
+ },
1449
+ {
1450
+ type: "error",
1451
+ name: "AlreadyClaimed",
1452
+ inputs: []
1453
+ },
1454
+ {
1455
+ type: "error",
1456
+ name: "DocumentHashMismatch",
1457
+ inputs: [{
1458
+ name: "expected",
1459
+ type: "bytes32",
1460
+ internalType: "bytes32"
1461
+ }, {
1462
+ name: "supplied",
1463
+ type: "bytes32",
1464
+ internalType: "bytes32"
1465
+ }]
1466
+ },
1467
+ {
1468
+ type: "error",
1469
+ name: "InvalidTimeParams",
1470
+ inputs: []
1471
+ },
1472
+ {
1473
+ type: "error",
1474
+ name: "NotCreator",
1475
+ inputs: []
1476
+ },
1477
+ {
1478
+ type: "error",
1479
+ name: "NotRecipient",
1480
+ inputs: []
1481
+ },
1482
+ {
1483
+ type: "error",
1484
+ name: "NothingToClaim",
1485
+ inputs: []
1486
+ },
1487
+ {
1488
+ type: "error",
1489
+ name: "SettlementIdConsumed",
1490
+ inputs: [{
1491
+ name: "settlementId",
1492
+ type: "bytes32",
1493
+ internalType: "bytes32"
1494
+ }]
1495
+ },
1496
+ {
1497
+ type: "error",
1498
+ name: "TokenCallReturnedFalse",
1499
+ inputs: [{
1500
+ name: "token",
1501
+ type: "address",
1502
+ internalType: "address"
1503
+ }]
1504
+ },
1505
+ {
1506
+ type: "error",
1507
+ name: "TokenHasNoCode",
1508
+ inputs: [{
1509
+ name: "token",
1510
+ type: "address",
1511
+ internalType: "address"
1512
+ }]
1513
+ },
1514
+ {
1515
+ type: "error",
1516
+ name: "ZeroAddress",
1517
+ inputs: []
1518
+ },
1519
+ {
1520
+ type: "error",
1521
+ name: "ZeroAmount",
1522
+ inputs: []
1523
+ },
1524
+ {
1525
+ type: "error",
1526
+ name: "ZeroDocumentHash",
1527
+ inputs: []
1528
+ },
1529
+ {
1530
+ type: "error",
1531
+ name: "ZeroSettlementId",
1532
+ inputs: []
1533
+ }
1534
+ ];
1535
+ /** Immutable CapxulPaymentsV2 deployment on Base Sepolia. */
1536
+ const CAPXUL_PAYMENTS_V2_ADDRESS = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
1537
+ //#endregion
1538
+ //#region ../config/src/route.ts
1539
+ /** USDX on Base Sepolia — the only settlement token in v1. */
1540
+ const USDX_BASE_SEPOLIA_TOKEN = {
1541
+ chainId: BASE_SEPOLIA_CHAIN_ID,
1542
+ address: USDX_ADDRESS_BASE_SEPOLIA,
1543
+ decimals: 6
1544
+ };
1545
+ USDX_BASE_SEPOLIA_TOKEN.chainId;
1546
+ USDX_BASE_SEPOLIA_TOKEN.chainId;
1547
+ 10n ** BigInt(6);
1548
+ function normalizeOrgRoleLabel(label) {
1549
+ const normalized = label.trim().replace(/\s+/g, " ");
1550
+ if (normalized.length === 0) throw Errors.invalidInput("role.label", "must be a non-empty role label");
1551
+ return normalized;
1552
+ }
1553
+ function orgRoleKeyForLabel(label) {
1554
+ return keccak256(toBytes(normalizeOrgRoleLabel(label).toLowerCase()));
1555
+ }
1556
+ padHex(stringToHex("FM_DAILY"), {
1557
+ size: 32,
1558
+ dir: "right"
1559
+ }), padHex(stringToHex("TL_DAILY"), {
1560
+ size: 32,
1561
+ dir: "right"
1562
+ });
1563
+ padHex(concat([MULTI_SEND_CALL_ONLY, "0x8d80ff0a"]), {
1564
+ dir: "right",
1565
+ size: 32
1566
+ });
1567
+ function paymentsV2Signature(name) {
1568
+ const item = CAPXUL_PAYMENTS_V2_ABI.find((candidate) => candidate.type === "function" && candidate.name === name);
1569
+ if (item === void 0) throw new Error(`CapxulPaymentsV2 ABI has no ${name} function`);
1570
+ return toFunctionSignature(item);
1571
+ }
1572
+ paymentsV2Signature("send");
1573
+ paymentsV2Signature("sendBatch");
1574
+ paymentsV2Signature("createCommitment");
1575
+ paymentsV2Signature("cancel");
1576
+ paymentsV2Signature("redirect");
1577
+ new Map([
1578
+ ["assignRoles(address,bytes32[],bool[])", "AssignRoles(address,bytes32[],bool[])"],
1579
+ ["allowTarget(bytes32,address,uint8)", "AllowTarget(bytes32,address,uint8)"],
1580
+ ["scopeTarget(bytes32,address)", "ScopeTarget(bytes32,address)"],
1581
+ ["revokeTarget(bytes32,address)", "RevokeTarget(bytes32,address)"],
1582
+ ["allowFunction(bytes32,address,bytes4,uint8)", "AllowFunction(bytes32,address,bytes4,uint8)"],
1583
+ ["scopeFunction(bytes32,address,bytes4,(uint8,uint8,uint8,bytes)[],uint8)", "ScopeFunction(bytes32,address,bytes4,(uint8,uint8,uint8,bytes)[],uint8)"],
1584
+ ["revokeFunction(bytes32,address,bytes4)", "RevokeFunction(bytes32,address,bytes4)"],
1585
+ ["setAllowance(bytes32,uint128,uint128,uint128,uint64,uint64)", "SetAllowance(bytes32,uint128,uint128,uint128,uint64,uint64)"]
1586
+ ].map(([functionSignature, eventSignature]) => [toFunctionSelector(functionSignature), toEventSelector(eventSignature)]));
1587
+ //#endregion
1588
+ //#region src/ports/auth-client.ts
1589
+ var AuthClientError = class extends Data.TaggedError("AuthClientError") {};
1590
+ var AuthClientPortTag = class extends Context.Service()("@capxul/sdk/ports/AuthClientPort") {};
1591
+ //#endregion
1592
+ //#region src/adapters/auth-client/effect-port.ts
1593
+ function authClientPortFromPromiseAdapter(adapter) {
1594
+ return {
1595
+ canSendOtp: (input, options) => fromResult("canSendOtp", () => adapter.canSendOtp(input, options)),
1596
+ sendOtp: (input, options) => fromResult("sendOtp", () => adapter.sendOtp(input, options)),
1597
+ verifyOtp: (input, options) => fromResult("verifyOtp", () => adapter.verifyOtp(input, options)),
1598
+ getSession: (options) => fromResult("getSession", () => adapter.getSession(options)),
1599
+ signOut: (options) => fromResult("signOut", () => adapter.signOut(options)),
1600
+ getConvexJwt: (options) => fromResult("getConvexJwt", () => adapter.getConvexJwt(options))
1601
+ };
1602
+ }
1603
+ function fromResult(operation, run) {
1604
+ return Effect.tryPromise({
1605
+ try: run,
1606
+ catch: (cause) => new AuthClientError({
1607
+ operation,
1608
+ kind: "thrown",
1609
+ cause
1610
+ })
1611
+ }).pipe(Effect.flatMap((result) => result.ok ? Effect.succeed(result.value) : Effect.fail(new AuthClientError({
1612
+ operation,
1613
+ kind: errorKind(result.error),
1614
+ cause: result.error
1615
+ }))));
1616
+ }
1617
+ function errorKind(error) {
1618
+ if (error.code === "CANCELLED") return "cancelled";
1619
+ if (error.code === "NETWORK_ERROR") return "network";
1620
+ if (error.code === "INVALID_INPUT" || error.code === "OTP_EXPIRED") return "validation";
1621
+ return "provider";
1622
+ }
1623
+ //#endregion
1624
+ //#region src/ports/clock.ts
1625
+ var ClockError = class extends Data.TaggedError("ClockError") {};
1626
+ var ClockPortTag = class extends Context.Service()("@capxul/sdk/ports/ClockPort") {};
1627
+ //#endregion
655
1628
  //#region src/ports/auth-cache.ts
656
1629
  var AuthCacheError = class extends Data.TaggedError("AuthCacheError") {};
657
1630
  var AuthCachePortTag = class extends Context.Service()("@capxul/sdk/ports/AuthCachePort") {};
@@ -760,4 +1733,24 @@ Layer.effect(AuthCachePortTag, Effect.sync(() => new InMemoryAuthCacheAdapter())
760
1733
  cause
761
1734
  }))));
762
1735
  //#endregion
763
- export { toPartyId as A, Errors as B, toDurationMs as C, toJwtToken as D, toEpochSeconds as E, toSessionToken as F, decodeChainCause as G, CHAIN_UPSTREAMS as H, decodeConvexError as I, revertSummaryText as J, failureFingerprint as K, CAPXUL_ERROR_CODES as L, toPayrollRunId as M, toPublishableKey as N, toKycTier as O, toRoleKey as P, CapxulError as R, toCurrencyCode as S, toEpochMs as T, FAILURE_MODES as U, isCapxulError as V, chainCauseProperties as W, toAppId as _, AuthCacheError as a, toChainId as b, BYTES32_RE as c, WEI_RE as d, ZERO_BYTES32 as f, toAllowedOrigin as g, toAddress as h, parseCachedJwt as i, toPayrollGroupId as j, toOrgId as k, EVM_ADDRESS_RE as l, toAccountId as m, BrowserAuthCacheAdapter as n, AuthCachePortTag as o, currencySymbolFor as p, isFailureMode as q, parseAuthSession as r, APP_ID_RE as s, InMemoryAuthCacheAdapter as t, SUPPORTED_CURRENCY_CODES as u, toAuthUserId as v, toEmail as w, toCountryCode as x, toBudgetId as y, EXPECTED_OPERATION_OUTCOMES as z };
1736
+ //#region src/adapters/_shared/clock.ts
1737
+ async function readClockNow(clock) {
1738
+ try {
1739
+ const result = await Effect.runPromise(Effect.result(clock.now));
1740
+ if (Result.isFailure(result)) return {
1741
+ ok: false,
1742
+ error: Errors.providerError("clock", "now", result.failure)
1743
+ };
1744
+ return {
1745
+ ok: true,
1746
+ value: result.success
1747
+ };
1748
+ } catch (cause) {
1749
+ return {
1750
+ ok: false,
1751
+ error: Errors.providerError("clock", "now", cause)
1752
+ };
1753
+ }
1754
+ }
1755
+ //#endregion
1756
+ export { CHAIN_UPSTREAMS as $, toBudgetId as A, toOrgId as B, ZERO_BYTES32 as C, toAllowedOrigin as D, toAddress as E, toEmail as F, toRoleKey as G, toPayrollGroupId as H, toEpochMs as I, CAPXUL_ERROR_CODES as J, toSessionToken as K, toEpochSeconds as L, toCountryCode as M, toCurrencyCode as N, toAppId as O, toDurationMs as P, isCapxulError as Q, toJwtToken as R, WEI_RE as S, toAccountId as T, toPayrollRunId as U, toPartyId as V, toPublishableKey as W, EXPECTED_OPERATION_OUTCOMES as X, CapxulError as Y, Errors as Z, deriveCapxulSafeAddress as _, parseCachedJwt as a, revertSummaryText as at, EVM_ADDRESS_RE as b, ClockError as c, AuthClientError as d, FAILURE_MODES as et, AuthClientPortTag as f, BASE_SEPOLIA_CHAIN_ID as g, normalizeBindingEmail as h, parseAuthSession as i, isFailureMode as it, toChainId as j, toAuthUserId as k, ClockPortTag as l, CAPXUL_PAYMENTS_V2_ADDRESS as m, InMemoryAuthCacheAdapter as n, decodeChainCause as nt, AuthCacheError as o, orgRoleKeyForLabel as p, decodeConvexError as q, BrowserAuthCacheAdapter as r, failureFingerprint as rt, AuthCachePortTag as s, readClockNow as t, chainCauseProperties as tt, authClientPortFromPromiseAdapter as u, APP_ID_RE as v, currencySymbolFor as w, SUPPORTED_CURRENCY_CODES as x, BYTES32_RE as y, toKycTier as z };