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/AGENTS.md +118 -164
- package/CLAUDE.md +16 -19
- package/README.md +163 -112
- package/package.json +3 -1
- package/scripts/check-changeset.js +28 -0
- package/src/api.js +41 -59
- package/src/cli.js +387 -353
- package/src/ens.js +163 -0
- package/src/update-check.js +35 -0
- package/vitest.e2e.config.js +10 -0
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:
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
1043
|
+
date: buildDateRange(days),
|
|
1062
1044
|
filters,
|
|
1063
1045
|
order_by: orderBy,
|
|
1064
1046
|
pagination
|