@owney/sdk 0.6.6-beta.3 → 0.6.6-beta.5

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.
Files changed (3) hide show
  1. package/dist/index.cjs +103 -31
  2. package/dist/index.js +103 -31
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -550,36 +550,71 @@ var isJwtExpired = (token) => {
550
550
  return false;
551
551
  }
552
552
  };
553
+ var memorySessions = /* @__PURE__ */ new Map();
554
+ var isFreshSession = (session) => !!session && !!session.token && !isJwtExpired(session.token);
553
555
  var readSession = (address, chainId) => {
556
+ if (typeof window === "undefined") return null;
557
+ const key = buildKey(address, chainId);
554
558
  const store = storage();
555
- if (!store) return null;
556
- const raw = store.getItem(buildKey(address, chainId));
557
- if (!raw) return null;
559
+ let raw = null;
558
560
  try {
559
- const parsed = JSON.parse(raw);
560
- if (!parsed.token || isJwtExpired(parsed.token)) {
561
- store.removeItem(buildKey(address, chainId));
562
- return null;
563
- }
564
- return parsed;
561
+ raw = store?.getItem(key) ?? null;
565
562
  } catch {
566
- store.removeItem(buildKey(address, chainId));
563
+ raw = null;
564
+ }
565
+ if (raw) {
566
+ try {
567
+ const parsed = JSON.parse(raw);
568
+ if (isFreshSession(parsed)) return parsed;
569
+ } catch {
570
+ }
571
+ memorySessions.delete(key);
572
+ try {
573
+ store?.removeItem(key);
574
+ } catch {
575
+ }
567
576
  return null;
568
577
  }
578
+ const cached = memorySessions.get(key);
579
+ if (isFreshSession(cached)) return cached;
580
+ if (cached) memorySessions.delete(key);
581
+ return null;
569
582
  };
570
583
  var writeSession = (address, chainId, session) => {
584
+ if (typeof window === "undefined") return;
585
+ const key = buildKey(address, chainId);
586
+ memorySessions.set(key, session);
571
587
  const store = storage();
572
- if (!store) return;
573
588
  try {
574
- store.setItem(buildKey(address, chainId), JSON.stringify(session));
589
+ store?.setItem(key, JSON.stringify(session));
575
590
  } catch {
576
591
  }
577
592
  };
578
593
  var clearSession = (address, chainId) => {
594
+ const key = buildKey(address, chainId);
595
+ memorySessions.delete(key);
596
+ const store = storage();
597
+ try {
598
+ store?.removeItem(key);
599
+ } catch {
600
+ }
601
+ };
602
+ var SESSION_KEY_PREFIX = "owney.zyfai.sessionkey";
603
+ var buildSessionKeyKey = (address, chainId) => `${SESSION_KEY_PREFIX}:${address.toLowerCase()}:${chainId}`;
604
+ var wasSessionKeyActivated = (address, chainId) => {
605
+ const store = storage();
606
+ if (!store) return false;
607
+ try {
608
+ return store.getItem(buildSessionKeyKey(address, chainId)) === "1";
609
+ } catch {
610
+ return false;
611
+ }
612
+ };
613
+ var markSessionKeyActivated = (address, chainId) => {
579
614
  const store = storage();
580
615
  if (!store) return;
581
616
  try {
582
- store.removeItem(buildKey(address, chainId));
617
+ store.setItem(buildSessionKeyKey(address, chainId), "1");
583
618
  } catch {
584
619
  }
585
620
  };
