cryptique-sdk 1.0.0 → 1.0.1

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/lib/cjs/index.js CHANGED
@@ -2447,6 +2447,12 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
2447
2447
  APIClient.updateUTMEventWithWallet().catch((error) => {
2448
2448
  console.error('Error updating UTM event with wallet:', error);
2449
2449
  });
2450
+
2451
+ // Automatic wallet address matching - check if wallet exists for another user
2452
+ IdentityManager.walletAddress(walletAddress).catch((error) => {
2453
+ console.warn('Error in automatic wallet address matching:', error);
2454
+ // Non-critical error, continue normally
2455
+ });
2450
2456
  }
2451
2457
 
2452
2458
  return {
@@ -5777,6 +5783,185 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
5777
5783
  }
5778
5784
  };
5779
5785
 
5786
+ // ============================================================================
5787
+ // SECTION 14: IDENTITY MANAGEMENT
5788
+ // ============================================================================
5789
+ // PURPOSE: Handle user identity merging via identify() and walletAddress() methods
5790
+ // Similar to Mixpanel's identify system
5791
+ // ============================================================================
5792
+
5793
+ const IdentityManager = {
5794
+ /**
5795
+ * Identify a user with a unique identifier
5796
+ *
5797
+ * When called, checks if this identify_id exists for another user.
5798
+ * If found, merges the current user_id with the existing user_id.
5799
+ *
5800
+ * @param {string} identifyId - Unique identifier for the user
5801
+ * @returns {Promise<Object>} Result object with merged status and new userId
5802
+ */
5803
+ async identify(identifyId) {
5804
+ if (!identifyId || typeof identifyId !== 'string' || identifyId.trim() === '') {
5805
+ console.error('❌ [Identity] identify() requires a non-empty string');
5806
+ return { success: false, error: 'Invalid identifyId' };
5807
+ }
5808
+
5809
+ try {
5810
+ // Get current session and user data
5811
+ const session = StorageManager.loadSession();
5812
+ if (!session || !session.id) {
5813
+ console.error('❌ [Identity] No active session found');
5814
+ return { success: false, error: 'No active session' };
5815
+ }
5816
+
5817
+ const currentUserId = StorageManager.getUserId();
5818
+ if (!currentUserId) {
5819
+ console.error('❌ [Identity] No user ID found');
5820
+ return { success: false, error: 'No user ID' };
5821
+ }
5822
+
5823
+ if (!SITE_ID) {
5824
+ console.error('❌ [Identity] Site ID not found');
5825
+ return { success: false, error: 'Site ID not found' };
5826
+ }
5827
+
5828
+ // Call API endpoint
5829
+ const apiUrl = CONFIG.API.TRACK.replace('/track', '/identify');
5830
+ const response = await fetch(apiUrl, {
5831
+ method: 'POST',
5832
+ headers: {
5833
+ 'Content-Type': 'application/json',
5834
+ 'X-Cryptique-Site-Id': SITE_ID
5835
+ },
5836
+ body: JSON.stringify({
5837
+ siteId: SITE_ID,
5838
+ sessionId: session.id,
5839
+ userId: currentUserId,
5840
+ identifyId: identifyId.trim()
5841
+ })
5842
+ });
5843
+
5844
+ if (!response.ok) {
5845
+ const errorData = await response.text();
5846
+ console.error('❌ [Identity] API error:', {
5847
+ status: response.status,
5848
+ statusText: response.statusText,
5849
+ error: errorData
5850
+ });
5851
+ throw new Error(`Identity API error: ${response.status} ${response.statusText} - ${errorData}`);
5852
+ }
5853
+
5854
+ const result = await response.json();
5855
+
5856
+ // If merge occurred, update localStorage and session data
5857
+ if (result.merged && result.newUserId) {
5858
+ // Update localStorage with new user ID
5859
+ localStorage.setItem(CONFIG.STORAGE_KEYS.USER_ID, result.newUserId);
5860
+
5861
+ // Update session data
5862
+ sessionData.userId = result.newUserId;
5863
+ session.userId = result.newUserId;
5864
+ StorageManager.saveSession(session);
5865
+
5866
+ // Update userSession
5867
+ userSession.userId = result.newUserId;
5868
+
5869
+ console.log(`✅ [Identity] User merged: ${currentUserId} → ${result.newUserId}`);
5870
+ }
5871
+
5872
+ return result;
5873
+ } catch (error) {
5874
+ console.error('❌ [Identity] Error in identify():', error);
5875
+ return { success: false, error: error.message };
5876
+ }
5877
+ },
5878
+
5879
+ /**
5880
+ * Set wallet address for current user
5881
+ *
5882
+ * If wallet address already exists for another user, merges identities.
5883
+ * Otherwise, sets wallet address for current user (primary or other_wallets).
5884
+ *
5885
+ * @param {string} walletAddress - Wallet address to set
5886
+ * @returns {Promise<Object>} Result object with merged status and new userId
5887
+ */
5888
+ async walletAddress(walletAddress) {
5889
+ if (!walletAddress || typeof walletAddress !== 'string' || walletAddress.trim() === '') {
5890
+ console.error('❌ [Identity] walletAddress() requires a non-empty string');
5891
+ return { success: false, error: 'Invalid wallet address' };
5892
+ }
5893
+
5894
+ try {
5895
+ // Get current session and user data
5896
+ const session = StorageManager.loadSession();
5897
+ if (!session || !session.id) {
5898
+ console.error('❌ [Identity] No active session found');
5899
+ return { success: false, error: 'No active session' };
5900
+ }
5901
+
5902
+ const currentUserId = StorageManager.getUserId();
5903
+ if (!currentUserId) {
5904
+ console.error('❌ [Identity] No user ID found');
5905
+ return { success: false, error: 'No user ID' };
5906
+ }
5907
+
5908
+ if (!SITE_ID) {
5909
+ console.error('❌ [Identity] Site ID not found');
5910
+ return { success: false, error: 'Site ID not found' };
5911
+ }
5912
+
5913
+ // Call API endpoint
5914
+ const apiUrl = CONFIG.API.TRACK.replace('/track', '/wallet-address');
5915
+ const response = await fetch(apiUrl, {
5916
+ method: 'POST',
5917
+ headers: {
5918
+ 'Content-Type': 'application/json',
5919
+ 'X-Cryptique-Site-Id': SITE_ID
5920
+ },
5921
+ body: JSON.stringify({
5922
+ siteId: SITE_ID,
5923
+ sessionId: session.id,
5924
+ userId: currentUserId,
5925
+ walletAddress: walletAddress.trim()
5926
+ })
5927
+ });
5928
+
5929
+ if (!response.ok) {
5930
+ const errorData = await response.text();
5931
+ console.error('❌ [Identity] API error:', {
5932
+ status: response.status,
5933
+ statusText: response.statusText,
5934
+ error: errorData
5935
+ });
5936
+ throw new Error(`Wallet Address API error: ${response.status} ${response.statusText} - ${errorData}`);
5937
+ }
5938
+
5939
+ const result = await response.json();
5940
+
5941
+ // If merge occurred, update localStorage and session data
5942
+ if (result.merged && result.newUserId) {
5943
+ // Update localStorage with new user ID
5944
+ localStorage.setItem(CONFIG.STORAGE_KEYS.USER_ID, result.newUserId);
5945
+
5946
+ // Update session data
5947
+ sessionData.userId = result.newUserId;
5948
+ session.userId = result.newUserId;
5949
+ StorageManager.saveSession(session);
5950
+
5951
+ // Update userSession
5952
+ userSession.userId = result.newUserId;
5953
+
5954
+ console.log(`✅ [Identity] User merged via wallet: ${currentUserId} → ${result.newUserId}`);
5955
+ }
5956
+
5957
+ return result;
5958
+ } catch (error) {
5959
+ console.error('❌ [Identity] Error in walletAddress():', error);
5960
+ return { success: false, error: error.message };
5961
+ }
5962
+ }
5963
+ };
5964
+
5780
5965
  // ============================================================================
