@ghostspeak/sdk
Version:
TypeScript SDK for GhostSpeak AI Agent Commerce Protocol - Production Ready Beta
262 lines (259 loc) • 8.58 kB
JavaScript
// src/core/errors.ts
var GhostSpeakError = class extends Error {
code;
context;
solution;
instruction;
constructor(code, message, context = {}, solution, instruction) {
super(message);
this.name = "GhostSpeakError";
this.code = code;
this.context = context;
this.solution = solution;
this.instruction = instruction;
}
/**
* Format error for display
*/
toString() {
let output = `${this.name} [${this.code}]: ${this.message}`;
if (Object.keys(this.context).length > 0) {
output += `
Context: ${JSON.stringify(this.context, null, 2)}`;
}
if (this.solution) {
output += `
\u{1F4A1} Solution: ${this.solution}`;
}
if (this.instruction) {
output += `
\u{1F4D6} Learn more: ${this.instruction}`;
}
return output;
}
/**
* Convert to SDK error type
*/
toSDKError() {
return {
code: this.code,
message: this.message,
context: this.context,
solution: this.solution,
instruction: this.instruction
};
}
};
var NetworkError = class extends GhostSpeakError {
constructor(endpoint, originalError) {
super(
"NETWORK_ERROR" /* NETWORK_ERROR */,
`Failed to connect to RPC endpoint: ${endpoint}`,
{ endpoint, originalError: originalError?.message },
"Check your internet connection and verify the RPC endpoint is correct. Try using a different RPC provider."
);
}
};
var InsufficientBalanceError = class extends GhostSpeakError {
constructor(required, available, address) {
const requiredSOL = Number(required) / 1e9;
const availableSOL = Number(available) / 1e9;
const neededSOL = requiredSOL - availableSOL;
super(
"INSUFFICIENT_BALANCE" /* INSUFFICIENT_BALANCE */,
`Insufficient balance: need ${requiredSOL} SOL but only have ${availableSOL} SOL`,
{
required: required.toString(),
available: available.toString(),
address,
requiredSOL,
availableSOL,
neededSOL
},
`You need ${neededSOL.toFixed(4)} more SOL. Try:
1. Request devnet SOL: solana airdrop ${Math.ceil(neededSOL)} ${address}
2. Or use: await ghostspeak.fund("${address}", ${Math.ceil(neededSOL)})`
);
}
};
var AccountNotFoundError = class extends GhostSpeakError {
constructor(address, accountType) {
super(
"ACCOUNT_NOT_FOUND" /* ACCOUNT_NOT_FOUND */,
`${accountType} account not found at address: ${address}`,
{ address, accountType },
`The ${accountType} account doesn't exist. Possible solutions:
1. Verify the address is correct
2. Ensure the account has been created
3. Check you're on the correct network (mainnet/devnet/testnet)`
);
}
};
var InvalidInputError = class extends GhostSpeakError {
constructor(field, value, requirement) {
super(
"INVALID_INPUT" /* INVALID_INPUT */,
`Invalid ${field}: ${JSON.stringify(value)}`,
{ field, value, requirement },
`The ${field} must ${requirement}`
);
}
};
var TransactionFailedError = class _TransactionFailedError extends GhostSpeakError {
constructor(signature, logs, programError) {
const errorLog = logs.find((log) => log.includes("Error") || log.includes("failed"));
super(
"TRANSACTION_FAILED" /* TRANSACTION_FAILED */,
`Transaction failed: ${programError ?? errorLog ?? "Unknown error"}`,
{ signature, logs, programError },
_TransactionFailedError.getSolution(logs, programError),
`https://explorer.solana.com/tx/${signature}?cluster=devnet`
);
}
static getSolution(logs, programError) {
if (logs.some((log) => log.includes("insufficient funds"))) {
return "Your account has insufficient SOL. Request an airdrop or add funds.";
}
if (logs.some((log) => log.includes("account is frozen"))) {
return "The token account is frozen. Contact the token authority to unfreeze.";
}
if (logs.some((log) => log.includes("owner does not match"))) {
return "You are not the owner of this account. Use the correct signer.";
}
if (logs.some((log) => log.includes("already in use"))) {
return "This account is already in use. Try a different account or wait.";
}
if (programError?.includes("custom program error")) {
const errorCode = programError.match(/0x([0-9a-f]+)/i)?.[1];
if (errorCode) {
return `Program error code: 0x${errorCode}. Check the program's error documentation.`;
}
}
return "Check the transaction logs for more details. Common issues:\n1. Insufficient balance\n2. Invalid account state\n3. Missing signatures\n4. Program-specific requirements not met";
}
};
var SimulationFailedError = class extends GhostSpeakError {
constructor(logs, unitsConsumed) {
super(
"SIMULATION_FAILED" /* SIMULATION_FAILED */,
"Transaction simulation failed",
{ logs, unitsConsumed: unitsConsumed?.toString() },
"The transaction would fail if submitted. Review the simulation logs to identify the issue."
);
}
};
var TimeoutError = class extends GhostSpeakError {
constructor(operation, timeoutMs) {
super(
"TIMEOUT" /* TIMEOUT */,
`Operation timed out after ${timeoutMs}ms: ${operation}`,
{ operation, timeoutMs },
"The operation took too long. Try:\n1. Increasing the timeout\n2. Using a faster RPC endpoint\n3. Retrying during lower network congestion"
);
}
};
var ErrorFactory = class {
/**
* Create error from program logs
*/
static fromProgramLogs(logs, signature) {
const errorLog = logs.find(
(log) => log.includes("Error") || log.includes("failed") || log.includes("custom program error")
);
if (errorLog?.includes("insufficient funds")) {
return new InsufficientBalanceError(0n, 0n, "unknown");
}
if (signature) {
return new TransactionFailedError(signature, logs, errorLog);
}
return new SimulationFailedError(logs);
}
/**
* Create error from RPC error
*/
static fromRpcError(error, endpoint) {
if (error instanceof Error) {
if (error.message.includes("fetch")) {
return new NetworkError(endpoint, error);
}
if (error.message.includes("429")) {
return new GhostSpeakError(
"RPC_ERROR" /* RPC_ERROR */,
"Rate limit exceeded",
{ endpoint, error: error.message },
"You are making too many requests. Try:\n1. Adding delays between requests\n2. Using a paid RPC endpoint\n3. Implementing request batching"
);
}
}
return new GhostSpeakError(
"RPC_ERROR" /* RPC_ERROR */,
"RPC request failed",
{ endpoint, error: String(error) },
"Check your RPC endpoint and network connection"
);
}
};
var ErrorHandler = class {
static handlers = /* @__PURE__ */ new Map();
/**
* Register error handler
*/
static on(code, handler) {
this.handlers.set(code, handler);
}
/**
* Handle error
*/
static handle(error) {
let ghostSpeakError;
if (error instanceof GhostSpeakError) {
ghostSpeakError = error;
} else if (error instanceof Error) {
ghostSpeakError = new GhostSpeakError(
"UNKNOWN_ERROR" /* UNKNOWN_ERROR */,
error.message,
{ originalError: error.name }
);
} else {
ghostSpeakError = new GhostSpeakError(
"UNKNOWN_ERROR" /* UNKNOWN_ERROR */,
String(error)
);
}
const handler = this.handlers.get(ghostSpeakError.code);
if (handler) {
handler(ghostSpeakError);
}
if (process.env.NODE_ENV === "development") {
console.error(ghostSpeakError.toString());
}
return ghostSpeakError.toSDKError();
}
};
var ValidationError = class extends GhostSpeakError {
constructor(message, context = {}) {
super(
"INVALID_INPUT" /* INVALID_INPUT */,
message,
context,
"Check input parameters and ensure they meet the required format and constraints"
);
this.name = "ValidationError";
}
};
var errors_default = {
GhostSpeakError,
NetworkError,
InsufficientBalanceError,
AccountNotFoundError,
InvalidInputError,
TransactionFailedError,
SimulationFailedError,
TimeoutError,
ValidationError,
ErrorFactory,
ErrorHandler
};
export { AccountNotFoundError, ErrorFactory, ErrorHandler, GhostSpeakError, InsufficientBalanceError, InvalidInputError, NetworkError, SimulationFailedError, TimeoutError, TransactionFailedError, ValidationError, errors_default };
//# sourceMappingURL=chunk-5DMB3UAV.js.map
//# sourceMappingURL=chunk-5DMB3UAV.js.map