Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/research-warn-unsupported-flags.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"nansen-cli": patch
---

Warn to stderr when --page/--limit is passed to historical-token-flow-summary or --sort is passed to historical-smart-money-balances, since those endpoints silently ignore those flags.
28 changes: 28 additions & 0 deletions src/__tests__/research.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,20 @@ describe('buildResearchCommands handler', () => {
expect(mockApi.researchTokenFlowSummary).toHaveBeenCalled();
});

it('warns to stderr when --page/--limit is passed to historical-token-flow-summary', async () => {
mockApi = makeMockApi();
const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => {});
try {
await cmds.research(['historical-token-flow-summary'], mockApi, {}, {
'token-address': TOKENS.solana, 'from-date': FROM, 'to-date': TO, page: 2, limit: 5,
});
const warned = stderrSpy.mock.calls.some(([msg]) => msg.includes('--page/--limit') && msg.includes('historical-token-flow-summary'));
expect(warned).toBe(true);
} finally {
stderrSpy.mockRestore();
}
});

it('dispatches historical-token-quant-scores with --as-of-date', async () => {
mockApi = makeMockApi();
await cmds.research(['historical-token-quant-scores'], mockApi, {}, {
Expand Down Expand Up @@ -356,6 +370,20 @@ describe('buildResearchCommands handler', () => {
}));
});

it('warns to stderr when --sort is passed to historical-smart-money-balances', async () => {
mockApi = makeMockApi();
const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => {});
try {
await cmds.research(['historical-smart-money-balances'], mockApi, {}, {
'as-of-date': AS_OF, sort: 'value_usd:desc',
});
const warned = stderrSpy.mock.calls.some(([msg]) => msg.includes('--sort') && msg.includes('historical-smart-money-balances'));
expect(warned).toBe(true);
} finally {
stderrSpy.mockRestore();
}
});

it('dispatches historical-token-screener with --timeframe-days and --to-date', async () => {
mockApi = makeMockApi();
await cmds.research(['historical-token-screener'], mockApi, {}, {
Expand Down
18 changes: 13 additions & 5 deletions src/commands/research.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,16 @@ export function buildResearchCommands(deps = {}) {
chain: options.chain,
fromDate, toDate, filters, orderBy, pagination,
}),
'historical-token-flow-summary': () => apiInstance.researchTokenFlowSummary({
tokenAddress: options['token-address'] || options.token,
chain: options.chain,
fromDate, toDate, filters, orderBy,
}),
'historical-token-flow-summary': () => {
if (pagination) {
process.stderr.write('⚠️ warning: --page/--limit is ignored by historical-token-flow-summary (endpoint does not support pagination)\n');
}
return apiInstance.researchTokenFlowSummary({
tokenAddress: options['token-address'] || options.token,
chain: options.chain,
fromDate, toDate, filters, orderBy,
});
},
'historical-who-bought-sold': () => apiInstance.researchWhoBoughtSold({
tokenAddress: options['token-address'] || options.token,
chain: options.chain,
Expand Down Expand Up @@ -240,6 +245,9 @@ export function buildResearchCommands(deps = {}) {
}

if (sub === 'historical-smart-money-balances') {
if (options.sort || options['order-by']) {
process.stderr.write('⚠️ warning: --sort is ignored by historical-smart-money-balances (endpoint does not support order_by)\n');
}
requireOptions({ 'as-of-date': asOfDate }, ['as-of-date']);
return apiInstance.researchSmartMoneyBalances({
chains: parseChains(options),
Expand Down
Loading