5781
5966
  // AUTO EVENTS CONFIGURATION HELPER
5782
5967
  // ============================================================================
@@ -6189,6 +6374,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6189
6374
  isWalletConnected: WalletManager.checkWalletConnected.bind(WalletManager),
6190
6375
  updateWalletInfo: WalletManager.updateWalletInfo.bind(WalletManager),
6191
6376
 
6377
+ // Identity Functions
6378
+ identify: IdentityManager.identify.bind(IdentityManager),
6379
+ walletAddress: IdentityManager.walletAddress.bind(IdentityManager),
6380
+
6192
6381
  // Consent Functions
6193
6382
  setTrackingConsent: StorageManager.setConsent.bind(StorageManager),
6194
6383
  getTrackingConsent: StorageManager.getConsent.bind(StorageManager),
@@ -6453,6 +6642,40 @@ const CryptiqueSDK = {
6453
6642
  return window.Cryptique;
6454
6643
  }
6455
6644
  return null;
6645
+ },
6646
+
6647
+ /**
6648
+ * Identify a user with a unique identifier
6649
+ *
6650
+ * When called, checks if this identify_id exists for another user.
6651
+ * If found, merges the current user_id with the existing user_id.
6652
+ *
6653
+ * @param {string} identifyId - Unique identifier for the user
6654
+ * @returns {Promise<Object>} Result object with merged status and new userId
6655
+ */
6656
+ async identify(identifyId) {
6657
+ const instance = this.getInstance();
6658
+ if (instance && instance.identify) {
6659
+ return await instance.identify(identifyId);
6660
+ }
6661
+ throw new Error('SDK not initialized. Call init() first.');
6662
+ },
6663
+
6664
+ /**
6665
+ * Set wallet address for current user
6666
+ *
6667
+ * If wallet address already exists for another user, merges identities.
6668
+ * Otherwise, sets wallet address for current user.
6669
+ *
6670
+ * @param {string} walletAddress - Wallet address to set
6671
+ * @returns {Promise<Object>} Result object with merged status and new userId
6672
+ */
6673
+ async walletAddress(walletAddress) {
6674
+ const instance = this.getInstance();
6675
+ if (instance && instance.walletAddress) {
6676
+ return await instance.walletAddress(walletAddress);
6677
+ }
6678
+ throw new Error('SDK not initialized. Call init() first.');
6456
6679
  }
