cryptique-sdk 1.2.2 → 1.2.4

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
@@ -24,6 +24,11 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
24
24
  window.Cryptique = window.Cryptique || {};
25
25
  window.Cryptique.initialized = true;
26
26
 
27
+ // Capture native fetch before any third-party library (wagmi, viem, etc.)
28
+ // can patch window.fetch. All SDK outgoing requests use this reference
29
+ // directly so they are never affected by external fetch wrappers.
30
+ const _nativeFetch = window.fetch.bind(window);
31
+
27
32
  // ============================================================================
28
33
  // SECTION 1: CONFIGURATION
29
34
  // ============================================================================
@@ -563,7 +568,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
563
568
  // Construct migration endpoint URL from track endpoint
564
569
  const migrationUrl = CONFIG.API.TRACK.replace('/track', '/migrate-user-id');
565
570
 
566
- const response = await fetch(migrationUrl, {
571
+ const response = await _nativeFetch(migrationUrl, {
567
572
  method: 'POST',
568
573
  headers: {
569
574
  'Content-Type': 'application/json'
@@ -2875,14 +2880,34 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
2875
2880
  });
2876
2881
 
2877
2882
  // Automatic wallet address matching - only call once per address per session
2878
- // Prevents repeated calls to /api/sdk/wallet-address on every interval tick
2883
+ // Prevents repeated calls to /api/sdk/wallet-address on every interval tick.
2884
+ // Also guards against the race condition where the wallet is detected before the
2885
+ // initial session POST has completed on the backend (which would return 404).
2886
+ // We wait until isInitialized is true (meaning sendInitialSessionData has run)
2887
+ // plus an extra 1 s buffer to ensure the backend has persisted the session.
2879
2888
  if (walletAddress !== runtimeState.reportedWalletAddress) {
2880
2889
  runtimeState.reportedWalletAddress = walletAddress;
2881
- IdentityManager.walletAddress(walletAddress).catch((error) => {
2882
- console.warn('Error in automatic wallet address matching:', error);
2883
- // Reset so it retries next time wallet info is updated
2884
- runtimeState.reportedWalletAddress = null;
2885
- });
2890
+ const _sendWalletAddress = () => {
2891
+ IdentityManager.walletAddress(walletAddress).catch((error) => {
2892
+ console.warn('Error in automatic wallet address matching:', error);
2893
+ // Reset so it retries next time wallet info is updated
2894
+ runtimeState.reportedWalletAddress = null;
2895
+ });
2896
+ };
2897
+ if (runtimeState.isInitialized) {
2898
+ // SDK already fully initialised - still give backend 1 s to persist session
2899
+ setTimeout(_sendWalletAddress, 1000);
2900
+ } else {
2901
+ // SDK still starting up - poll until initialised then add 1 s buffer
2902
+ const _waitAndSend = () => {
2903
+ if (runtimeState.isInitialized) {
2904
+ setTimeout(_sendWalletAddress, 1000);
2905
+ } else {
2906
+ setTimeout(_waitAndSend, 200);
2907
+ }
2908
+ };
2909
+ setTimeout(_waitAndSend, 200);
2910
+ }
2886
2911
  }
2887
2912
  }
2888
2913
 
@@ -4420,7 +4445,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4420
4445
  fetchOptions.body = JSON.stringify(payload);
4421
4446
  }
4422
4447
 
4423
- const response = await fetch(endpoint, fetchOptions);
4448
+ const response = await _nativeFetch(endpoint, fetchOptions);
4424
4449
 
4425
4450
  clearTimeout(timeoutId);
4426
4451
  timeoutId = null;
@@ -4603,7 +4628,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4603
4628
  };
4604
4629
 
4605
4630
  // Send PATCH request to update wallet address
