nansen-cli 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/api.js CHANGED
@@ -391,6 +391,17 @@ function parseRetryAfter(headerValue) {
391
391
  return null;
392
392
  }
393
393
 
394
+ /**
395
+ * Build a date range from today back N days
396
+ * @param {number} days - Number of days back from today
397
+ * @returns {{from: string, to: string}} Date range with YYYY-MM-DD strings
398
+ */
399
+ export function buildDateRange(days) {
400
+ const to = new Date().toISOString().split('T')[0];
401
+ const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
402
+ return { from, to };
403
+ }
404
+
394
405
  export class NansenAPI {
395
406
  constructor(apiKey = config.apiKey, baseUrl = config.baseUrl, options = {}) {
396
407
  this.apiKey = apiKey || null;
@@ -624,11 +635,9 @@ export class NansenAPI {
624
635
 
625
636
  async smartMoneyHistoricalHoldings(params = {}) {
626
637
  const { chains = ['solana'], filters = {}, orderBy, pagination, days = 30 } = params;
627
- const to = new Date().toISOString().split('T')[0];
628
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
629
638
  return this.request('/api/v1/smart-money/historical-holdings', {
630
639
  chains,
631
- date_range: { from, to },
640
+ date_range: buildDateRange(days),
632
641
  filters,
633
642
  order_by: orderBy,
634
643
  pagination
@@ -671,11 +680,7 @@ export class NansenAPI {
671
680
  const validation = validateAddress(address, chain);
672
681
  if (!validation.valid) throw new NansenError(validation.error, validation.code);
673
682
  }
674
- const dateRange = date || (() => {
675
- const to = new Date().toISOString().split('T')[0];
676
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
677
- return { from, to };
678
- })();
683
+ const dateRange = date || buildDateRange(days);
679
684
  return this.request('/api/v1/profiler/address/transactions', {
680
685
  address,
681
686
  chain,
@@ -692,13 +697,7 @@ export class NansenAPI {
692
697
  const validation = validateAddress(address, chain);
693
698
  if (!validation.valid) throw new NansenError(validation.error, validation.code);
694
699
  }
695
- // Build date range
696
- let dateRange = date;
697
- if (!dateRange) {
698
- const to = new Date().toISOString().split('T')[0];
699
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
700
- dateRange = { from, to };
701
- }
700
+ const dateRange = date || buildDateRange(days);
702
701
  return this.request('/api/v1/profiler/address/pnl', {
703
702
  address,
704
703
  chain,
@@ -734,12 +733,10 @@ export class NansenAPI {
734
733
  const validation = validateAddress(address, chain);
735
734
  if (!validation.valid) throw new NansenError(validation.error, validation.code);
736
735
  }
737
- const to = new Date().toISOString().split('T')[0];
738
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
739
736
  return this.request('/api/v1/profiler/address/historical-balances', {
740
737
  address,
741
738
  chain,
742
- date: { from, to },
739
+ date: buildDateRange(days),
743
740
  filters,
744
741
  order_by: orderBy,
745
742
  pagination
@@ -766,12 +763,10 @@ export class NansenAPI {
766
763
  const validation = validateAddress(address, chain);
767
764
  if (!validation.valid) throw new NansenError(validation.error, validation.code);
768
765
  }
769
- const to = new Date().toISOString().split('T')[0];
770
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
771
766
  return this.request('/api/v1/profiler/address/counterparties', {
772
767
  address,
773
768
  chain,
774
- date: { from, to },
769
+ date: buildDateRange(days),
775
770
  filters,
776
771
  order_by: orderBy,
777
772
  pagination
@@ -784,12 +779,10 @@ export class NansenAPI {
784
779
  const validation = validateAddress(address, chain);
785
780
  if (!validation.valid) throw new NansenError(validation.error, validation.code);
786
781
  }
787
- const to = new Date().toISOString().split('T')[0];
788
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
789
782
  return this.request('/api/v1/profiler/address/pnl-summary', {
790
783
  address,
791
784
  chain,
792
- date: { from, to },
785
+ date: buildDateRange(days),
793
786
  order_by: orderBy,
794
787
  pagination
795
788
  });
@@ -808,11 +801,9 @@ export class NansenAPI {
808
801
 
809
802
  async addressPerpTrades(params = {}) {
810
803
  const { address, filters = {}, orderBy, pagination, days = 30 } = params;
811
- const to = new Date().toISOString().split('T')[0];
812
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
813
804
  return this.request('/api/v1/profiler/perp-trades', {
814
805
  address,
815
- date: { from, to },
806
+ date: buildDateRange(days),
816
807
  filters,
817
808
  order_by: orderBy,
818
809
  pagination
@@ -854,11 +845,7 @@ export class NansenAPI {
854
845
  const validation = validateTokenAddress(tokenAddress, chain);
855
846
  if (!validation.valid) throw new NansenError(validation.error, validation.code);
856
847
  }
857
- const dateRange = date || (() => {
858
- const to = new Date().toISOString().split('T')[0];
859
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
860
- return { from, to };
861
- })();
848
+ const dateRange = date || buildDateRange(days);
862
849
  return this.request('/api/v1/tgm/flows', {
863
850
  token_address: tokenAddress,
864
851
  chain,
@@ -875,9 +862,6 @@ export class NansenAPI {
875
862
  const validation = validateTokenAddress(tokenAddress, chain);
876
863
  if (!validation.valid) throw new NansenError(validation.error, validation.code);
877
864
  }
878
- const to = new Date().toISOString().split('T')[0];
879
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
880
-
881
865
  // Apply smart money filter via filters object
882
866
  if (onlySmartMoney) {
883
867
  filters.include_smart_money_labels = filters.include_smart_money_labels ||
@@ -887,7 +871,7 @@ export class NansenAPI {
887
871
  return this.request('/api/v1/tgm/dex-trades', {
888
872
  token_address: tokenAddress,
889
873
  chain,
890
- date: { from, to },
874
+ date: buildDateRange(days),
891
875
  filters,
892
876
  order_by: orderBy,
893
877
  pagination
@@ -900,12 +884,10 @@ export class NansenAPI {
900
884
  const validation = validateTokenAddress(tokenAddress, chain);
901
885
  if (!validation.valid) throw new NansenError(validation.error, validation.code);
902
886
  }
903
- const to = new Date().toISOString().split('T')[0];
904
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
905
887
  return this.request('/api/v1/tgm/pnl-leaderboard', {
906
888
  token_address: tokenAddress,
907
889
  chain,
908
- date: { from, to },
890
+ date: buildDateRange(days),
909
891
  filters,
910
892
  order_by: orderBy,
911
893
  pagination
@@ -918,11 +900,7 @@ export class NansenAPI {
918
900
  const validation = validateTokenAddress(tokenAddress, chain);
919
901
  if (!validation.valid) throw new NansenError(validation.error, validation.code);
920
902
  }
921
- const dateRange = date || (() => {
922
- const to = new Date().toISOString().split('T')[0];
923
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
924
- return { from, to };
925
- })();
903
+ const dateRange = date || buildDateRange(days);
926
904
  return this.request('/api/v1/tgm/who-bought-sold', {
927
905
  token_address: tokenAddress,
928
906
  chain,
@@ -951,12 +929,10 @@ export class NansenAPI {
951
929
  const validation = validateTokenAddress(tokenAddress, chain);
952
930
  if (!validation.valid) throw new NansenError(validation.error, validation.code);
953
931
  }
954
- const to = new Date().toISOString().split('T')[0];
955
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
956
932
  return this.request('/api/v1/tgm/transfers', {
957
933
  token_address: tokenAddress,
958
934
  chain,
959
- date: { from, to },
935
+ date: buildDateRange(days),
960
936
  filters,
961
937
  order_by: orderBy,
962
938
  pagination
@@ -980,11 +956,9 @@ export class NansenAPI {
980
956
 
981
957
  async tokenPerpTrades(params = {}) {
982
958
  const { tokenSymbol, filters = {}, orderBy, pagination, days = 30 } = params;
983
- const to = new Date().toISOString().split('T')[0];
984
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
985
959
  return this.request('/api/v1/tgm/perp-trades', {
986
960
  token_symbol: tokenSymbol,
987
- date: { from, to },
961
+ date: buildDateRange(days),
988
962
  filters,
989
963
  order_by: orderBy,
990
964
  pagination
@@ -1003,11 +977,9 @@ export class NansenAPI {
1003
977
 
1004
978
  async tokenPerpPnlLeaderboard(params = {}) {
1005
979
  const { tokenSymbol, filters = {}, orderBy, pagination, days = 30 } = params;
1006
- const to = new Date().toISOString().split('T')[0];
1007
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
1008
980
  return this.request('/api/v1/tgm/perp-pnl-leaderboard', {
1009
981
  token_symbol: tokenSymbol,
1010
- date: { from, to },
982
+ date: buildDateRange(days),
1011
983
  filters,
1012
984
  order_by: orderBy,
1013
985
  pagination
@@ -1026,6 +998,20 @@ export class NansenAPI {
1026
998
  });
1027
999
  }
1028
1000
 
1001
+ async tokenOhlcv(params = {}) {
1002
+ const { tokenAddress, chain = 'solana', timeframe, pagination } = params;
1003
+ if (tokenAddress) {
1004
+ const validation = validateTokenAddress(tokenAddress, chain);
1005
+ if (!validation.valid) throw new NansenError(validation.error, validation.code);
1006
+ }
1007
+ return this.request('/api/v1/tgm/token-ohlcv', {
1008
+ token_address: tokenAddress,
1009
+ chain,
1010
+ timeframe,
1011
+ pagination
1012
+ });
1013
+ }
1014
+
1029
1015
  async tokenInformation(params = {}) {
1030
1016
  const { tokenAddress, chain = 'solana', timeframe = '1d' } = params;
1031
1017
  if (tokenAddress) {
@@ -1043,10 +1029,8 @@ export class NansenAPI {
1043
1029
 
1044
1030
  async perpScreener(params = {}) {
1045
1031
  const { filters = {}, orderBy, pagination, days = 30 } = params;
1046
- const to = new Date().toISOString().split('T')[0];
1047
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
1048
1032
  return this.request('/api/v1/perp-screener', {
1049
- date: { from, to },
1033
+ date: buildDateRange(days),
1050
1034
  filters,
1051
1035
  order_by: orderBy,
1052
1036
  pagination
@@ -1055,10 +1039,8 @@ export class NansenAPI {
1055
1039
 
1056
1040
  async perpLeaderboard(params = {}) {
1057
1041
  const { filters = {}, orderBy, pagination, days = 30 } = params;
1058
- const to = new Date().toISOString().split('T')[0];
1059
- const from = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
1060
1042
  return this.request('/api/v1/perp-leaderboard', {
1061
- date: { from, to },
1043
+ date: buildDateRange(days),
1062
1044
  filters,
1063
1045
  order_by: orderBy,
1064
1046
  pagination