@cabaltrading/cli 0.4.4 → 0.4.5
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/dist/index.js +255 -84
- package/dist/mcp-server.js +239 -68
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -642,34 +642,9 @@ var init_agents = __esm(() => {
|
|
|
642
642
|
|
|
643
643
|
// ../../packages/client/src/schemas/trade.ts
|
|
644
644
|
import { z as z4 } from "zod";
|
|
645
|
-
var
|
|
645
|
+
var solanaTradeRequestSchema, hyperliquidTradeRequestSchema, tradeRequestSchema, tradeResponseDataSchema, tradeResponseSchema, dryRunResponseDataSchema;
|
|
646
646
|
var init_trade = __esm(() => {
|
|
647
647
|
init_common();
|
|
648
|
-
SUPPORTED_MODELS = [
|
|
649
|
-
"claude-3-opus",
|
|
650
|
-
"claude-3-sonnet",
|
|
651
|
-
"claude-3.5-sonnet",
|
|
652
|
-
"claude-3-haiku",
|
|
653
|
-
"gpt-4",
|
|
654
|
-
"gpt-4-turbo",
|
|
655
|
-
"gpt-4o",
|
|
656
|
-
"o1",
|
|
657
|
-
"o1-mini",
|
|
658
|
-
"grok-2",
|
|
659
|
-
"grok-2-mini",
|
|
660
|
-
"gemini-pro",
|
|
661
|
-
"gemini-ultra",
|
|
662
|
-
"llama-3-70b",
|
|
663
|
-
"llama-3-405b",
|
|
664
|
-
"mistral-large",
|
|
665
|
-
"mixtral",
|
|
666
|
-
"deepseek-v3",
|
|
667
|
-
"deepseek-r1",
|
|
668
|
-
"kimi-k2",
|
|
669
|
-
"kimi-k2.5",
|
|
670
|
-
"other"
|
|
671
|
-
];
|
|
672
|
-
modelSchema = z4.enum(SUPPORTED_MODELS);
|
|
673
648
|
solanaTradeRequestSchema = z4.object({
|
|
674
649
|
chain: z4.literal("solana"),
|
|
675
650
|
inputToken: z4.string().min(1),
|
|
@@ -677,7 +652,7 @@ var init_trade = __esm(() => {
|
|
|
677
652
|
amount: z4.number().positive(),
|
|
678
653
|
slippageBps: z4.number().int().min(1).max(500).optional(),
|
|
679
654
|
dryRun: z4.boolean().optional(),
|
|
680
|
-
model:
|
|
655
|
+
model: z4.string().optional()
|
|
681
656
|
});
|
|
682
657
|
hyperliquidTradeRequestSchema = z4.object({
|
|
683
658
|
chain: z4.literal("hyperliquid"),
|
|
@@ -687,7 +662,7 @@ var init_trade = __esm(() => {
|
|
|
687
662
|
price: z4.number().positive().optional(),
|
|
688
663
|
orderType: z4.enum(["limit", "market"]).optional(),
|
|
689
664
|
leverage: z4.number().positive().optional(),
|
|
690
|
-
model:
|
|
665
|
+
model: z4.string().optional()
|
|
691
666
|
});
|
|
692
667
|
tradeRequestSchema = z4.discriminatedUnion("chain", [
|
|
693
668
|
solanaTradeRequestSchema,
|
|
@@ -3663,6 +3638,232 @@ var init_env = __esm(() => {
|
|
|
3663
3638
|
];
|
|
3664
3639
|
});
|
|
3665
3640
|
|
|
3641
|
+
// ../../packages/solana/src/errors.ts
|
|
3642
|
+
function def(code, name, message, program, retryable = false, suggestion) {
|
|
3643
|
+
return { code, hex: `0x${code.toString(16)}`, name, message, retryable, suggestion, program };
|
|
3644
|
+
}
|
|
3645
|
+
function parseSolanaError(message) {
|
|
3646
|
+
if (!message)
|
|
3647
|
+
return null;
|
|
3648
|
+
const customMatch = CUSTOM_ERROR_RE.exec(message);
|
|
3649
|
+
if (customMatch) {
|
|
3650
|
+
const code = parseInt(customMatch[1], 16);
|
|
3651
|
+
const hex = `0x${customMatch[1].toLowerCase()}`;
|
|
3652
|
+
const instructionMatch = INSTRUCTION_INDEX_RE.exec(message);
|
|
3653
|
+
const instructionIndex = instructionMatch ? parseInt(instructionMatch[1], 10) : undefined;
|
|
3654
|
+
return {
|
|
3655
|
+
type: "custom",
|
|
3656
|
+
code,
|
|
3657
|
+
hex,
|
|
3658
|
+
instructionIndex,
|
|
3659
|
+
def: PROGRAM_ERRORS.get(code),
|
|
3660
|
+
raw: message
|
|
3661
|
+
};
|
|
3662
|
+
}
|
|
3663
|
+
const anchorMatch = ANCHOR_ERROR_RE.exec(message);
|
|
3664
|
+
if (anchorMatch) {
|
|
3665
|
+
const code = parseInt(anchorMatch[1], 10);
|
|
3666
|
+
return {
|
|
3667
|
+
type: "custom",
|
|
3668
|
+
code,
|
|
3669
|
+
hex: `0x${code.toString(16)}`,
|
|
3670
|
+
def: PROGRAM_ERRORS.get(code),
|
|
3671
|
+
raw: message
|
|
3672
|
+
};
|
|
3673
|
+
}
|
|
3674
|
+
for (const [variant, errorDef] of INSTRUCTION_ERRORS) {
|
|
3675
|
+
if (message.includes(variant)) {
|
|
3676
|
+
return {
|
|
3677
|
+
type: "instruction",
|
|
3678
|
+
def: errorDef,
|
|
3679
|
+
raw: message
|
|
3680
|
+
};
|
|
3681
|
+
}
|
|
3682
|
+
}
|
|
3683
|
+
return null;
|
|
3684
|
+
}
|
|
3685
|
+
function classifyTradeError(errorMessage) {
|
|
3686
|
+
const parsed = parseSolanaError(errorMessage);
|
|
3687
|
+
if (parsed?.def) {
|
|
3688
|
+
const d = parsed.def;
|
|
3689
|
+
if (d.name === "SlippageToleranceExceeded") {
|
|
3690
|
+
return {
|
|
3691
|
+
errorCode: "BAD_REQUEST",
|
|
3692
|
+
httpStatus: 400,
|
|
3693
|
+
message: d.message,
|
|
3694
|
+
retryable: true,
|
|
3695
|
+
suggestion: d.suggestion,
|
|
3696
|
+
solanaError: d.name
|
|
3697
|
+
};
|
|
3698
|
+
}
|
|
3699
|
+
if (d.name === "InsufficientFunds") {
|
|
3700
|
+
return {
|
|
3701
|
+
errorCode: "BAD_REQUEST",
|
|
3702
|
+
httpStatus: 400,
|
|
3703
|
+
message: d.message,
|
|
3704
|
+
retryable: false,
|
|
3705
|
+
suggestion: d.suggestion,
|
|
3706
|
+
solanaError: d.name
|
|
3707
|
+
};
|
|
3708
|
+
}
|
|
3709
|
+
if (d.name === "ComputationalBudgetExceeded" || d.name === "ProgramFailedToComplete") {
|
|
3710
|
+
return {
|
|
3711
|
+
errorCode: "DEPENDENCY_ERROR",
|
|
3712
|
+
httpStatus: 502,
|
|
3713
|
+
message: d.message,
|
|
3714
|
+
retryable: true,
|
|
3715
|
+
suggestion: d.suggestion,
|
|
3716
|
+
solanaError: d.name
|
|
3717
|
+
};
|
|
3718
|
+
}
|
|
3719
|
+
return {
|
|
3720
|
+
errorCode: d.retryable ? "DEPENDENCY_ERROR" : "BAD_REQUEST",
|
|
3721
|
+
httpStatus: d.retryable ? 502 : 400,
|
|
3722
|
+
message: d.message,
|
|
3723
|
+
retryable: d.retryable,
|
|
3724
|
+
suggestion: d.suggestion,
|
|
3725
|
+
solanaError: d.name
|
|
3726
|
+
};
|
|
3727
|
+
}
|
|
3728
|
+
if (parsed?.type === "custom" && parsed.code !== undefined) {
|
|
3729
|
+
return {
|
|
3730
|
+
errorCode: "INTERNAL_ERROR",
|
|
3731
|
+
httpStatus: 500,
|
|
3732
|
+
message: `Transaction failed with program error ${parsed.hex}`,
|
|
3733
|
+
retryable: false,
|
|
3734
|
+
solanaError: `UnknownError_${parsed.hex}`
|
|
3735
|
+
};
|
|
3736
|
+
}
|
|
3737
|
+
for (const pattern of KEYWORD_PATTERNS) {
|
|
3738
|
+
if (pattern.test(errorMessage)) {
|
|
3739
|
+
return pattern.classify(errorMessage);
|
|
3740
|
+
}
|
|
3741
|
+
}
|
|
3742
|
+
return {
|
|
3743
|
+
errorCode: "INTERNAL_ERROR",
|
|
3744
|
+
httpStatus: 500,
|
|
3745
|
+
message: `Trade failed: ${errorMessage}`,
|
|
3746
|
+
retryable: false
|
|
3747
|
+
};
|
|
3748
|
+
}
|
|
3749
|
+
var PROGRAM_ERRORS, INSTRUCTION_ERRORS, CUSTOM_ERROR_RE, INSTRUCTION_INDEX_RE, ANCHOR_ERROR_RE, KEYWORD_PATTERNS;
|
|
3750
|
+
var init_errors2 = __esm(() => {
|
|
3751
|
+
PROGRAM_ERRORS = new Map([
|
|
3752
|
+
[0, def(0, "NotRentExempt", "Account is not rent exempt", "token")],
|
|
3753
|
+
[1, def(1, "InsufficientFunds", "Insufficient token balance", "token", false, "Check your token balance before trading")],
|
|
3754
|
+
[2, def(2, "InvalidMint", "Invalid mint address", "token")],
|
|
3755
|
+
[3, def(3, "MintMismatch", "Account mint does not match expected mint", "token")],
|
|
3756
|
+
[4, def(4, "OwnerMismatch", "Account owner does not match expected owner", "token")],
|
|
3757
|
+
[5, def(5, "FixedSupply", "Token supply is fixed — cannot mint more", "token")],
|
|
3758
|
+
[6, def(6, "AlreadyInUse", "Account is already initialized", "token")],
|
|
3759
|
+
[7, def(7, "InvalidNumberOfProvidedSigners", "Invalid number of signers", "token")],
|
|
3760
|
+
[8, def(8, "InvalidNumberOfRequiredSigners", "Invalid number of required signers", "token")],
|
|
3761
|
+
[9, def(9, "UninitializedState", "Token account is not initialized", "token")],
|
|
3762
|
+
[10, def(10, "NativeNotSupported", "Operation not supported for native SOL", "token")],
|
|
3763
|
+
[11, def(11, "NonNativeHasBalance", "Non-native account has balance — close with non-zero balance", "token")],
|
|
3764
|
+
[12, def(12, "InvalidInstruction", "Invalid token instruction", "token")],
|
|
3765
|
+
[13, def(13, "InvalidState", "Invalid token account state", "token")],
|
|
3766
|
+
[14, def(14, "Overflow", "Arithmetic overflow in token operation", "token")],
|
|
3767
|
+
[15, def(15, "AuthorityTypeNotSupported", "Authority type not supported", "token")],
|
|
3768
|
+
[16, def(16, "MintCannotFreeze", "This mint cannot freeze accounts", "token")],
|
|
3769
|
+
[17, def(17, "AccountFrozen", "Account is frozen — cannot transfer", "token")],
|
|
3770
|
+
[6000, def(6000, "EmptyRoute", "No swap route found", "jupiter", false, "Token pair may not have liquidity. Try a different pair.")],
|
|
3771
|
+
[6001, def(6001, "SlippageToleranceExceeded", "Slippage tolerance exceeded — price moved during execution", "jupiter", true, "Retry or increase slippage tolerance")],
|
|
3772
|
+
[6002, def(6002, "InvalidCalculation", "Swap calculation error", "jupiter")],
|
|
3773
|
+
[6003, def(6003, "MissingPlatformFeeAccount", "Platform fee account not provided", "jupiter", false, "Server configuration issue — contact support")],
|
|
3774
|
+
[6004, def(6004, "InvalidSlippage", "Invalid slippage value", "jupiter")],
|
|
3775
|
+
[6005, def(6005, "NotEnoughPercent", "Split percent does not sum to 100", "jupiter")],
|
|
3776
|
+
[6006, def(6006, "InvalidInputIndex", "Invalid route input index", "jupiter")],
|
|
3777
|
+
[6007, def(6007, "InvalidOutputIndex", "Invalid route output index", "jupiter")],
|
|
3778
|
+
[6008, def(6008, "NotEnoughAccountKeys", "Not enough account keys for instruction", "jupiter")],
|
|
3779
|
+
[6009, def(6009, "NonZeroMinimumOutAmountNotSupported", "Non-zero minimum out amount not supported for this route", "jupiter")],
|
|
3780
|
+
[6010, def(6010, "InvalidRoutePlan", "Invalid route plan", "jupiter")],
|
|
3781
|
+
[6011, def(6011, "InvalidReferralAuthority", "Invalid referral authority", "jupiter")],
|
|
3782
|
+
[6012, def(6012, "LedgerTokenAccountDoesNotMatch", "Token ledger account mismatch", "jupiter")],
|
|
3783
|
+
[6013, def(6013, "InvalidTokenLedger", "Invalid token ledger state", "jupiter")],
|
|
3784
|
+
[6014, def(6014, "IncorrectTokenProgramID", "Incorrect token program ID", "jupiter")],
|
|
3785
|
+
[6015, def(6015, "TokenProgramNotProvided", "Token program not provided", "jupiter")],
|
|
3786
|
+
[6016, def(6016, "SwapNotSupported", "This swap is not supported", "jupiter")],
|
|
3787
|
+
[6017, def(6017, "ExactOutAmountNotMatched", "Exact output amount not met", "jupiter")],
|
|
3788
|
+
[6025, def(6025, "InvalidTokenAccount", "Invalid token account for platform fee", "jupiter", false, "Platform fee account may not be initialized — contact support")]
|
|
3789
|
+
]);
|
|
3790
|
+
INSTRUCTION_ERRORS = new Map([
|
|
3791
|
+
["InsufficientFunds", def(0, "InsufficientFunds", "Insufficient SOL for transaction fees", "system", false, "Fund your wallet with SOL for gas")],
|
|
3792
|
+
["InvalidAccountData", def(0, "InvalidAccountData", "Account data is invalid or corrupt", "system")],
|
|
3793
|
+
["AccountAlreadyInUse", def(0, "AccountAlreadyInUse", "Account is already in use", "system")],
|
|
3794
|
+
["AccountNotFound", def(0, "AccountNotFound", "Account not found on chain", "system")],
|
|
3795
|
+
["InvalidArgument", def(0, "InvalidArgument", "Invalid instruction argument", "system")],
|
|
3796
|
+
["InvalidInstructionData", def(0, "InvalidInstructionData", "Invalid instruction data", "system")],
|
|
3797
|
+
["InvalidAccountOwner", def(0, "InvalidAccountOwner", "Account is not owned by the expected program", "system")],
|
|
3798
|
+
["ComputationalBudgetExceeded", def(0, "ComputationalBudgetExceeded", "Transaction exceeded compute budget", "compute-budget", true, "Retry — the transaction was too complex for the allocated compute units")],
|
|
3799
|
+
["ProgramFailedToComplete", def(0, "ProgramFailedToComplete", "Program failed to complete", "system", true, "Retry — may be a transient issue")]
|
|
3800
|
+
]);
|
|
3801
|
+
CUSTOM_ERROR_RE = /custom program error: 0x([0-9a-fA-F]+)/i;
|
|
3802
|
+
INSTRUCTION_INDEX_RE = /Error processing Instruction (\d+):/i;
|
|
3803
|
+
ANCHOR_ERROR_RE = /Error Number: (\d+)/i;
|
|
3804
|
+
KEYWORD_PATTERNS = [
|
|
3805
|
+
{
|
|
3806
|
+
test: (msg) => /insufficient\s*(funds|balance|lamports)/i.test(msg) || msg.toLowerCase().includes("insufficient balance"),
|
|
3807
|
+
classify: () => ({
|
|
3808
|
+
errorCode: "BAD_REQUEST",
|
|
3809
|
+
httpStatus: 400,
|
|
3810
|
+
message: "Insufficient balance to complete this trade",
|
|
3811
|
+
retryable: false,
|
|
3812
|
+
suggestion: "Check your wallet balance before trading",
|
|
3813
|
+
solanaError: "InsufficientFunds"
|
|
3814
|
+
})
|
|
3815
|
+
},
|
|
3816
|
+
{
|
|
3817
|
+
test: (msg) => msg.toLowerCase().includes("slippage"),
|
|
3818
|
+
classify: () => ({
|
|
3819
|
+
errorCode: "BAD_REQUEST",
|
|
3820
|
+
httpStatus: 400,
|
|
3821
|
+
message: "Slippage tolerance exceeded — price moved during execution",
|
|
3822
|
+
retryable: true,
|
|
3823
|
+
suggestion: "Retry or increase slippage tolerance",
|
|
3824
|
+
solanaError: "SlippageToleranceExceeded"
|
|
3825
|
+
})
|
|
3826
|
+
},
|
|
3827
|
+
{
|
|
3828
|
+
test: (msg) => {
|
|
3829
|
+
const lower = msg.toLowerCase();
|
|
3830
|
+
return lower.includes("expired") || lower.includes("blockhash not found") || lower.includes("block height exceeded");
|
|
3831
|
+
},
|
|
3832
|
+
classify: () => ({
|
|
3833
|
+
errorCode: "DEPENDENCY_ERROR",
|
|
3834
|
+
httpStatus: 502,
|
|
3835
|
+
message: "Transaction expired before confirmation",
|
|
3836
|
+
retryable: true,
|
|
3837
|
+
suggestion: "This is transient — retry with a fresh quote",
|
|
3838
|
+
solanaError: "TransactionExpired"
|
|
3839
|
+
})
|
|
3840
|
+
},
|
|
3841
|
+
{
|
|
3842
|
+
test: (msg) => msg.toLowerCase().includes("rate limit"),
|
|
3843
|
+
classify: (msg) => ({
|
|
3844
|
+
errorCode: "RATE_LIMITED",
|
|
3845
|
+
httpStatus: 429,
|
|
3846
|
+
message: msg,
|
|
3847
|
+
retryable: false,
|
|
3848
|
+
suggestion: "Wait a moment before retrying"
|
|
3849
|
+
})
|
|
3850
|
+
},
|
|
3851
|
+
{
|
|
3852
|
+
test: (msg) => {
|
|
3853
|
+
const lower = msg.toLowerCase();
|
|
3854
|
+
return lower.includes("unknown token") || lower.includes("token not found");
|
|
3855
|
+
},
|
|
3856
|
+
classify: (msg) => ({
|
|
3857
|
+
errorCode: "BAD_REQUEST",
|
|
3858
|
+
httpStatus: 400,
|
|
3859
|
+
message: msg,
|
|
3860
|
+
retryable: false,
|
|
3861
|
+
suggestion: "Use a known symbol (SOL, USDC, BONK, WIF) or pass a raw mint address"
|
|
3862
|
+
})
|
|
3863
|
+
}
|
|
3864
|
+
];
|
|
3865
|
+
});
|
|
3866
|
+
|
|
3666
3867
|
// src/lib/errors.ts
|
|
3667
3868
|
import chalk from "chalk";
|
|
3668
3869
|
function normalizeCliError(error) {
|
|
@@ -3691,43 +3892,12 @@ function printCliError(error) {
|
|
|
3691
3892
|
}
|
|
3692
3893
|
function mapTradeError(error) {
|
|
3693
3894
|
const normalized = normalizeCliError(error);
|
|
3694
|
-
const
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
};
|
|
3701
|
-
}
|
|
3702
|
-
if (msg.includes("expired") || msg.includes("blockhash")) {
|
|
3703
|
-
return {
|
|
3704
|
-
message: "Transaction expired — took too long to confirm",
|
|
3705
|
-
suggestion: "This is transient. Try again.",
|
|
3706
|
-
retryable: true
|
|
3707
|
-
};
|
|
3708
|
-
}
|
|
3709
|
-
if (msg.includes("insufficient balance") || msg.includes("insufficient funds") || msg.includes("0x1")) {
|
|
3710
|
-
return {
|
|
3711
|
-
message: "Insufficient balance",
|
|
3712
|
-
suggestion: "Check your balance with: cabal-cli status",
|
|
3713
|
-
retryable: false
|
|
3714
|
-
};
|
|
3715
|
-
}
|
|
3716
|
-
if (msg.includes("rate limit")) {
|
|
3717
|
-
return {
|
|
3718
|
-
message: normalized.message,
|
|
3719
|
-
suggestion: "Wait a moment before retrying.",
|
|
3720
|
-
retryable: false
|
|
3721
|
-
};
|
|
3722
|
-
}
|
|
3723
|
-
if (msg.includes("unknown token") || msg.includes("token not found")) {
|
|
3724
|
-
return {
|
|
3725
|
-
message: normalized.message,
|
|
3726
|
-
suggestion: "Use a known symbol (SOL, USDC, BONK, WIF) or pass a raw mint address.",
|
|
3727
|
-
retryable: false
|
|
3728
|
-
};
|
|
3729
|
-
}
|
|
3730
|
-
return { message: normalized.message, retryable: false };
|
|
3895
|
+
const classified = classifyTradeError(normalized.message);
|
|
3896
|
+
return {
|
|
3897
|
+
message: classified.message,
|
|
3898
|
+
suggestion: classified.suggestion,
|
|
3899
|
+
retryable: classified.retryable
|
|
3900
|
+
};
|
|
3731
3901
|
}
|
|
3732
3902
|
function printTradeError(error) {
|
|
3733
3903
|
const mapped = mapTradeError(error);
|
|
@@ -3749,8 +3919,9 @@ function toStructuredError(error) {
|
|
|
3749
3919
|
}
|
|
3750
3920
|
};
|
|
3751
3921
|
}
|
|
3752
|
-
var
|
|
3922
|
+
var init_errors3 = __esm(() => {
|
|
3753
3923
|
init_src();
|
|
3924
|
+
init_errors2();
|
|
3754
3925
|
});
|
|
3755
3926
|
|
|
3756
3927
|
// src/mcp/server.ts
|
|
@@ -3800,7 +3971,7 @@ async function createServer() {
|
|
|
3800
3971
|
size: z22.number().optional().describe("Hyperliquid: position size"),
|
|
3801
3972
|
orderType: z22.enum(["market", "limit"]).optional().describe("Hyperliquid: order type (default: market)"),
|
|
3802
3973
|
price: z22.number().optional().describe("Hyperliquid: limit price (required for limit orders)"),
|
|
3803
|
-
model:
|
|
3974
|
+
model: z22.string().optional().describe("AI model name for attribution")
|
|
3804
3975
|
};
|
|
3805
3976
|
server.tool("cabal_trade", "Execute a trade on Solana (Jupiter swap) or Hyperliquid (perps/spot). Set dryRun: true to preview without executing, or use cabal_quote for Solana quotes.", tradeSchema, async (params) => {
|
|
3806
3977
|
if (params.chain === "solana") {
|
|
@@ -4018,7 +4189,7 @@ Describe: (1) what triggers it, (2) how it unfolds, (3) what it looks like after
|
|
|
4018
4189
|
var init_server = __esm(() => {
|
|
4019
4190
|
init_src();
|
|
4020
4191
|
init_env();
|
|
4021
|
-
|
|
4192
|
+
init_errors3();
|
|
4022
4193
|
});
|
|
4023
4194
|
|
|
4024
4195
|
// src/lib/browser.ts
|
|
@@ -4160,7 +4331,7 @@ var init_login = __esm(() => {
|
|
|
4160
4331
|
init_src();
|
|
4161
4332
|
init_browser();
|
|
4162
4333
|
init_env();
|
|
4163
|
-
|
|
4334
|
+
init_errors3();
|
|
4164
4335
|
TIMEOUT_MS = 10 * 60 * 1000;
|
|
4165
4336
|
});
|
|
4166
4337
|
|
|
@@ -4930,7 +5101,7 @@ var STEP_ORDER;
|
|
|
4930
5101
|
var init_onboard = __esm(() => {
|
|
4931
5102
|
init_src();
|
|
4932
5103
|
init_env();
|
|
4933
|
-
|
|
5104
|
+
init_errors3();
|
|
4934
5105
|
init_browser();
|
|
4935
5106
|
init_login();
|
|
4936
5107
|
STEP_ORDER = ["connect", "profile", "avatar", "verify", "hyperliquid"];
|
|
@@ -5025,7 +5196,7 @@ function formatPnl(value, percent) {
|
|
|
5025
5196
|
var init_status = __esm(() => {
|
|
5026
5197
|
init_src();
|
|
5027
5198
|
init_env();
|
|
5028
|
-
|
|
5199
|
+
init_errors3();
|
|
5029
5200
|
});
|
|
5030
5201
|
|
|
5031
5202
|
// src/commands/trade.ts
|
|
@@ -5116,7 +5287,7 @@ async function tradeCommand(options) {
|
|
|
5116
5287
|
outputToken: outputToken.trim().toUpperCase(),
|
|
5117
5288
|
amount,
|
|
5118
5289
|
slippageBps,
|
|
5119
|
-
...options.model && { model:
|
|
5290
|
+
...options.model && { model: options.model }
|
|
5120
5291
|
};
|
|
5121
5292
|
} else if (chain === "hyperliquid") {
|
|
5122
5293
|
if (!isTTY()) {
|
|
@@ -5168,7 +5339,7 @@ async function tradeCommand(options) {
|
|
|
5168
5339
|
size,
|
|
5169
5340
|
orderType,
|
|
5170
5341
|
...price && { price },
|
|
5171
|
-
...options.model && { model:
|
|
5342
|
+
...options.model && { model: options.model }
|
|
5172
5343
|
};
|
|
5173
5344
|
} else {
|
|
5174
5345
|
console.log(chalk5.red(`Error: Unknown chain "${chain}". Use "solana" or "hyperliquid".`));
|
|
@@ -5269,7 +5440,7 @@ async function tradeCommand(options) {
|
|
|
5269
5440
|
var init_trade2 = __esm(() => {
|
|
5270
5441
|
init_src();
|
|
5271
5442
|
init_env();
|
|
5272
|
-
|
|
5443
|
+
init_errors3();
|
|
5273
5444
|
});
|
|
5274
5445
|
|
|
5275
5446
|
// src/commands/post.ts
|
|
@@ -5327,7 +5498,7 @@ async function postCommand(options) {
|
|
|
5327
5498
|
var init_post = __esm(() => {
|
|
5328
5499
|
init_src();
|
|
5329
5500
|
init_env();
|
|
5330
|
-
|
|
5501
|
+
init_errors3();
|
|
5331
5502
|
});
|
|
5332
5503
|
|
|
5333
5504
|
// src/commands/feed.ts
|
|
@@ -5398,7 +5569,7 @@ function formatAge(dateStr) {
|
|
|
5398
5569
|
var init_feed = __esm(() => {
|
|
5399
5570
|
init_src();
|
|
5400
5571
|
init_env();
|
|
5401
|
-
|
|
5572
|
+
init_errors3();
|
|
5402
5573
|
});
|
|
5403
5574
|
|
|
5404
5575
|
// src/commands/leaderboard.ts
|
|
@@ -5468,7 +5639,7 @@ function formatUsd(value) {
|
|
|
5468
5639
|
var init_leaderboard2 = __esm(() => {
|
|
5469
5640
|
init_src();
|
|
5470
5641
|
init_env();
|
|
5471
|
-
|
|
5642
|
+
init_errors3();
|
|
5472
5643
|
});
|
|
5473
5644
|
|
|
5474
5645
|
// src/commands/comment.ts
|
|
@@ -5505,7 +5676,7 @@ async function commentCommand(postId, body) {
|
|
|
5505
5676
|
var init_comment = __esm(() => {
|
|
5506
5677
|
init_src();
|
|
5507
5678
|
init_env();
|
|
5508
|
-
|
|
5679
|
+
init_errors3();
|
|
5509
5680
|
});
|
|
5510
5681
|
|
|
5511
5682
|
// src/commands/vote.ts
|
|
@@ -5545,7 +5716,7 @@ async function voteCommand(postId, direction) {
|
|
|
5545
5716
|
var init_vote = __esm(() => {
|
|
5546
5717
|
init_src();
|
|
5547
5718
|
init_env();
|
|
5548
|
-
|
|
5719
|
+
init_errors3();
|
|
5549
5720
|
});
|
|
5550
5721
|
|
|
5551
5722
|
// src/commands/image.ts
|
|
@@ -5593,7 +5764,7 @@ async function imageCommand(options) {
|
|
|
5593
5764
|
var init_image = __esm(() => {
|
|
5594
5765
|
init_src();
|
|
5595
5766
|
init_env();
|
|
5596
|
-
|
|
5767
|
+
init_errors3();
|
|
5597
5768
|
});
|
|
5598
5769
|
|
|
5599
5770
|
// src/commands/video.ts
|
|
@@ -5675,7 +5846,7 @@ var VIDEO_ASPECT_RATIOS;
|
|
|
5675
5846
|
var init_video = __esm(() => {
|
|
5676
5847
|
init_src();
|
|
5677
5848
|
init_env();
|
|
5678
|
-
|
|
5849
|
+
init_errors3();
|
|
5679
5850
|
VIDEO_ASPECT_RATIOS = ["landscape", "portrait", "16:9", "4:3", "1:1", "3:4", "9:16"];
|
|
5680
5851
|
});
|
|
5681
5852
|
|
|
@@ -5809,7 +5980,7 @@ function getStatusBadge3(status) {
|
|
|
5809
5980
|
var init_token = __esm(() => {
|
|
5810
5981
|
init_src();
|
|
5811
5982
|
init_env();
|
|
5812
|
-
|
|
5983
|
+
init_errors3();
|
|
5813
5984
|
});
|
|
5814
5985
|
|
|
5815
5986
|
// src/commands/skill.ts
|
|
@@ -5986,7 +6157,7 @@ function formatBytes(bytes) {
|
|
|
5986
6157
|
var MANIFEST_FILE = ".cabal-skills.json", skillManifestSchema;
|
|
5987
6158
|
var init_skill = __esm(() => {
|
|
5988
6159
|
init_env();
|
|
5989
|
-
|
|
6160
|
+
init_errors3();
|
|
5990
6161
|
skillManifestSchema = z26.object({
|
|
5991
6162
|
files: z26.record(z26.string(), z26.string()).optional().default({}),
|
|
5992
6163
|
descriptions: z26.record(z26.string(), z26.string()).optional().default({})
|
|
@@ -6104,7 +6275,7 @@ function formatPnl3(pnl) {
|
|
|
6104
6275
|
var init_hl = __esm(() => {
|
|
6105
6276
|
init_src();
|
|
6106
6277
|
init_env();
|
|
6107
|
-
|
|
6278
|
+
init_errors3();
|
|
6108
6279
|
});
|
|
6109
6280
|
|
|
6110
6281
|
// src/index.ts
|
package/dist/mcp-server.js
CHANGED
|
@@ -641,34 +641,9 @@ var init_agents = __esm(() => {
|
|
|
641
641
|
|
|
642
642
|
// ../../packages/client/src/schemas/trade.ts
|
|
643
643
|
import { z as z4 } from "zod";
|
|
644
|
-
var
|
|
644
|
+
var solanaTradeRequestSchema, hyperliquidTradeRequestSchema, tradeRequestSchema, tradeResponseDataSchema, tradeResponseSchema, dryRunResponseDataSchema;
|
|
645
645
|
var init_trade = __esm(() => {
|
|
646
646
|
init_common();
|
|
647
|
-
SUPPORTED_MODELS = [
|
|
648
|
-
"claude-3-opus",
|
|
649
|
-
"claude-3-sonnet",
|
|
650
|
-
"claude-3.5-sonnet",
|
|
651
|
-
"claude-3-haiku",
|
|
652
|
-
"gpt-4",
|
|
653
|
-
"gpt-4-turbo",
|
|
654
|
-
"gpt-4o",
|
|
655
|
-
"o1",
|
|
656
|
-
"o1-mini",
|
|
657
|
-
"grok-2",
|
|
658
|
-
"grok-2-mini",
|
|
659
|
-
"gemini-pro",
|
|
660
|
-
"gemini-ultra",
|
|
661
|
-
"llama-3-70b",
|
|
662
|
-
"llama-3-405b",
|
|
663
|
-
"mistral-large",
|
|
664
|
-
"mixtral",
|
|
665
|
-
"deepseek-v3",
|
|
666
|
-
"deepseek-r1",
|
|
667
|
-
"kimi-k2",
|
|
668
|
-
"kimi-k2.5",
|
|
669
|
-
"other"
|
|
670
|
-
];
|
|
671
|
-
modelSchema = z4.enum(SUPPORTED_MODELS);
|
|
672
647
|
solanaTradeRequestSchema = z4.object({
|
|
673
648
|
chain: z4.literal("solana"),
|
|
674
649
|
inputToken: z4.string().min(1),
|
|
@@ -676,7 +651,7 @@ var init_trade = __esm(() => {
|
|
|
676
651
|
amount: z4.number().positive(),
|
|
677
652
|
slippageBps: z4.number().int().min(1).max(500).optional(),
|
|
678
653
|
dryRun: z4.boolean().optional(),
|
|
679
|
-
model:
|
|
654
|
+
model: z4.string().optional()
|
|
680
655
|
});
|
|
681
656
|
hyperliquidTradeRequestSchema = z4.object({
|
|
682
657
|
chain: z4.literal("hyperliquid"),
|
|
@@ -686,7 +661,7 @@ var init_trade = __esm(() => {
|
|
|
686
661
|
price: z4.number().positive().optional(),
|
|
687
662
|
orderType: z4.enum(["limit", "market"]).optional(),
|
|
688
663
|
leverage: z4.number().positive().optional(),
|
|
689
|
-
model:
|
|
664
|
+
model: z4.string().optional()
|
|
690
665
|
});
|
|
691
666
|
tradeRequestSchema = z4.discriminatedUnion("chain", [
|
|
692
667
|
solanaTradeRequestSchema,
|
|
@@ -3662,6 +3637,232 @@ var init_env = __esm(() => {
|
|
|
3662
3637
|
];
|
|
3663
3638
|
});
|
|
3664
3639
|
|
|
3640
|
+
// ../../packages/solana/src/errors.ts
|
|
3641
|
+
function def(code, name, message, program, retryable = false, suggestion) {
|
|
3642
|
+
return { code, hex: `0x${code.toString(16)}`, name, message, retryable, suggestion, program };
|
|
3643
|
+
}
|
|
3644
|
+
function parseSolanaError(message) {
|
|
3645
|
+
if (!message)
|
|
3646
|
+
return null;
|
|
3647
|
+
const customMatch = CUSTOM_ERROR_RE.exec(message);
|
|
3648
|
+
if (customMatch) {
|
|
3649
|
+
const code = parseInt(customMatch[1], 16);
|
|
3650
|
+
const hex = `0x${customMatch[1].toLowerCase()}`;
|
|
3651
|
+
const instructionMatch = INSTRUCTION_INDEX_RE.exec(message);
|
|
3652
|
+
const instructionIndex = instructionMatch ? parseInt(instructionMatch[1], 10) : undefined;
|
|
3653
|
+
return {
|
|
3654
|
+
type: "custom",
|
|
3655
|
+
code,
|
|
3656
|
+
hex,
|
|
3657
|
+
instructionIndex,
|
|
3658
|
+
def: PROGRAM_ERRORS.get(code),
|
|
3659
|
+
raw: message
|
|
3660
|
+
};
|
|
3661
|
+
}
|
|
3662
|
+
const anchorMatch = ANCHOR_ERROR_RE.exec(message);
|
|
3663
|
+
if (anchorMatch) {
|
|
3664
|
+
const code = parseInt(anchorMatch[1], 10);
|
|
3665
|
+
return {
|
|
3666
|
+
type: "custom",
|
|
3667
|
+
code,
|
|
3668
|
+
hex: `0x${code.toString(16)}`,
|
|
3669
|
+
def: PROGRAM_ERRORS.get(code),
|
|
3670
|
+
raw: message
|
|
3671
|
+
};
|
|
3672
|
+
}
|
|
3673
|
+
for (const [variant, errorDef] of INSTRUCTION_ERRORS) {
|
|
3674
|
+
if (message.includes(variant)) {
|
|
3675
|
+
return {
|
|
3676
|
+
type: "instruction",
|
|
3677
|
+
def: errorDef,
|
|
3678
|
+
raw: message
|
|
3679
|
+
};
|
|
3680
|
+
}
|
|
3681
|
+
}
|
|
3682
|
+
return null;
|
|
3683
|
+
}
|
|
3684
|
+
function classifyTradeError(errorMessage) {
|
|
3685
|
+
const parsed = parseSolanaError(errorMessage);
|
|
3686
|
+
if (parsed?.def) {
|
|
3687
|
+
const d = parsed.def;
|
|
3688
|
+
if (d.name === "SlippageToleranceExceeded") {
|
|
3689
|
+
return {
|
|
3690
|
+
errorCode: "BAD_REQUEST",
|
|
3691
|
+
httpStatus: 400,
|
|
3692
|
+
message: d.message,
|
|
3693
|
+
retryable: true,
|
|
3694
|
+
suggestion: d.suggestion,
|
|
3695
|
+
solanaError: d.name
|
|
3696
|
+
};
|
|
3697
|
+
}
|
|
3698
|
+
if (d.name === "InsufficientFunds") {
|
|
3699
|
+
return {
|
|
3700
|
+
errorCode: "BAD_REQUEST",
|
|
3701
|
+
httpStatus: 400,
|
|
3702
|
+
message: d.message,
|
|
3703
|
+
retryable: false,
|
|
3704
|
+
suggestion: d.suggestion,
|
|
3705
|
+
solanaError: d.name
|
|
3706
|
+
};
|
|
3707
|
+
}
|
|
3708
|
+
if (d.name === "ComputationalBudgetExceeded" || d.name === "ProgramFailedToComplete") {
|
|
3709
|
+
return {
|
|
3710
|
+
errorCode: "DEPENDENCY_ERROR",
|
|
3711
|
+
httpStatus: 502,
|
|
3712
|
+
message: d.message,
|
|
3713
|
+
retryable: true,
|
|
3714
|
+
suggestion: d.suggestion,
|
|
3715
|
+
solanaError: d.name
|
|
3716
|
+
};
|
|
3717
|
+
}
|
|
3718
|
+
return {
|
|
3719
|
+
errorCode: d.retryable ? "DEPENDENCY_ERROR" : "BAD_REQUEST",
|
|
3720
|
+
httpStatus: d.retryable ? 502 : 400,
|
|
3721
|
+
message: d.message,
|
|
3722
|
+
retryable: d.retryable,
|
|
3723
|
+
suggestion: d.suggestion,
|
|
3724
|
+
solanaError: d.name
|
|
3725
|
+
};
|
|
3726
|
+
}
|
|
3727
|
+
if (parsed?.type === "custom" && parsed.code !== undefined) {
|
|
3728
|
+
return {
|
|
3729
|
+
errorCode: "INTERNAL_ERROR",
|
|
3730
|
+
httpStatus: 500,
|
|
3731
|
+
message: `Transaction failed with program error ${parsed.hex}`,
|
|
3732
|
+
retryable: false,
|
|
3733
|
+
solanaError: `UnknownError_${parsed.hex}`
|
|
3734
|
+
};
|
|
3735
|
+
}
|
|
3736
|
+
for (const pattern of KEYWORD_PATTERNS) {
|
|
3737
|
+
if (pattern.test(errorMessage)) {
|
|
3738
|
+
return pattern.classify(errorMessage);
|
|
3739
|
+
}
|
|
3740
|
+
}
|
|
3741
|
+
return {
|
|
3742
|
+
errorCode: "INTERNAL_ERROR",
|
|
3743
|
+
httpStatus: 500,
|
|
3744
|
+
message: `Trade failed: ${errorMessage}`,
|
|
3745
|
+
retryable: false
|
|
3746
|
+
};
|
|
3747
|
+
}
|
|
3748
|
+
var PROGRAM_ERRORS, INSTRUCTION_ERRORS, CUSTOM_ERROR_RE, INSTRUCTION_INDEX_RE, ANCHOR_ERROR_RE, KEYWORD_PATTERNS;
|
|
3749
|
+
var init_errors2 = __esm(() => {
|
|
3750
|
+
PROGRAM_ERRORS = new Map([
|
|
3751
|
+
[0, def(0, "NotRentExempt", "Account is not rent exempt", "token")],
|
|
3752
|
+
[1, def(1, "InsufficientFunds", "Insufficient token balance", "token", false, "Check your token balance before trading")],
|
|
3753
|
+
[2, def(2, "InvalidMint", "Invalid mint address", "token")],
|
|
3754
|
+
[3, def(3, "MintMismatch", "Account mint does not match expected mint", "token")],
|
|
3755
|
+
[4, def(4, "OwnerMismatch", "Account owner does not match expected owner", "token")],
|
|
3756
|
+
[5, def(5, "FixedSupply", "Token supply is fixed — cannot mint more", "token")],
|
|
3757
|
+
[6, def(6, "AlreadyInUse", "Account is already initialized", "token")],
|
|
3758
|
+
[7, def(7, "InvalidNumberOfProvidedSigners", "Invalid number of signers", "token")],
|
|
3759
|
+
[8, def(8, "InvalidNumberOfRequiredSigners", "Invalid number of required signers", "token")],
|
|
3760
|
+
[9, def(9, "UninitializedState", "Token account is not initialized", "token")],
|
|
3761
|
+
[10, def(10, "NativeNotSupported", "Operation not supported for native SOL", "token")],
|
|
3762
|
+
[11, def(11, "NonNativeHasBalance", "Non-native account has balance — close with non-zero balance", "token")],
|
|
3763
|
+
[12, def(12, "InvalidInstruction", "Invalid token instruction", "token")],
|
|
3764
|
+
[13, def(13, "InvalidState", "Invalid token account state", "token")],
|
|
3765
|
+
[14, def(14, "Overflow", "Arithmetic overflow in token operation", "token")],
|
|
3766
|
+
[15, def(15, "AuthorityTypeNotSupported", "Authority type not supported", "token")],
|
|
3767
|
+
[16, def(16, "MintCannotFreeze", "This mint cannot freeze accounts", "token")],
|
|
3768
|
+
[17, def(17, "AccountFrozen", "Account is frozen — cannot transfer", "token")],
|
|
3769
|
+
[6000, def(6000, "EmptyRoute", "No swap route found", "jupiter", false, "Token pair may not have liquidity. Try a different pair.")],
|
|
3770
|
+
[6001, def(6001, "SlippageToleranceExceeded", "Slippage tolerance exceeded — price moved during execution", "jupiter", true, "Retry or increase slippage tolerance")],
|
|
3771
|
+
[6002, def(6002, "InvalidCalculation", "Swap calculation error", "jupiter")],
|
|
3772
|
+
[6003, def(6003, "MissingPlatformFeeAccount", "Platform fee account not provided", "jupiter", false, "Server configuration issue — contact support")],
|
|
3773
|
+
[6004, def(6004, "InvalidSlippage", "Invalid slippage value", "jupiter")],
|
|
3774
|
+
[6005, def(6005, "NotEnoughPercent", "Split percent does not sum to 100", "jupiter")],
|
|
3775
|
+
[6006, def(6006, "InvalidInputIndex", "Invalid route input index", "jupiter")],
|
|
3776
|
+
[6007, def(6007, "InvalidOutputIndex", "Invalid route output index", "jupiter")],
|
|
3777
|
+
[6008, def(6008, "NotEnoughAccountKeys", "Not enough account keys for instruction", "jupiter")],
|
|
3778
|
+
[6009, def(6009, "NonZeroMinimumOutAmountNotSupported", "Non-zero minimum out amount not supported for this route", "jupiter")],
|
|
3779
|
+
[6010, def(6010, "InvalidRoutePlan", "Invalid route plan", "jupiter")],
|
|
3780
|
+
[6011, def(6011, "InvalidReferralAuthority", "Invalid referral authority", "jupiter")],
|
|
3781
|
+
[6012, def(6012, "LedgerTokenAccountDoesNotMatch", "Token ledger account mismatch", "jupiter")],
|
|
3782
|
+
[6013, def(6013, "InvalidTokenLedger", "Invalid token ledger state", "jupiter")],
|
|
3783
|
+
[6014, def(6014, "IncorrectTokenProgramID", "Incorrect token program ID", "jupiter")],
|
|
3784
|
+
[6015, def(6015, "TokenProgramNotProvided", "Token program not provided", "jupiter")],
|
|
3785
|
+
[6016, def(6016, "SwapNotSupported", "This swap is not supported", "jupiter")],
|
|
3786
|
+
[6017, def(6017, "ExactOutAmountNotMatched", "Exact output amount not met", "jupiter")],
|
|
3787
|
+
[6025, def(6025, "InvalidTokenAccount", "Invalid token account for platform fee", "jupiter", false, "Platform fee account may not be initialized — contact support")]
|
|
3788
|
+
]);
|
|
3789
|
+
INSTRUCTION_ERRORS = new Map([
|
|
3790
|
+
["InsufficientFunds", def(0, "InsufficientFunds", "Insufficient SOL for transaction fees", "system", false, "Fund your wallet with SOL for gas")],
|
|
3791
|
+
["InvalidAccountData", def(0, "InvalidAccountData", "Account data is invalid or corrupt", "system")],
|
|
3792
|
+
["AccountAlreadyInUse", def(0, "AccountAlreadyInUse", "Account is already in use", "system")],
|
|
3793
|
+
["AccountNotFound", def(0, "AccountNotFound", "Account not found on chain", "system")],
|
|
3794
|
+
["InvalidArgument", def(0, "InvalidArgument", "Invalid instruction argument", "system")],
|
|
3795
|
+
["InvalidInstructionData", def(0, "InvalidInstructionData", "Invalid instruction data", "system")],
|
|
3796
|
+
["InvalidAccountOwner", def(0, "InvalidAccountOwner", "Account is not owned by the expected program", "system")],
|
|
3797
|
+
["ComputationalBudgetExceeded", def(0, "ComputationalBudgetExceeded", "Transaction exceeded compute budget", "compute-budget", true, "Retry — the transaction was too complex for the allocated compute units")],
|
|
3798
|
+
["ProgramFailedToComplete", def(0, "ProgramFailedToComplete", "Program failed to complete", "system", true, "Retry — may be a transient issue")]
|
|
3799
|
+
]);
|
|
3800
|
+
CUSTOM_ERROR_RE = /custom program error: 0x([0-9a-fA-F]+)/i;
|
|
3801
|
+
INSTRUCTION_INDEX_RE = /Error processing Instruction (\d+):/i;
|
|
3802
|
+
ANCHOR_ERROR_RE = /Error Number: (\d+)/i;
|
|
3803
|
+
KEYWORD_PATTERNS = [
|
|
3804
|
+
{
|
|
3805
|
+
test: (msg) => /insufficient\s*(funds|balance|lamports)/i.test(msg) || msg.toLowerCase().includes("insufficient balance"),
|
|
3806
|
+
classify: () => ({
|
|
3807
|
+
errorCode: "BAD_REQUEST",
|
|
3808
|
+
httpStatus: 400,
|
|
3809
|
+
message: "Insufficient balance to complete this trade",
|
|
3810
|
+
retryable: false,
|
|
3811
|
+
suggestion: "Check your wallet balance before trading",
|
|
3812
|
+
solanaError: "InsufficientFunds"
|
|
3813
|
+
})
|
|
3814
|
+
},
|
|
3815
|
+
{
|
|
3816
|
+
test: (msg) => msg.toLowerCase().includes("slippage"),
|
|
3817
|
+
classify: () => ({
|
|
3818
|
+
errorCode: "BAD_REQUEST",
|
|
3819
|
+
httpStatus: 400,
|
|
3820
|
+
message: "Slippage tolerance exceeded — price moved during execution",
|
|
3821
|
+
retryable: true,
|
|
3822
|
+
suggestion: "Retry or increase slippage tolerance",
|
|
3823
|
+
solanaError: "SlippageToleranceExceeded"
|
|
3824
|
+
})
|
|
3825
|
+
},
|
|
3826
|
+
{
|
|
3827
|
+
test: (msg) => {
|
|
3828
|
+
const lower = msg.toLowerCase();
|
|
3829
|
+
return lower.includes("expired") || lower.includes("blockhash not found") || lower.includes("block height exceeded");
|
|
3830
|
+
},
|
|
3831
|
+
classify: () => ({
|
|
3832
|
+
errorCode: "DEPENDENCY_ERROR",
|
|
3833
|
+
httpStatus: 502,
|
|
3834
|
+
message: "Transaction expired before confirmation",
|
|
3835
|
+
retryable: true,
|
|
3836
|
+
suggestion: "This is transient — retry with a fresh quote",
|
|
3837
|
+
solanaError: "TransactionExpired"
|
|
3838
|
+
})
|
|
3839
|
+
},
|
|
3840
|
+
{
|
|
3841
|
+
test: (msg) => msg.toLowerCase().includes("rate limit"),
|
|
3842
|
+
classify: (msg) => ({
|
|
3843
|
+
errorCode: "RATE_LIMITED",
|
|
3844
|
+
httpStatus: 429,
|
|
3845
|
+
message: msg,
|
|
3846
|
+
retryable: false,
|
|
3847
|
+
suggestion: "Wait a moment before retrying"
|
|
3848
|
+
})
|
|
3849
|
+
},
|
|
3850
|
+
{
|
|
3851
|
+
test: (msg) => {
|
|
3852
|
+
const lower = msg.toLowerCase();
|
|
3853
|
+
return lower.includes("unknown token") || lower.includes("token not found");
|
|
3854
|
+
},
|
|
3855
|
+
classify: (msg) => ({
|
|
3856
|
+
errorCode: "BAD_REQUEST",
|
|
3857
|
+
httpStatus: 400,
|
|
3858
|
+
message: msg,
|
|
3859
|
+
retryable: false,
|
|
3860
|
+
suggestion: "Use a known symbol (SOL, USDC, BONK, WIF) or pass a raw mint address"
|
|
3861
|
+
})
|
|
3862
|
+
}
|
|
3863
|
+
];
|
|
3864
|
+
});
|
|
3865
|
+
|
|
3665
3866
|
// src/lib/errors.ts
|
|
3666
3867
|
import chalk from "chalk";
|
|
3667
3868
|
function normalizeCliError(error) {
|
|
@@ -3690,43 +3891,12 @@ function printCliError(error) {
|
|
|
3690
3891
|
}
|
|
3691
3892
|
function mapTradeError(error) {
|
|
3692
3893
|
const normalized = normalizeCliError(error);
|
|
3693
|
-
const
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
};
|
|
3700
|
-
}
|
|
3701
|
-
if (msg.includes("expired") || msg.includes("blockhash")) {
|
|
3702
|
-
return {
|
|
3703
|
-
message: "Transaction expired — took too long to confirm",
|
|
3704
|
-
suggestion: "This is transient. Try again.",
|
|
3705
|
-
retryable: true
|
|
3706
|
-
};
|
|
3707
|
-
}
|
|
3708
|
-
if (msg.includes("insufficient balance") || msg.includes("insufficient funds") || msg.includes("0x1")) {
|
|
3709
|
-
return {
|
|
3710
|
-
message: "Insufficient balance",
|
|
3711
|
-
suggestion: "Check your balance with: cabal-cli status",
|
|
3712
|
-
retryable: false
|
|
3713
|
-
};
|
|
3714
|
-
}
|
|
3715
|
-
if (msg.includes("rate limit")) {
|
|
3716
|
-
return {
|
|
3717
|
-
message: normalized.message,
|
|
3718
|
-
suggestion: "Wait a moment before retrying.",
|
|
3719
|
-
retryable: false
|
|
3720
|
-
};
|
|
3721
|
-
}
|
|
3722
|
-
if (msg.includes("unknown token") || msg.includes("token not found")) {
|
|
3723
|
-
return {
|
|
3724
|
-
message: normalized.message,
|
|
3725
|
-
suggestion: "Use a known symbol (SOL, USDC, BONK, WIF) or pass a raw mint address.",
|
|
3726
|
-
retryable: false
|
|
3727
|
-
};
|
|
3728
|
-
}
|
|
3729
|
-
return { message: normalized.message, retryable: false };
|
|
3894
|
+
const classified = classifyTradeError(normalized.message);
|
|
3895
|
+
return {
|
|
3896
|
+
message: classified.message,
|
|
3897
|
+
suggestion: classified.suggestion,
|
|
3898
|
+
retryable: classified.retryable
|
|
3899
|
+
};
|
|
3730
3900
|
}
|
|
3731
3901
|
function printTradeError(error) {
|
|
3732
3902
|
const mapped = mapTradeError(error);
|
|
@@ -3748,8 +3918,9 @@ function toStructuredError(error) {
|
|
|
3748
3918
|
}
|
|
3749
3919
|
};
|
|
3750
3920
|
}
|
|
3751
|
-
var
|
|
3921
|
+
var init_errors3 = __esm(() => {
|
|
3752
3922
|
init_src();
|
|
3923
|
+
init_errors2();
|
|
3753
3924
|
});
|
|
3754
3925
|
|
|
3755
3926
|
// src/mcp/server.ts
|
|
@@ -3799,7 +3970,7 @@ async function createServer() {
|
|
|
3799
3970
|
size: z22.number().optional().describe("Hyperliquid: position size"),
|
|
3800
3971
|
orderType: z22.enum(["market", "limit"]).optional().describe("Hyperliquid: order type (default: market)"),
|
|
3801
3972
|
price: z22.number().optional().describe("Hyperliquid: limit price (required for limit orders)"),
|
|
3802
|
-
model:
|
|
3973
|
+
model: z22.string().optional().describe("AI model name for attribution")
|
|
3803
3974
|
};
|
|
3804
3975
|
server.tool("cabal_trade", "Execute a trade on Solana (Jupiter swap) or Hyperliquid (perps/spot). Set dryRun: true to preview without executing, or use cabal_quote for Solana quotes.", tradeSchema, async (params) => {
|
|
3805
3976
|
if (params.chain === "solana") {
|
|
@@ -4017,7 +4188,7 @@ Describe: (1) what triggers it, (2) how it unfolds, (3) what it looks like after
|
|
|
4017
4188
|
var init_server = __esm(() => {
|
|
4018
4189
|
init_src();
|
|
4019
4190
|
init_env();
|
|
4020
|
-
|
|
4191
|
+
init_errors3();
|
|
4021
4192
|
});
|
|
4022
4193
|
|
|
4023
4194
|
// src/mcp-server.ts
|