6457
6680
  };
6458
6681
 
package/lib/esm/index.js CHANGED
@@ -2445,6 +2445,12 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
2445
2445
  APIClient.updateUTMEventWithWallet().catch((error) => {
2446
2446
  console.error('Error updating UTM event with wallet:', error);
2447
2447
  });
2448
+
2449
+ // Automatic wallet address matching - check if wallet exists for another user
2450
+ IdentityManager.walletAddress(walletAddress).catch((error) => {
2451
+ console.warn('Error in automatic wallet address matching:', error);
2452
+ // Non-critical error, continue normally
2453
+ });
2448
2454
  }
2449
2455
 
2450
2456
  return {
@@ -5775,6 +5781,185 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
5775
5781
  }
5776
5782
  };
5777
5783
 
5784
+ // ============================================================================
5785
+ // SECTION 14: IDENTITY MANAGEMENT
5786
+ // ============================================================================
5787
+ // PURPOSE: Handle user identity merging via identify() and walletAddress() methods
5788
+ // Similar to Mixpanel's identify system
5789
+ // ============================================================================
5790
+
5791
+ const IdentityManager = {
5792
+ /**
5793
+ * Identify a user with a unique identifier
5794
+ *
5795
+ * When called, checks if this identify_id exists for another user.
5796
+ * If found, merges the current user_id with the existing user_id.
5797
+ *
5798
+ * @param {string} identifyId - Unique identifier for the user
5799
+ * @returns {Promise<Object>} Result object with merged status and new userId
5800
+ */
5801
+ async identify(identifyId) {
5802
+ if (!identifyId || typeof identifyId !== 'string' || identifyId.trim() === '') {
5803
+ console.error('❌ [Identity] identify() requires a non-empty string');
5804
+ return { success: false, error: 'Invalid identifyId' };
5805
+ }
5806
+
5807
+ try {
5808
+ // Get current session and user data
5809
+ const session = StorageManager.loadSession();
5810
+ if (!session || !session.id) {
5811
+ console.error('❌ [Identity] No active session found');
5812
+ return { success: false, error: 'No active session' };
5813
+ }
5814
+
5815
+ const currentUserId = StorageManager.getUserId();
5816
+ if (!currentUserId) {
5817
+ console.error('❌ [Identity] No user ID found');
5818
+ return { success: false, error: 'No user ID' };
5819
+ }
5820
+
5821
+ if (!SITE_ID) {
5822
+ console.error('❌ [Identity] Site ID not found');
5823
+ return { success: false, error: 'Site ID not found' };
5824
+ }
5825
+
5826
+ // Call API endpoint
5827
+ const apiUrl = CONFIG.API.TRACK.replace('/track', '/identify');
5828
+ const response = await fetch(apiUrl, {
5829
+ method: 'POST',
5830
+ headers: {
5831
+ 'Content-Type': 'application/json',
5832
+ 'X-Cryptique-Site-Id': SITE_ID
5833
+ },
5834
+ body: JSON.stringify({
5835
+ siteId: SITE_ID,
5836
+ sessionId: session.id,
5837
+ userId: currentUserId,
5838
+ identifyId: identifyId.trim()
5839
+ })
5840
+ });
5841
+
5842
+ if (!response.ok) {
5843
+ const errorData = await response.text();
5844
+ console.error('❌ [Identity] API error:', {
5845
+ status: response.status,
5846
+ statusText: response.statusText,
5847
+ error: errorData
5848
+ });
5849
+ throw new Error(`Identity API error: ${response.status} ${response.statusText} - ${errorData}`);
5850
+ }
5851
+
5852
+ const result = await response.json();
5853
+
5854
+ // If merge occurred, update localStorage and session data
5855
+ if (result.merged && result.newUserId) {
5856
+ // Update localStorage with new user ID
5857
+ localStorage.setItem(CONFIG.STORAGE_KEYS.USER_ID, result.newUserId);
5858
+
5859
+ // Update session data
5860
+ sessionData.userId = result.newUserId;
5861
+ session.userId = result.newUserId;
5862
+ StorageManager.saveSession(session);
5863
+
5864
+ // Update userSession
5865
+ userSession.userId = result.newUserId;
5866
+
5867
+ console.log(`✅ [Identity] User merged: ${currentUserId} → ${result.newUserId}`);
5868
+ }
5869
+
5870
+ return result;
5871
+ } catch (error) {
5872
+ console.error('❌ [Identity] Error in identify():', error);
5873
+ return { success: false, error: error.message };
5874
+ }
5875
+ },
5876
+
5877
+ /**
5878
+ * Set wallet address for current user
5879
+ *
5880
+ * If wallet address already exists for another user, merges identities.
5881
+ * Otherwise, sets wallet address for current user (primary or other_wallets).
5882
+ *
5883
+ * @param {string} walletAddress - Wallet address to set
5884
+ * @returns {Promise<Object>} Result object with merged status and new userId
5885
+ */
5886
+ async walletAddress(walletAddress) {
5887
+ if (!walletAddress || typeof walletAddress !== 'string' || walletAddress.trim() === '') {
5888
+ console.error('❌ [Identity] walletAddress() requires a non-empty string');
5889
+ return { success: false, error: 'Invalid wallet address' };
5890
+ }
5891
+
5892
+ try {
5893
+ // Get current session and user data
5894
+ const session = StorageManager.loadSession();
5895
+ if (!session || !session.id) {
5896
+ console.error('❌ [Identity] No active session found');
5897
+ return { success: false, error: 'No active session' };
5898
+ }
5899
+
5900
+ const currentUserId = StorageManager.getUserId();
5901
+ if (!currentUserId) {
5902
+ console.error('❌ [Identity] No user ID found');
5903
+ return { success: false, error: 'No user ID' };
5904
+ }
5905
+
5906
+ if (!SITE_ID) {
5907
+ console.error('❌ [Identity] Site ID not found');
5908
+ return { success: false, error: 'Site ID not found' };
5909
+ }
5910
+
5911
+ // Call API endpoint
5912
+ const apiUrl = CONFIG.API.TRACK.replace('/track', '/wallet-address');
5913
+ const response = await fetch(apiUrl, {
5914
+ method: 'POST',
5915
+ headers: {
5916
+ 'Content-Type': 'application/json',
5917
+ 'X-Cryptique-Site-Id': SITE_ID
5918
+ },
5919
+ body: JSON.stringify({
5920
+ siteId: SITE_ID,
5921
+ sessionId: session.id,
5922
+ userId: currentUserId,
5923
+ walletAddress: walletAddress.trim()
5924
+ })
5925
+ });
5926
+
5927
+ if (!response.ok) {
5928
+ const errorData = await response.text();
5929
+ console.error('❌ [Identity] API error:', {
5930
+ status: response.status,
5931
+ statusText: response.statusText,
5932
+ error: errorData
5933
+ });
5934
+ throw new Error(`Wallet Address API error: ${response.status} ${response.statusText} - ${errorData}`);
5935
+ }
5936
+
5937
+ const result = await response.json();
5938
+
5939
+ // If merge occurred, update localStorage and session data
5940
+ if (result.merged && result.newUserId) {
5941
+ // Update localStorage with new user ID
5942
+ localStorage.setItem(CONFIG.STORAGE_KEYS.USER_ID, result.newUserId);
5943
+
5944
+ // Update session data
5945
+ sessionData.userId = result.newUserId;
5946
+ session.userId = result.newUserId;
5947
+ StorageManager.saveSession(session);
5948
+
5949
+ // Update userSession
5950
+ userSession.userId = result.newUserId;
5951
+
5952
+ console.log(`✅ [Identity] User merged via wallet: ${currentUserId} → ${result.newUserId}`);
5953
+ }
5954
+
5955
+ return result;
5956
+ } catch (error) {
5957
+ console.error('❌ [Identity] Error in walletAddress():', error);
5958
+ return { success: false, error: error.message };
5959
+ }
5960
+ }
5961
+ };
5962
+
5778
5963
  // ============================================================================
