nansen-cli 1.23.0 → 1.23.1
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 +14 -0
- package/package.json +1 -1
- package/src/commands/alerts.js +4 -1
- package/src/trade-validation.js +54 -0
- package/src/trading.js +11 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.23.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#361](https://github.com/nansen-ai/nansen-cli/pull/361) [`ff22da3`](https://github.com/nansen-ai/nansen-cli/commit/ff22da376c1072ef06e84054f6ee31c058e6e08c) Thanks [@TimNooren](https://github.com/TimNooren)! - fix(alerts): error when --webhook-secret is passed without --webhook
|
|
8
|
+
|
|
9
|
+
Previously, passing --webhook-secret with a non-webhook channel (e.g. --telegram)
|
|
10
|
+
silently discarded the secret with no warning. The alert was created successfully
|
|
11
|
+
but without any signing, giving the false impression that the secret was active.
|
|
12
|
+
|
|
13
|
+
Now throws an actionable error: "--webhook-secret requires --webhook".
|
|
14
|
+
|
|
15
|
+
- [#358](https://github.com/nansen-ai/nansen-cli/pull/358) [`70ee712`](https://github.com/nansen-ai/nansen-cli/commit/70ee71205343fb2d003eb5f50144e266bdc6109e) Thanks [@TimNooren](https://github.com/TimNooren)! - Add pre-quote trade input validation: rejects same-token swaps, invalid address formats, and non-positive amounts before any network call.
|
|
16
|
+
|
|
3
17
|
## 1.23.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/package.json
CHANGED
package/src/commands/alerts.js
CHANGED
|
@@ -560,8 +560,11 @@ USAGE:
|
|
|
560
560
|
return;
|
|
561
561
|
}
|
|
562
562
|
|
|
563
|
-
// Build channels array from --telegram/--slack/--discord flags
|
|
563
|
+
// Build channels array from --telegram/--slack/--discord/--webhook flags
|
|
564
564
|
function buildChannels() {
|
|
565
|
+
if (options["webhook-secret"] && !options.webhook) {
|
|
566
|
+
throw new NansenError('--webhook-secret requires --webhook', ErrorCode.INVALID_PARAMS);
|
|
567
|
+
}
|
|
565
568
|
const channels = [];
|
|
566
569
|
if (options.telegram) channels.push({ type: 'telegram', data: { chatId: String(options.telegram) } });
|
|
567
570
|
if (options.slack) channels.push({ type: 'slack', data: { webhookUrl: options.slack } });
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trade input validation for the Nansen CLI.
|
|
3
|
+
* Catches common agent errors (wrong addresses, same-token swaps,
|
|
4
|
+
* bad amounts) before any network call.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { validateAddress } from './api.js';
|
|
8
|
+
|
|
9
|
+
const SUPPORTED_CHAINS = ['solana', 'base'];
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Validate quote inputs before any network call.
|
|
13
|
+
* Throws on validation failure with an actionable error message.
|
|
14
|
+
*/
|
|
15
|
+
export function validateQuoteInput({ chain, from, to, amount }) {
|
|
16
|
+
// 1. Chain must be supported
|
|
17
|
+
const normalizedChain = chain?.toLowerCase();
|
|
18
|
+
if (!SUPPORTED_CHAINS.includes(normalizedChain)) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`Unsupported chain "${chain}". Supported chains: ${SUPPORTED_CHAINS.join(', ')}.`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 2. Amount must be a positive finite number
|
|
25
|
+
const numAmount = Number(amount);
|
|
26
|
+
if (!Number.isFinite(numAmount) || numAmount <= 0) {
|
|
27
|
+
throw new Error(
|
|
28
|
+
`Invalid amount "${amount}". Must be a positive number.`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 3. Token address format must match the chain (reuses api.js validateAddress)
|
|
33
|
+
const fromResult = validateAddress(from, normalizedChain);
|
|
34
|
+
if (!fromResult.valid) {
|
|
35
|
+
throw new Error(
|
|
36
|
+
`Invalid sell token address for ${normalizedChain}. ${fromResult.error}`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
const toResult = validateAddress(to, normalizedChain);
|
|
40
|
+
if (!toResult.valid) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
`Invalid buy token address for ${normalizedChain}. ${toResult.error}`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 4. Sell and buy tokens must be different
|
|
47
|
+
const fromNorm = normalizedChain === 'solana' ? from : from.toLowerCase();
|
|
48
|
+
const toNorm = normalizedChain === 'solana' ? to : to.toLowerCase();
|
|
49
|
+
if (fromNorm === toNorm) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Cannot swap ${from} for itself. Sell and buy tokens must be different.`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
package/src/trading.js
CHANGED
|
@@ -13,6 +13,7 @@ import { base58Decode } from './transfer.js';
|
|
|
13
13
|
import { keccak256, signSecp256k1, rlpEncode } from './crypto.js';
|
|
14
14
|
import { getWalletConnectAddress, sendTransactionViaWalletConnect, sendSolanaTransactionViaWalletConnect, sendApprovalViaWalletConnect } from './walletconnect-trading.js';
|
|
15
15
|
import { retrievePassword } from './keychain.js';
|
|
16
|
+
import { validateQuoteInput } from './trade-validation.js';
|
|
16
17
|
import { CHAIN_RPCS } from './rpc-urls.js';
|
|
17
18
|
|
|
18
19
|
// ============= Constants =============
|
|
@@ -877,6 +878,16 @@ EXAMPLES:
|
|
|
877
878
|
return;
|
|
878
879
|
}
|
|
879
880
|
|
|
881
|
+
// Static input validation — catches common agent errors (wrong addresses,
|
|
882
|
+
// same-token swaps, bad amounts) before any network or wallet call.
|
|
883
|
+
try {
|
|
884
|
+
validateQuoteInput({ chain, from, to, amount });
|
|
885
|
+
} catch (validationErr) {
|
|
886
|
+
log(`Error: ${validationErr.message}`);
|
|
887
|
+
exit(1);
|
|
888
|
+
return;
|
|
889
|
+
}
|
|
890
|
+
|
|
880
891
|
// When --amount-unit token is used, resolve decimals and convert to base units.
|
|
881
892
|
// Otherwise, validate that the amount is already in base units (integer).
|
|
882
893
|
let resolvedAmount = amount;
|