nansen-cli 1.31.0 → 1.32.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/CHANGELOG.md +12 -0
- package/package.json +1 -1
- package/src/api.js +14 -0
- package/src/cli.js +5 -1
- package/src/schema.json +15 -0
- package/src/trade-validation.js +13 -2
- package/src/trading.js +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.32.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#451](https://github.com/nansen-ai/nansen-cli/pull/451) [`73600d9`](https://github.com/nansen-ai/nansen-cli/commit/73600d9cd13248a265332ec0728c602b16f44868) Thanks [@kome12](https://github.com/kome12)! - Add `nansen research profiler dex-trades` command for DEX trade history
|
|
8
|
+
|
|
9
|
+
## 1.31.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#443](https://github.com/nansen-ai/nansen-cli/pull/443) [`0ee84db`](https://github.com/nansen-ai/nansen-cli/commit/0ee84db6cdab06054c6ae79c6d871bae0b4f3edb) Thanks [@araa47](https://github.com/araa47)! - Skip native gas pre-check for trades >= $10 USD, where gasless/solver-paid routes (e.g. Relay) are viable. When gas is insufficient on smaller trades, the error now also suggests increasing the trade value as an alternative to topping up gas.
|
|
14
|
+
|
|
3
15
|
## 1.31.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -973,6 +973,20 @@ export class NansenAPI {
|
|
|
973
973
|
});
|
|
974
974
|
}
|
|
975
975
|
|
|
976
|
+
async addressDexTrades(params = {}) {
|
|
977
|
+
const { address, chain = 'ethereum', filters = {}, orderBy, pagination, days = 30, date } = params;
|
|
978
|
+
if (address) requireValidAddress(address, chain);
|
|
979
|
+
const dateRange = date || buildDateRange(days);
|
|
980
|
+
return this.request('/api/v1/profiler/dex-trades', {
|
|
981
|
+
address,
|
|
982
|
+
chain,
|
|
983
|
+
date: dateRange,
|
|
984
|
+
filters,
|
|
985
|
+
order_by: orderBy,
|
|
986
|
+
pagination
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
|
|
976
990
|
// ============= Token God Mode Endpoints =============
|
|
977
991
|
|
|
978
992
|
async tokenScreener(params = {}) {
|
package/src/cli.js
CHANGED
|
@@ -1148,6 +1148,10 @@ export function buildCommands(deps = {}) {
|
|
|
1148
1148
|
'pnl-summary': () => apiInstance.addressPnlSummary({ address, chain, orderBy, pagination, days }),
|
|
1149
1149
|
'perp-positions': () => apiInstance.addressPerpPositions({ address, filters, orderBy, pagination }),
|
|
1150
1150
|
'perp-trades': () => apiInstance.addressPerpTrades({ address, filters, orderBy, pagination, days }),
|
|
1151
|
+
'dex-trades': () => {
|
|
1152
|
+
const date = parseDateOption(options.date, days);
|
|
1153
|
+
return apiInstance.addressDexTrades({ address, chain, filters, orderBy, pagination, days, date });
|
|
1154
|
+
},
|
|
1151
1155
|
'batch': () => {
|
|
1152
1156
|
let addresses = [];
|
|
1153
1157
|
if (options.addresses) {
|
|
@@ -1186,7 +1190,7 @@ export function buildCommands(deps = {}) {
|
|
|
1186
1190
|
return compareWallets(apiInstance, { addresses: addrs, chain, days });
|
|
1187
1191
|
},
|
|
1188
1192
|
'help': () => ({
|
|
1189
|
-
commands: ['balance', 'labels', 'transactions', 'pnl', 'search', 'historical-balances', 'related-wallets', 'counterparties', 'pnl-summary', 'perp-positions', 'perp-trades', 'batch', 'trace', 'compare'],
|
|
1193
|
+
commands: ['balance', 'labels', 'transactions', 'pnl', 'search', 'historical-balances', 'related-wallets', 'counterparties', 'pnl-summary', 'perp-positions', 'perp-trades', 'dex-trades', 'batch', 'trace', 'compare'],
|
|
1190
1194
|
description: 'Wallet profiling endpoints',
|
|
1191
1195
|
example: 'nansen research profiler compare --addresses "0xABC...,0xDEF..." --chain ethereum'
|
|
1192
1196
|
})
|
package/src/schema.json
CHANGED
|
@@ -203,6 +203,21 @@
|
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
},
|
|
206
|
+
"dex-trades": {
|
|
207
|
+
"endpoint": "/api/v1/profiler/dex-trades",
|
|
208
|
+
"description": "DEX trade history for a wallet",
|
|
209
|
+
"options": {
|
|
210
|
+
"address": {
|
|
211
|
+
"required": true
|
|
212
|
+
},
|
|
213
|
+
"chain": {
|
|
214
|
+
"default": "ethereum"
|
|
215
|
+
},
|
|
216
|
+
"days": {
|
|
217
|
+
"default": 30
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
},
|
|
206
221
|
"search": {
|
|
207
222
|
"endpoint": "/api/v1/search/entity-name",
|
|
208
223
|
"description": "Search for entities by name",
|
package/src/trade-validation.js
CHANGED
|
@@ -136,6 +136,10 @@ const FEE_BUFFER = { solana: 0.005, base: 0.00004 };
|
|
|
136
136
|
const HIGH_PERCENTAGE_THRESHOLD = 95;
|
|
137
137
|
const AUTO_ADJUST_THRESHOLD_PERCENT = 2;
|
|
138
138
|
|
|
139
|
+
// Trades at or above this USD value can use gasless/solver-paid routes (e.g. Relay),
|
|
140
|
+
// so the native gas pre-check is skipped for them.
|
|
141
|
+
export const GASLESS_MIN_TRADE_USD = 10;
|
|
142
|
+
|
|
139
143
|
/**
|
|
140
144
|
* Check if an address is USDC or the native token for a chain (case-insensitive for EVM).
|
|
141
145
|
*/
|
|
@@ -306,12 +310,19 @@ export async function resolvePercentAmount({ chain, from, walletAddress, percent
|
|
|
306
310
|
*
|
|
307
311
|
* Returns { hasSufficientNative } or throws on validation failure.
|
|
308
312
|
* Best-effort: if RPC fails, returns passing result.
|
|
313
|
+
*
|
|
314
|
+
* Gasless bypass: trades >= $10 USD can use solver-paid options (e.g. Relay),
|
|
315
|
+
* so the gas check is skipped in that case.
|
|
309
316
|
*/
|
|
310
|
-
export async function validateGasBalance({ chain, walletAddress }) {
|
|
317
|
+
export async function validateGasBalance({ chain, walletAddress, tradeValueUsd }) {
|
|
311
318
|
const normalizedChain = chain.toLowerCase();
|
|
312
319
|
const minGas = MIN_GAS_AMOUNTS[normalizedChain];
|
|
313
320
|
if (minGas === undefined) return { hasSufficientNative: true };
|
|
314
321
|
|
|
322
|
+
// High-value trades can use gasless/solver-paid routes — skip the check.
|
|
323
|
+
const tradeUsd = parseFloat(tradeValueUsd) || 0;
|
|
324
|
+
if (tradeUsd >= GASLESS_MIN_TRADE_USD) return { hasSufficientNative: true };
|
|
325
|
+
|
|
315
326
|
const balance = await fetchNativeBalance(normalizedChain, walletAddress);
|
|
316
327
|
|
|
317
328
|
// RPC failure — proceed without validation.
|
|
@@ -323,7 +334,7 @@ export async function validateGasBalance({ chain, walletAddress }) {
|
|
|
323
334
|
|
|
324
335
|
const symbol = NATIVE_SYMBOLS[normalizedChain] || 'native token';
|
|
325
336
|
throw new Error(
|
|
326
|
-
`Insufficient ${symbol} for gas fees. Wallet has ${balance} ${symbol} but needs at least ${minGas} ${symbol}.
|
|
337
|
+
`Insufficient ${symbol} for gas fees. Wallet has ${balance} ${symbol} but needs at least ${minGas} ${symbol}. Either fund the wallet with ${symbol} or trade a value of $${GASLESS_MIN_TRADE_USD}+ to use gasless options.`
|
|
327
338
|
);
|
|
328
339
|
}
|
|
329
340
|
|
package/src/trading.js
CHANGED
|
@@ -1331,8 +1331,10 @@ CROSS-CHAIN NOTES (when using --to-chain):
|
|
|
1331
1331
|
response.quotes.forEach((q, i) => log(formatQuote(q, i)));
|
|
1332
1332
|
|
|
1333
1333
|
// Gas balance validation — check that the wallet has enough native token for gas.
|
|
1334
|
+
// High-value trades (>= $10) can use gasless/solver-paid routes and bypass this check.
|
|
1334
1335
|
try {
|
|
1335
|
-
|
|
1336
|
+
const tradeValueUsd = response.quotes[0]?.inUsdValue;
|
|
1337
|
+
await validateGasBalance({ chain, walletAddress, tradeValueUsd });
|
|
1336
1338
|
} catch (gasErr) {
|
|
1337
1339
|
throw new CommandError(`Error: ${gasErr.message}`, 'INSUFFICIENT_GAS');
|
|
1338
1340
|
}
|