5779
5964
  // AUTO EVENTS CONFIGURATION HELPER
5780
5965
  // ============================================================================
@@ -6187,6 +6372,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6187
6372
  isWalletConnected: WalletManager.checkWalletConnected.bind(WalletManager),
6188
6373
  updateWalletInfo: WalletManager.updateWalletInfo.bind(WalletManager),
6189
6374
 
6375
+ // Identity Functions
6376
+ identify: IdentityManager.identify.bind(IdentityManager),
6377
+ walletAddress: IdentityManager.walletAddress.bind(IdentityManager),
6378
+
6190
6379
  // Consent Functions
6191
6380
  setTrackingConsent: StorageManager.setConsent.bind(StorageManager),
6192
6381
  getTrackingConsent: StorageManager.getConsent.bind(StorageManager),
@@ -6451,6 +6640,40 @@ const CryptiqueSDK = {
6451
6640
  return window.Cryptique;
6452
6641
  }
6453
6642
  return null;
6643
+ },
6644
+
6645
+ /**
6646
+ * Identify a user with a unique identifier
6647
+ *
6648
+ * When called, checks if this identify_id exists for another user.
6649
+ * If found, merges the current user_id with the existing user_id.
6650
+ *
6651
+ * @param {string} identifyId - Unique identifier for the user
6652
+ * @returns {Promise<Object>} Result object with merged status and new userId
6653
+ */
6654
+ async identify(identifyId) {
6655
+ const instance = this.getInstance();
6656
+ if (instance && instance.identify) {
6657
+ return await instance.identify(identifyId);
6658
+ }
6659
+ throw new Error('SDK not initialized. Call init() first.');
6660
+ },
6661
+
6662
+ /**
6663
+ * Set wallet address for current user
6664
+ *
6665
+ * If wallet address already exists for another user, merges identities.
6666
+ * Otherwise, sets wallet address for current user.
6667
+ *
6668
+ * @param {string} walletAddress - Wallet address to set
6669
+ * @returns {Promise<Object>} Result object with merged status and new userId
6670
+ */
6671
+ async walletAddress(walletAddress) {
6672
+ const instance = this.getInstance();
6673
+ if (instance && instance.walletAddress) {
6674
+ return await instance.walletAddress(walletAddress);
6675
+ }
6676
+ throw new Error('SDK not initialized. Call init() first.');
6454
6677
  }