4606
- const response = await fetch(CONFIG.API.UTM_EVENTS + '/update-wallet', {
4631
+ const response = await _nativeFetch(CONFIG.API.UTM_EVENTS + '/update-wallet', {
4607
4632
  method: 'PATCH',
4608
4633
  headers: {
4609
4634
  'Content-Type': 'application/json',
@@ -5319,7 +5344,8 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
5319
5344
  startNetworkTracking() {
5320
5345
  try {
5321
5346
  // Track fetch errors - only intercept calls to our own backend
5322
- const originalFetch = window.fetch;
5347
+ // Use _nativeFetch as the base so the wrapper always delegates to the
5348
+ // true browser fetch, regardless of what other libraries have patched.
5323
5349
  window.fetch = function(...args) {
5324
5350
  const startTime = Date.now();
5325
5351
  const url = typeof args[0] === 'string' ? args[0] : (args[0]?.url || '');
@@ -5327,10 +5353,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
5327
5353
  // Pass third-party requests through completely untouched — no interception,
5328
5354
  // no involvement of our SDK in their call stack or error handling
5329
5355
  if (!url.includes('backend.cryptique.io')) {
5330
- return originalFetch.apply(this, args);
5356
+ return _nativeFetch.apply(this, args);
5331
5357
  }
5332
5358
 
5333
- return originalFetch.apply(this, args).then(response => {
5359
+ return _nativeFetch.apply(this, args).then(response => {
5334
5360
  // Only track error status codes (4xx, 5xx)
5335
5361
  if (response.status >= 400) {
5336
5362
  const networkErrorData = {
@@ -6225,7 +6251,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6225
6251
  */
6226
6252
  async _sendEvent(eventData) {
6227
6253
  try {
6228
- const response = await fetch(CONFIG.API.EVENTS, {
6254
+ const response = await _nativeFetch(CONFIG.API.EVENTS, {
6229
6255
  method: 'POST',
6230
6256
  headers: {
6231
6257
  'Content-Type': 'application/json',
@@ -6375,7 +6401,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6375
6401
 
6376
6402
  // Call API endpoint
6377
6403
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/identify');
6378
- const response = await fetch(apiUrl, {
6404
+ const response = await _nativeFetch(apiUrl, {
6379
6405
  method: 'POST',
6380
6406
  headers: {
6381
6407
  'Content-Type': 'application/json',
@@ -6486,7 +6512,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6486
6512
 
6487
6513
  // Call backend endpoint to ensure new anonymous identity exists
6488
6514
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/reset');
6489
- const response = await fetch(apiUrl, {
6515
+ const response = await _nativeFetch(apiUrl, {
6490
6516
  method: 'POST',
6491
6517
  headers: {
6492
6518
  'Content-Type': 'application/json',
@@ -6601,7 +6627,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6601
6627
  // Call API endpoint to update user_identity and session in database
6602
6628
  // This handles merging and immediate session update if session exists
6603
6629
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/wallet-address');
6604
- const response = await fetch(apiUrl, {
6630
+ const response = await _nativeFetch(apiUrl, {
6605
6631
  method: 'POST',
6606
6632
  headers: {
6607
6633
  'Content-Type': 'application/json',
@@ -7335,7 +7361,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7335
7361
  }
7336
7362
 
7337
7363
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/set');
7338
- const response = await fetch(apiUrl, {
7364
+ const response = await _nativeFetch(apiUrl, {
7339
7365
  method: 'POST',
7340
7366
  headers: {
7341
7367
  'Content-Type': 'application/json',
@@ -7384,7 +7410,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7384
7410
  }
7385
7411
 
7386
7412
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/set_once');
7387
- const response = await fetch(apiUrl, {
7413
+ const response = await _nativeFetch(apiUrl, {
7388
7414
  method: 'POST',
7389
7415
  headers: {
7390
7416
  'Content-Type': 'application/json',
@@ -7433,7 +7459,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7433
7459
  }
7434
7460
 
7435
7461
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/unset');
7436
- const response = await fetch(apiUrl, {
7462
+ const response = await _nativeFetch(apiUrl, {
7437
7463
  method: 'POST',
7438
7464
  headers: {
7439
7465
  'Content-Type': 'application/json',
@@ -7488,7 +7514,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7488
7514
  }
7489
7515
 
7490
7516
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/increment');
7491
- const response = await fetch(apiUrl, {
7517
+ const response = await _nativeFetch(apiUrl, {
7492
7518
  method: 'POST',
7493
7519
  headers: {
7494
7520
  'Content-Type': 'application/json',
@@ -7544,7 +7570,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7544
7570
  }
7545
7571
 
7546
7572
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/append');
7547
- const response = await fetch(apiUrl, {
7573
+ const response = await _nativeFetch(apiUrl, {
7548
7574
  method: 'POST',
7549
7575
  headers: {
7550
7576
  'Content-Type': 'application/json',
@@ -7600,7 +7626,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7600
7626
  }
7601
7627
 
7602
7628
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/union');
7603
- const response = await fetch(apiUrl, {
7629
+ const response = await _nativeFetch(apiUrl, {
7604
7630
  method: 'POST',
7605
7631
  headers: {
7606
7632
  'Content-Type': 'application/json',
@@ -7656,7 +7682,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7656
7682
  }
7657
7683
 
7658
7684
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/remove');
7659
- const response = await fetch(apiUrl, {
7685
+ const response = await _nativeFetch(apiUrl, {
7660
7686
  method: 'POST',
7661
7687
  headers: {
7662
7688
  'Content-Type': 'application/json',
@@ -7707,7 +7733,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7707
7733
  }
7708
7734
 
7709
7735
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/track_charge');
7710
- const response = await fetch(apiUrl, {
7736
+ const response = await _nativeFetch(apiUrl, {
7711
7737
  method: 'POST',
7712
7738
  headers: {
7713
7739
  'Content-Type': 'application/json',
@@ -7751,7 +7777,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7751
7777
  }
7752
7778
 
7753
7779
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/clear_charges');
7754
- const response = await fetch(apiUrl, {
7780
+ const response = await _nativeFetch(apiUrl, {
7755
7781
  method: 'POST',
7756
7782
  headers: {
7757
7783
  'Content-Type': 'application/json',
@@ -7793,7 +7819,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7793
7819
  }
7794
7820
 
7795
7821
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/delete_user');
7796
- const response = await fetch(apiUrl, {
7822
+ const response = await _nativeFetch(apiUrl, {
7797
7823
  method: 'POST',
7798
7824
  headers: {
7799
7825
  'Content-Type': 'application/json',
package/lib/esm/index.js CHANGED
@@ -22,6 +22,11 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
22
22
  window.Cryptique = window.Cryptique || {};
23
23
  window.Cryptique.initialized = true;
24
24
 
25
+ // Capture native fetch before any third-party library (wagmi, viem, etc.)
26
+ // can patch window.fetch. All SDK outgoing requests use this reference
27
+ // directly so they are never affected by external fetch wrappers.
28
+ const _nativeFetch = window.fetch.bind(window);
29
+
25
30
  // ============================================================================
26
31
  // SECTION 1: CONFIGURATION
27
32
  // ============================================================================
@@ -561,7 +566,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
561
566
  // Construct migration endpoint URL from track endpoint
562
567
  const migrationUrl = CONFIG.API.TRACK.replace('/track', '/migrate-user-id');
563
568
 
564
- const response = await fetch(migrationUrl, {
569
+ const response = await _nativeFetch(migrationUrl, {
565
570
  method: 'POST',
566
571
  headers: {
567
572
  'Content-Type': 'application/json'
@@ -2873,14 +2878,34 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
2873
2878
  });
2874
2879
 
2875
2880
  // Automatic wallet address matching - only call once per address per session
2876
- // Prevents repeated calls to /api/sdk/wallet-address on every interval tick
2881
+ // Prevents repeated calls to /api/sdk/wallet-address on every interval tick.
2882
+ // Also guards against the race condition where the wallet is detected before the
2883
+ // initial session POST has completed on the backend (which would return 404).
2884
+ // We wait until isInitialized is true (meaning sendInitialSessionData has run)
2885
+ // plus an extra 1 s buffer to ensure the backend has persisted the session.
2877
2886
  if (walletAddress !== runtimeState.reportedWalletAddress) {
2878
2887
  runtimeState.reportedWalletAddress = walletAddress;
2879
- IdentityManager.walletAddress(walletAddress).catch((error) => {
2880
- console.warn('Error in automatic wallet address matching:', error);
2881
- // Reset so it retries next time wallet info is updated
2882
- runtimeState.reportedWalletAddress = null;
2883
- });
2888
+ const _sendWalletAddress = () => {
2889
+ IdentityManager.walletAddress(walletAddress).catch((error) => {
2890
+ console.warn('Error in automatic wallet address matching:', error);
2891
+ // Reset so it retries next time wallet info is updated
2892
+ runtimeState.reportedWalletAddress = null;
2893
+ });
2894
+ };
2895
+ if (runtimeState.isInitialized) {
2896
+ // SDK already fully initialised - still give backend 1 s to persist session
2897
+ setTimeout(_sendWalletAddress, 1000);
2898
+ } else {
2899
+ // SDK still starting up - poll until initialised then add 1 s buffer
2900
+ const _waitAndSend = () => {
2901
+ if (runtimeState.isInitialized) {
2902
+ setTimeout(_sendWalletAddress, 1000);
2903
+ } else {
2904
+ setTimeout(_waitAndSend, 200);
2905
+ }
2906
+ };
2907
+ setTimeout(_waitAndSend, 200);
2908
+ }
2884
2909
  }
2885
2910
  }
2886
2911
 
@@ -4418,7 +4443,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4418
4443
  fetchOptions.body = JSON.stringify(payload);
4419
4444
  }
4420
4445
 
4421
- const response = await fetch(endpoint, fetchOptions);
4446
+ const response = await _nativeFetch(endpoint, fetchOptions);
4422
4447
 
4423
4448
  clearTimeout(timeoutId);
4424
4449
  timeoutId = null;
@@ -4601,7 +4626,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
4601
4626
  };
4602
4627
 
4603
4628
  // Send PATCH request to update wallet address
4604
- const response = await fetch(CONFIG.API.UTM_EVENTS + '/update-wallet', {
4629
+ const response = await _nativeFetch(CONFIG.API.UTM_EVENTS + '/update-wallet', {
4605
4630
  method: 'PATCH',
4606
4631
  headers: {
4607
4632
  'Content-Type': 'application/json',
@@ -5317,7 +5342,8 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
5317
5342
  startNetworkTracking() {
5318
5343
  try {
5319
5344
  // Track fetch errors - only intercept calls to our own backend
5320
- const originalFetch = window.fetch;
5345
+ // Use _nativeFetch as the base so the wrapper always delegates to the
5346
+ // true browser fetch, regardless of what other libraries have patched.
5321
5347
  window.fetch = function(...args) {
5322
5348
  const startTime = Date.now();
5323
5349
  const url = typeof args[0] === 'string' ? args[0] : (args[0]?.url || '');
@@ -5325,10 +5351,10 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
5325
5351
  // Pass third-party requests through completely untouched — no interception,
5326
5352
  // no involvement of our SDK in their call stack or error handling
5327
5353
  if (!url.includes('backend.cryptique.io')) {
5328
- return originalFetch.apply(this, args);
5354
+ return _nativeFetch.apply(this, args);
5329
5355
  }
5330
5356
 
5331
- return originalFetch.apply(this, args).then(response => {
5357
+ return _nativeFetch.apply(this, args).then(response => {
5332
5358
  // Only track error status codes (4xx, 5xx)
5333
5359
  if (response.status >= 400) {
5334
5360
  const networkErrorData = {
@@ -6223,7 +6249,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6223
6249
  */
6224
6250
  async _sendEvent(eventData) {
6225
6251
  try {
6226
- const response = await fetch(CONFIG.API.EVENTS, {
6252
+ const response = await _nativeFetch(CONFIG.API.EVENTS, {
6227
6253
  method: 'POST',
6228
6254
  headers: {
6229
6255
  'Content-Type': 'application/json',
@@ -6373,7 +6399,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6373
6399
 
6374
6400
  // Call API endpoint
6375
6401
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/identify');
6376
- const response = await fetch(apiUrl, {
6402
+ const response = await _nativeFetch(apiUrl, {
6377
6403
  method: 'POST',
6378
6404
  headers: {
6379
6405
  'Content-Type': 'application/json',
@@ -6484,7 +6510,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6484
6510
 
6485
6511
  // Call backend endpoint to ensure new anonymous identity exists
6486
6512
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/reset');
6487
- const response = await fetch(apiUrl, {
6513
+ const response = await _nativeFetch(apiUrl, {
6488
6514
  method: 'POST',
6489
6515
  headers: {
6490
6516
  'Content-Type': 'application/json',
@@ -6599,7 +6625,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
6599
6625
  // Call API endpoint to update user_identity and session in database
6600
6626
  // This handles merging and immediate session update if session exists
6601
6627
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/wallet-address');
6602
- const response = await fetch(apiUrl, {
6628
+ const response = await _nativeFetch(apiUrl, {
6603
6629
  method: 'POST',
6604
6630
  headers: {
6605
6631
  'Content-Type': 'application/json',
@@ -7333,7 +7359,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7333
7359
  }
7334
7360
 
7335
7361
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/set');
7336
- const response = await fetch(apiUrl, {
7362
+ const response = await _nativeFetch(apiUrl, {
7337
7363
  method: 'POST',
7338
7364
  headers: {
7339
7365
  'Content-Type': 'application/json',
@@ -7382,7 +7408,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7382
7408
  }
7383
7409
 
7384
7410
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/set_once');
7385
- const response = await fetch(apiUrl, {
7411
+ const response = await _nativeFetch(apiUrl, {
7386
7412
  method: 'POST',
7387
7413
  headers: {
7388
7414
  'Content-Type': 'application/json',
@@ -7431,7 +7457,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7431
7457
  }
7432
7458
 
7433
7459
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/unset');
7434
- const response = await fetch(apiUrl, {
7460
+ const response = await _nativeFetch(apiUrl, {
7435
7461
  method: 'POST',
7436
7462
  headers: {
7437
7463
  'Content-Type': 'application/json',
@@ -7486,7 +7512,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7486
7512
  }
7487
7513
 
7488
7514
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/increment');
7489
- const response = await fetch(apiUrl, {
7515
+ const response = await _nativeFetch(apiUrl, {
7490
7516
  method: 'POST',
7491
7517
  headers: {
7492
7518
  'Content-Type': 'application/json',
@@ -7542,7 +7568,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7542
7568
  }
7543
7569
 
7544
7570
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/append');
7545
- const response = await fetch(apiUrl, {
7571
+ const response = await _nativeFetch(apiUrl, {
7546
7572
  method: 'POST',
7547
7573
  headers: {
7548
7574
  'Content-Type': 'application/json',
@@ -7598,7 +7624,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7598
7624
  }
7599
7625
 
7600
7626
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/union');
7601
- const response = await fetch(apiUrl, {
7627
+ const response = await _nativeFetch(apiUrl, {
7602
7628
  method: 'POST',
7603
7629
  headers: {
7604
7630
  'Content-Type': 'application/json',
@@ -7654,7 +7680,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7654
7680
  }
7655
7681
 
7656
7682
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/remove');
7657
- const response = await fetch(apiUrl, {
7683
+ const response = await _nativeFetch(apiUrl, {
7658
7684
  method: 'POST',
7659
7685
  headers: {
7660
7686
  'Content-Type': 'application/json',
@@ -7705,7 +7731,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7705
7731
  }
7706
7732
 
7707
7733
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/track_charge');
7708
- const response = await fetch(apiUrl, {
7734
+ const response = await _nativeFetch(apiUrl, {
7709
7735
  method: 'POST',
7710
7736
  headers: {
7711
7737
  'Content-Type': 'application/json',
@@ -7749,7 +7775,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7749
7775
  }
7750
7776
 
7751
7777
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/clear_charges');
7752
- const response = await fetch(apiUrl, {
7778
+ const response = await _nativeFetch(apiUrl, {
7753
7779
  method: 'POST',
7754
7780
  headers: {
7755
7781
  'Content-Type': 'application/json',
@@ -7791,7 +7817,7 @@ if (window.Cryptique && window.Cryptique.initialized) ; else {
7791
7817
  }
7792
7818
 
7793
7819
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/delete_user');
7794
- const response = await fetch(apiUrl, {
7820
+ const response = await _nativeFetch(apiUrl, {
7795
7821
  method: 'POST',
7796
7822
  headers: {
7797
7823
  'Content-Type': 'application/json',
package/lib/umd/index.js CHANGED
@@ -28,6 +28,11 @@
28
28
  window.Cryptique = window.Cryptique || {};
29
29
  window.Cryptique.initialized = true;
30
30
 
31
+ // Capture native fetch before any third-party library (wagmi, viem, etc.)
32
+ // can patch window.fetch. All SDK outgoing requests use this reference
33
+ // directly so they are never affected by external fetch wrappers.
34
+ const _nativeFetch = window.fetch.bind(window);
35
+
31
36
  // ============================================================================
32
37
  // SECTION 1: CONFIGURATION
33
38
  // ============================================================================
@@ -567,7 +572,7 @@
567
572
  // Construct migration endpoint URL from track endpoint
568
573
  const migrationUrl = CONFIG.API.TRACK.replace('/track', '/migrate-user-id');
569
574
 
570
- const response = await fetch(migrationUrl, {
575
+ const response = await _nativeFetch(migrationUrl, {
571
576
  method: 'POST',
572
577
  headers: {
573
578
  'Content-Type': 'application/json'
@@ -2879,14 +2884,34 @@
2879
2884
  });
2880
2885
 
2881
2886
  // Automatic wallet address matching - only call once per address per session
2882
- // Prevents repeated calls to /api/sdk/wallet-address on every interval tick
2887
+ // Prevents repeated calls to /api/sdk/wallet-address on every interval tick.
2888
+ // Also guards against the race condition where the wallet is detected before the
2889
+ // initial session POST has completed on the backend (which would return 404).
2890
+ // We wait until isInitialized is true (meaning sendInitialSessionData has run)
2891
+ // plus an extra 1 s buffer to ensure the backend has persisted the session.
2883
2892
  if (walletAddress !== runtimeState.reportedWalletAddress) {
2884
2893
  runtimeState.reportedWalletAddress = walletAddress;
2885
- IdentityManager.walletAddress(walletAddress).catch((error) => {
2886
- console.warn('Error in automatic wallet address matching:', error);
2887
- // Reset so it retries next time wallet info is updated
2888
- runtimeState.reportedWalletAddress = null;
2889
- });
2894
+ const _sendWalletAddress = () => {
2895
+ IdentityManager.walletAddress(walletAddress).catch((error) => {
2896
+ console.warn('Error in automatic wallet address matching:', error);
2897
+ // Reset so it retries next time wallet info is updated
2898
+ runtimeState.reportedWalletAddress = null;
2899
+ });
2900
+ };
2901
+ if (runtimeState.isInitialized) {
2902
+ // SDK already fully initialised - still give backend 1 s to persist session
2903
+ setTimeout(_sendWalletAddress, 1000);
2904
+ } else {
2905
+ // SDK still starting up - poll until initialised then add 1 s buffer
2906
+ const _waitAndSend = () => {
2907
+ if (runtimeState.isInitialized) {
2908
+ setTimeout(_sendWalletAddress, 1000);
2909
+ } else {
2910
+ setTimeout(_waitAndSend, 200);
2911
+ }
2912
+ };
2913
+ setTimeout(_waitAndSend, 200);
2914
+ }
2890
2915
  }
2891
2916
  }
2892
2917
 
@@ -4424,7 +4449,7 @@
4424
4449
  fetchOptions.body = JSON.stringify(payload);
4425
4450
  }
4426
4451
 
4427
- const response = await fetch(endpoint, fetchOptions);
4452
+ const response = await _nativeFetch(endpoint, fetchOptions);
4428
4453
 
4429
4454
  clearTimeout(timeoutId);
4430
4455
  timeoutId = null;
@@ -4607,7 +4632,7 @@
4607
4632
  };
4608
4633
 
4609
4634
  // Send PATCH request to update wallet address
4610
- const response = await fetch(CONFIG.API.UTM_EVENTS + '/update-wallet', {
4635
+ const response = await _nativeFetch(CONFIG.API.UTM_EVENTS + '/update-wallet', {
4611
4636
  method: 'PATCH',
4612
4637
  headers: {
4613
4638
  'Content-Type': 'application/json',
@@ -5323,7 +5348,8 @@
5323
5348
  startNetworkTracking() {
5324
5349
  try {
5325
5350
  // Track fetch errors - only intercept calls to our own backend
5326
- const originalFetch = window.fetch;
5351
+ // Use _nativeFetch as the base so the wrapper always delegates to the
5352
+ // true browser fetch, regardless of what other libraries have patched.
5327
5353
  window.fetch = function(...args) {
5328
5354
  const startTime = Date.now();
5329
5355
  const url = typeof args[0] === 'string' ? args[0] : (args[0]?.url || '');
@@ -5331,10 +5357,10 @@
5331
5357
  // Pass third-party requests through completely untouched — no interception,
5332
5358
  // no involvement of our SDK in their call stack or error handling
5333
5359
  if (!url.includes('backend.cryptique.io')) {
5334
- return originalFetch.apply(this, args);
5360
+ return _nativeFetch.apply(this, args);
5335
5361
  }
5336
5362
 
5337
- return originalFetch.apply(this, args).then(response => {
5363
+ return _nativeFetch.apply(this, args).then(response => {
5338
5364
  // Only track error status codes (4xx, 5xx)
5339
5365
  if (response.status >= 400) {
5340
5366
  const networkErrorData = {
@@ -6229,7 +6255,7 @@
6229
6255
  */
6230
6256
  async _sendEvent(eventData) {
6231
6257
  try {
6232
- const response = await fetch(CONFIG.API.EVENTS, {
6258
+ const response = await _nativeFetch(CONFIG.API.EVENTS, {
6233
6259
  method: 'POST',
6234
6260
  headers: {
6235
6261
  'Content-Type': 'application/json',
@@ -6379,7 +6405,7 @@
6379
6405
 
6380
6406
  // Call API endpoint
6381
6407
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/identify');
6382
- const response = await fetch(apiUrl, {
6408
+ const response = await _nativeFetch(apiUrl, {
6383
6409
  method: 'POST',
6384
6410
  headers: {
6385
6411
  'Content-Type': 'application/json',
@@ -6490,7 +6516,7 @@
6490
6516
 
6491
6517
  // Call backend endpoint to ensure new anonymous identity exists
6492
6518
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/reset');
6493
- const response = await fetch(apiUrl, {
6519
+ const response = await _nativeFetch(apiUrl, {
6494
6520
  method: 'POST',
6495
6521
  headers: {
6496
6522
  'Content-Type': 'application/json',
@@ -6605,7 +6631,7 @@
6605
6631
  // Call API endpoint to update user_identity and session in database
6606
6632
  // This handles merging and immediate session update if session exists
6607
6633
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/wallet-address');
6608
- const response = await fetch(apiUrl, {
6634
+ const response = await _nativeFetch(apiUrl, {
6609
6635
  method: 'POST',
6610
6636
  headers: {
6611
6637
  'Content-Type': 'application/json',
@@ -7339,7 +7365,7 @@
7339
7365
  }
7340
7366
 
7341
7367
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/set');
7342
- const response = await fetch(apiUrl, {
7368
+ const response = await _nativeFetch(apiUrl, {
7343
7369
  method: 'POST',
7344
7370
  headers: {
7345
7371
  'Content-Type': 'application/json',
@@ -7388,7 +7414,7 @@
7388
7414
  }
7389
7415
 
7390
7416
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/set_once');
7391
- const response = await fetch(apiUrl, {
7417
+ const response = await _nativeFetch(apiUrl, {
7392
7418
  method: 'POST',
7393
7419
  headers: {
7394
7420
  'Content-Type': 'application/json',
@@ -7437,7 +7463,7 @@
7437
7463
  }
7438
7464
 
7439
7465
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/unset');
7440
- const response = await fetch(apiUrl, {
7466
+ const response = await _nativeFetch(apiUrl, {
7441
7467
  method: 'POST',
7442
7468
  headers: {
7443
7469
  'Content-Type': 'application/json',
@@ -7492,7 +7518,7 @@
7492
7518
  }
7493
7519
 
7494
7520
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/increment');
7495
- const response = await fetch(apiUrl, {
7521
+ const response = await _nativeFetch(apiUrl, {
7496
7522
  method: 'POST',
7497
7523
  headers: {
7498
7524
  'Content-Type': 'application/json',
@@ -7548,7 +7574,7 @@
7548
7574
  }
7549
7575
 
7550
7576
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/append');
7551
- const response = await fetch(apiUrl, {
7577
+ const response = await _nativeFetch(apiUrl, {
7552
7578
  method: 'POST',
7553
7579
  headers: {
7554
7580
  'Content-Type': 'application/json',
@@ -7604,7 +7630,7 @@
7604
7630
  }
7605
7631
 
7606
7632
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/union');
7607
- const response = await fetch(apiUrl, {
7633
+ const response = await _nativeFetch(apiUrl, {
7608
7634
  method: 'POST',
7609
7635
  headers: {
7610
7636
  'Content-Type': 'application/json',
@@ -7660,7 +7686,7 @@
7660
7686
  }
7661
7687
 
7662
7688
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/remove');
7663
- const response = await fetch(apiUrl, {
7689
+ const response = await _nativeFetch(apiUrl, {
7664
7690
  method: 'POST',
7665
7691
  headers: {
7666
7692
  'Content-Type': 'application/json',
@@ -7711,7 +7737,7 @@
7711
7737
  }
7712
7738
 
7713
7739
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/track_charge');
7714
- const response = await fetch(apiUrl, {
7740
+ const response = await _nativeFetch(apiUrl, {
7715
7741
  method: 'POST',
7716
7742
  headers: {
7717
7743
  'Content-Type': 'application/json',
@@ -7755,7 +7781,7 @@
7755
7781
  }
7756
7782
 
7757
7783
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/clear_charges');
7758
- const response = await fetch(apiUrl, {
7784
+ const response = await _nativeFetch(apiUrl, {
7759
7785
  method: 'POST',
7760
7786
  headers: {
7761
7787
  'Content-Type': 'application/json',
@@ -7797,7 +7823,7 @@
7797
7823
  }
7798
7824
 
7799
7825
  const apiUrl = CONFIG.API.TRACK.replace('/track', '/people/delete_user');
7800
- const response = await fetch(apiUrl, {
7826
+ const response = await _nativeFetch(apiUrl, {
7801
7827
  method: 'POST',
7802
7828
  headers: {
7803
7829
  'Content-Type': 'application/json',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cryptique-sdk",
3
- "version": "1.2.2",
3
+ "version": "1.2.4",
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",