@zyfai/sdk 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -54,8 +54,6 @@ interface AddSessionKeyResponse {
54
54
  }
55
55
  interface SessionKeyResponse {
56
56
  success: boolean;
57
- /** Session key address (not available when alreadyActive is true) */
58
- sessionKeyAddress?: Address;
59
57
  /** Signature (not available when alreadyActive is true) */
60
58
  signature?: Hex;
61
59
  sessionNonces?: bigint[];
@@ -410,10 +408,10 @@ declare class ZyfaiSDK {
410
408
  private signer;
411
409
  private walletClient;
412
410
  private bundlerApiKey?;
413
- private isAuthenticated;
414
411
  private authenticatedUserId;
415
412
  private hasActiveSessionKey;
416
413
  private environment;
414
+ private currentProvider;
417
415
  constructor(config: SDKConfig | string);
418
416
  /**
419
417
  * Authenticate user with SIWE (Sign-In with Ethereum) & JWT token
@@ -439,6 +437,12 @@ declare class ZyfaiSDK {
439
437
  * ```
440
438
  */
441
439
  updateUserProfile(request: UpdateUserProfileRequest): Promise<UpdateUserProfileResponse>;
440
+ /**
441
+ * Handle account changes from wallet provider
442
+ * Resets authentication state when wallet is switched
443
+ * @private
444
+ */
445
+ private handleAccountsChanged;
442
446
  /**
443
447
  * Connect account for signing transactions
444
448
  * Accepts either a private key string or a modern wallet provider
package/dist/index.d.ts CHANGED
@@ -54,8 +54,6 @@ interface AddSessionKeyResponse {
54
54
  }
55
55
  interface SessionKeyResponse {
56
56
  success: boolean;
57
- /** Session key address (not available when alreadyActive is true) */
58
- sessionKeyAddress?: Address;
59
57
  /** Signature (not available when alreadyActive is true) */
60
58
  signature?: Hex;
61
59
  sessionNonces?: bigint[];
@@ -410,10 +408,10 @@ declare class ZyfaiSDK {
410
408
  private signer;
411
409
  private walletClient;
412
410
  private bundlerApiKey?;
413
- private isAuthenticated;
414
411
  private authenticatedUserId;
415
412
  private hasActiveSessionKey;
416
413
  private environment;
414
+ private currentProvider;
417
415
  constructor(config: SDKConfig | string);
418
416
  /**
419
417
  * Authenticate user with SIWE (Sign-In with Ethereum) & JWT token
@@ -439,6 +437,12 @@ declare class ZyfaiSDK {
439
437
  * ```
440
438
  */
441
439
  updateUserProfile(request: UpdateUserProfileRequest): Promise<UpdateUserProfileResponse>;
440
+ /**
441
+ * Handle account changes from wallet provider
442
+ * Resets authentication state when wallet is switched
443
+ * @private
444
+ */
445
+ private handleAccountsChanged;
442
446
  /**
443
447
  * Connect account for signing transactions
444
448
  * Accepts either a private key string or a modern wallet provider
package/dist/index.js CHANGED
@@ -620,14 +620,15 @@ var signSessionKey = async (config, sessions, allPublicClients) => {
620
620
  // src/core/ZyfaiSDK.ts
621
621
  var import_siwe = require("siwe");
622
622
  var ZyfaiSDK = class {
623
- // TODO: The environment should be removed. Having the same key for staging and production is not ideal, but for now it's fine.
623
+ // Store reference to current provider for event handling
624
624
  constructor(config) {
625
625
  this.signer = null;
626
626
  this.walletClient = null;
627
- this.isAuthenticated = false;
628
627
  this.authenticatedUserId = null;
629
- // Stored from login response
628
+ // If non-null, user is authenticated
630
629
  this.hasActiveSessionKey = false;
630
+ // TODO: The environment should be removed. Having the same key for staging and production is not ideal, but for now it's fine.
631
+ this.currentProvider = null;
631
632
  const sdkConfig = typeof config === "string" ? { apiKey: config } : config;
632
633
  const { apiKey, dataApiKey, environment, bundlerApiKey } = sdkConfig;
633
634
  if (!apiKey) {
@@ -646,7 +647,7 @@ var ZyfaiSDK = class {
646
647
  */
647
648
  async authenticateUser() {
648
649
  try {
649
- if (this.isAuthenticated) {
650
+ if (this.authenticatedUserId !== null) {
650
651
  return;
651
652
  }
652
653
  const walletClient = this.getWalletClient();
@@ -685,14 +686,13 @@ var ZyfaiSDK = class {
685
686
  signature
686
687
  }
687
688
  );
688
- const authToken = loginResponse.accessToken || loginResponse.token;
689
+ const authToken = loginResponse.accessToken;
689
690
  if (!authToken) {
690
691
  throw new Error("Authentication response missing access token");
691
692
  }
692
693
  this.httpClient.setAuthToken(authToken);
693
694
  this.authenticatedUserId = loginResponse.userId || null;
694
695
  this.hasActiveSessionKey = loginResponse.hasActiveSessionKey || false;
695
- this.isAuthenticated = true;
696
696
  } catch (error) {
697
697
  throw new Error(
698
698
  `Failed to authenticate user: ${error.message}`
@@ -733,6 +733,43 @@ var ZyfaiSDK = class {
733
733
  );
734
734
  }
735
735
  }
736
+ /**
737
+ * Handle account changes from wallet provider
738
+ * Resets authentication state when wallet is switched
739
+ * @private
740
+ */
741
+ async handleAccountsChanged(accounts) {
742
+ if (!accounts || accounts.length === 0) {
743
+ await this.disconnectAccount();
744
+ return;
745
+ }
746
+ const newAddress = accounts[0];
747
+ const currentAddress = this.walletClient?.account?.address;
748
+ if (currentAddress && newAddress.toLowerCase() === currentAddress.toLowerCase()) {
749
+ return;
750
+ }
751
+ this.authenticatedUserId = null;
752
+ this.hasActiveSessionKey = false;
753
+ this.httpClient.clearAuthToken();
754
+ if (this.walletClient && this.currentProvider) {
755
+ const chainConfig = getChainConfig(
756
+ this.walletClient.chain?.id || 42161
757
+ );
758
+ this.walletClient = (0, import_viem4.createWalletClient)({
759
+ account: newAddress,
760
+ chain: chainConfig.chain,
761
+ transport: (0, import_viem4.custom)(this.currentProvider)
762
+ });
763
+ try {
764
+ await this.authenticateUser();
765
+ } catch (error) {
766
+ console.warn(
767
+ "Failed to authenticate after wallet switch:",
768
+ error.message
769
+ );
770
+ }
771
+ }
772
+ }
736
773
  /**
737
774
  * Connect account for signing transactions
738
775
  * Accepts either a private key string or a modern wallet provider
@@ -754,8 +791,14 @@ var ZyfaiSDK = class {
754
791
  if (!isSupportedChain(chainId)) {
755
792
  throw new Error(`Unsupported chain ID: ${chainId}`);
756
793
  }
757
- this.isAuthenticated = false;
794
+ this.authenticatedUserId = null;
758
795
  this.httpClient.clearAuthToken();
796
+ if (this.currentProvider?.removeAllListeners) {
797
+ try {
798
+ this.currentProvider.removeAllListeners("accountsChanged");
799
+ } catch (error) {
800
+ }
801
+ }
759
802
  const chainConfig = getChainConfig(chainId);
760
803
  let connectedAddress;
761
804
  if (typeof account === "string") {
@@ -770,6 +813,7 @@ var ZyfaiSDK = class {
770
813
  transport: (0, import_viem4.http)(chainConfig.rpcUrl)
771
814
  });
772
815
  connectedAddress = this.signer.address;
816
+ this.currentProvider = null;
773
817
  } else {
774
818
  const provider = account;
775
819
  if (!provider) {
@@ -790,6 +834,10 @@ var ZyfaiSDK = class {
790
834
  transport: (0, import_viem4.custom)(provider)
791
835
  });
792
836
  connectedAddress = accounts[0];
837
+ this.currentProvider = provider;
838
+ if (provider.on) {
839
+ provider.on("accountsChanged", this.handleAccountsChanged.bind(this));
840
+ }
793
841
  } else if (provider.account && provider.transport) {
794
842
  this.walletClient = (0, import_viem4.createWalletClient)({
795
843
  account: provider.account,
@@ -797,6 +845,7 @@ var ZyfaiSDK = class {
797
845
  transport: provider.transport
798
846
  });
799
847
  connectedAddress = provider.account.address;
848
+ this.currentProvider = null;
800
849
  } else {
801
850
  throw new Error(
802
851
  "Invalid wallet provider. Expected EIP-1193 provider or viem WalletClient."
@@ -817,9 +866,15 @@ var ZyfaiSDK = class {
817
866
  * ```
818
867
  */
819
868
  async disconnectAccount() {
869
+ if (this.currentProvider?.removeAllListeners) {
870
+ try {
871
+ this.currentProvider.removeAllListeners("accountsChanged");
872
+ } catch (error) {
873
+ }
874
+ }
820
875
  this.signer = null;
821
876
  this.walletClient = null;
822
- this.isAuthenticated = false;
877
+ this.currentProvider = null;
823
878
  this.authenticatedUserId = null;
824
879
  this.hasActiveSessionKey = false;
825
880
  this.httpClient.clearAuthToken();
@@ -1072,7 +1127,6 @@ var ZyfaiSDK = class {
1072
1127
  });
1073
1128
  return {
1074
1129
  success: true,
1075
- sessionKeyAddress: safeAddress,
1076
1130
  signature,
1077
1131
  sessionNonces
1078
1132
  };
package/dist/index.mjs CHANGED
@@ -599,14 +599,15 @@ var signSessionKey = async (config, sessions, allPublicClients) => {
599
599
  // src/core/ZyfaiSDK.ts
600
600
  import { SiweMessage } from "siwe";
601
601
  var ZyfaiSDK = class {
602
- // TODO: The environment should be removed. Having the same key for staging and production is not ideal, but for now it's fine.
602
+ // Store reference to current provider for event handling
603
603
  constructor(config) {
604
604
  this.signer = null;
605
605
  this.walletClient = null;
606
- this.isAuthenticated = false;
607
606
  this.authenticatedUserId = null;
608
- // Stored from login response
607
+ // If non-null, user is authenticated
609
608
  this.hasActiveSessionKey = false;
609
+ // TODO: The environment should be removed. Having the same key for staging and production is not ideal, but for now it's fine.
610
+ this.currentProvider = null;
610
611
  const sdkConfig = typeof config === "string" ? { apiKey: config } : config;
611
612
  const { apiKey, dataApiKey, environment, bundlerApiKey } = sdkConfig;
612
613
  if (!apiKey) {
@@ -625,7 +626,7 @@ var ZyfaiSDK = class {
625
626
  */
626
627
  async authenticateUser() {
627
628
  try {
628
- if (this.isAuthenticated) {
629
+ if (this.authenticatedUserId !== null) {
629
630
  return;
630
631
  }
631
632
  const walletClient = this.getWalletClient();
@@ -664,14 +665,13 @@ var ZyfaiSDK = class {
664
665
  signature
665
666
  }
666
667
  );
667
- const authToken = loginResponse.accessToken || loginResponse.token;
668
+ const authToken = loginResponse.accessToken;
668
669
  if (!authToken) {
669
670
  throw new Error("Authentication response missing access token");
670
671
  }
671
672
  this.httpClient.setAuthToken(authToken);
672
673
  this.authenticatedUserId = loginResponse.userId || null;
673
674
  this.hasActiveSessionKey = loginResponse.hasActiveSessionKey || false;
674
- this.isAuthenticated = true;
675
675
  } catch (error) {
676
676
  throw new Error(
677
677
  `Failed to authenticate user: ${error.message}`
@@ -712,6 +712,43 @@ var ZyfaiSDK = class {
712
712
  );
713
713
  }
714
714
  }
715
+ /**
716
+ * Handle account changes from wallet provider
717
+ * Resets authentication state when wallet is switched
718
+ * @private
719
+ */
720
+ async handleAccountsChanged(accounts) {
721
+ if (!accounts || accounts.length === 0) {
722
+ await this.disconnectAccount();
723
+ return;
724
+ }
725
+ const newAddress = accounts[0];
726
+ const currentAddress = this.walletClient?.account?.address;
727
+ if (currentAddress && newAddress.toLowerCase() === currentAddress.toLowerCase()) {
728
+ return;
729
+ }
730
+ this.authenticatedUserId = null;
731
+ this.hasActiveSessionKey = false;
732
+ this.httpClient.clearAuthToken();
733
+ if (this.walletClient && this.currentProvider) {
734
+ const chainConfig = getChainConfig(
735
+ this.walletClient.chain?.id || 42161
736
+ );
737
+ this.walletClient = createWalletClient({
738
+ account: newAddress,
739
+ chain: chainConfig.chain,
740
+ transport: custom(this.currentProvider)
741
+ });
742
+ try {
743
+ await this.authenticateUser();
744
+ } catch (error) {
745
+ console.warn(
746
+ "Failed to authenticate after wallet switch:",
747
+ error.message
748
+ );
749
+ }
750
+ }
751
+ }
715
752
  /**
716
753
  * Connect account for signing transactions
717
754
  * Accepts either a private key string or a modern wallet provider
@@ -733,8 +770,14 @@ var ZyfaiSDK = class {
733
770
  if (!isSupportedChain(chainId)) {
734
771
  throw new Error(`Unsupported chain ID: ${chainId}`);
735
772
  }
736
- this.isAuthenticated = false;
773
+ this.authenticatedUserId = null;
737
774
  this.httpClient.clearAuthToken();
775
+ if (this.currentProvider?.removeAllListeners) {
776
+ try {
777
+ this.currentProvider.removeAllListeners("accountsChanged");
778
+ } catch (error) {
779
+ }
780
+ }
738
781
  const chainConfig = getChainConfig(chainId);
739
782
  let connectedAddress;
740
783
  if (typeof account === "string") {
@@ -749,6 +792,7 @@ var ZyfaiSDK = class {
749
792
  transport: http3(chainConfig.rpcUrl)
750
793
  });
751
794
  connectedAddress = this.signer.address;
795
+ this.currentProvider = null;
752
796
  } else {
753
797
  const provider = account;
754
798
  if (!provider) {
@@ -769,6 +813,10 @@ var ZyfaiSDK = class {
769
813
  transport: custom(provider)
770
814
  });
771
815
  connectedAddress = accounts[0];
816
+ this.currentProvider = provider;
817
+ if (provider.on) {
818
+ provider.on("accountsChanged", this.handleAccountsChanged.bind(this));
819
+ }
772
820
  } else if (provider.account && provider.transport) {
773
821
  this.walletClient = createWalletClient({
774
822
  account: provider.account,
@@ -776,6 +824,7 @@ var ZyfaiSDK = class {
776
824
  transport: provider.transport
777
825
  });
778
826
  connectedAddress = provider.account.address;
827
+ this.currentProvider = null;
779
828
  } else {
780
829
  throw new Error(
781
830
  "Invalid wallet provider. Expected EIP-1193 provider or viem WalletClient."
@@ -796,9 +845,15 @@ var ZyfaiSDK = class {
796
845
  * ```
797
846
  */
798
847
  async disconnectAccount() {
848
+ if (this.currentProvider?.removeAllListeners) {
849
+ try {
850
+ this.currentProvider.removeAllListeners("accountsChanged");
851
+ } catch (error) {
852
+ }
853
+ }
799
854
  this.signer = null;
800
855
  this.walletClient = null;
801
- this.isAuthenticated = false;
856
+ this.currentProvider = null;
802
857
  this.authenticatedUserId = null;
803
858
  this.hasActiveSessionKey = false;
804
859
  this.httpClient.clearAuthToken();
@@ -1051,7 +1106,6 @@ var ZyfaiSDK = class {
1051
1106
  });
1052
1107
  return {
1053
1108
  success: true,
1054
- sessionKeyAddress: safeAddress,
1055
1109
  signature,
1056
1110
  sessionNonces
1057
1111
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zyfai/sdk",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "TypeScript SDK for ZyFAI Yield Optimization Engine - Deploy Safe smart wallets, manage session keys, and interact with DeFi protocols",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -28,7 +28,13 @@
28
28
  "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
29
29
  "lint": "eslint src --ext .ts",
30
30
  "test": "jest",
31
- "prepublishOnly": "npm run build"
31
+ "prepublishOnly": "npm run build",
32
+ "docs": "typedoc",
33
+ "docs:watch": "typedoc --watch",
34
+ "docs:json": "typedoc --json docs/api.json",
35
+ "docs:dev": "cd website && pnpm start",
36
+ "docs:build": "pnpm docs && cd website && pnpm build",
37
+ "docs:serve": "cd website && pnpm serve"
32
38
  },
33
39
  "keywords": [
34
40
  "zyfai",
@@ -70,6 +76,8 @@
70
76
  "@types/node": "^20.0.0",
71
77
  "dotenv": "^17.2.3",
72
78
  "tsup": "^8.0.0",
79
+ "typedoc": "^0.28.15",
80
+ "typedoc-plugin-markdown": "^4.9.0",
73
81
  "typescript": "^5.3.0"
74
82
  },
75
83
  "peerDependencies": {