6455
6678
  };
6456
6679
 
@@ -79,6 +79,18 @@ export default class CryptiqueSDK {
79
79
  */
80
80
  updateWalletInfo(): Promise<any>;
81
81
 
82
+ /**
83
+ * Identify a user with a unique identifier
84
+ * Merges identities if the identifier already exists for another user
85
+ */
86
+ identify(identifyId: string): Promise<{ success: boolean; merged?: boolean; newUserId?: string; error?: string }>;
87
+
88
+ /**
89
+ * Set wallet address for current user
90
+ * Merges identities if wallet address already exists for another user
91
+ */
92
+ walletAddress(walletAddress: string): Promise<{ success: boolean; merged?: boolean; newUserId?: string; error?: string }>;
93
+
82
94
  /**
83
95
  * Set tracking consent
84
96
  */
package/lib/umd/index.js CHANGED
@@ -2451,6 +2451,12 @@
2451
2451
  APIClient.updateUTMEventWithWallet().catch((error) => {
2452
2452
  console.error('Error updating UTM event with wallet:', error);
2453
2453
  });
2454
+
2455
+ // Automatic wallet address matching - check if wallet exists for another user
2456
+ IdentityManager.walletAddress(walletAddress).catch((error) => {
2457
+ console.warn('Error in automatic wallet address matching:', error);
2458
+ // Non-critical error, continue normally
2459
+ });
2454
2460
  }
