Skip to content

Commit 1ca2600

Browse files
Pepewitchclaude
andcommitted
fix: add slippage-bps validation in create, handle 5xx ghost orders
- Validate --slippage-bps range (0-10000) in create, matching update - On 5xx errors during order creation, check recent orders to warn about potential duplicates before the user retries Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2dcc49c commit 1ca2600

1 file changed

Lines changed: 30 additions & 5 deletions

File tree

src/limit-order.js

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,12 @@ export function buildLimitOrderCommands(deps = {}) {
490490
const expiresStr = options.expires || '30d';
491491
const walletName = options.wallet;
492492

493+
if (slippageBps != null && (isNaN(slippageBps) || slippageBps < 0 || slippageBps > 10000)) {
494+
log('Error: --slippage-bps must be between 0 and 10000 basis points.');
495+
exit(1);
496+
return;
497+
}
498+
493499
if (!from || !to || !amount || triggerPrice == null || !triggerMintRaw || !triggerCondition) {
494500
log(`
495501
Usage: nansen trade limit create --from <token> --to <token> --amount <amount> --trigger-mint <token> --trigger-condition <above|below> --trigger-price <usd>
@@ -584,12 +590,16 @@ EXAMPLES:
584590
return;
585591
}
586592

593+
let authToken = null;
594+
let walletPubkey = null;
595+
587596
try {
588597
// 1. Resolve wallet
589598
const resolved = await resolveSolanaWallet(walletName, deps);
590599
if (!resolved) return;
591600

592601
let { pubkey, walletType, walletInfo } = resolved;
602+
walletPubkey = pubkey;
593603

594604
// For local wallets, load private key now
595605
if (walletType === 'local') {
@@ -604,25 +614,25 @@ EXAMPLES:
604614
log(` Trigger: $${price} (${triggerCondition})`);
605615

606616
// 2. Authenticate
607-
const token = await authenticate(pubkey, walletType, walletInfo, log);
617+
authToken = await authenticate(pubkey, walletType, walletInfo, log);
608618

609619
// 3. Check vault, auto-register if needed
610620
// Backend returns { vaultPubkey: "..." } when vault exists, or throws/returns empty when not
611621
let hasVault = false;
612622
try {
613-
const vaultInfo = await getVault(token, pubkey);
623+
const vaultInfo = await getVault(authToken, pubkey);
614624
hasVault = !!vaultInfo?.vaultPubkey;
615625
} catch {
616626
// No vault found
617627
}
618628
if (!hasVault) {
619629
log(' Registering vault for first-time use...');
620-
await registerVault(token);
630+
await registerVault(authToken);
621631
}
622632

623633
// 4. Craft deposit transaction
624634
log(' Crafting deposit transaction...');
625-
const deposit = await craftDeposit(token, {
635+
const deposit = await craftDeposit(authToken, {
626636
inputMint: from,
627637
outputMint: to,
628638
userAddress: pubkey,
@@ -650,7 +660,7 @@ EXAMPLES:
650660
...(expiresAt != null ? { expiresAt } : {}),
651661
};
652662

653-
const result = await createOrder(token, orderParams);
663+
const result = await createOrder(authToken, orderParams);
654664

655665
log(`\n ✓ Limit order created`);
656666
log(` Order ID: ${result.id}`);
@@ -659,6 +669,21 @@ EXAMPLES:
659669
log('');
660670

661671
} catch (err) {
672+
// 5xx errors may indicate the order was created despite the error (e.g. gateway timeout).
673+
// Check recent orders to warn the user before they retry and create duplicates.
674+
if (err.status >= 500 && authToken && walletPubkey) {
675+
log(`Warning: Order submission returned a server error, but may have succeeded.`);
676+
log(` Checking order status...`);
677+
try {
678+
const check = await listOrders(authToken, walletPubkey, { limit: 1 });
679+
const recent = check.orders?.[0];
680+
if (recent && recent.inputMint === from && recent.outputMint === to) {
681+
log(` Found recent matching order ${recent.id} (status: ${recent.status}).`);
682+
log(` Run: nansen trade limit list`);
683+
return;
684+
}
685+
} catch { /* list check failed, fall through to error */ }
686+
}
662687
log(`Error: ${err.message}`);
663688
if (err.details) log(` Details: ${JSON.stringify(err.details)}`);
664689
if (err.cause) log(` Cause: ${err.cause.message || err.cause}`);

0 commit comments

Comments
 (0)