@capxul/sdk 2.8.0 → 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,5 +1,5 @@
1
- import { A as toPartyId, B as Errors, G as failureFingerprint, H as CHAIN_UPSTREAMS, K as isFailureMode, M as toPayrollRunId, P as toRoleKey, R as CapxulError, S as toCurrencyCode, U as FAILURE_MODES$1, V as isCapxulError, W as chainCauseProperties, b as toChainId, c as BYTES32_RE, d as WEI_RE, f as ZERO_BYTES32, h as toAddress, j as toPayrollGroupId, k as toOrgId, l as EVM_ADDRESS_RE$1, m as toAccountId, n as BrowserAuthCacheAdapter, q as revertSummaryText, s as APP_ID_RE, t as InMemoryAuthCacheAdapter, u as SUPPORTED_CURRENCY_CODES, v as toAuthUserId, w as toEmail, x as toCountryCode, y as toBudgetId, z as EXPECTED_OPERATION_OUTCOMES } from "./InMemoryAuthCacheAdapter-FptQ2p7C.mjs";
2
- import { concat, encodeAbiParameters, encodeFunctionData, encodePacked, formatUnits, getContractAddress, keccak256, padHex, parseUnits, recoverAddress, stringToHex, toBytes, toEventSelector, toFunctionSelector, toFunctionSignature } from "viem";
1
+ import { $ as CHAIN_UPSTREAMS, A as toBudgetId, B as toOrgId, C as ZERO_BYTES32, E as toAddress, F as toEmail, G as toRoleKey, H as toPayrollGroupId, J as CAPXUL_ERROR_CODES, M as toCountryCode, N as toCurrencyCode, Q as isCapxulError, S as WEI_RE, T as toAccountId, U as toPayrollRunId, V as toPartyId, X as EXPECTED_OPERATION_OUTCOMES, Y as CapxulError, Z as Errors, _ as deriveCapxulSafeAddress, at as revertSummaryText, b as EVM_ADDRESS_RE$1, et as FAILURE_MODES$1, it as isFailureMode, j as toChainId, k as toAuthUserId, n as InMemoryAuthCacheAdapter, nt as decodeChainCause, p as orgRoleKeyForLabel, r as BrowserAuthCacheAdapter, rt as failureFingerprint, tt as chainCauseProperties, v as APP_ID_RE, x as SUPPORTED_CURRENCY_CODES, y as BYTES32_RE } from "./clock-0c5NM-TY.mjs";
2
+ import { formatUnits, keccak256, parseUnits, recoverAddress, toBytes } from "viem";
3
3
  import { Context, Data, Deferred, Duration, Effect, Exit, Fiber, Layer, Queue, Ref, Result, Schema, SchemaGetter, Scope } from "effect";
4
4
  import { makeFunctionReference } from "convex/server";
5
5
  //#region src/domain/identity/model.ts