@@ -836,7 +871,7 @@ var ZyfaiAgent = class {
836
871
  const wallet = await this.sdk.getSmartWalletAddress(address, validChainId);
837
872
  this.smartWalletCache.set(`${address}_${validChainId}`, wallet.address);
838
873
  if (!wallet.isDeployed) {
839
- await this.sdk.deploySafe(address, validChainId, "aggressive", true);
874
+ await this.sdk.deploySafe(address, validChainId, "aggressive", false);
840
875
  try {
841
876
  if (validChainId === 42161) {
842
877
  await this.sdk.updateUserProfile({
@@ -854,10 +889,33 @@ var ZyfaiAgent = class {
854
889
  );
855
890
  }
856
891
  }
857
- const user = await this.sdk.getUserDetails();
858
- if (!user.hasActiveSessionKey) {
859
- await this.sdk.createSessionKey(address, validChainId);
860
- }
892
+ await this.ensureSessionKey(address, validChainId);
893
+ }
894
+ /**
895
+ * Ensures a session key is active for THIS chain.
896
+ *
897
+ * The Zyfai SDK tracks session-key state with a single global boolean — the
898
+ * in-memory `hasActiveSessionKey` and the `/users/me` field of the same name
899
+ * are neither chain-scoped. Once a key is activated on one chain, both
900
+ * `getUserDetails()` and the SDK's own `createSessionKey` guard report
901
+ * "active" on every other chain, so a deposit on a freshly-used chain runs
902
+ * without a valid session key and reverts. See [[zyfai-per-chain-session-key]].
903
+ *
904
+ * We keep our own per-(address, chainId) record of activated chains (in
905
+ * localStorage). On a miss we clear the SDK's global guard so
906
+ * `createSessionKey` actually signs and activates for THIS chain.
907
+ *
908
+ * Cost: on a chain we've never recorded (e.g. a key created on another device
909
+ * or a prior app version), this forces one `createSessionKey` — an extra
910
+ * wallet signature, idempotent on the backend. A prompt-free variant would
911
+ * read the session-validator module state on-chain instead of self-tracking.
912
+ */
913
+ async ensureSessionKey(address, chainId) {
914
+ if (wasSessionKeyActivated(address, chainId)) return;
915
+ const internals = this.sdk;
916
+ internals.hasActiveSessionKey = false;
917
+ await this.sdk.createSessionKey(address, chainId);
918
+ markSessionKeyActivated(address, chainId);
861
919
  }
862
920
  /** Connect + resolve smart wallet address for read operations. */
863
921
  async resolveSmartWallet(state, chainId) {
@@ -1007,9 +1065,7 @@ var ZyfaiAgent = class {
1007
1065
  await this.connectAuth(state, chainId);
1008
1066
  const validChainId = isValidChainId(chainId);
1009
1067
  const raw = await this.sdk.getUserDetails();
1010
- if (!raw.hasActiveSessionKey) {
1011
- await this.sdk.createSessionKey(this.getAddress(), validChainId);
1012
- }
1068
+ await this.ensureSessionKey(this.getAddress(), validChainId);
1013
1069
  return mapUserProfile(raw, this.connectedAddress);
1014
1070
  }
1015
1071
  async ensureAutoSelectProtocols(state, chainId, asset) {
@@ -2662,31 +2718,47 @@ var storage2 = () => {
2662
2718
  }
2663
2719
  };
2664
2720
  var buildKey2 = (address, chainId) => `${KEY_PREFIX2}:${address.toLowerCase()}:${chainId}`;
2721
+ var memorySiwxSessions = /* @__PURE__ */ new Map();
2665
2722
  var readSiwxSession = (address, chainId) => {
2723
+ if (typeof window === "undefined") return null;
2724
+ const key = buildKey2(address, chainId);
2666
2725
  const store = storage2();
2667
- if (!store) return null;
2668
- const raw = store.getItem(buildKey2(address, chainId));
2669
- if (!raw) return null;
2726
+ let raw = null;
2670
2727
  try {
2671
- return JSON.parse(raw);
2728
+ raw = store?.getItem(key) ?? null;
2672
2729
  } catch {
2673
- store.removeItem(buildKey2(address, chainId));
2674
- return null;
2730
+ raw = null;
2731
+ }
2732
+ if (raw) {
2733
+ try {
2734
+ return JSON.parse(raw);
2735
+ } catch {
2736
+ memorySiwxSessions.delete(key);
2737
+ try {
2738
+ store?.removeItem(key);
2739
+ } catch {
2740
+ }
2741
+ return null;
2742
+ }
2675
2743
  }
2744
+ return memorySiwxSessions.get(key) ?? null;
2676
2745
  };
2677
2746
  var writeSiwxSession = (address, chainId, session) => {
2747
+ if (typeof window === "undefined") return;
2748
+ const key = buildKey2(address, chainId);
2749
+ memorySiwxSessions.set(key, session);
2678
2750
  const store = storage2();
2679
- if (!store) return;
2680
2751
  try {
2681
- store.setItem(buildKey2(address, chainId), JSON.stringify(session));
2752
+ store?.setItem(key, JSON.stringify(session));
2682
2753
  } catch {
2683
2754
  }
2684
2755
  };
2685
2756
  var clearSiwxSession = (address, chainId) => {
2757
+ const key = buildKey2(address, chainId);
2758
+ memorySiwxSessions.delete(key);
2686
2759
  const store = storage2();
2687
- if (!store) return;
2688
2760
  try {
2689
- store.removeItem(buildKey2(address, chainId));
2761
+ store?.removeItem(key);
2690
2762
  } catch {
2691
2763
  }
2692
2764
  };
package/dist/index.js CHANGED
@@ -518,36 +518,71 @@ var isJwtExpired = (token) => {
518
518
  return false;
519
519
  }
520
520
  };
521
+ var memorySessions = /* @__PURE__ */ new Map();
522
+ var isFreshSession = (session) => !!session && !!session.token && !isJwtExpired(session.token);
521
523
  var readSession = (address, chainId) => {
524
+ if (typeof window === "undefined") return null;
525
+ const key = buildKey(address, chainId);
522
526
  const store = storage();
523
- if (!store) return null;
524
- const raw = store.getItem(buildKey(address, chainId));
525
- if (!raw) return null;
527
+ let raw = null;
526
528
  try {
527
- const parsed = JSON.parse(raw);
528
- if (!parsed.token || isJwtExpired(parsed.token)) {
529
- store.removeItem(buildKey(address, chainId));
530
- return null;
531
- }
532
- return parsed;
529
+ raw = store?.getItem(key) ?? null;
533
530
  } catch {
534
- store.removeItem(buildKey(address, chainId));
531
+ raw = null;
532
+ }
533
+ if (raw) {
534
+ try {
535
+ const parsed = JSON.parse(raw);
536
+ if (isFreshSession(parsed)) return parsed;
537
+ } catch {
538
+ }
539
+ memorySessions.delete(key);
540
+ try {
541
+ store?.removeItem(key);
542
+ } catch {
543
+ }
535
544
  return null;
536
545
  }
546
+ const cached = memorySessions.get(key);
547
+ if (isFreshSession(cached)) return cached;
548
+ if (cached) memorySessions.delete(key);
549
+ return null;
537
550
  };
538
551
  var writeSession = (address, chainId, session) => {
552
+ if (typeof window === "undefined") return;
553
+ const key = buildKey(address, chainId);
554
+ memorySessions.set(key, session);
539
555
  const store = storage();
540
- if (!store) return;
541
556
  try {
542
- store.setItem(buildKey(address, chainId), JSON.stringify(session));
557
+ store?.setItem(key, JSON.stringify(session));
543
558
  } catch {
544
559
  }
545
560
  };
546
561
  var clearSession = (address, chainId) => {
562
+ const key = buildKey(address, chainId);
563
+ memorySessions.delete(key);
564
+ const store = storage();
565
+ try {
566
+ store?.removeItem(key);
567
+ } catch {
568
+ }
569
+ };
570
+ var SESSION_KEY_PREFIX = "owney.zyfai.sessionkey";
571
+ var buildSessionKeyKey = (address, chainId) => `${SESSION_KEY_PREFIX}:${address.toLowerCase()}:${chainId}`;
572
+ var wasSessionKeyActivated = (address, chainId) => {
573
+ const store = storage();
574
+ if (!store) return false;
575
+ try {
576
+ return store.getItem(buildSessionKeyKey(address, chainId)) === "1";
577
+ } catch {
578
+ return false;
579
+ }
580
+ };
581
+ var markSessionKeyActivated = (address, chainId) => {
547
582
  const store = storage();
548
583
  if (!store) return;
549
584
  try {
550
- store.removeItem(buildKey(address, chainId));
585
+ store.setItem(buildSessionKeyKey(address, chainId), "1");
551
586
  } catch {
552
587
  }
553
588
  };
@@ -804,7 +839,7 @@ var ZyfaiAgent = class {
804
839
  const wallet = await this.sdk.getSmartWalletAddress(address, validChainId);
805
840
  this.smartWalletCache.set(`${address}_${validChainId}`, wallet.address);
806
841
  if (!wallet.isDeployed) {
807
- await this.sdk.deploySafe(address, validChainId, "aggressive", true);
842
+ await this.sdk.deploySafe(address, validChainId, "aggressive", false);
808
843
  try {
809
844
  if (validChainId === 42161) {
810
845
  await this.sdk.updateUserProfile({
@@ -822,10 +857,33 @@ var ZyfaiAgent = class {
822
857
  );
823
858
  }
824
859
  }
825
- const user = await this.sdk.getUserDetails();
826
- if (!user.hasActiveSessionKey) {
827
- await this.sdk.createSessionKey(address, validChainId);
828
- }
860
+ await this.ensureSessionKey(address, validChainId);
861
+ }
862
+ /**
863
+ * Ensures a session key is active for THIS chain.
864
+ *
865
+ * The Zyfai SDK tracks session-key state with a single global boolean — the
866
+ * in-memory `hasActiveSessionKey` and the `/users/me` field of the same name
867
+ * are neither chain-scoped. Once a key is activated on one chain, both
868
+ * `getUserDetails()` and the SDK's own `createSessionKey` guard report
869
+ * "active" on every other chain, so a deposit on a freshly-used chain runs
870
+ * without a valid session key and reverts. See [[zyfai-per-chain-session-key]].
871
+ *
872
+ * We keep our own per-(address, chainId) record of activated chains (in
873
+ * localStorage). On a miss we clear the SDK's global guard so
874
+ * `createSessionKey` actually signs and activates for THIS chain.
875
+ *
876
+ * Cost: on a chain we've never recorded (e.g. a key created on another device
877
+ * or a prior app version), this forces one `createSessionKey` — an extra
878
+ * wallet signature, idempotent on the backend. A prompt-free variant would
879
+ * read the session-validator module state on-chain instead of self-tracking.
880
+ */
881
+ async ensureSessionKey(address, chainId) {
882
+ if (wasSessionKeyActivated(address, chainId)) return;
883
+ const internals = this.sdk;
884
+ internals.hasActiveSessionKey = false;
885
+ await this.sdk.createSessionKey(address, chainId);
886
+ markSessionKeyActivated(address, chainId);
829
887
  }
830
888
  /** Connect + resolve smart wallet address for read operations. */
831
889
  async resolveSmartWallet(state, chainId) {
@@ -975,9 +1033,7 @@ var ZyfaiAgent = class {
975
1033
  await this.connectAuth(state, chainId);
976
1034
  const validChainId = isValidChainId(chainId);
977
1035
  const raw = await this.sdk.getUserDetails();
978
- if (!raw.hasActiveSessionKey) {
979
- await this.sdk.createSessionKey(this.getAddress(), validChainId);
980
- }
1036
+ await this.ensureSessionKey(this.getAddress(), validChainId);
981
1037
  return mapUserProfile(raw, this.connectedAddress);
982
1038
  }
983
1039
  async ensureAutoSelectProtocols(state, chainId, asset) {
@@ -2634,31 +2690,47 @@ var storage2 = () => {
2634
2690
  }
2635
2691
  };
2636
2692
  var buildKey2 = (address, chainId) => `${KEY_PREFIX2}:${address.toLowerCase()}:${chainId}`;
2693
+ var memorySiwxSessions = /* @__PURE__ */ new Map();
2637
2694
  var readSiwxSession = (address, chainId) => {
2695
+ if (typeof window === "undefined") return null;
2696
+ const key = buildKey2(address, chainId);
2638
2697
  const store = storage2();
2639
- if (!store) return null;
2640
- const raw = store.getItem(buildKey2(address, chainId));
2641
- if (!raw) return null;
2698
+ let raw = null;
2642
2699
  try {
2643
- return JSON.parse(raw);
2700
+ raw = store?.getItem(key) ?? null;
2644
2701
  } catch {
2645
- store.removeItem(buildKey2(address, chainId));
2646
- return null;
2702
+ raw = null;
2703
+ }
2704
+ if (raw) {
2705
+ try {
2706
+ return JSON.parse(raw);
2707
+ } catch {
2708
+ memorySiwxSessions.delete(key);
2709
+ try {
2710
+ store?.removeItem(key);
2711
+ } catch {
2712
+ }
2713
+ return null;
2714
+ }
2647
2715
  }
2716
+ return memorySiwxSessions.get(key) ?? null;
2648
2717
  };
2649
2718
  var writeSiwxSession = (address, chainId, session) => {
2719
+ if (typeof window === "undefined") return;
2720
+ const key = buildKey2(address, chainId);
2721
+ memorySiwxSessions.set(key, session);
2650
2722
  const store = storage2();
2651
- if (!store) return;
2652
2723
  try {
2653
- store.setItem(buildKey2(address, chainId), JSON.stringify(session));
2724
+ store?.setItem(key, JSON.stringify(session));
2654
2725
  } catch {
2655
2726
  }
2656
2727
  };
2657
2728
  var clearSiwxSession = (address, chainId) => {
2729
+ const key = buildKey2(address, chainId);
2730
+ memorySiwxSessions.delete(key);
2658
2731
  const store = storage2();
2659
- if (!store) return;
2660
2732
  try {
2661
- store.removeItem(buildKey2(address, chainId));
2733
+ store?.removeItem(key);
2662
2734
  } catch {
2663
2735
  }
2664
2736
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.6.6-beta.3",
3
+ "version": "0.6.6-beta.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",