2455
2461
 
2456
2462
  return {
@@ -5781,6 +5787,185 @@
5781
5787
  }
5782
5788
  };
5783
5789
 
5790
+ // ============================================================================
5791
+ // SECTION 14: IDENTITY MANAGEMENT
5792
+ // ============================================================================
5793
+ // PURPOSE: Handle user identity merging via identify() and walletAddress() methods
5794
+ // Similar to Mixpanel's identify system
5795
+ // ============================================================================
5796
+
5797
+ const IdentityManager = {
5798
+ /**
5799
+ * Identify a user with a unique identifier
5800
+ *
5801
+ * When called, checks if this identify_id exists for another user.
5802
+ * If found, merges the current user_id with the existing user_id.
5803
+ *
5804
+ * @param {string} identifyId - Unique identifier for the user
5805
+ * @returns {Promise<Object>} Result object with merged status and new userId
5806
+ */
5807
+ async identify(identifyId) {
5808
+ if (!identifyId || typeof identifyId !== 'string' || identifyId.trim() === '') {
5809
+ console.error('❌ [Identity] identify() requires a non-empty string');
5810
+ return { success: false, error: 'Invalid identifyId' };
5811
+ }
5812
+
5813
+ try {
5814
+ // Get current session and user data
5815
+ const session = StorageManager.loadSession();
5816
+ if (!session || !session.id) {
5817
+ console.error('❌ [Identity] No active session found');
5818
+ return { success: false, error: 'No active session' };
5819
+ }
5820
+
5821
+ const currentUserId = StorageManager.getUserId();
5822
+ if (!currentUserId) {
5823
+ console.error('❌ [Identity] No user ID found');
5824
+ return { success: false, error: 'No user ID' };
5825
+ }
5826
+
5827
+ if (!SITE_ID) {
5828
+ console.error('❌ [Identity] Site ID not found');
5829
+ return { success: false, error: 'Site ID not found' };
5830
+ }
5831
+
5832
+ // Call API endpoint
5833
+ const apiUrl = CONFIG.API.TRACK.replace('/track', '/identify');
5834
+ const response = await fetch(apiUrl, {
5835
+ method: 'POST',
5836
+ headers: {
5837
+ 'Content-Type': 'application/json',
5838
+ 'X-Cryptique-Site-Id': SITE_ID
5839
+ },
5840
+ body: JSON.stringify({
5841
+ siteId: SITE_ID,
5842
+ sessionId: session.id,
5843
+ userId: currentUserId,
5844
+ identifyId: identifyId.trim()
5845
+ })
5846
+ });
5847
+
5848
+ if (!response.ok) {
5849
+ const errorData = await response.text();
5850
+ console.error('❌ [Identity] API error:', {
5851
+ status: response.status,
5852
+ statusText: response.statusText,
5853
+ error: errorData
5854
+ });
5855
+ throw new Error(`Identity API error: ${response.status} ${response.statusText} - ${errorData}`);
5856
+ }
5857
+
5858
+ const result = await response.json();
5859
+
5860
+ // If merge occurred, update localStorage and session data
5861
+ if (result.merged && result.newUserId) {
5862
+ // Update localStorage with new user ID
5863
+ localStorage.setItem(CONFIG.STORAGE_KEYS.USER_ID, result.newUserId);
5864
+
5865
+ // Update session data
5866
+ sessionData.userId = result.newUserId;
5867
+ session.userId = result.newUserId;
5868
+ StorageManager.saveSession(session);
5869
+
5870
+ // Update userSession
5871
+ userSession.userId = result.newUserId;
5872
+
5873
+ console.log(`✅ [Identity] User merged: ${currentUserId} → ${result.newUserId}`);
5874
+ }
5875
+
5876
+ return result;
5877
+ } catch (error) {
5878
+ console.error('❌ [Identity] Error in identify():', error);
5879
+ return { success: false, error: error.message };
5880
+ }
5881
+ },
5882
+
5883
+ /**
5884
+ * Set wallet address for current user
5885
+ *
5886
+ * If wallet address already exists for another user, merges identities.
5887
+ * Otherwise, sets wallet address for current user (primary or other_wallets).
5888
+ *
5889
+ * @param {string} walletAddress - Wallet address to set
5890
+ * @returns {Promise<Object>} Result object with merged status and new userId
5891
+ */
5892
+ async walletAddress(walletAddress) {
5893
+ if (!walletAddress || typeof walletAddress !== 'string' || walletAddress.trim() === '') {
5894
+ console.error('❌ [Identity] walletAddress() requires a non-empty string');
5895
+ return { success: false, error: 'Invalid wallet address' };
5896
+ }
5897
+
5898
+ try {
5899
+ // Get current session and user data
5900
+ const session = StorageManager.loadSession();
5901
+ if (!session || !session.id) {
5902
+ console.error('❌ [Identity] No active session found');
5903
+ return { success: false, error: 'No active session' };
5904
+ }
5905
+
5906
+ const currentUserId = StorageManager.getUserId();
5907
+ if (!currentUserId) {
5908
+ console.error('❌ [Identity] No user ID found');
5909
+ return { success: false, error: 'No user ID' };
5910
+ }
5911
+
5912
+ if (!SITE_ID) {
5913
+ console.error('❌ [Identity] Site ID not found');
5914
+ return { success: false, error: 'Site ID not found' };
5915
+ }
5916
+
5917
+ // Call API endpoint
5918
+ const apiUrl = CONFIG.API.TRACK.replace('/track', '/wallet-address');
5919
+ const response = await fetch(apiUrl, {
5920
+ method: 'POST',
5921
+ headers: {
5922
+ 'Content-Type': 'application/json',
5923
+ 'X-Cryptique-Site-Id': SITE_ID
5924
+ },
5925
+ body: JSON.stringify({
5926
+ siteId: SITE_ID,
5927
+ sessionId: session.id,
5928
+ userId: currentUserId,
5929
+ walletAddress: walletAddress.trim()
5930
+ })
5931
+ });
5932
+
5933
+ if (!response.ok) {
5934
+ const errorData = await response.text();
5935
+ console.error('❌ [Identity] API error:', {
5936
+ status: response.status,
5937
+ statusText: response.statusText,
5938
+ error: errorData
5939
+ });
5940
+ throw new Error(`Wallet Address API error: ${response.status} ${response.statusText} - ${errorData}`);
5941
+ }
5942
+
5943
+ const result = await response.json();
5944
+
5945
+ // If merge occurred, update localStorage and session data
5946
+ if (result.merged && result.newUserId) {
5947
+ // Update localStorage with new user ID
5948
+ localStorage.setItem(CONFIG.STORAGE_KEYS.USER_ID, result.newUserId);
5949
+
5950
+ // Update session data
5951
+ sessionData.userId = result.newUserId;
5952
+ session.userId = result.newUserId;
5953
+ StorageManager.saveSession(session);
5954
+
5955
+ // Update userSession
5956
+ userSession.userId = result.newUserId;
5957
+
5958
+ console.log(`✅ [Identity] User merged via wallet: ${currentUserId} → ${result.newUserId}`);
5959
+ }
5960
+
5961
+ return result;
5962
+ } catch (error) {
5963
+ console.error('❌ [Identity] Error in walletAddress():', error);
5964
+ return { success: false, error: error.message };
5965
+ }
5966
+ }
5967
+ };
5968
+
5784
5969
  // ============================================================================