@@ -14,6 +14,7 @@ const DEFINITIVE_PROVIDER_MODES = /* @__PURE__ */ new Set([
14
14
  "auth-origin-mismatch",
15
15
  "app-env-allowlist",
16
16
  "no-secure-context",
17
+ "signer-not-ready",
17
18
  "revert",
18
19
  "insufficient-balance",
19
20
  "insufficient-allowance",
@@ -397,938 +398,6 @@ const isRestoring = (state) => {
397
398
  * it in #1521; this ticket ships the selector they move onto. */
398
399
  const isClaimed = (state) => state.phase === "authenticated" && state.account.at === "claimed";
399
400
  //#endregion
400
- //#region ../config/src/tokens.ts
401
- /** `TestUSDC` ("USDX") — Base Sepolia, 6 decimals, open `mint`. (Canon §1.) */
402
- const USDX_ADDRESS_BASE_SEPOLIA = "0xf09fcbb6df9f8f918e58f9c8ab15a76ade862b77";
403
- USDX_ADDRESS_BASE_SEPOLIA.toLowerCase();
404
- //#endregion
405
- //#region ../config/src/org-payments.ts
406
- /** Zodiac MultiSendCallOnly module on Base Sepolia. */
407
- const MULTI_SEND_CALL_ONLY = "0x9641d764fc13c8b624c04430c7356c1c7c8102e2";
408
- //#endregion
409
- //#region ../config/src/safe.ts
410
- const BASE_SEPOLIA_CHAIN_ID = 84532;
411
- const SAFE_PROXY_FACTORY = "0x4e1DCf7AD4e460CfD30791CCC4F9c8a4f820ec67";
412
- const SAFE_L2_SINGLETON = "0x29fcB43b46531BcA003ddC8FCB67FFE91900C762";
413
- const SAFE_MODULE_SETUP = "0x2dd68b007B46fBe91B9A7c3EDa5A7a1063cB5b47";
414
- const SAFE_4337_MODULE = "0x75cf11467937ce3F2f357CE24ffc3DBF8fD5c226";
415
- const MULTI_SEND = "0x38869bf66a61cF6bDB996A6aE40D5853Fd43B526";
416
- /**
417
- * The Capxul bootstrap owner — the sole `setup()` owner of every unclaimed
418
- * personal Safe under derivation v2. This address is part of the CREATE2
419
- * preimage of EVERY personal Safe address: treat it exactly like
420
- * `SAFE_PROXY_FACTORY` (changing it is a derivation-version event → v3).
421
- * The private key lives backend-only (`CAPXUL_BOOTSTRAP_OWNER_PRIVATE_KEY`)
422
- * and signs exactly one kind of operation: the claim userOp that deploys the
423
- * Safe and swaps this owner out for the user's signer (PRD #462). The earlier
424
- * ClaimGuard derivation-v3 placeholder (#461) is closed; future mainnet-scale
425
- * hardening should be filed against the current payments/claim architecture.
426
- */
427
- const CAPXUL_BOOTSTRAP_OWNER = "0x425fca96f4a3e18fb80974e38096b5da460f2704";
428
- const SAFE_PROXY_CREATION_CODE = "0x608060405234801561001057600080fd5b506040516101e63803806101e68339818101604052602081101561003357600080fd5b8101908080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156100ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101c46022913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505060ab806101196000396000f3fe608060405273ffffffffffffffffffffffffffffffffffffffff600054167fa619486e0000000000000000000000000000000000000000000000000000000060003514156050578060005260206000f35b3660008037600080366000845af43d6000803e60008114156070573d6000fd5b3d6000f3fea264697066735822122003d1488ee65e08fa41e58e888a9865554c535f2c77126a82cb4c0f917f31441364736f6c63430007060033496e76616c69642073696e676c65746f6e20616464726573732070726f7669646564";
429
- /**
430
- * Normalize an email for use as a Capxul Safe salt input.
431
- *
432
- * Trims surrounding whitespace and lowercases the address so that
433
- * `" User+Demo@Example.COM "` and `"user+demo@example.com"` derive
434
- * the same `safeAddress`. This is the canonical normalization rule —
435
- * any future change here would shift every existing user's Safe
436
- * address, so the rule is pinned by the fixture matrix in
437
- * `packages/config/tests/safe-address-conformance.test.ts`.
438
- *
439
- * @param email - The raw email address to normalize
440
- * @returns The trimmed, lowercased email
441
- */
442
- function normalizeSafeSaltEmail(email) {
443
- return email.trim().toLowerCase();
444
- }
445
- /**
446
- * Compute the deterministic Safe salt nonce for a `(namespace, email)`
447
- * pair. The salt nonce is the `bigint` reading of
448
- * `keccak256(namespace + ":" + normalizeSafeSaltEmail(email))`.
449
- *
450
- * Namespace defaults to `CAPXUL_SAFE_SALT_NAMESPACE`
451
- * (`"capxul:safe:email:v2"`) — the per-version Capxul scheme. Pass a
452
- * different namespace only for pinned pre-v2 artifacts
453
- * (`CAPXUL_SAFE_SALT_NAMESPACE_V1`, faucet Safe) or when bumping the scheme.
454
- *
455
- * @param input.email - The email to derive the salt nonce from
456
- * @param input.namespace - Optional namespace override (defaults to `CAPXUL_SAFE_SALT_NAMESPACE`)
457
- * @returns The Capxul-namespaced salt nonce as a `bigint`
458
- */
459
- function computeCapxulSafeSaltNonce(input) {
460
- const namespace = input.namespace ?? "capxul:safe:email:v2";
461
- const normalizedEmail = normalizeSafeSaltEmail(input.email);
462
- return BigInt(keccak256(toBytes(`${namespace}:${normalizedEmail}`)));
463
- }
464
- const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
465
- const safeSetupAbi = [{
466
- type: "function",
467
- name: "setup",
468
- stateMutability: "nonpayable",
469
- inputs: [
470
- {
471
- name: "_owners",
472
- type: "address[]"
473
- },
474
- {
475
- name: "_threshold",
476
- type: "uint256"
477
- },
478
- {
479
- name: "to",
480
- type: "address"
481
- },
482
- {
483
- name: "data",
484
- type: "bytes"
485
- },
486
- {
487
- name: "fallbackHandler",
488
- type: "address"
489
- },
490
- {
491
- name: "paymentToken",
492
- type: "address"
493
- },
494
- {
495
- name: "payment",
496
- type: "uint256"
497
- },
498
- {
499
- name: "paymentReceiver",
500
- type: "address"
501
- }
502
- ],
503
- outputs: []
504
- }];
505
- const enableModulesAbi = [{
506
- type: "function",
507
- name: "enableModules",
508
- stateMutability: "nonpayable",
509
- inputs: [{
510
- name: "modules",
511
- type: "address[]"
512
- }],
513
- outputs: []
514
- }];
515
- const multiSendAbi = [{
516
- type: "function",
517
- name: "multiSend",
518
- stateMutability: "payable",
519
- inputs: [{
520
- name: "transactions",
521
- type: "bytes"
522
- }],
523
- outputs: []
524
- }];
525
- function buildCapxulSafeInitializer(owner) {
526
- const enableModulesCall = encodeFunctionData({
527
- abi: enableModulesAbi,
528
- functionName: "enableModules",
529
- args: [[SAFE_4337_MODULE]]
530
- });
531
- const enableModulesByteLen = BigInt((enableModulesCall.length - 2) / 2);
532
- const multiSendPayload = encodePacked([
533
- "uint8",
534
- "address",
535
- "uint256",
536
- "uint256",
537
- "bytes"
538
- ], [
539
- 1,
540
- SAFE_MODULE_SETUP,
541
- 0n,
542
- enableModulesByteLen,
543
- enableModulesCall
544
- ]);
545
- const setupData = encodeFunctionData({
546
- abi: multiSendAbi,
547
- functionName: "multiSend",
548
- args: [multiSendPayload]
549
- });
550
- return encodeFunctionData({
551
- abi: safeSetupAbi,
552
- functionName: "setup",
553
- args: [
554
- [owner],
555
- 1n,
556
- MULTI_SEND,
557
- setupData,
558
- SAFE_4337_MODULE,
559
- ZERO_ADDRESS,
560
- 0n,
561
- ZERO_ADDRESS
562
- ]
563
- });
564
- }
565
- const ADDRESS_REGEX = /^0x[0-9a-fA-F]{40}$/;
566
- function validateAndNormalizeAddress(field, value) {
567
- const address = value.toLowerCase();
568
- if (!ADDRESS_REGEX.test(address)) throw Errors.invalidInput(field, `must be 0x + 40 hex chars, got ${value}`);
569
- return address;
570
- }
571
- /**
572
- * Pure derivation of the Capxul personal Safe address — **v2: email only**
573
- * (PRD #462). The Safe v1.4.1 (SafeL2) + 4337-module initializer's sole owner
574
- * is the fixed `CAPXUL_BOOTSTRAP_OWNER`, so the address is a pure function of
575
- * the (normalized) email and exists before any user signer does. The user's
576
- * signer is installed at claim time via `swapOwner` — signer rotation can
577
- * never move the address (org-domain rule D7, now system-wide).
578
- *
579
- * Returns the lowercased `0x` + 40 hex string (raw — no brand applied so this
580
- * function is callable from both `@capxul/config` consumers that don't have
581
- * `@capxul/types` available, and from packages that re-brand at their own
582
- * boundary).
583
- *
584
- * Algorithm: exactly mirrors `permissionless.toSafeSmartAccount({ version:
585
- * "1.4.1", safeSingletonAddress: SAFE_L2_SINGLETON, owners: [BOOTSTRAP] })`
586
- * + the Capxul-canonical module setup (delegatecall into
587
- * `SafeModuleSetup.enableModules([SAFE_4337_MODULE])` via the MultiSend lane
588
- * during proxy setup). The proxy creation code is pinned at
589
- * `SAFE_PROXY_CREATION_CODE`; the salt is Capxul-namespaced (v2) via
590
- * `computeCapxulSafeSaltNonce({ email })`.
591
- *
592
- * Canonical: SDK deployment adapters and
593
- * `packages/backend/convex/smartAccount/mutations.ts:provision` import this
594
- * function; the conformance test at
595
- * `packages/config/tests/safe-address-conformance.test.ts` pins the matrix.
596
- */
597
- function deriveCapxulSafeAddress(input) {
598
- return deriveCapxulSafeAddressForOwner({
599
- ownerAddress: CAPXUL_BOOTSTRAP_OWNER,
600
- email: input.email
601
- });
602
- }
603
- /**
604
- * Owner-parametrized derivation core. Two callers only:
605
- * 1. `deriveCapxulSafeAddress` (canonical v2: owner = bootstrap, namespace v2);
606
- * 2. the backend faucet Safe (`testUsdcMint.ts`: owner = deployer EOA,
607
- * namespace pinned to `CAPXUL_SAFE_SALT_NAMESPACE_V1` so its deployed
608
- * address never moves).
609
- * Do NOT introduce new owner-parametrized lanes — per-user owners in the
610
- * derivation is exactly the v1 mistake v2 removes.
611
- */
612
- function deriveCapxulSafeAddressForOwner(input) {
613
- const initializer = buildCapxulSafeInitializer(validateAndNormalizeAddress("ownerAddress", input.ownerAddress));
614
- const saltNonce = computeCapxulSafeSaltNonce(input.namespace === void 0 ? { email: input.email } : {
615
- email: input.email,
616
- namespace: input.namespace
617
- });
618
- const salt = keccak256(encodePacked(["bytes32", "uint256"], [keccak256(initializer), saltNonce]));
619
- const deploymentCode = concat([SAFE_PROXY_CREATION_CODE, encodeAbiParameters([{ type: "uint256" }], [BigInt(SAFE_L2_SINGLETON)])]);
620
- return getContractAddress({
621
- opcode: "CREATE2",
622
- from: SAFE_PROXY_FACTORY,
623
- salt,
624
- bytecodeHash: keccak256(deploymentCode)
625
- }).toLowerCase();
626
- }
627
- /**
628
- * Normalize a raw email for binding id + Safe salt derivation.
629
- * Delegates to {@link normalizeSafeSaltEmail} so binding resolution and
630
- * `deriveCapxulSafeAddress` never drift apart.
631
- */
632
- function normalizeBindingEmail(email) {
633
- return normalizeSafeSaltEmail(email);
634
- }
635
- //#endregion
636
- //#region ../config/src/capxul-payments-v2.ts
637
- /** The exact compiled CapxulPaymentsV2 ABI. */
638
- const CAPXUL_PAYMENTS_V2_ABI = [
639
- {
640
- type: "function",
641
- name: "cancel",
642
- inputs: [{
643
- name: "commitmentId",
644
- type: "uint256",
645
- internalType: "uint256"
646
- }, {
647
- name: "documentHash",
648
- type: "bytes32",
649
- internalType: "bytes32"
650
- }],
651
- outputs: [],
652
- stateMutability: "nonpayable"
653
- },
654
- {
655
- type: "function",
656
- name: "claim",
657
- inputs: [{
658
- name: "commitmentId",
659
- type: "uint256",
660
- internalType: "uint256"
661
- }],
662
- outputs: [],
663
- stateMutability: "nonpayable"
664
- },
665
- {
666
- type: "function",
667
- name: "claimableAmount",
668
- inputs: [{
669
- name: "commitmentId",
670
- type: "uint256",
671
- internalType: "uint256"
672
- }],
673
- outputs: [{
674
- name: "",
675
- type: "uint256",
676
- internalType: "uint256"
677
- }],
678
- stateMutability: "view"
679
- },
680
- {
681
- type: "function",
682
- name: "commitments",
683
- inputs: [{
684
- name: "",
685
- type: "uint256",
686
- internalType: "uint256"
687
- }],
688
- outputs: [
689
- {
690
- name: "settlementId",
691
- type: "bytes32",
692
- internalType: "bytes32"
693
- },
694
- {
695
- name: "creator",
696
- type: "address",
697
- internalType: "address"
698
- },
699
- {
700
- name: "recipient",
701
- type: "address",
702
- internalType: "address"
703
- },
704
- {
705
- name: "token",
706
- type: "address",
707
- internalType: "address"
708
- },
709
- {
710
- name: "totalAmount",
711
- type: "uint256",
712
- internalType: "uint256"
713
- },
714
- {
715
- name: "claimed",
716
- type: "uint256",
717
- internalType: "uint256"
718
- },
719
- {
720
- name: "startTime",
721
- type: "uint48",
722
- internalType: "uint48"
723
- },
724
- {
725
- name: "cliffTime",
726
- type: "uint48",
727
- internalType: "uint48"
728
- },
729
- {
730
- name: "endTime",
731
- type: "uint48",
732
- internalType: "uint48"
733
- },
734
- {
735
- name: "kind",
736
- type: "uint16",
737
- internalType: "uint16"
738
- },
739
- {
740
- name: "documentHash",
741
- type: "bytes32",
742
- internalType: "bytes32"
743
- },
744
- {
745
- name: "cancelled",
746
- type: "bool",
747
- internalType: "bool"
748
- }
749
- ],
750
- stateMutability: "view"
751
- },
752
- {
753
- type: "function",
754
- name: "createCommitment",
755
- inputs: [{
756
- name: "input",
757
- type: "tuple",
758
- internalType: "struct CapxulPaymentsV2.CommitmentInput",
759
- components: [
760
- {
761
- name: "settlementId",
762
- type: "bytes32",
763
- internalType: "bytes32"
764
- },
765
- {
766
- name: "recipient",
767
- type: "address",
768
- internalType: "address"
769
- },
770
- {
771
- name: "token",
772
- type: "address",
773
- internalType: "address"
774
- },
775
- {
776
- name: "totalAmount",
777
- type: "uint256",
778
- internalType: "uint256"
779
- },
780
- {
781
- name: "startTime",
782
- type: "uint48",
783
- internalType: "uint48"
784
- },
785
- {
786
- name: "cliffTime",
787
- type: "uint48",
788
- internalType: "uint48"
789
- },
790
- {
791
- name: "endTime",
792
- type: "uint48",
793
- internalType: "uint48"
794
- },
795
- {
796
- name: "kind",
797
- type: "uint16",
798
- internalType: "uint16"
799
- },
800
- {
801
- name: "documentHash",
802
- type: "bytes32",
803
- internalType: "bytes32"
804
- }
805
- ]
806
- }],
807
- outputs: [{
808
- name: "commitmentId",
809
- type: "uint256",
810
- internalType: "uint256"
811
- }],
812
- stateMutability: "nonpayable"
813
- },
814
- {
815
- type: "function",
816
- name: "nextCommitmentId",
817
- inputs: [],
818
- outputs: [{
819
- name: "",
820
- type: "uint256",
821
- internalType: "uint256"
822
- }],
823
- stateMutability: "view"
824
- },
825
- {
826
- type: "function",
827
- name: "redirect",
828
- inputs: [
829
- {
830
- name: "commitmentId",
831
- type: "uint256",
832
- internalType: "uint256"
833
- },
834
- {
835
- name: "recipient",
836
- type: "address",
837
- internalType: "address"
838
- },
839
- {
840
- name: "documentHash",
841
- type: "bytes32",
842
- internalType: "bytes32"
843
- }
844
- ],
845
- outputs: [],
846
- stateMutability: "nonpayable"
847
- },
848
- {
849
- type: "function",
850
- name: "send",
851
- inputs: [{
852
- name: "item",
853
- type: "tuple",
854
- internalType: "struct CapxulPaymentsV2.PaymentItem",
855
- components: [
856
- {
857
- name: "settlementId",
858
- type: "bytes32",
859
- internalType: "bytes32"
860
- },
861
- {
862
- name: "recipient",
863
- type: "address",
864
- internalType: "address"
865
- },
866
- {
867
- name: "token",
868
- type: "address",
869
- internalType: "address"
870
- },
871
- {
872
- name: "amount",
873
- type: "uint256",
874
- internalType: "uint256"
875
- },
876
- {
877
- name: "kind",
878
- type: "uint16",
879
- internalType: "uint16"
880
- },
881
- {
882
- name: "documentHash",
883
- type: "bytes32",
884
- internalType: "bytes32"
885
- }
886
- ]
887
- }],
888
- outputs: [],
889
- stateMutability: "nonpayable"
890
- },
891
- {
892
- type: "function",
893
- name: "sendBatch",
894
- inputs: [{
895
- name: "items",
896
- type: "tuple[]",
897
- internalType: "struct CapxulPaymentsV2.PaymentItem[]",
898
- components: [
899
- {
900
- name: "settlementId",
901
- type: "bytes32",
902
- internalType: "bytes32"
903
- },
904
- {
905
- name: "recipient",
906
- type: "address",
907
- internalType: "address"
908
- },
909
- {
910
- name: "token",
911
- type: "address",
912
- internalType: "address"
913
- },
914
- {
915
- name: "amount",
916
- type: "uint256",
917
- internalType: "uint256"
918
- },
919
- {
920
- name: "kind",
921
- type: "uint16",
922
- internalType: "uint16"
923
- },
924
- {
925
- name: "documentHash",
926
- type: "bytes32",
927
- internalType: "bytes32"
928
- }
929
- ]
930
- }],
931
- outputs: [],
932
- stateMutability: "nonpayable"
933
- },
934
- {
935
- type: "function",
936
- name: "vestedAmount",
937
- inputs: [{
938
- name: "commitmentId",
939
- type: "uint256",
940
- internalType: "uint256"
941
- }],
942
- outputs: [{
943
- name: "",
944
- type: "uint256",
945
- internalType: "uint256"
946
- }],
947
- stateMutability: "view"
948
- },
949
- {
950
- type: "event",
951
- name: "CommitmentCancelled",
952
- inputs: [
953
- {
954
- name: "commitmentId",
955
- type: "uint256",
956
- indexed: true,
957
- internalType: "uint256"
958
- },
959
- {
960
- name: "settlementId",
961
- type: "bytes32",
962
- indexed: true,
963
- internalType: "bytes32"
964
- },
965
- {
966
- name: "creator",
967
- type: "address",
968
- indexed: true,
969
- internalType: "address"
970
- },
971
- {
972
- name: "vestedUnclaimed",
973
- type: "uint256",
974
- indexed: false,
975
- internalType: "uint256"
976
- },
977
- {
978
- name: "unvestedReturned",
979
- type: "uint256",
980
- indexed: false,
981
- internalType: "uint256"
982
- },
983
- {
984
- name: "documentHash",
985
- type: "bytes32",
986
- indexed: false,
987
- internalType: "bytes32"
988
- }
989
- ],
990
- anonymous: false
991
- },
992
- {
993
- type: "event",
994
- name: "CommitmentCreated",
995
- inputs: [
996
- {
997
- name: "commitmentId",
998
- type: "uint256",
999
- indexed: true,
1000
- internalType: "uint256"
1001
- },
1002
- {
1003
- name: "settlementId",
1004
- type: "bytes32",
1005
- indexed: true,
1006
- internalType: "bytes32"
1007
- },
1008
- {
1009
- name: "creator",
1010
- type: "address",
1011
- indexed: true,
1012
- internalType: "address"
1013
- },
1014
- {
1015
- name: "recipient",
1016
- type: "address",
1017
- indexed: false,
1018
- internalType: "address"
1019
- },
1020
- {
1021
- name: "token",
1022
- type: "address",
1023
- indexed: false,
1024
- internalType: "address"
1025
- },
1026
- {
1027
- name: "totalAmount",
1028
- type: "uint256",
1029
- indexed: false,
1030
- internalType: "uint256"
1031
- },
1032
- {
1033
- name: "startTime",
1034
- type: "uint48",
1035
- indexed: false,
1036
- internalType: "uint48"
1037
- },
1038
- {
1039
- name: "cliffTime",
1040
- type: "uint48",
1041
- indexed: false,
1042
- internalType: "uint48"
1043
- },
1044
- {
1045
- name: "endTime",
1046
- type: "uint48",
1047
- indexed: false,
1048
- internalType: "uint48"
1049
- },
1050
- {
1051
- name: "kind",
1052
- type: "uint16",
1053
- indexed: false,
1054
- internalType: "uint16"
1055
- },
1056
- {
1057
- name: "documentHash",
1058
- type: "bytes32",
1059
- indexed: false,
1060
- internalType: "bytes32"
1061
- }
1062
- ],
1063
- anonymous: false
1064
- },
1065
- {
1066
- type: "event",
1067
- name: "CommitmentRedirected",
1068
- inputs: [
1069
- {
1070
- name: "commitmentId",
1071
- type: "uint256",
1072
- indexed: true,
1073
- internalType: "uint256"
1074
- },
1075
- {
1076
- name: "settlementId",
1077
- type: "bytes32",
1078
- indexed: true,
1079
- internalType: "bytes32"
1080
- },
1081
- {
1082
- name: "oldRecipient",
1083
- type: "address",
1084
- indexed: true,
1085
- internalType: "address"
1086
- },
1087
- {
1088
- name: "newRecipient",
1089
- type: "address",
1090
- indexed: false,
1091
- internalType: "address"
1092
- },
1093
- {
1094
- name: "documentHash",
1095
- type: "bytes32",
1096
- indexed: false,
1097
- internalType: "bytes32"
1098
- }
1099
- ],
1100
- anonymous: false
1101
- },
1102
- {
1103
- type: "event",
1104
- name: "FundsClaimed",
1105
- inputs: [
1106
- {
1107
- name: "commitmentId",
1108
- type: "uint256",
1109
- indexed: true,
1110
- internalType: "uint256"
1111
- },
1112
- {
1113
- name: "settlementId",
1114
- type: "bytes32",
1115
- indexed: true,
1116
- internalType: "bytes32"
1117
- },
1118
- {
1119
- name: "recipient",
1120
- type: "address",
1121
- indexed: true,
1122
- internalType: "address"
1123
- },
1124
- {
1125
- name: "amount",
1126
- type: "uint256",
1127
- indexed: false,
1128
- internalType: "uint256"
1129
- },
1130
- {
1131
- name: "documentHash",
1132
- type: "bytes32",
1133
- indexed: false,
1134
- internalType: "bytes32"
1135
- }
1136
- ],
1137
- anonymous: false
1138
- },
1139
- {
1140
- type: "event",
1141
- name: "PaymentSent",
1142
- inputs: [
1143
- {
1144
- name: "settlementId",
1145
- type: "bytes32",
1146
- indexed: true,
1147
- internalType: "bytes32"
1148
- },
1149
- {
1150
- name: "sender",
1151
- type: "address",
1152
- indexed: true,
1153
- internalType: "address"
1154
- },
1155
- {
1156
- name: "recipient",
1157
- type: "address",
1158
- indexed: true,
1159
- internalType: "address"
1160
- },
1161
- {
1162
- name: "token",
1163
- type: "address",
1164
- indexed: false,
1165
- internalType: "address"
1166
- },
1167
- {
1168
- name: "amount",
1169
- type: "uint256",
1170
- indexed: false,
1171
- internalType: "uint256"
1172
- },
1173
- {
1174
- name: "kind",
1175
- type: "uint16",
1176
- indexed: false,
1177
- internalType: "uint16"
1178
- },
1179
- {
1180
- name: "documentHash",
1181
- type: "bytes32",
1182
- indexed: false,
1183
- internalType: "bytes32"
1184
- }
1185
- ],
1186
- anonymous: false
1187
- },
1188
- {
1189
- type: "error",
1190
- name: "AlreadyCancelled",
1191
- inputs: []
1192
- },
1193
- {
1194
- type: "error",
1195
- name: "AlreadyClaimed",
1196
- inputs: []
1197
- },
1198
- {
1199
- type: "error",
1200
- name: "DocumentHashMismatch",
1201
- inputs: [{
1202
- name: "expected",
1203
- type: "bytes32",
1204
- internalType: "bytes32"
1205
- }, {
1206
- name: "supplied",
1207
- type: "bytes32",
1208
- internalType: "bytes32"
1209
- }]
1210
- },
1211
- {
1212
- type: "error",
1213
- name: "InvalidTimeParams",
1214
- inputs: []
1215
- },
1216
- {
1217
- type: "error",
1218
- name: "NotCreator",
1219
- inputs: []
1220
- },
1221
- {
1222
- type: "error",
1223
- name: "NotRecipient",
1224
- inputs: []
1225
- },
1226
- {
1227
- type: "error",
1228
- name: "NothingToClaim",
1229
- inputs: []
1230
- },
1231
- {
1232
- type: "error",
1233
- name: "SettlementIdConsumed",
1234
- inputs: [{
1235
- name: "settlementId",
1236
- type: "bytes32",
1237
- internalType: "bytes32"
1238
- }]
1239
- },
1240
- {
1241
- type: "error",
1242
- name: "TokenCallReturnedFalse",
1243
- inputs: [{
1244
- name: "token",
1245
- type: "address",
1246
- internalType: "address"
1247
- }]
1248
- },
1249
- {
1250
- type: "error",
1251
- name: "TokenHasNoCode",
1252
- inputs: [{
1253
- name: "token",
1254
- type: "address",
1255
- internalType: "address"
1256
- }]
1257
- },
1258
- {
1259
- type: "error",
1260
- name: "ZeroAddress",
1261
- inputs: []
1262
- },
1263
- {
1264
- type: "error",
1265
- name: "ZeroAmount",
1266
- inputs: []
1267
- },
1268
- {
1269
- type: "error",
1270
- name: "ZeroDocumentHash",
1271
- inputs: []
1272
- },
1273
- {
1274
- type: "error",
1275
- name: "ZeroSettlementId",
1276
- inputs: []
1277
- }
1278
- ];
1279
- /** Immutable CapxulPaymentsV2 deployment on Base Sepolia. */
1280
- const CAPXUL_PAYMENTS_V2_ADDRESS = "0x7a5c25aB7ce91d7a475B71cd1ec33E230291f8a4";
1281
- //#endregion
1282
- //#region ../config/src/route.ts
1283
- /** USDX on Base Sepolia — the only settlement token in v1. */
1284
- const USDX_BASE_SEPOLIA_TOKEN = {
1285
- chainId: BASE_SEPOLIA_CHAIN_ID,
1286
- address: USDX_ADDRESS_BASE_SEPOLIA,
1287
- decimals: 6
1288
- };
1289
- USDX_BASE_SEPOLIA_TOKEN.chainId;
1290
- USDX_BASE_SEPOLIA_TOKEN.chainId;
1291
- 10n ** BigInt(6);
1292
- function normalizeOrgRoleLabel(label) {
1293
- const normalized = label.trim().replace(/\s+/g, " ");
1294
- if (normalized.length === 0) throw Errors.invalidInput("role.label", "must be a non-empty role label");
1295
- return normalized;
1296
- }
1297
- function orgRoleKeyForLabel(label) {
1298
- return keccak256(toBytes(normalizeOrgRoleLabel(label).toLowerCase()));
1299
- }
1300
- padHex(stringToHex("FM_DAILY"), {
1301
- size: 32,
1302
- dir: "right"
1303
- }), padHex(stringToHex("TL_DAILY"), {
1304
- size: 32,
1305
- dir: "right"
1306
- });
1307
- padHex(concat([MULTI_SEND_CALL_ONLY, "0x8d80ff0a"]), {
1308
- dir: "right",
1309
- size: 32
1310
- });
1311
- function paymentsV2Signature(name) {
1312
- const item = CAPXUL_PAYMENTS_V2_ABI.find((candidate) => candidate.type === "function" && candidate.name === name);
1313
- if (item === void 0) throw new Error(`CapxulPaymentsV2 ABI has no ${name} function`);
1314
- return toFunctionSignature(item);
1315
- }
1316
- paymentsV2Signature("send");
1317
- paymentsV2Signature("sendBatch");
1318
- paymentsV2Signature("createCommitment");
1319
- paymentsV2Signature("cancel");
1320
- paymentsV2Signature("redirect");
1321
- new Map([
1322
- ["assignRoles(address,bytes32[],bool[])", "AssignRoles(address,bytes32[],bool[])"],
1323
- ["allowTarget(bytes32,address,uint8)", "AllowTarget(bytes32,address,uint8)"],
1324
- ["scopeTarget(bytes32,address)", "ScopeTarget(bytes32,address)"],
1325
- ["revokeTarget(bytes32,address)", "RevokeTarget(bytes32,address)"],
1326
- ["allowFunction(bytes32,address,bytes4,uint8)", "AllowFunction(bytes32,address,bytes4,uint8)"],
1327
- ["scopeFunction(bytes32,address,bytes4,(uint8,uint8,uint8,bytes)[],uint8)", "ScopeFunction(bytes32,address,bytes4,(uint8,uint8,uint8,bytes)[],uint8)"],
1328
- ["revokeFunction(bytes32,address,bytes4)", "RevokeFunction(bytes32,address,bytes4)"],
1329
- ["setAllowance(bytes32,uint128,uint128,uint128,uint64,uint64)", "SetAllowance(bytes32,uint128,uint128,uint128,uint64,uint64)"]
1330
- ].map(([functionSignature, eventSignature]) => [toFunctionSelector(functionSignature), toEventSelector(eventSignature)]));
1331
- //#endregion
1332
401
  //#region ../wire/src/brands.ts
1333
402
  const lowercasedString = Schema.String.pipe(Schema.decodeTo(Schema.String, {
1334
403
  decode: SchemaGetter.transform((value) => value.toLowerCase()),
@@ -3044,6 +2113,50 @@ function isSafeField(field, value) {
3044
2113
  return value.length > 0 && value.length <= rule.maxLength && value === value.trim() && !value.includes("://") && !containsSensitiveMaterial(value) && rule.pattern.test(value);
3045
2114
  }
3046
2115
  //#endregion
2116
+ //#region src/internal/invocation-observation.ts
2117
+ const INVOCATION_OBSERVATION = Symbol("capxul.invocation-observation");
2118
+ const FAILURE_INVOCATION_SNAPSHOT = Symbol("capxul.failure-invocation-snapshot");
2119
+ /** @internal Attach one immutable, non-wire invocation snapshot to an SDK-owned object. */
2120
+ function attachInvocationObservation(target, source) {
2121
+ const snapshot = Object.freeze(source.context === void 0 ? { active: source.active } : {
2122
+ active: source.active,
2123
+ context: Object.freeze({ ...source.context })
2124
+ });
2125
+ Object.defineProperty(target, INVOCATION_OBSERVATION, {
2126
+ configurable: false,
2127
+ enumerable: false,
2128
+ value: snapshot,
2129
+ writable: false
2130
+ });
2131
+ return target;
2132
+ }
2133
+ /** @internal Read the snapshot without exposing its symbol or adding a wire field. */
2134
+ function readInvocationObservation(source) {
2135
+ if (typeof source !== "object" || source === null) return void 0;
2136
+ return source[INVOCATION_OBSERVATION];
2137
+ }
2138
+ /** @internal Carry a snapshot across an SDK adapter projection without resolving again. */
2139
+ function copyInvocationObservation(source, target) {
2140
+ const snapshot = readInvocationObservation(source);
2141
+ return snapshot === void 0 ? target : attachInvocationObservation(target, snapshot);
2142
+ }
2143
+ /** @internal Carry the public call-start delivery decision with its failure envelope. */
2144
+ function markFailureInvocationSnapshot(failure, snapshot) {
2145
+ Object.defineProperty(failure, FAILURE_INVOCATION_SNAPSHOT, {
2146
+ configurable: false,
2147
+ enumerable: false,
2148
+ value: Object.freeze(snapshot),
2149
+ writable: false
2150
+ });
2151
+ return failure;
2152
+ }
2153
+ /** @internal Read the call-start delivery decision; undefined means a direct adapter call. */
2154
+ function readFailureInvocationSnapshot(failure) {
2155
+ if (typeof failure !== "object" || failure === null) return void 0;
2156
+ const snapshot = failure[FAILURE_INVOCATION_SNAPSHOT];
2157
+ return typeof snapshot === "object" && snapshot !== null && "active" in snapshot ? snapshot : void 0;
2158
+ }
2159
+ //#endregion
3047
2160
  //#region src/surface/_shared/provisioning-telemetry.ts
3048
2161
  async function emitProvisioningTelemetry(telemetry, smartAccount) {
3049
2162
  if (telemetry === void 0) return;
@@ -3121,9 +2234,29 @@ function* causeChain(cause) {
3121
2234
  current = current.cause;
3122
2235
  }
3123
2236
  }
2237
+ const SIGNER_NOT_READY_CODES = /* @__PURE__ */ new Set(["MISSING_SIGNER", "NOT_CONFIGURED"]);
2238
+ function isOpenfortSignerNotReadyCode(value) {
2239
+ return typeof value === "string" && SIGNER_NOT_READY_CODES.has(value);
2240
+ }
2241
+ /** Return the exact Openfort code that requires an embedded-signer rebuild. */
2242
+ function openfortSignerNotReadyCode(cause) {
2243
+ for (const link of causeChain(cause)) {
2244
+ const error = link;
2245
+ for (const value of [
2246
+ error.error,
2247
+ error.code,
2248
+ error.details?.provider_error_code
2249
+ ]) if (isOpenfortSignerNotReadyCode(value)) return value;
2250
+ }
2251
+ }
2252
+ /** Openfort's typed signal that its embedded signer state must be rebuilt. */
2253
+ function isSignerNotReadySignal(cause) {
2254
+ return openfortSignerNotReadyCode(cause) !== void 0;
2255
+ }
3124
2256
  /** Fold a signer throw into the public error contract. */
3125
2257
  function signerFailure(source, operation, cause) {
3126
2258
  let failureMode;
2259
+ const providerErrorCode = source === "openfort-embedded" ? openfortSignerNotReadyCode(cause) : void 0;
3127
2260
  for (const link of causeChain(cause)) {
3128
2261
  if (link instanceof CapxulError && link.code === "SIGNER_REJECTED") return link;
3129
2262
  failureMode = getFailureMode(link) ?? failureMode;
@@ -3132,8 +2265,15 @@ function signerFailure(source, operation, cause) {
3132
2265
  source,
3133
2266
  cause
3134
2267
  });
2268
+ if (providerErrorCode !== void 0) failureMode = "signer-not-ready";
3135
2269
  }
3136
- return Errors.providerError("signer", operation, cause, failureMode === void 0 ? void 0 : { failure_mode: failureMode });
2270
+ return Errors.providerError("signer", operation, cause, failureMode === void 0 && providerErrorCode === void 0 ? void 0 : {
2271
+ ...failureMode === void 0 ? {} : { failure_mode: failureMode },
2272
+ ...providerErrorCode === void 0 ? {} : { details: {
2273
+ provider_error_source: "openfort",
2274
+ provider_error_code: providerErrorCode
2275
+ } }
2276
+ });
3137
2277
  }
3138
2278
  /**
3139
2279
  * Browser `CapxulSigner` backed by an injected EIP-1193 wallet (MetaMask, etc.).
@@ -3185,50 +2325,6 @@ async function recoverRawDigestSigner(input) {
3185
2325
  }
3186
2326
  }
3187
2327
  //#endregion
3188
- //#region src/internal/invocation-observation.ts
3189
- const INVOCATION_OBSERVATION = Symbol("capxul.invocation-observation");
3190
- const FAILURE_INVOCATION_SNAPSHOT = Symbol("capxul.failure-invocation-snapshot");
3191
- /** @internal Attach one immutable, non-wire invocation snapshot to an SDK-owned object. */
3192
- function attachInvocationObservation(target, source) {
3193
- const snapshot = Object.freeze(source.context === void 0 ? { active: source.active } : {
3194
- active: source.active,
3195
- context: Object.freeze({ ...source.context })
3196
- });
3197
- Object.defineProperty(target, INVOCATION_OBSERVATION, {
3198
- configurable: false,
3199
- enumerable: false,
3200
- value: snapshot,
3201
- writable: false
3202
- });
3203
- return target;
3204
- }
3205
- /** @internal Read the snapshot without exposing its symbol or adding a wire field. */
3206
- function readInvocationObservation(source) {
3207
- if (typeof source !== "object" || source === null) return void 0;
3208
- return source[INVOCATION_OBSERVATION];
3209
- }
3210
- /** @internal Carry a snapshot across an SDK adapter projection without resolving again. */
3211
- function copyInvocationObservation(source, target) {
3212
- const snapshot = readInvocationObservation(source);
3213
- return snapshot === void 0 ? target : attachInvocationObservation(target, snapshot);
3214
- }
3215
- /** @internal Carry the public call-start delivery decision with its failure envelope. */
3216
- function markFailureInvocationSnapshot(failure, snapshot) {
3217
- Object.defineProperty(failure, FAILURE_INVOCATION_SNAPSHOT, {
3218
- configurable: false,
3219
- enumerable: false,
3220
- value: Object.freeze(snapshot),
3221
- writable: false
3222
- });
3223
- return failure;
3224
- }
3225
- /** @internal Read the call-start delivery decision; undefined means a direct adapter call. */
3226
- function readFailureInvocationSnapshot(failure) {
3227
- if (typeof failure !== "object" || failure === null) return void 0;
3228
- const snapshot = failure[FAILURE_INVOCATION_SNAPSHOT];
3229
- return typeof snapshot === "object" && snapshot !== null && "active" in snapshot ? snapshot : void 0;
3230
- }
3231
- //#endregion
3232
2328
  //#region src/domain/machine/telemetry.ts
3233
2329
  const definedEntries = (values) => Object.fromEntries(Object.entries(values).filter((entry) => entry[1] !== void 0));
3234
2330
  const SAFE_ENGINEERING_ID = /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u;
@@ -3690,21 +2786,27 @@ async function runIdentityFacade(verb, controls, run, runPromise = Effect.runPro
3690
2786
  async function runPortEffect(effect, controls, operation = "port", runPromise = Effect.runPromise) {
3691
2787
  const deadlineDelay = controls?.deadlineMs === void 0 ? void 0 : Math.max(0, controls.deadlineMs - Date.now());
3692
2788
  const timeoutMs = controls?.timeoutMs === void 0 ? deadlineDelay : deadlineDelay === void 0 ? controls.timeoutMs : Math.min(controls.timeoutMs, deadlineDelay);
3693
- const observed = (timeoutMs === void 0 ? effect : effect.pipe(Effect.timeoutOrElse({
2789
+ return runCapxulEffect((timeoutMs === void 0 ? effect : effect.pipe(Effect.timeoutOrElse({
3694
2790
  duration: `${timeoutMs} millis`,
3695
2791
  orElse: () => Effect.fail({ publicError: Errors.providerTimeout("sdk", operation, timeoutMs) })
3696
- }))).pipe(Effect.tap(() => Effect.annotateCurrentSpan({ outcome: "succeeded" })), Effect.tapError((failure) => {
3697
- const mode = failure.publicError.details?.failure_mode;
2792
+ }))).pipe(Effect.mapError((failure) => failure.publicError)), controls, operation, runPromise);
2793
+ }
2794
+ /** Observe a public Effect that already uses the canonical CapxulError channel. */
2795
+ async function runCapxulEffect(effect, controls, operation = "port", runPromise = Effect.runPromise) {
2796
+ const invocation = readInvocationObservation(controls);
2797
+ const correlationId = safeEngineeringIdentifier(controls?.correlation_id ?? invocation?.context?.correlationId);
2798
+ const observed = effect.pipe(Effect.tap(() => Effect.annotateCurrentSpan({ outcome: "succeeded" })), Effect.tapError((error) => {
2799
+ const mode = error.mode ?? error.details?.failure_mode;
3698
2800
  return Effect.annotateCurrentSpan({
3699
- outcome: portFailureOutcome(failure.publicError.code),
3700
- failure_code: failure.publicError.code,
2801
+ outcome: portFailureOutcome(error.code),
2802
+ failure_code: error.code,
3701
2803
  ...typeof mode === "string" ? { mode } : {}
3702
2804
  });
3703
2805
  }), Effect.tapDefect(() => Effect.annotateCurrentSpan({
3704
2806
  outcome: "failed",
3705
2807
  failure_code: "UNKNOWN"
3706
- })), Effect.withSpan(`identity.port.${operation}`));
3707
- return runIfActive(controls?.signal, operation, () => withInvocationParentSpan(observed, controls), runPromise);
2808
+ })), Effect.withSpan(`identity.port.${operation}`), Effect.annotateSpans(correlationId === void 0 ? {} : { correlation_id: correlationId }));
2809
+ return runIfActive(controls?.signal, operation, () => withInvocationParentSpan(observed, controls).pipe(Effect.mapError((publicError) => ({ publicError }))), runPromise);
3708
2810
  }
3709
2811
  /** Map machine-internal failure state onto the public SDK error vocabulary. */
3710
2812
  function publicIdentityFailure(failure) {
@@ -4419,7 +3521,7 @@ function makeAccountMethods(deps) {
4419
3521
  value: provisioningPhase(deps.actor.snapshot())
4420
3522
  };
4421
3523
  };
4422
- const resolveLifecycle = async () => {
3524
+ const resolveLifecycle = async (controls) => {
4423
3525
  const phase = provisioningPhase(deps.actor.snapshot());
4424
3526
  const status = await getStatus();
4425
3527
  if (!status.ok) return accountFailureResult(status.error);
@@ -4427,7 +3529,7 @@ function makeAccountMethods(deps) {
4427
3529
  if (status.value.status !== "notAuthenticated" && (phase.status === "ready" || isRequirementMet(status.value, requirement))) {
4428
3530
  const accountReadPort = deps.accountReadPort;
4429
3531
  if (accountReadPort === void 0) return accountFailureResult(Errors.invalidInput("account", "accountReadPort is required to resolve ready lifecycle"));
4430
- const account = await runPortEffect(accountReadPort.readBalance({ chainId: toChainId(deps.chainId) }));
3532
+ const account = await runPortEffect(accountReadPort.readBalance(copyInvocationObservation(controls, { chainId: toChainId(deps.chainId) })), controls, "accounts.read", deps.runPromise);
4431
3533
  if (!account.ok) return accountFailureResult(account.error);
4432
3534
  accountId = String(account.value.id);
4433
3535
  }
@@ -4441,8 +3543,9 @@ function makeAccountMethods(deps) {
4441
3543
  })
4442
3544
  };
4443
3545
  };
4444
- const getLifecycle = () => resolveLifecycle();
3546
+ const getLifecycle = () => resolveLifecycle(deps.invocationControls?.());
4445
3547
  const retrySetup = async () => {
3548
+ const controls = deps.invocationControls?.();
4446
3549
  const resetSession = deps.signer?.resetSession;
4447
3550
  if (typeof resetSession === "function") try {
4448
3551
  resetSession.call(deps.signer);
@@ -4451,7 +3554,7 @@ function makeAccountMethods(deps) {
4451
3554
  }
4452
3555
  const retried = await drive({ _tag: "RetryAccount" });
4453
3556
  if (!retried.ok) return accountFailureResult(retried.error);
4454
- return resolveLifecycle();
3557
+ return resolveLifecycle(controls);
4455
3558
  };
4456
3559
  return {
4457
3560
  methods: {
@@ -4511,146 +3614,45 @@ const moneyExecutionContract = {
4511
3614
  };
4512
3615
  //#endregion
4513
3616
  //#region package.json
4514
- var version = "2.8.0";
3617
+ var version = "3.0.0";
4515
3618
  //#endregion
4516
- //#region src/telemetry/stack-frame-parser.ts
4517
- /**
4518
- * Regex for V8/Chrome stack trace frame lines.
4519
- * Matches:
4520
- * `at functionName (url:line:col)`
4521
- * `at url:line:col`
4522
- * `at async functionName (url:line:col)`
4523
- * `at new ClassName (url:line:col)`
4524
- */
4525
- const V8_FRAME_RE = /^\s*at\s+(?:(.+?)\s+\()?(?:(.+?)(?::(\d+):(\d+))?|(.+?))\)?\s*$/;
4526
- function isNonUrlName(name) {
4527
- return name === "<anonymous>" || name.startsWith("eval") || name.startsWith("new ") || name.startsWith("async ");
4528
- }
4529
- /**
4530
- * Parse a V8/Chrome-style stack trace string into PostHog `ExceptionFrame` objects.
4531
- * Returns an empty array when `error.stack` is absent or empty.
4532
- *
4533
- * Handles:
4534
- * - Standard `at functionName (url:line:col)`
4535
- * - Bare `at url:line:col` (no function name)
4536
- * - `at async functionName (url:line:col)`
4537
- * - `at new ClassName (url:line:col)`
4538
- * - Native frames: `at Array.forEach (<anonymous>)`
4539
- */
4540
- function parseV8StackFrames(error) {
4541
- const stack = error.stack;
4542
- if (stack === void 0 || stack === null || stack === "") return [];
4543
- const lines = stack.split("\n");
4544
- const frames = [];
4545
- for (const line of lines) {
4546
- const trimmed = line.trim();
4547
- if (!trimmed.startsWith("at ")) continue;
4548
- const match = V8_FRAME_RE.exec(trimmed);
4549
- if (match === null) continue;
4550
- if (match[1] !== void 0) frames.push({
4551
- function: match[1],
4552
- filename: match[2],
4553
- lineno: match[3] !== void 0 ? Number(match[3]) : null,
4554
- colno: match[4] !== void 0 ? Number(match[4]) : null
4555
- });
4556
- else if (match[2] !== void 0 && !isNonUrlName(match[2])) frames.push({
4557
- function: "<anonymous>",
4558
- filename: match[2],
4559
- lineno: match[3] !== void 0 ? Number(match[3]) : null,
4560
- colno: match[4] !== void 0 ? Number(match[4]) : null
4561
- });
4562
- else frames.push({
4563
- function: match[1] ?? match[2] ?? match[5] ?? "<anonymous>",
4564
- filename: match[2] ?? match[5] ?? "<anonymous>",
4565
- lineno: match[3] !== void 0 ? Number(match[3]) : null,
4566
- colno: match[4] !== void 0 ? Number(match[4]) : null
4567
- });
4568
- }
4569
- return frames;
3619
+ //#region src/telemetry/exception-projection.ts
3620
+ /** Fixed fallback for failures that have no safe message. */
3621
+ const EXCEPTION_MESSAGE = "Capxul SDK operation failed";
3622
+ const SDK_VERSION = version;
3623
+ /** The one PostHog Error Tracking projection for every SDK exception emitter. */
3624
+ function projectSdkException(input) {
3625
+ const operation = normalizeExceptionOperation(input.operation);
3626
+ const errorKind = normalizeExceptionErrorKind(input.errorKind);
3627
+ const mode = isFailureMode(input.failureMode) ? input.failureMode : void 0;
3628
+ const message = input.message ?? "Capxul SDK operation failed";
3629
+ const where = input.chainUpstream === void 0 ? "" : ` on ${input.chainUpstream}${input.chainMethod === void 0 ? "" : ` during ${input.chainMethod}`}`;
3630
+ return {
3631
+ ...input.properties,
3632
+ sdk_version: input.sdkVersion,
3633
+ operation,
3634
+ error_kind: errorKind,
3635
+ handled: true,
3636
+ $exception_type: errorKind,
3637
+ $exception_message: message,
3638
+ $exception_level: "error",
3639
+ $exception_fingerprint: failureFingerprint(errorKind, mode, operation),
3640
+ $issue_name: `${errorKind}${mode === void 0 ? "" : `: ${mode}`}${where} (${operation})`,
3641
+ $issue_description: input.issueDescription ?? message,
3642
+ $exception_list: input.exceptionList
3643
+ };
4570
3644
  }
4571
- /** Fixed, leak-safe frame used when the error carries no parseable stack. */
4572
- const SDK_BOUNDARY_FILENAME = "capxul-sdk-observation://boundary";
4573
- /**
4574
- * Build PostHog's `$exception_list` (always a single entry). Error Tracking
4575
- * groups on `type`, so it is ALWAYS present (the CapxulError code) — the
4576
- * previous `[{ frames }]` shape omitted it and PostHog dropped the event as
4577
- * "missing field `type`". When the error has no parseable stack, a synthetic
4578
- * boundary frame stands in so the event still ingests as a real Issue (#1031).
4579
- */
4580
- function buildExceptionList(input) {
4581
- const frames = input.frames.length > 0 ? input.frames : [{
4582
- filename: SDK_BOUNDARY_FILENAME,
4583
- function: input.operation ?? "unknown",
4584
- lineno: 1,
4585
- colno: 1
4586
- }];
4587
- return [{
4588
- type: input.type,
4589
- value: input.value,
4590
- mechanism: {
4591
- handled: true,
4592
- type: "capxul_sdk_boundary"
4593
- },
4594
- stacktrace: { frames }
4595
- }];
3645
+ function normalizeExceptionOperation(value) {
3646
+ return typeof value === "string" && /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,255}$/u.test(value) ? value : "unknown";
4596
3647
  }
4597
- //#endregion
4598
- //#region src/telemetry/capture-exception.ts
4599
- /** Fixed, leak-safe message — the raw error message may carry PII and never ships. */
4600
- const EXCEPTION_MESSAGE = "Capxul SDK operation failed";
4601
- /**
4602
- * Capture an error as a `$exception` event through the telemetry port,
4603
- * formatted for PostHog Error Tracking.
4604
- *
4605
- * Parses stack traces into `$exception_list` format, extracts structured
4606
- * metadata from CapxulError objects, and supplements with context props.
4607
- * Fire-and-forget: telemetry defects are silently swallowed.
4608
- * Returns `Effect<void, never>` for use in Effect pipelines; the underlying
4609
- * adapter work is synchronous, so callers outside Effect contexts can
4610
- * use `Effect.runSync`.
4611
- */
4612
- function captureException(telemetry, error, context) {
4613
- return Effect.catchDefect(Effect.sync(() => {
4614
- const frames = error instanceof Error ? parseV8StackFrames(error) : [];
4615
- const capxulError = isCapxulError(error) ? error : null;
4616
- const errorCode = capxulError?.code ?? context?.capxul_error_code ?? "UNKNOWN";
4617
- const props = {
4618
- capxul_error_code: errorCode,
4619
- $exception_type: errorCode,
4620
- $exception_message: EXCEPTION_MESSAGE,
4621
- $exception_list: buildExceptionList({
4622
- type: errorCode,
4623
- value: EXCEPTION_MESSAGE,
4624
- ...context?.operation === void 0 ? {} : { operation: context.operation },
4625
- frames
4626
- }),
4627
- layer: capxulError?.layer ?? context?.layer,
4628
- operation: context?.operation,
4629
- provider: context?.provider,
4630
- failure_mode: resolveFailureMode(error, context?.failure_mode)
4631
- };
4632
- if (capxulError?.details !== void 0) props.details = JSON.stringify(capxulError.details);
4633
- for (const key of Object.keys(props)) if (props[key] === void 0) delete props[key];
4634
- return telemetry.emit({
4635
- name: "$exception",
4636
- props
4637
- });
4638
- }).pipe(Effect.flatten), () => Effect.void);
3648
+ function normalizeExceptionErrorKind(value) {
3649
+ return safeExceptionLabel(value) ?? "UNKNOWN";
4639
3650
  }
4640
- /**
4641
- * Synchronous fire-and-forget capture. Runs the Effect inline with
4642
- * `Effect.runSync` so callers outside an Effect context can report errors
4643
- * without awaiting. Core SDK public methods use the assembled observation
4644
- * boundary instead.
4645
- */
4646
- function captureExceptionSync(telemetry, error, context) {
4647
- try {
4648
- Effect.runSync(captureException(telemetry, error, context));
4649
- } catch {}
3651
+ function safeExceptionLabel(value) {
3652
+ return typeof value === "string" && /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/u.test(value) ? value : void 0;
4650
3653
  }
4651
3654
  //#endregion
4652
3655
  //#region src/observation.ts
4653
- const SDK_VERSION = version;
4654
3656
  /** Stable PostHog event used for typed failures that are expected product outcomes. */
4655
3657
  const CAPXUL_SDK_EXPECTED_OUTCOME_EVENT = "capxul_sdk_expected_outcome";
4656
3658
  /**
@@ -4676,13 +3678,13 @@ function postHogFailureObservation(policy, fixedSnapshot) {
4676
3678
  }));
4677
3679
  return;
4678
3680
  }
4679
- policy.deliver(() => policy.client.capture("$exception", postHogExceptionProperties(safeFailure, properties)));
3681
+ policy.deliver(() => policy.client.capture("$exception", projectFailureException(safeFailure, properties)));
4680
3682
  };
4681
3683
  const captureException = (failure) => {
4682
3684
  const prepared = prepare(failure);
4683
3685
  if (prepared === void 0 || policy.client === null || policy.client === void 0) return;
4684
3686
  const [safeFailure, properties] = prepared;
4685
- policy.deliver(() => policy.client.capture("$exception", postHogExceptionProperties(safeFailure, properties)));
3687
+ policy.deliver(() => policy.client.capture("$exception", projectFailureException(safeFailure, properties)));
4686
3688
  };
4687
3689
  return {
4688
3690
  resolveContext: () => {
@@ -4809,7 +3811,7 @@ function report(adapter, kind, operation, cause, invocation, origin) {
4809
3811
  }
4810
3812
  } else if (reportedByMachine(cause)) return;
4811
3813
  const operationName = normalizeOperation(operation);
4812
- const kindName = normalizeErrorKind(errorKind$1(cause));
3814
+ const kindName = normalizeErrorKind(errorKind(cause));
4813
3815
  const context = sanitizeObservationContext({
4814
3816
  ...invocation.context,
4815
3817
  ...isCapxulError(cause) && cause.correlationId !== void 0 ? { correlationId: cause.correlationId } : {}
@@ -4893,19 +3895,20 @@ function postHogProperties(failure, context) {
4893
3895
  ...observationContextProps(merged)
4894
3896
  };
4895
3897
  }
4896
- function postHogExceptionProperties(failure, properties) {
3898
+ function projectFailureException(failure, properties) {
4897
3899
  const filename = `capxul-sdk-observation://boundary/${failure.operation}`;
4898
3900
  const message = failure.message ?? "Capxul SDK operation failed";
4899
- const mode = failure.detail?.failure_mode;
4900
- return {
4901
- ...properties,
4902
- $exception_type: failure.errorKind,
4903
- $exception_message: message,
4904
- $exception_level: "error",
4905
- $exception_fingerprint: failureFingerprint(failure.errorKind, isFailureMode(mode) ? mode : void 0, failure.operation),
4906
- $issue_name: issueName(failure, isFailureMode(mode) ? mode : void 0),
4907
- $issue_description: issueDescription(failure, message),
4908
- $exception_list: [{
3901
+ return projectSdkException({
3902
+ properties,
3903
+ sdkVersion: failure.sdkVersion,
3904
+ operation: failure.operation,
3905
+ errorKind: failure.errorKind,
3906
+ failureMode: failure.detail?.failure_mode,
3907
+ message,
3908
+ issueDescription: issueDescription(failure, message),
3909
+ ...failure.detail?.chain_upstream === void 0 ? {} : { chainUpstream: failure.detail.chain_upstream },
3910
+ ...failure.detail?.chain_method === void 0 ? {} : { chainMethod: failure.detail.chain_method },
3911
+ exceptionList: [{
4909
3912
  type: failure.errorKind,
4910
3913
  value: message,
4911
3914
  mechanism: {
@@ -4926,7 +3929,7 @@ function postHogExceptionProperties(failure, properties) {
4926
3929
  },
4927
3930
  ...failure.stack === void 0 ? {} : { stack: failure.stack }
4928
3931
  }]
4929
- };
3932
+ });
4930
3933
  }
4931
3934
  /**
4932
3935
  * The decoded revert leads the description: the provider's own message masks
@@ -4944,13 +3947,6 @@ function issueDescription(failure, message) {
4944
3947
  });
4945
3948
  return providerMessage === void 0 ? revert : `${revert}; ${providerMessage}`;
4946
3949
  }
4947
- function issueName(failure, mode) {
4948
- const upstream = failure.detail?.chain_upstream;
4949
- const method = failure.detail?.chain_method;
4950
- const cause = mode === void 0 ? "" : `: ${mode}`;
4951
- const where = typeof upstream !== "string" ? "" : ` on ${upstream}${typeof method === "string" ? ` during ${method}` : ""}`;
4952
- return `${failure.errorKind}${cause}${where} (${failure.operation})`;
4953
- }
4954
3950
  const MAX_EVIDENCE_TEXT = 4e3;
4955
3951
  const MAX_CAUSE_DEPTH = 8;
4956
3952
  function evidenceText(value) {
@@ -5017,7 +4013,7 @@ function failureEvidence(cause) {
5017
4013
  return {};
5018
4014
  }
5019
4015
  }
5020
- function errorKind$1(cause) {
4016
+ function errorKind(cause) {
5021
4017
  try {
5022
4018
  if (isCapxulError(cause)) return normalizeErrorKind(cause.code);
5023
4019
  if (cause instanceof Error) return normalizeErrorKind(cause.name);
@@ -5054,18 +4050,45 @@ function sanitizeFailureObservation(failure) {
5054
4050
  * Shared by the failure boundary and the `bootstrap_failed` product event.
5055
4051
  */
5056
4052
  function failureDetail(cause) {
5057
- if (!isCapxulError(cause)) return void 0;
5058
- const details = cause.details;
4053
+ const error = observationError(cause);
4054
+ if (error === void 0) return void 0;
4055
+ const details = error.details;
5059
4056
  const source = typeof details === "object" && details !== null ? details : {};
5060
4057
  return sanitizeFailureDetail({
5061
4058
  provider: source.provider,
5062
4059
  provider_operation: source.operation,
5063
- failure_mode: cause.mode ?? source.failure_mode,
4060
+ provider_error_source: source.provider_error_source,
4061
+ provider_error_code: source.provider_error_code,
4062
+ target_host: source.target_host,
4063
+ failure_mode: error.mode ?? source.failure_mode,
5064
4064
  reason: source.reason,
5065
4065
  http_status: source.httpStatus,
5066
- ...cause.chain === void 0 ? {} : chainCauseProperties(cause.chain)
4066
+ connection_id: source.connection_id,
4067
+ connection_count: source.connection_count,
4068
+ connection_retries: source.connection_retries,
4069
+ close_code: source.close_code,
4070
+ close_was_clean: source.close_was_clean,
4071
+ close_reason_present: source.close_reason_present,
4072
+ document_visibility: source.document_visibility,
4073
+ navigator_online: source.navigator_online,
4074
+ last_browser_event: source.last_browser_event,
4075
+ ms_since_browser_event: source.ms_since_browser_event,
4076
+ ...error.chain === void 0 ? {} : chainCauseProperties(error.chain)
5067
4077
  });
5068
4078
  }
4079
+ const CAPXUL_ERROR_CODE_SET = new Set(CAPXUL_ERROR_CODES);
4080
+ function observationError(cause) {
4081
+ if (isCapxulError(cause)) return cause;
4082
+ if (typeof cause !== "object" || cause === null) return void 0;
4083
+ const candidate = cause;
4084
+ if (typeof candidate.code !== "string" || !CAPXUL_ERROR_CODE_SET.has(candidate.code) || typeof candidate.message !== "string") return;
4085
+ const chain = decodeChainCause(candidate.chain);
4086
+ return {
4087
+ ...candidate.details === void 0 ? {} : { details: candidate.details },
4088
+ ...candidate.mode === void 0 ? {} : { mode: candidate.mode },
4089
+ ...chain === null ? {} : { chain }
4090
+ };
4091
+ }
5069
4092
  /** The chain-cause half of {@link sanitizeFailureDetail}: same bounds, same masking. */
5070
4093
  function sanitizeChainDetail(source, detail) {
5071
4094
  for (const key of [
@@ -5077,6 +4100,7 @@ function sanitizeChainDetail(source, detail) {
5077
4100
  const value = source[key];
5078
4101
  if (typeof value === "string" && ENUMERATED_DETAIL_RE.test(value)) detail[key] = value;
5079
4102
  }
4103
+ sanitizeProviderErrorDetail(source, detail);
5080
4104
  const status = source.http_status;
5081
4105
  if (typeof status === "number" && Number.isInteger(status) && status >= 100 && status <= 599) detail.http_status = status;
5082
4106
  for (const key of [
@@ -5105,15 +4129,51 @@ function sanitizeChainDetail(source, detail) {
5105
4129
  const providerMessage = evidenceText(source.chain_provider_message);
5106
4130
  if (providerMessage !== void 0) detail.chain_provider_message = providerMessage;
5107
4131
  }
4132
+ function sanitizeProviderErrorDetail(source, detail) {
4133
+ if (source.provider_error_source !== "openfort") return;
4134
+ detail.provider_error_source = "openfort";
4135
+ if (isOpenfortSignerNotReadyCode(source.provider_error_code)) detail.provider_error_code = source.provider_error_code;
4136
+ }
4137
+ function sanitizeConnectionDetail(source, detail) {
4138
+ const targetHost = source.target_host;
4139
+ if (typeof targetHost === "string" && TARGET_HOST_RE.test(targetHost)) detail.target_host = targetHost;
4140
+ for (const key of [
4141
+ "connection_id",
4142
+ "document_visibility",
4143
+ "last_browser_event"
4144
+ ]) {
4145
+ const value = source[key];
4146
+ if (typeof value === "string" && ENUMERATED_DETAIL_RE.test(value)) detail[key] = value;
4147
+ }
4148
+ for (const key of [
4149
+ "connection_count",
4150
+ "connection_retries",
4151
+ "close_code",
4152
+ "ms_since_browser_event"
4153
+ ]) {
4154
+ const value = source[key];
4155
+ if (typeof value === "number" && Number.isSafeInteger(value) && value >= 0 && (key !== "close_code" || value <= 4999)) detail[key] = value;
4156
+ }
4157
+ for (const key of [
4158
+ "close_was_clean",
4159
+ "close_reason_present",
4160
+ "navigator_online"
4161
+ ]) {
4162
+ const value = source[key];
4163
+ if (typeof value === "boolean") detail[key] = value;
4164
+ }
4165
+ }
5108
4166
  function sanitizeFailureDetail(input) {
5109
4167
  if (typeof input !== "object" || input === null) return void 0;
5110
4168
  const source = input;
5111
4169
  const detail = {};
4170
+ sanitizeConnectionDetail(source, detail);
5112
4171
  sanitizeChainDetail(source, detail);
5113
4172
  return Object.keys(detail).length === 0 ? void 0 : detail;
5114
4173
  }
5115
4174
  /** Enumerated codes only (`convex`, `no-secure-context`, `bootstrap-encode`); free text fails. */
5116
4175
  const ENUMERATED_DETAIL_RE = /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/u;
4176
+ const TARGET_HOST_RE = /^[A-Za-z0-9.[\]:-]{1,253}$/u;
5117
4177
  /** A four-byte revert selector, or the bare `0x` of an empty revert. */
5118
4178
  const REVERT_SELECTOR_RE = /^0x(?:[0-9a-fA-F]{8})?$/u;
5119
4179
  function normalizeSdkVersion(value) {
@@ -6222,42 +5282,6 @@ function mapOk(result, f) {
6222
5282
  }
6223
5283
  }
6224
5284
  //#endregion
6225
- //#region src/ports/auth-client.ts
6226
- var AuthClientError = class extends Data.TaggedError("AuthClientError") {};
6227
- var AuthClientPortTag = class extends Context.Service()("@capxul/sdk/ports/AuthClientPort") {};
6228
- //#endregion
6229
- //#region src/adapters/auth-client/effect-port.ts
6230
- function authClientPortFromPromiseAdapter(adapter) {
6231
- return {
6232
- canSendOtp: (input, options) => fromResult("canSendOtp", () => adapter.canSendOtp(input, options)),
6233
- sendOtp: (input, options) => fromResult("sendOtp", () => adapter.sendOtp(input, options)),
6234
- verifyOtp: (input, options) => fromResult("verifyOtp", () => adapter.verifyOtp(input, options)),
6235
- getSession: (options) => fromResult("getSession", () => adapter.getSession(options)),
6236
- signOut: (options) => fromResult("signOut", () => adapter.signOut(options)),
6237
- getConvexJwt: (options) => fromResult("getConvexJwt", () => adapter.getConvexJwt(options))
6238
- };
6239
- }
6240
- function fromResult(operation, run) {
6241
- return Effect.tryPromise({
6242
- try: run,
6243
- catch: (cause) => new AuthClientError({
6244
- operation,
6245
- kind: "thrown",
6246
- cause
6247
- })
6248
- }).pipe(Effect.flatMap((result) => result.ok ? Effect.succeed(result.value) : Effect.fail(new AuthClientError({
6249
- operation,
6250
- kind: errorKind(result.error),
6251
- cause: result.error
6252
- }))));
6253
- }
6254
- function errorKind(error) {
6255
- if (error.code === "CANCELLED") return "cancelled";
6256
- if (error.code === "NETWORK_ERROR") return "network";
6257
- if (error.code === "INVALID_INPUT" || error.code === "OTP_EXPIRED") return "validation";
6258
- return "provider";
6259
- }
6260
- //#endregion
6261
5285
  //#region src/ports/bootstrap.ts
6262
5286
  var BootstrapError = class extends Data.TaggedError("BootstrapError") {};
6263
5287
  function bootstrapErrorFromCapxul(kind, error) {
@@ -6271,19 +5295,16 @@ function bootstrapErrorFromCapxul(kind, error) {
6271
5295
  }
6272
5296
  var BootstrapPortTag = class extends Context.Service()("@capxul/sdk/ports/BootstrapPort") {};
6273
5297
  //#endregion
6274
- //#region src/ports/clock.ts
6275
- var ClockError = class extends Data.TaggedError("ClockError") {};
6276
- var ClockPortTag = class extends Context.Service()("@capxul/sdk/ports/ClockPort") {};
6277
- //#endregion
6278
5298
  //#region src/ports/convex-call.ts
6279
5299
  var ConvexCallError = class extends Data.TaggedError("ConvexCallError") {};
6280
- function convexCallErrorFromCapxul(operation, error) {
5300
+ function convexCallErrorFromCapxul(operation, error, transport) {
6281
5301
  return new ConvexCallError({
6282
5302
  operation,
6283
5303
  publicCode: error.code,
6284
5304
  publicError: error,
6285
5305
  cause: error,
6286
- ...error.details === void 0 ? {} : { details: error.details }
5306
+ ...error.details === void 0 ? {} : { details: error.details },
5307
+ ...transport === void 0 ? {} : { transport }
6287
5308
  });
6288
5309
  }
6289
5310
  var ConvexCallPortTag = class extends Context.Service()("@capxul/sdk/ports/ConvexCallPort") {};
@@ -6324,31 +5345,56 @@ function wireChainId(chainId) {
6324
5345
  return chainId;
6325
5346
  }
6326
5347
  //#endregion
6327
- //#region src/ports/account-read.ts
6328
- var AccountReadError = class extends Data.TaggedError("AccountReadError") {};
6329
- function accountReadErrorFromCapxul(operation, error, cause = error) {
6330
- return new AccountReadError({
6331
- operation,
6332
- publicCode: error.code,
6333
- publicError: error,
6334
- cause,
6335
- ...error.details === void 0 ? {} : { details: error.details }
6336
- });
5348
+ //#region src/telemetry/invocation.ts
5349
+ const PRODUCT_INVOCATION = Symbol("capxul.product-telemetry-invocation");
5350
+ function bindProductTelemetryInvocation(telemetry, source) {
5351
+ return telemetry[PRODUCT_INVOCATION]?.(source) ?? telemetry;
6337
5352
  }
6338
- var AccountReadPortTag = class extends Context.Service()("@capxul/sdk/ports/AccountReadPort") {};
6339
5353
  //#endregion
6340
- //#region src/ports/smart-account.ts
6341
- var SmartAccountError = class extends Data.TaggedError("SmartAccountError") {};
6342
- function smartAccountErrorFromCapxul(operation, error, cause = error) {
6343
- return new SmartAccountError({
6344
- operation,
6345
- publicCode: error.code,
6346
- publicError: error,
6347
- cause,
6348
- ...error.details === void 0 ? {} : { details: error.details }
5354
+ //#region src/adapters/convex-call/retry-idempotent-read.ts
5355
+ const MAX_RETRIES = 2;
5356
+ function isConnectionLoss(error) {
5357
+ return error.publicCode === "NETWORK_ERROR" && error.publicError.mode === "upstream-down" && error.publicError.details?.reason === "connection-lost-in-flight";
5358
+ }
5359
+ function retryIdempotentRead(effect, operation, telemetry, invocationSource) {
5360
+ return Effect.suspend(() => {
5361
+ let attempt = 0;
5362
+ const invocationTelemetry = telemetry === void 0 ? void 0 : bindProductTelemetryInvocation(telemetry, invocationSource);
5363
+ return effect.pipe(Effect.tapError((error) => {
5364
+ if (!isConnectionLoss(error) || attempt >= MAX_RETRIES) return Effect.void;
5365
+ attempt += 1;
5366
+ const eventFields = {
5367
+ operation,
5368
+ failure_mode: "upstream-down",
5369
+ reason: "connection-lost-in-flight",
5370
+ attempt,
5371
+ delay_ms: 0,
5372
+ ...error.transport === void 0 ? {} : {
5373
+ connection_id: error.transport.connection_id,
5374
+ connection_count: error.transport.connection_count
5375
+ }
5376
+ };
5377
+ const transport = error.transport;
5378
+ const connection = transport === void 0 ? void 0 : omitTransportKind(transport);
5379
+ const log = Effect.logInfo("capxul.operation.retried").pipe(Effect.annotateLogs(connection === void 0 ? eventFields : {
5380
+ ...eventFields,
5381
+ ...connection
5382
+ }), Effect.catchCause(() => Effect.void));
5383
+ if (invocationTelemetry === void 0) return log;
5384
+ return log.pipe(Effect.andThen(invocationTelemetry.emit({
5385
+ name: "operation_retried",
5386
+ props: eventFields
5387
+ })), Effect.catchCause(() => Effect.void));
5388
+ }), Effect.retry({
5389
+ times: MAX_RETRIES,
5390
+ while: isConnectionLoss
5391
+ }));
6349
5392
  });
6350
5393
  }
6351
- var SmartAccountPortTag = class extends Context.Service()("@capxul/sdk/ports/SmartAccountPort") {};
5394
+ function omitTransportKind(transport) {
5395
+ const { kind: _kind, ...connection } = transport;
5396
+ return connection;
5397
+ }
6352
5398
  //#endregion
6353
5399
  //#region ../observability/src/index.ts
6354
5400
  const PII = Schema.String.pipe(Schema.brand("PII"));
@@ -6500,7 +5546,10 @@ const BootstrapFailedProps = Schema.Struct({
6500
5546
  applicationId: OptionalAppId,
6501
5547
  durationMs: OptionalDurationMs,
6502
5548
  origin: OptionalString,
6503
- reason: OptionalString
5549
+ provider: OptionalString,
5550
+ provider_operation: OptionalString,
5551
+ reason: OptionalString,
5552
+ target_host: OptionalString
6504
5553
  });
6505
5554
  const AccountBalanceReadProps = Schema.Struct({
6506
5555
  ...TelemetryEnvelopeProps,
@@ -6565,6 +5614,9 @@ const OperationRetriedProps = Schema.Struct({
6565
5614
  ...TelemetryEnvelopeProps,
6566
5615
  operation: Schema.String,
6567
5616
  failure_mode: FailureModeSchema,
5617
+ reason: Schema.optional(Schema.Literal("connection-lost-in-flight")),
5618
+ connection_id: OptionalString,
5619
+ connection_count: Schema.optional(Schema.Number),
6568
5620
  attempt: Schema.Number,
6569
5621
  delay_ms: DurationMsSchema
6570
5622
  });
@@ -6741,7 +5793,9 @@ const PaymentVerificationRetryProps = Schema.Struct({
6741
5793
  command_id: Schema.String,
6742
5794
  attempt: Schema.Number,
6743
5795
  reason_code: Schema.String,
6744
- chain_id: Schema.Number
5796
+ chain_id: Schema.Number,
5797
+ delay_ms: DurationMsSchema,
5798
+ outcome: Schema.Literals(["scheduled", "unresolved"])
6745
5799
  });
6746
5800
  const DepositInitiatedProps = Schema.Struct({ ...TelemetryEnvelopeProps });
6747
5801
  const DepositSettledProps = Schema.Struct({
@@ -6982,7 +6036,7 @@ function redactTelemetryEvent(event, options = {}) {
6982
6036
  }
6983
6037
  function redactTelemetryProps(name, props, options = {}) {
6984
6038
  if (props === void 0) return void 0;
6985
- const clone = cloneProps$1(props);
6039
+ const clone = cloneProps(props);
6986
6040
  if (options.rawMode === true) return clone;
6987
6041
  for (const key of PII_PROP_KEYS_BY_EVENT[name] ?? []) redactProperty(clone, key);
6988
6042
  return clone;
@@ -6997,17 +6051,17 @@ function redactProperty(props, key) {
6997
6051
  const value = props[key];
6998
6052
  if (typeof value === "string") props[key] = sha256Hex(value).slice(0, 12);
6999
6053
  }
7000
- function cloneProps$1(props) {
6054
+ function cloneProps(props) {
7001
6055
  const cloned = {};
7002
- for (const [key, value] of Object.entries(props)) cloned[key] = cloneTelemetryValue$1(value);
6056
+ for (const [key, value] of Object.entries(props)) cloned[key] = cloneTelemetryValue(value);
7003
6057
  return cloned;
7004
6058
  }
7005
- function cloneTelemetryValue$1(value) {
7006
- if (Array.isArray(value)) return value.map(cloneTelemetryValue$1);
6059
+ function cloneTelemetryValue(value) {
6060
+ if (Array.isArray(value)) return value.map(cloneTelemetryValue);
7007
6061
  if (value === null || typeof value !== "object") return value;
7008
6062
  if (Object.getPrototypeOf(value) !== Object.prototype) return value;
7009
6063
  const cloned = {};
7010
- for (const [key, nested] of Object.entries(value)) cloned[key] = cloneTelemetryValue$1(nested);
6064
+ for (const [key, nested] of Object.entries(value)) cloned[key] = cloneTelemetryValue(nested);
7011
6065
  return cloned;
7012
6066
  }
7013
6067
  const SHA256_INITIAL_HASH = [
@@ -7165,89 +6219,31 @@ function rotr(value, bits) {
7165
6219
  //#region src/ports/telemetry.ts
7166
6220
  var TelemetryPortTag = class extends Context.Service()("@capxul/sdk/ports/TelemetryPort") {};
7167
6221
  //#endregion
7168
- //#region src/adapters/telemetry/PostHogTelemetryAdapter.ts
7169
- var PostHogTelemetryAdapter = class {
7170
- #capture;
7171
- #identify;
7172
- #group;
7173
- #reset;
7174
- constructor(deps) {
7175
- this.#capture = deps.capture;
7176
- this.#identify = deps.identify ?? (() => void 0);
7177
- this.#group = deps.group ?? (() => void 0);
7178
- this.#reset = deps.reset ?? (() => void 0);
7179
- }
7180
- emit(event) {
7181
- return this.#run(() => this.#capture(event.name, redactTelemetryProps(event.name, cloneProps(event.props)), event), "emit", event.name);
7182
- }
7183
- identify(input) {
7184
- return this.#run(() => this.#identify(cloneIdentifyInput(input)), "identify");
7185
- }
7186
- group(input) {
7187
- return this.#run(() => this.#group(cloneGroupInput(input)), "group");
7188
- }
7189
- reset() {
7190
- return this.#run(() => this.#reset(), "reset");
7191
- }
7192
- #run(operation, operationName, eventName) {
7193
- const diagnose = Effect.logWarning("product.telemetry.transport.dropped").pipe(Effect.annotateLogs({
7194
- operation: operationName,
7195
- ...eventName === void 0 ? {} : { product_event: eventName }
7196
- }), Effect.catchCause(() => Effect.void));
7197
- return Effect.suspend(() => {
7198
- let pending;
7199
- try {
7200
- pending = operation();
7201
- } catch {
7202
- return diagnose;
7203
- }
7204
- if (pending === void 0) return Effect.void;
7205
- const transport = Effect.tryPromise({
7206
- try: () => pending,
7207
- catch: () => void 0
7208
- }).pipe(Effect.catch(() => diagnose));
7209
- return Effect.forkDetach(transport, { startImmediately: true }).pipe(Effect.asVoid);
7210
- });
7211
- }
7212
- };
7213
- function PostHogTelemetryLayer(deps) {
7214
- return Layer.succeed(TelemetryPortTag, new PostHogTelemetryAdapter(deps));
7215
- }
7216
- function cloneIdentifyInput(input) {
7217
- const traits = input.traits === void 0 ? void 0 : cloneProps(input.traits);
7218
- const properties = input.properties === void 0 ? void 0 : cloneProps(input.properties);
7219
- return {
7220
- distinctId: input.distinctId,
7221
- ...input.anonDistinctId === void 0 ? {} : { anonDistinctId: input.anonDistinctId },
7222
- ...traits === void 0 ? {} : { traits },
7223
- ...properties === void 0 ? {} : { properties }
7224
- };
7225
- }
7226
- function cloneGroupInput(input) {
7227
- const properties = input.properties === void 0 ? void 0 : cloneProps(input.properties);
7228
- return properties === void 0 ? {
7229
- groupType: input.groupType,
7230
- groupKey: input.groupKey
7231
- } : {
7232
- groupType: input.groupType,
7233
- groupKey: input.groupKey,
7234
- properties
7235
- };
7236
- }
7237
- function cloneProps(props) {
7238
- if (props === void 0) return void 0;
7239
- const cloned = {};
7240
- for (const [key, value] of Object.entries(props)) cloned[key] = cloneTelemetryValue(value);
7241
- return cloned;
6222
+ //#region src/ports/account-read.ts
6223
+ var AccountReadError = class extends Data.TaggedError("AccountReadError") {};
6224
+ function accountReadErrorFromCapxul(operation, error, cause = error) {
6225
+ return new AccountReadError({
6226
+ operation,
6227
+ publicCode: error.code,
6228
+ publicError: error,
6229
+ cause,
6230
+ ...error.details === void 0 ? {} : { details: error.details }
6231
+ });
7242
6232
  }
7243
- function cloneTelemetryValue(value) {
7244
- if (Array.isArray(value)) return value.map(cloneTelemetryValue);
7245
- if (value === null || typeof value !== "object") return value;
7246
- if (Object.getPrototypeOf(value) !== Object.prototype) return value;
7247
- const cloned = {};
7248
- for (const [key, nested] of Object.entries(value)) cloned[key] = cloneTelemetryValue(nested);
7249
- return cloned;
6233
+ var AccountReadPortTag = class extends Context.Service()("@capxul/sdk/ports/AccountReadPort") {};
6234
+ //#endregion
6235
+ //#region src/ports/smart-account.ts
6236
+ var SmartAccountError = class extends Data.TaggedError("SmartAccountError") {};
6237
+ function smartAccountErrorFromCapxul(operation, error, cause = error) {
6238
+ return new SmartAccountError({
6239
+ operation,
6240
+ publicCode: error.code,
6241
+ publicError: error,
6242
+ cause,
6243
+ ...error.details === void 0 ? {} : { details: error.details }
6244
+ });
7250
6245
  }
6246
+ var SmartAccountPortTag = class extends Context.Service()("@capxul/sdk/ports/SmartAccountPort") {};
7251
6247
  //#endregion
7252
6248
  //#region src/flows/identity.ts
7253
6249
  const IDENTITY_SLOT = {
@@ -8167,7 +7163,7 @@ function accountsDepsLayer(deps) {
8167
7163
  }
8168
7164
  const readAccountProgram = Effect.gen(function* () {
8169
7165
  const deps = yield* AccountsDepsTag;
8170
- return yield* deps.accountReadPort.readBalance({ chainId: deps.chainId }).pipe(Effect.tapError((error) => Effect.promise(() => emitAccountBalanceFailed(deps.telemetry, error.publicError))), Effect.mapError((error) => error.publicError));
7166
+ return yield* deps.accountReadPort.readBalance(copyInvocationObservation(deps.invocationSource, { chainId: deps.chainId })).pipe(Effect.tapError((error) => Effect.promise(() => emitAccountBalanceFailed(deps.telemetry, error.publicError))), Effect.mapError((error) => error.publicError));
8171
7167
  });
8172
7168
  function fundFromFaucetProgram(amount) {
8173
7169
  return Effect.gen(function* () {
@@ -8197,7 +7193,11 @@ function makeAccountsMethods(deps) {
8197
7193
  ok: false,
8198
7194
  error: Errors.cancelled({ operation: "accounts.read" })
8199
7195
  };
8200
- return toCapxulResult(readAccountProgram, accountsDepsLayer(deps));
7196
+ const controls = deps.invocationControls?.(options) ?? options;
7197
+ return runCapxulEffect(readAccountProgram.pipe(Effect.provide(accountsDepsLayer({
7198
+ ...deps,
7199
+ ...controls === void 0 ? {} : { invocationSource: controls }
7200
+ }))), controls, "accounts.read", deps.runPromise);
8201
7201
  },
8202
7202
  async fund(amount, options) {
8203
7203
  if (options?.signal?.aborted) return {
@@ -8962,7 +7962,7 @@ function emitCreationFunnelTail(telemetry, org, chainId) {
8962
7962
  function readTreasuryProgram(orgId) {
8963
7963
  return Effect.gen(function* () {
8964
7964
  const deps = yield* OrgDepsTag;
8965
- if (deps.orgPort !== void 0) return yield* deps.orgPort.readTreasury({ orgId }).pipe(Effect.mapError((error) => error.publicError));
7965
+ if (deps.orgPort !== void 0) return yield* deps.orgPort.readTreasury(copyInvocationObservation(deps.invocationSource, { orgId })).pipe(Effect.mapError((error) => error.publicError));
8966
7966
  return zeroTreasury(orgId);
8967
7967
  });
8968
7968
  }
@@ -9046,7 +8046,7 @@ function detectAndAcceptPendingInvitationsProgram() {
9046
8046
  function listOrgsProgram() {
9047
8047
  return Effect.gen(function* () {
9048
8048
  const deps = yield* OrgDepsTag;
9049
- if (deps.orgPort !== void 0) return yield* deps.orgPort.listOrgs({}).pipe(Effect.mapError((error) => error.publicError));
8049
+ if (deps.orgPort !== void 0) return yield* deps.orgPort.listOrgs(copyInvocationObservation(deps.invocationSource, {})).pipe(Effect.mapError((error) => error.publicError));
9050
8050
  return [];
9051
8051
  });
9052
8052
  }
@@ -9134,11 +8134,28 @@ function isRetryableOrganizationSetupFailure(error) {
9134
8134
  * state. The closed-over `orgId` is its only entity reference.
9135
8135
  */
9136
8136
  function makeOrgMethods(deps) {
9137
- const layer = orgDepsLayer({
8137
+ const orgDeps = {
9138
8138
  ...deps.orgPort === void 0 ? {} : { orgPort: deps.orgPort },
9139
8139
  ...deps.chainId === void 0 ? {} : { chainId: deps.chainId },
9140
8140
  ...deps.telemetry === void 0 ? {} : { telemetry: deps.telemetry }
9141
- });
8141
+ };
8142
+ const layer = orgDepsLayer(orgDeps);
8143
+ const treasury = (orgId, controls) => {
8144
+ return runCapxulEffect(readTreasuryProgram(orgId).pipe(Effect.provide(orgDepsLayer({
8145
+ ...orgDeps,
8146
+ ...controls === void 0 ? {} : { invocationSource: controls }
8147
+ }))), controls, "org.treasury", deps.runPromise);
8148
+ };
8149
+ const listOrganizations = (controls) => {
8150
+ if (controls?.signal?.aborted) return Promise.resolve({
8151
+ ok: false,
8152
+ error: Errors.cancelled({ operation: "org.orgs" })
8153
+ });
8154
+ return runCapxulEffect(listOrgsProgram().pipe(Effect.provide(orgDepsLayer({
8155
+ ...orgDeps,
8156
+ ...controls === void 0 ? {} : { invocationSource: controls }
8157
+ }))), controls, "org.orgs", deps.runPromise);
8158
+ };
9142
8159
  return {
9143
8160
  createOrg(input, options) {
9144
8161
  if (options?.signal?.aborted) return Promise.resolve({
@@ -9147,13 +8164,7 @@ function makeOrgMethods(deps) {
9147
8164
  });
9148
8165
  return toCapxulResult(createOrgProgram(input), layer);
9149
8166
  },
9150
- orgs: Object.assign((options) => {
9151
- if (options?.signal?.aborted) return Promise.resolve({
9152
- ok: false,
9153
- error: Errors.cancelled({ operation: "org.orgs" })
9154
- });
9155
- return toCapxulResult(listOrgsProgram(), layer);
9156
- }, { detectAndAcceptPendingInvitations(options) {
8167
+ orgs: Object.assign((options) => listOrganizations(deps.invocationControls?.(options) ?? options), { detectAndAcceptPendingInvitations(options) {
9157
8168
  if (options?.signal?.aborted) return Promise.resolve({
9158
8169
  ok: false,
9159
8170
  error: Errors.cancelled({ operation: "orgs.detectAndAcceptPendingInvitations" })
@@ -9225,19 +8236,20 @@ function makeOrgMethods(deps) {
9225
8236
  ok: false,
9226
8237
  error: Errors.cancelled({ operation: "org.treasury" })
9227
8238
  });
9228
- return toCapxulResult(readTreasuryProgram(orgId), layer);
8239
+ return treasury(orgId, deps.invocationControls?.(options) ?? options);
9229
8240
  },
9230
8241
  account: { async get(options) {
9231
8242
  if (options?.signal?.aborted) return {
9232
8243
  ok: false,
9233
8244
  error: Errors.cancelled({ operation: "org.account.get" })
9234
8245
  };
9235
- const treasury = await toCapxulResult(readTreasuryProgram(orgId), layer);
9236
- if (!treasury.ok) return {
8246
+ const controls = deps.invocationControls?.(options) ?? options;
8247
+ const treasuryResult = await treasury(orgId, controls);
8248
+ if (!treasuryResult.ok) return {
9237
8249
  ok: false,
9238
- error: treasury.error
8250
+ error: treasuryResult.error
9239
8251
  };
9240
- const orgList = await toCapxulResult(listOrgsProgram(), layer);
8252
+ const orgList = await listOrganizations(controls);
9241
8253
  if (!orgList.ok) return {
9242
8254
  ok: false,
9243
8255
  error: orgList.error
@@ -9246,10 +8258,10 @@ function makeOrgMethods(deps) {
9246
8258
  return {
9247
8259
  ok: true,
9248
8260
  value: {
9249
- id: treasury.value.id,
8261
+ id: treasuryResult.value.id,
9250
8262
  address: org?.safeAddress ?? null,
9251
- balance: treasury.value.balance,
9252
- available: treasury.value.available
8263
+ balance: treasuryResult.value.balance,
8264
+ available: treasuryResult.value.available
9253
8265
  }
9254
8266
  };
9255
8267
  } },
@@ -9401,13 +8413,16 @@ function compareDecimal(first, second) {
9401
8413
  //#region src/surface/holdings.ts
9402
8414
  function makeHoldingsMethods(deps) {
9403
8415
  const functions = deps.functions ?? holdingsContract;
9404
- const read = (operation, actor, signal, pick) => runIfActive(signal, operation, () => deps.convexCall.action(functions.current, actor?.kind === "organization" ? { actor: {
9405
- kind: "organization",
9406
- orgId: actor.organizationId
9407
- } } : {}).pipe(Effect.map(pick)));
8416
+ const read = (operation, actor, options, pick) => {
8417
+ const controls = deps.invocationControls?.(options) ?? options;
8418
+ return runCapxulEffect(retryIdempotentRead(deps.convexCall.action(functions.current, copyInvocationObservation(controls, actor?.kind === "organization" ? { actor: {
8419
+ kind: "organization",
8420
+ orgId: actor.organizationId
8421
+ } } : {})), operation, deps.telemetry, controls).pipe(Effect.map(pick), Effect.mapError((error) => error.publicError)), controls, operation, deps.runPromise);
8422
+ };
9408
8423
  return {
9409
- current: (input, options) => read("holdings.current", input?.actor, options?.signal, (snapshot) => snapshot),
9410
- primary: (input, options) => read("holdings.primary", input?.actor, options?.signal, (snapshot) => primaryHolding(snapshot.rows))
8424
+ current: (input, options) => read("holdings.current", input?.actor, options, (snapshot) => snapshot),
8425
+ primary: (input, options) => read("holdings.primary", input?.actor, options, (snapshot) => primaryHolding(snapshot.rows))
9411
8426
  };
9412
8427
  }
9413
8428
  //#endregion
@@ -9418,78 +8433,6 @@ function detectAuthCacheAdapter() {
9418
8433
  return new InMemoryAuthCacheAdapter();
9419
8434
  }
9420
8435
  //#endregion
9421
- //#region src/telemetry/from-posthog.ts
9422
- const PRODUCT_INVOCATION = Symbol("capxul.product-telemetry-invocation");
9423
- /** @internal Bind paired emit/identify/reset work to one call-start snapshot. */
9424
- function bindProductTelemetryInvocation(telemetry, source) {
9425
- return telemetry[PRODUCT_INVOCATION]?.(source) ?? telemetry;
9426
- }
9427
- /**
9428
- * Drop props that must never cross to a host-owned external sink. Today that is
9429
- * the `$exception` `details` blob: `captureException` serializes
9430
- * `CapxulError.details` (e.g. `{ asset, available, required }`, `{ name }`,
9431
- * `{ accountId }` — errors.ts) into it, and the shared redactor has no
9432
- * `$exception` rule, so it is stripped here at the boundary (infra#1037). The
9433
- * safe fields (error code, operation, failure_mode, the fixed leak-safe message,
9434
- * stack frames) are preserved.
9435
- */
9436
- function stripHostUnsafeProps(props) {
9437
- if (props === void 0) return void 0;
9438
- const { details: _details, ...safe } = props;
9439
- return safe;
9440
- }
9441
- /**
9442
- * The subset of a posthog-js client the seam calls. `identify` / `group` /
9443
- * `reset` are optional — a host that only wants event capture can omit them.
9444
- */
9445
- /**
9446
- * Adapt the host's already-initialized posthog-like client into a
9447
- * `TelemetryPort` for the `telemetry` prop / input. This port SUPPLANTS the
9448
- * SDK's no-op default telemetry sink (`production.ts` binds it via
9449
- * `Layer.succeed`, not `compose` — there is no client-side success relay to
9450
- * compose with); it is additive to Capxul's backend first-party record and
9451
- * never owns the client.
9452
- */
9453
- function postHogProductTelemetry(policy, fixedSnapshot) {
9454
- const telemetry = new PostHogTelemetryAdapter({
9455
- capture: (name, props, source) => {
9456
- const snapshot = readInvocationObservation(source) ?? fixedSnapshot ?? policy.snapshot();
9457
- if (!snapshot.active || policy.client === null || policy.client === void 0) return;
9458
- const event = stampTelemetryEnvelope({
9459
- name,
9460
- props
9461
- }, {
9462
- capxul_env: policy.capxulEnv,
9463
- producer: "sdk"
9464
- });
9465
- policy.deliver(() => policy.client.capture(name, {
9466
- ...stripHostUnsafeProps(event.props),
9467
- ...observationContextProps(snapshot.context)
9468
- }));
9469
- },
9470
- identify: (input) => {
9471
- if (!(fixedSnapshot ?? policy.snapshot()).active || policy.client?.identify === void 0) return;
9472
- policy.deliver(() => policy.client.identify(input.distinctId, {
9473
- ...input.traits,
9474
- ...input.properties
9475
- }));
9476
- },
9477
- group: (input) => {
9478
- if (!(fixedSnapshot ?? policy.snapshot()).active || policy.client?.group === void 0) return;
9479
- policy.deliver(() => policy.client.group(input.groupType, input.groupKey, input.properties === void 0 ? void 0 : { ...input.properties }));
9480
- },
9481
- reset: () => {
9482
- if (!(fixedSnapshot ?? policy.snapshot()).active || policy.client?.reset === void 0) return;
9483
- policy.deliver(() => policy.client.reset());
9484
- }
9485
- });
9486
- Object.defineProperty(telemetry, PRODUCT_INVOCATION, {
9487
- enumerable: false,
9488
- value: (source) => postHogProductTelemetry(policy, readInvocationObservation(source) ?? fixedSnapshot ?? policy.snapshot())
9489
- });
9490
- return telemetry;
9491
- }
9492
- //#endregion
9493
8436
  //#region src/telemetry/identity-product.ts
9494
8437
  const NONE = null;
9495
8438
  const IDENTITY_EVENT_TAG_SET = new Set(IDENTITY_EVENT_TAGS);
@@ -9686,6 +8629,8 @@ function assembleCapxulClient(input) {
9686
8629
  accountReadPort: input.ports.accountRead,
9687
8630
  profileMethods: financialOps.me,
9688
8631
  convexCall: input.ports.convexCall,
8632
+ runPromise: effectRunner.runPromise,
8633
+ invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls),
9689
8634
  ...input.signer === void 0 ? {} : { signer: input.signer }
9690
8635
  });
9691
8636
  kickProvisioning = accountBundle.kickProvisioning;
@@ -9723,16 +8668,25 @@ function assembleCapxulClient(input) {
9723
8668
  });
9724
8669
  const system = makeSystemMethods({ convexCall: input.ports.convexCall });
9725
8670
  const media = makeMediaMethods({ convexCall: input.ports.convexCall });
9726
- const holdings = makeHoldingsMethods({ convexCall: input.ports.convexCall });
8671
+ const holdings = makeHoldingsMethods({
8672
+ convexCall: input.ports.convexCall,
8673
+ telemetry: input.ports.telemetry,
8674
+ runPromise: effectRunner.runPromise,
8675
+ invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls)
8676
+ });
9727
8677
  const accounts = makeAccountsMethods({
9728
8678
  accountReadPort: input.ports.accountRead,
9729
8679
  chainId: input.bootstrap.chainId,
9730
- telemetry: input.ports.telemetry
8680
+ telemetry: input.ports.telemetry,
8681
+ runPromise: effectRunner.runPromise,
8682
+ invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls)
9731
8683
  });
9732
8684
  const orgMethods = makeOrgMethods({
9733
8685
  actor,
9734
8686
  chainId: input.bootstrap.chainId,
9735
8687
  telemetry: input.ports.telemetry,
8688
+ runPromise: effectRunner.runPromise,
8689
+ invocationControls: (controls) => withHostObservationControls(observation.hostObservationSnapshot, controls),
9736
8690
  requestKeyScope: `${input.bootstrap.convexUrl}:${String(input.bootstrap.chainId)}`,
9737
8691
  ...selectedOrgPort === void 0 ? {} : { orgPort: selectedOrgPort },
9738
8692
  convexCall: input.ports.convexCall,
@@ -9869,11 +8823,7 @@ function transitionError(record) {
9869
8823
  }
9870
8824
  function withHostObservation(actor, snapshot) {
9871
8825
  if (snapshot === void 0) return actor;
9872
- const controls = (input) => {
9873
- const captured = snapshot();
9874
- const copied = { ...input };
9875
- return captured === void 0 ? copied : attachInvocationObservation(copied, captured);
9876
- };
8826
+ const controls = (input) => withHostObservationControls(snapshot, input);
9877
8827
  return {
9878
8828
  ...actor,
9879
8829
  ask: (event, input) => actor.ask(event, controls(input)),
@@ -9881,5 +8831,10 @@ function withHostObservation(actor, snapshot) {
9881
8831
  restoreAuthSession: (session, input) => actor.restoreAuthSession(session, controls(input))
9882
8832
  };
9883
8833
  }
8834
+ function withHostObservationControls(snapshot, input) {
8835
+ const copied = { ...input };
8836
+ const captured = snapshot?.();
8837
+ return captured === void 0 ? copied : attachInvocationObservation(copied, captured);
8838
+ }
9884
8839
  //#endregion
9885
- export { deriveCapxulSafeAddress as $, postHogFailureObservation as A, injectedWalletSigner as B, fingerprintPaymentIntent as C, failureEvidenceProps as D, failureDetail as E, isSettingUpLifecycle as F, PAYMENT_DIRECTIONS as G, OBSERVATION_CONTEXT_HEADER as H, formatTraceparent as I, BootstrapEnvelope as J, PAYMENT_STATUSES as K, copyInvocationObservation as L, captureExceptionSync as M, version as N, observationContextProps as O, fromWei as P, BASE_SEPOLIA_CHAIN_ID as Q, readInvocationObservation as R, AuthClientPortTag as S, CAPXUL_SDK_EXPECTED_OUTCOME_EVENT as T, encodeObservationContextHeader as U, signerFailure as V, sanitizeObservationContext as W, CAPXUL_PAYMENTS_V2_ADDRESS as X, EngineeringTelemetryBootstrapPolicy as Y, normalizeBindingEmail as Z, ClockPortTag as _, TelemetryPortTag as a, authClientPortFromPromiseAdapter as b, smartAccountErrorFromCapxul as c, wireChainId as d, destination as et, IdentityPortTag as f, ClockError as g, convexCallErrorFromCapxul as h, PostHogTelemetryLayer as i, captureException as j, observeFailedResult as k, AccountReadPortTag as l, ConvexCallPortTag as m, postHogProductTelemetry as n, isRestoring as nt, redactTelemetryEvent as o, identityErrorFromCapxul as p, CAPXUL_FUNCTIONS as q, detectAuthCacheAdapter as r, SmartAccountPortTag as s, assembleCapxulClient as t, isClaimed as tt, accountReadErrorFromCapxul as u, BootstrapPortTag as v, toWei as w, AuthClientError as x, bootstrapErrorFromCapxul as y, causeChain as z };
8840
+ export { EngineeringTelemetryBootstrapPolicy as $, normalizeExceptionErrorKind as A, isSignerNotReadySignal as B, failureDetail as C, postHogFailureObservation as D, observeFailedResult as E, fromWei as F, readInvocationObservation as G, signerFailure as H, isSettingUpLifecycle as I, sanitizeObservationContext as J, OBSERVATION_CONTEXT_HEADER as K, formatTraceparent as L, projectSdkException as M, safeExceptionLabel as N, EXCEPTION_MESSAGE as O, version as P, BootstrapEnvelope as Q, causeChain as R, CAPXUL_SDK_EXPECTED_OUTCOME_EVENT as S, observationContextProps as T, resolveFailureMode as U, openfortSignerNotReadyCode as V, copyInvocationObservation as W, PAYMENT_STATUSES as X, PAYMENT_DIRECTIONS as Y, CAPXUL_FUNCTIONS as Z, convexCallErrorFromCapxul as _, AccountReadPortTag as a, fingerprintPaymentIntent as b, redactTelemetryEvent as c, retryIdempotentRead as d, destination as et, PRODUCT_INVOCATION as f, ConvexCallPortTag as g, identityErrorFromCapxul as h, smartAccountErrorFromCapxul as i, normalizeExceptionOperation as j, SDK_VERSION as k, redactTelemetryProps as l, IdentityPortTag as m, detectAuthCacheAdapter as n, isRestoring as nt, accountReadErrorFromCapxul as o, wireChainId as p, encodeObservationContextHeader as q, SmartAccountPortTag as r, TelemetryPortTag as s, assembleCapxulClient as t, isClaimed as tt, stampTelemetryEnvelope as u, BootstrapPortTag as v, failureEvidenceProps as w, toWei as x, bootstrapErrorFromCapxul as y, injectedWalletSigner as z };