5785
5970
  // AUTO EVENTS CONFIGURATION HELPER
5786
5971
  // ============================================================================
@@ -6193,6 +6378,10 @@
6193
6378
  isWalletConnected: WalletManager.checkWalletConnected.bind(WalletManager),
6194
6379
  updateWalletInfo: WalletManager.updateWalletInfo.bind(WalletManager),
6195
6380
 
6381
+ // Identity Functions
6382
+ identify: IdentityManager.identify.bind(IdentityManager),
6383
+ walletAddress: IdentityManager.walletAddress.bind(IdentityManager),
6384
+
6196
6385
  // Consent Functions
6197
6386
  setTrackingConsent: StorageManager.setConsent.bind(StorageManager),
6198
6387
  getTrackingConsent: StorageManager.getConsent.bind(StorageManager),
@@ -6457,6 +6646,40 @@
6457
6646
  return window.Cryptique;
6458
6647
  }
6459
6648
  return null;
6649
+ },
6650
+
6651
+ /**
6652
+ * Identify a user with a unique identifier
6653
+ *
6654
+ * When called, checks if this identify_id exists for another user.
6655
+ * If found, merges the current user_id with the existing user_id.
6656
+ *
6657
+ * @param {string} identifyId - Unique identifier for the user
6658
+ * @returns {Promise<Object>} Result object with merged status and new userId
6659
+ */
6660
+ async identify(identifyId) {
6661
+ const instance = this.getInstance();
6662
+ if (instance && instance.identify) {
6663
+ return await instance.identify(identifyId);
6664
+ }
6665
+ throw new Error('SDK not initialized. Call init() first.');
6666
+ },
6667
+
6668
+ /**
6669
+ * Set wallet address for current user
6670
+ *
6671
+ * If wallet address already exists for another user, merges identities.
6672
+ * Otherwise, sets wallet address for current user.
6673
+ *
6674
+ * @param {string} walletAddress - Wallet address to set
6675
+ * @returns {Promise<Object>} Result object with merged status and new userId
6676
+ */
6677
+ async walletAddress(walletAddress) {
6678
+ const instance = this.getInstance();
6679
+ if (instance && instance.walletAddress) {
6680
+ return await instance.walletAddress(walletAddress);
6681
+ }
6682
+ throw new Error('SDK not initialized. Call init() first.');
6460
6683
  }
6461
6684
  };
6462
6685
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cryptique-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "description": "Cryptique Analytics SDK - Comprehensive web analytics and user tracking for modern web applications",
6
6
  "main": "lib/cjs/index.js",
@@ -34,7 +34,7 @@
34
34
  "license": "ISC",
35
35
  "repository": {
36
36
  "type": "git",
37
- "url": "https://github.com/cryptique/cryptique-sdk.git"
37
+ "url": "git+https://github.com/cryptique/cryptique-sdk.git"
38
38
  },
39
39
  "exports": {
40
40
  ".": {