From 30b4680ad1d3afff45876650b553878bc9e973c7 Mon Sep 17 00:00:00 2001
From: Sayo <82053242+wtfsayo@users.noreply.github.com>
Date: Wed, 8 Jan 2025 21:38:49 +0530
Subject: [PATCH 1/3] remove defillama plugin

---
 packages/plugin-defillama/README.md           |  0
 packages/plugin-defillama/package.json        | 29 -------------------
 .../src/actions/get-price.action.ts           | 18 ------------
 packages/plugin-defillama/src/environment.ts  |  8 -----
 packages/plugin-defillama/src/index.ts        | 14 ---------
 .../src/providers/defillama.provider.ts       | 24 ---------------
 packages/plugin-defillama/tsconfig.json       | 10 -------
 packages/plugin-defillama/tsup.config.ts      | 17 -----------
 8 files changed, 120 deletions(-)
 delete mode 100644 packages/plugin-defillama/README.md
 delete mode 100644 packages/plugin-defillama/package.json
 delete mode 100644 packages/plugin-defillama/src/actions/get-price.action.ts
 delete mode 100644 packages/plugin-defillama/src/environment.ts
 delete mode 100644 packages/plugin-defillama/src/index.ts
 delete mode 100644 packages/plugin-defillama/src/providers/defillama.provider.ts
 delete mode 100644 packages/plugin-defillama/tsconfig.json
 delete mode 100644 packages/plugin-defillama/tsup.config.ts

diff --git a/packages/plugin-defillama/README.md b/packages/plugin-defillama/README.md
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/packages/plugin-defillama/package.json b/packages/plugin-defillama/package.json
deleted file mode 100644
index 8413f4b7e15..00000000000
--- a/packages/plugin-defillama/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-    "name": "@elizaos/plugin-defillama",
-    "version": "0.1.0",
-    "type": "module",
-    "main": "dist/index.js",
-    "module": "dist/index.js",
-    "types": "dist/index.d.ts",
-    "exports": {
-        "./package.json": "./package.json",
-        ".": {
-            "import": {
-                "@elizaos/source": "./src/index.ts",
-                "types": "./dist/index.d.ts",
-                "default": "./dist/index.js"
-            }
-        }
-    },
-    "files": [
-        "dist"
-    ],
-    "dependencies": {
-        "@elizaos/core": "workspace:*",
-        "axios": "^1.6.0",
-        "tsup": "^8.3.5"
-    },
-    "scripts": {
-        "build": "tsup --format esm --dts"
-    }
-}
\ No newline at end of file
diff --git a/packages/plugin-defillama/src/actions/get-price.action.ts b/packages/plugin-defillama/src/actions/get-price.action.ts
deleted file mode 100644
index 35fb1b2bc91..00000000000
--- a/packages/plugin-defillama/src/actions/get-price.action.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { createAction } from "@elizaos/core";
-import { z } from "zod";
-import { DefiLlamaProvider } from "../providers/defillama.provider";
-
-export const GetPriceSchema = z.object({
-    tokenId: z.string(),
-});
-
-export const getPriceAction = createAction({
-    name: "get-price",
-    description: "Get current price for a token from DefiLlama",
-    schema: GetPriceSchema,
-    handler: async ({ tokenId }, { provider }) => {
-        const defiLlama = provider as DefiLlamaProvider;
-        const price = await defiLlama.getCurrentPrice(tokenId);
-        return { price };
-    },
-});
\ No newline at end of file
diff --git a/packages/plugin-defillama/src/environment.ts b/packages/plugin-defillama/src/environment.ts
deleted file mode 100644
index 0d7f41870cb..00000000000
--- a/packages/plugin-defillama/src/environment.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import { z } from "zod";
-
-export const DefiLlamaEnvironmentSchema = z.object({
-    DEFILLAMA_API_URL: z.string().default("https://coins.llama.fi"),
-    DEFILLAMA_TIMEOUT: z.coerce.number().default(10000),
-});
-
-export type DefiLlamaEnvironment = z.infer<typeof DefiLlamaEnvironmentSchema>;
diff --git a/packages/plugin-defillama/src/index.ts b/packages/plugin-defillama/src/index.ts
deleted file mode 100644
index 60e2d2a526f..00000000000
--- a/packages/plugin-defillama/src/index.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import { createPlugin } from "@elizaos/core";
-import { getPriceAction } from "./actions/get-price.action";
-import { DefiLlamaEnvironmentSchema } from "./environment";
-import { DefiLlamaProvider } from "./providers/defillama.provider";
-
-export const DefiLlamaPlugin = createPlugin({
-    name: "defillama",
-    version: "0.1.0",
-    environment: DefiLlamaEnvironmentSchema,
-    provider: ({ environment }) => new DefiLlamaProvider(environment),
-    actions: [getPriceAction],
-});
-
-export * from "./environment";
diff --git a/packages/plugin-defillama/src/providers/defillama.provider.ts b/packages/plugin-defillama/src/providers/defillama.provider.ts
deleted file mode 100644
index a5a62c1b8d3..00000000000
--- a/packages/plugin-defillama/src/providers/defillama.provider.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import axios, { AxiosInstance } from "axios";
-import { DefiLlamaEnvironment } from "../environment";
-
-export class DefiLlamaProvider {
-    private client: AxiosInstance;
-
-    constructor(environment: DefiLlamaEnvironment) {
-        this.client = axios.create({
-            baseURL: environment.DEFILLAMA_API_URL,
-            timeout: environment.DEFILLAMA_TIMEOUT,
-        });
-    }
-
-    async getCurrentPrice(tokenId: string): Promise<number> {
-        const { data } = await this.client.get(`/prices/current/${tokenId}`);
-        const priceData = data.coins[tokenId];
-
-        if (!priceData) {
-            throw new Error(`No price data found for token: ${tokenId}`);
-        }
-
-        return priceData.price;
-    }
-}
\ No newline at end of file
diff --git a/packages/plugin-defillama/tsconfig.json b/packages/plugin-defillama/tsconfig.json
deleted file mode 100644
index 73993deaaf7..00000000000
--- a/packages/plugin-defillama/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    "extends": "../core/tsconfig.json",
-    "compilerOptions": {
-        "outDir": "dist",
-        "rootDir": "src"
-    },
-    "include": [
-        "src/**/*.ts"
-    ]
-}
\ No newline at end of file
diff --git a/packages/plugin-defillama/tsup.config.ts b/packages/plugin-defillama/tsup.config.ts
deleted file mode 100644
index 98c2d8e4c70..00000000000
--- a/packages/plugin-defillama/tsup.config.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-import { defineConfig } from "tsup";
-
-export default defineConfig({
-    entry: ["src/index.ts"],
-    outDir: "dist",
-    sourcemap: true,
-    clean: true,
-    format: ["esm"],
-    external: [
-        "dotenv",
-        "fs",
-        "path",
-        "https",
-        "http",
-        "agentkeepalive",
-    ],
-});

From f8ef4d7a7e7915f1290a8ca197f687472416505e Mon Sep 17 00:00:00 2001
From: Sayo <82053242+wtfsayo@users.noreply.github.com>
Date: Wed, 8 Jan 2025 21:48:14 +0530
Subject: [PATCH 2/3] final: fix rabbi trader

---
 packages/client-twitter/src/base.ts           |    2 +-
 packages/plugin-coinmarketcap/README.md       |    2 +-
 packages/plugin-coinprice/README.md           |    2 +-
 packages/plugin-letzai/README.md              |    2 +-
 packages/plugin-node/README.md                |    2 +-
 .../src/example/NAVALS-VAULT.md               |    2 +-
 .../src/actions/analyzeTrade.ts               |  142 +-
 packages/plugin-rabbi-trader/src/index.ts     | 1996 +++++++++--------
 .../src/services/simulationService.ts         |   15 +-
 .../plugin-rabbi-trader/src/tokenUtils.ts     |   28 +-
 packages/plugin-rabbi-trader/src/utils.ts     |  278 +--
 packages/plugin-rabbi-trader/src/wallet.ts    |  479 ++--
 packages/plugin-solana/src/index.ts           |    3 +-
 pnpm-lock.yaml                                |  231 +-
 14 files changed, 1669 insertions(+), 1515 deletions(-)

diff --git a/packages/client-twitter/src/base.ts b/packages/client-twitter/src/base.ts
index 5ad8b67039f..f49516dc8c4 100644
--- a/packages/client-twitter/src/base.ts
+++ b/packages/client-twitter/src/base.ts
@@ -361,7 +361,7 @@ export class ClientBase extends EventEmitter {
             .slice(0, count);
         // TODO: Once the 'count' parameter is fixed in the 'fetchTimeline' method of the 'agent-twitter-client',
         // this workaround can be removed.
-        // Related issue: https://github.com/elizaOS/agent-twitter-client/issues/43
+        // Related issue: https://github.com/elizaos/agent-twitter-client/issues/43
     }
 
     async fetchSearchTweets(
diff --git a/packages/plugin-coinmarketcap/README.md b/packages/plugin-coinmarketcap/README.md
index 08e62948826..9c042d9e576 100644
--- a/packages/plugin-coinmarketcap/README.md
+++ b/packages/plugin-coinmarketcap/README.md
@@ -124,4 +124,4 @@ For support, please open an issue in the repository or reach out to the maintain
 
 - [CoinMarketCap API Documentation](https://coinmarketcap.com/api/documentation/v1/)
 
-- [GitHub Repository](https://github.com/elizaOS/eliza/tree/main/packages/plugin-coinmarketcap)
+- [GitHub Repository](https://github.com/elizaos/eliza/tree/main/packages/plugin-coinmarketcap)
diff --git a/packages/plugin-coinprice/README.md b/packages/plugin-coinprice/README.md
index 97644a2d6e5..63ab6aa0448 100644
--- a/packages/plugin-coinprice/README.md
+++ b/packages/plugin-coinprice/README.md
@@ -131,4 +131,4 @@ For support, please open an issue in the repository or reach out to the maintain
 - [CoinGecko API Documentation](https://www.coingecko.com/en/api)
 - [CoinCap API Documentation](https://docs.coincap.io/)
 - [CoinMarketCap API Documentation](https://coinmarketcap.com/api/documentation/v1/)
-- [GitHub Repository](https://github.com/elizaOS/eliza/tree/main/packages/plugin-coinprice)
+- [GitHub Repository](https://github.com/elizaos/eliza/tree/main/packages/plugin-coinprice)
diff --git a/packages/plugin-letzai/README.md b/packages/plugin-letzai/README.md
index 7d21df07e3b..2e86b4228a5 100644
--- a/packages/plugin-letzai/README.md
+++ b/packages/plugin-letzai/README.md
@@ -2,7 +2,7 @@
 
 ![LetzAI Logo](https://letz.ai/_next/image?url=%2FL.png&w=64&q=100)
 
-A plugin to integrate LetzAI Image Generation capabilities into the elizaOS ecosystem.
+A plugin to integrate LetzAI Image Generation capabilities into the elizaos ecosystem.
 
 It uses the [LetzAI API](https://www.letz.ai/docs/api) and can use any models available to API user.
 
diff --git a/packages/plugin-node/README.md b/packages/plugin-node/README.md
index 99a5f098508..7b6bfb1bcba 100644
--- a/packages/plugin-node/README.md
+++ b/packages/plugin-node/README.md
@@ -65,7 +65,7 @@ import { createNodePlugin } from "@elizaos/plugin-node";
 const nodePlugin = createNodePlugin();
 
 // Register with Eliza OS
-elizaOS.registerPlugin(nodePlugin);
+elizaos.registerPlugin(nodePlugin);
 ```
 
 ## Services
diff --git a/packages/plugin-obsidian/src/example/NAVALS-VAULT.md b/packages/plugin-obsidian/src/example/NAVALS-VAULT.md
index 19731e46ea5..0c48934dcfd 100644
--- a/packages/plugin-obsidian/src/example/NAVALS-VAULT.md
+++ b/packages/plugin-obsidian/src/example/NAVALS-VAULT.md
@@ -31,7 +31,7 @@ https://drive.google.com/drive/folders/1EZiUhASpNQBYka3Z8NNkBzYnrb7TCfmG
 - Install the Obsidian Rest API plugin and activate it
 - Copy the API token from the plugin settings
 - Setup the agent with the API token and the Vault Rest API URL
-- Run the elizaOS agent
+- Run the elizaos agent
 - Prompt the agent to create the knowledge base (Take a couple minutes to complete): **"Create knowledge base"**
 
 Have fun talking to Naval's digital brain!
diff --git a/packages/plugin-rabbi-trader/src/actions/analyzeTrade.ts b/packages/plugin-rabbi-trader/src/actions/analyzeTrade.ts
index 574af302852..12fc6fd8365 100644
--- a/packages/plugin-rabbi-trader/src/actions/analyzeTrade.ts
+++ b/packages/plugin-rabbi-trader/src/actions/analyzeTrade.ts
@@ -1,47 +1,47 @@
 import {
-  Action,
-  composeContext,
-  elizaLogger,
-  generateText,
-  ModelClass,
-  parseJSONObjectFromText,
-} from "@elizaOS/core";
+    Action,
+    composeContext,
+    elizaLogger,
+    generateText,
+    ModelClass,
+    parseJSONObjectFromText,
+} from "@elizaos/core";
 
 export const analyzeTradeAction: Action = {
-  name: "ANALYZE_TRADE",
-  description: "Analyze a token for trading opportunities",
-  similes: [
-    "ANALYZE",
-    "ANALYZE_TOKEN",
-    "TRADE",
-    "ANALYZE_TRADE",
-    "EVALUATE",
-    "ASSESS",
-  ],
-  examples: [],
-  validate: async () => true,
-  handler: async (runtime, memory, state, params, callback) => {
-    try {
-      // composeState
-      if (!state) {
-        state = await runtime.composeState(memory);
-      } else state = await runtime.updateRecentMessageState(state);
+    name: "ANALYZE_TRADE",
+    description: "Analyze a token for trading opportunities",
+    similes: [
+        "ANALYZE",
+        "ANALYZE_TOKEN",
+        "TRADE",
+        "ANALYZE_TRADE",
+        "EVALUATE",
+        "ASSESS",
+    ],
+    examples: [],
+    validate: async () => true,
+    handler: async (runtime, memory, state, params, callback) => {
+        try {
+            // composeState
+            if (!state) {
+                state = await runtime.composeState(memory);
+            } else state = await runtime.updateRecentMessageState(state);
 
-      const tokenData = {
-        walletBalance: params.walletBalance,
-        tokenAddress: params.tokenAddress,
-        price: params.price,
-        volume: params.volume,
-        marketCap: params.marketCap,
-        liquidity: params.liquidity,
-        holderDistribution: params.holderDistribution,
-        trustScore: params.trustScore,
-        dexscreener: params.dexscreener,
-        position: params.position,
-      };
+            const tokenData = {
+                walletBalance: params.walletBalance,
+                tokenAddress: params.tokenAddress,
+                price: params.price,
+                volume: params.volume,
+                marketCap: params.marketCap,
+                liquidity: params.liquidity,
+                holderDistribution: params.holderDistribution,
+                trustScore: params.trustScore,
+                dexscreener: params.dexscreener,
+                position: params.position,
+            };
 
-      // Direct prompt instead of template
-      const prompt = `Analyze the following token data and provide a trading recommendation.
+            // Direct prompt instead of template
+            const prompt = `Analyze the following token data and provide a trading recommendation.
 Return the response as a JSON object with the following structure:
 {
   "recommendation": "BUY" | "SELL" | "HOLD",
@@ -54,41 +54,41 @@ Return the response as a JSON object with the following structure:
 Token Data:
 ${JSON.stringify(tokenData, null, 2)}`;
 
-      // Generate analysis using direct prompt
-      const content = await generateText({
-        runtime,
-        context: prompt,
-        modelClass: ModelClass.LARGE,
-      });
+            // Generate analysis using direct prompt
+            const content = await generateText({
+                runtime,
+                context: prompt,
+                modelClass: ModelClass.LARGE,
+            });
 
-      if (!content) {
-        throw new Error("No analysis generated");
-      }
+            if (!content) {
+                throw new Error("No analysis generated");
+            }
 
-      elizaLogger.log(`Raw analysis response:`, content);
+            elizaLogger.log(`Raw analysis response:`, content);
 
-      // Parse the response to get the recommended action
-      const recommendation = parseJSONObjectFromText(content);
-      elizaLogger.log(
-        `Parsed recommendation for ${params.tokenAddress}:`,
-        recommendation,
-      );
+            // Parse the response to get the recommended action
+            const recommendation = parseJSONObjectFromText(content);
+            elizaLogger.log(
+                `Parsed recommendation for ${params.tokenAddress}:`,
+                recommendation
+            );
 
-      // Send result through callback
-      if (callback) {
-        await callback({
-          text: JSON.stringify(recommendation),
-          type: "analysis",
-        });
-      }
+            // Send result through callback
+            if (callback) {
+                await callback({
+                    text: JSON.stringify(recommendation),
+                    type: "analysis",
+                });
+            }
 
-      return true;
-    } catch (error) {
-      elizaLogger.error(`Analysis failed:`, {
-        error: error instanceof Error ? error.message : "Unknown error",
-        stack: error instanceof Error ? error.stack : undefined,
-      });
-      return false;
-    }
-  },
+            return true;
+        } catch (error) {
+            elizaLogger.error(`Analysis failed:`, {
+                error: error instanceof Error ? error.message : "Unknown error",
+                stack: error instanceof Error ? error.stack : undefined,
+            });
+            return false;
+        }
+    },
 };
diff --git a/packages/plugin-rabbi-trader/src/index.ts b/packages/plugin-rabbi-trader/src/index.ts
index 434311e4867..14c686afecc 100644
--- a/packages/plugin-rabbi-trader/src/index.ts
+++ b/packages/plugin-rabbi-trader/src/index.ts
@@ -1,1152 +1,1218 @@
-import type { Plugin, IAgentRuntime, Memory, State } from "@elizaOS/core";
-import { elizaLogger, settings } from "@elizaOS/core";
+import type { Plugin, IAgentRuntime, Memory, State } from "@elizaos/core";
+import { elizaLogger, settings } from "@elizaos/core";
 import { z } from "zod";
-import { TwitterClientInterface } from "@elizaOS/client-twitter";
+import { TwitterClientInterface } from "@elizaos/client-twitter";
 import {
-  solanaPlugin,
-  trustScoreProvider,
-  trustEvaluator,
-} from "@elizaOS/plugin-solana";
+    solanaPlugin,
+    trustScoreProvider,
+    trustEvaluator,
+    getTokenBalance,
+} from "@elizaos/plugin-solana";
 import { TokenProvider } from "./providers/token";
 import { Connection, PublicKey } from "@solana/web3.js";
 import type { Chain, WalletClient, Signature, Balance } from "@goat-sdk/core";
-import { getTokenBalance } from "@elizaOS/plugin-solana/src/providers/tokenUtils";
 import * as fs from "fs";
 import * as path from "path";
 import { TrustScoreProvider } from "./providers/trustScoreProvider";
 import { SimulationService } from "./services/simulationService";
 import { SAFETY_LIMITS } from "./constants";
 import NodeCache from "node-cache";
-import { TrustScoreDatabase } from "@elizaOS/packlages/plugin-trustdb";
+import { TrustScoreDatabase } from "@elizaos/plugin-trustdb";
 import { v4 as uuidv4 } from "uuid";
 import { actions } from "./actions";
 import {
-  TradeAlert,
-  TradeBuyAlert,
-  tweetTrade,
-  TwitterConfigSchema,
-  TwitterService,
+    TradeAlert,
+    TradeBuyAlert,
+    tweetTrade,
+    TwitterConfigSchema,
+    TwitterService,
 } from "./services/twitter";
 import {
-  executeTrade,
-  getChainWalletBalance,
-  getWalletBalance,
-  getWalletKeypair,
+    executeTrade,
+    getChainWalletBalance,
+    getWalletBalance,
+    getWalletKeypair,
 } from "./wallet";
 import { ProcessedTokenData } from "./types";
 import { analyzeTradeAction } from "./actions/analyzeTrade";
 
 // Update Balance interface to include formatted
 interface ExtendedBalance extends Balance {
-  formatted: string;
+    formatted: string;
 }
 
 // Extended WalletProvider interface to ensure proper typing
 interface ExtendedWalletProvider extends WalletClient {
-  connection: Connection;
-  signMessage(message: string): Promise<Signature>;
-  getFormattedPortfolio: (runtime: IAgentRuntime) => Promise<string>;
-  balanceOf: (tokenAddress: string) => Promise<ExtendedBalance>;
-  getMaxBuyAmount: (tokenAddress: string) => Promise<number>;
-  executeTrade: (params: {
-    tokenIn: string;
-    tokenOut: string;
-    amountIn: number;
-    slippage: number;
-  }) => Promise<any>;
+    connection: Connection;
+    signMessage(message: string): Promise<Signature>;
+    getFormattedPortfolio: (runtime: IAgentRuntime) => Promise<string>;
+    balanceOf: (tokenAddress: string) => Promise<ExtendedBalance>;
+    getMaxBuyAmount: (tokenAddress: string) => Promise<number>;
+    executeTrade: (params: {
+        tokenIn: string;
+        tokenOut: string;
+        amountIn: number;
+        slippage: number;
+    }) => Promise<any>;
 }
 
 const REQUIRED_SETTINGS = {
-  WALLET_PUBLIC_KEY: "Solana wallet public key",
-  DEXSCREENER_WATCHLIST_ID: "DexScreener watchlist ID",
-  COINGECKO_API_KEY: "CoinGecko API key",
+    WALLET_PUBLIC_KEY: "Solana wallet public key",
+    DEXSCREENER_WATCHLIST_ID: "DexScreener watchlist ID",
+    COINGECKO_API_KEY: "CoinGecko API key",
 } as const;
 
 // Add near the top imports
 interface ExtendedPlugin extends Plugin {
-  name: string;
-  description: string;
-  evaluators: any[];
-  providers: any[];
-  actions: any[];
-  services: any[];
-  autoStart?: boolean;
+    name: string;
+    description: string;
+    evaluators: any[];
+    providers: any[];
+    actions: any[];
+    services: any[];
+    autoStart?: boolean;
 }
 
 // Add this helper function
 function validateSolanaAddress(address: string | undefined): boolean {
-  if (!address) return false;
-  try {
-    // Handle Solana addresses
-    if (!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address)) {
-      elizaLogger.warn(`Solana address failed format check: ${address}`);
-      return false;
-    }
+    if (!address) return false;
+    try {
+        // Handle Solana addresses
+        if (!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address)) {
+            elizaLogger.warn(`Solana address failed format check: ${address}`);
+            return false;
+        }
 
-    // Verify it's a valid Solana public key
-    const pubKey = new PublicKey(address);
-    const isValid = Boolean(pubKey.toBase58());
-    elizaLogger.log(
-      `Solana address validation result for ${address}: ${isValid}`
-    );
-    return isValid;
-  } catch (error) {
-    elizaLogger.error(`Address validation error for ${address}:`, error);
-    return false;
-  }
+        // Verify it's a valid Solana public key
+        const pubKey = new PublicKey(address);
+        const isValid = Boolean(pubKey.toBase58());
+        elizaLogger.log(
+            `Solana address validation result for ${address}: ${isValid}`
+        );
+        return isValid;
+    } catch (error) {
+        elizaLogger.error(`Address validation error for ${address}:`, error);
+        return false;
+    }
 }
 
 // Add function to load token addresses
 export function loadTokenAddresses(): string[] {
-  try {
-    const filePath = path.resolve(
-      process.cwd(),
-      "../characters/tokens/tokenaddresses.json"
-    );
-    const data = fs.readFileSync(filePath, "utf8");
-    const addresses = JSON.parse(data);
+    try {
+        const filePath = path.resolve(
+            process.cwd(),
+            "../characters/tokens/tokenaddresses.json"
+        );
+        const data = fs.readFileSync(filePath, "utf8");
+        const addresses = JSON.parse(data);
 
-    // Validate addresses
-    const validAddresses = addresses.filter((addr: string) => {
-      // Solana address validation
-      return validateSolanaAddress(addr);
-    });
+        // Validate addresses
+        const validAddresses = addresses.filter((addr: string) => {
+            // Solana address validation
+            return validateSolanaAddress(addr);
+        });
 
-    elizaLogger.log("Loaded token addresses:", {
-      total: validAddresses.length,
-      solana: validAddresses.filter((addr) => !addr.startsWith("0x")).length,
-      base: validAddresses.filter((addr) => addr.startsWith("0x")).length,
-    });
+        elizaLogger.log("Loaded token addresses:", {
+            total: validAddresses.length,
+            solana: validAddresses.filter((addr) => !addr.startsWith("0x"))
+                .length,
+            base: validAddresses.filter((addr) => addr.startsWith("0x")).length,
+        });
 
-    return validAddresses;
-  } catch (error) {
-    elizaLogger.error("Failed to load token addresses:", error);
-    throw new Error("Token addresses file not found or invalid");
-  }
+        return validAddresses;
+    } catch (error) {
+        elizaLogger.error("Failed to load token addresses:", error);
+        throw new Error("Token addresses file not found or invalid");
+    }
 }
 
 // Add cache configuration after other interfaces
 interface CacheEntry {
-  lastAnalysis: number;
-  tokenData: any;
-  trustScore: number;
-  analysisResult: any;
+    lastAnalysis: number;
+    tokenData: any;
+    trustScore: number;
+    analysisResult: any;
 }
 
 // Add cache instance before createGoatPlugin
 const tokenCache = new NodeCache({
-  stdTTL: 1200, // 20 minutes in seconds
-  checkperiod: 120, // Check for expired entries every 2 minutes
+    stdTTL: 1200, // 20 minutes in seconds
+    checkperiod: 120, // Check for expired entries every 2 minutes
 });
 
 // Add near the top with other interfaces
 interface SkipWaitCache {
-  lastTweet: number;
-  action: "WAIT" | "SKIP";
+    lastTweet: number;
+    action: "WAIT" | "SKIP";
 }
 
 // Add near other cache instances
 const skipWaitCache = new NodeCache({
-  stdTTL: 7200, // 2 hours in seconds
-  checkperiod: 600, // Check for expired entries every 10 minutes
+    stdTTL: 7200, // 2 hours in seconds
+    checkperiod: 600, // Check for expired entries every 10 minutes
 });
 
 // Add near other interfaces
 interface TweetRateLimit {
-  lastTweet: number;
-  count: number; // Track number of tweets in the time window
+    lastTweet: number;
+    count: number; // Track number of tweets in the time window
 }
 
 // Add near other cache instances
 const tweetRateCache = new NodeCache({
-  stdTTL: 86400, // 24 hours in seconds
-  checkperiod: 3600, // Check every hour
+    stdTTL: 86400, // 24 hours in seconds
+    checkperiod: 3600, // Check every hour
 });
 
 // Add helper function
 function canTweet(tweetType: "trade" | "market_search"): boolean {
-  const now = Date.now();
-  const hourKey = `tweets_${tweetType}_${Math.floor(now / 3600000)}`; // Key by hour and type
-  const rateLimit: TweetRateLimit = tweetRateCache.get(hourKey) || {
-    lastTweet: now,
-    count: 0,
-  };
-
-  // Different limits for different tweet types
-  const MAX_TWEETS_PER_HOUR = {
-    trade: 10,
-    market_search: 10, // Lower limit for market search tweets
-  };
-
-  if (rateLimit.count >= MAX_TWEETS_PER_HOUR[tweetType]) {
-    elizaLogger.warn(
-      `Tweet rate limit reached for ${tweetType}: ${rateLimit.count} tweets this hour`
-    );
-    return false;
-  }
+    const now = Date.now();
+    const hourKey = `tweets_${tweetType}_${Math.floor(now / 3600000)}`; // Key by hour and type
+    const rateLimit: TweetRateLimit = tweetRateCache.get(hourKey) || {
+        lastTweet: now,
+        count: 0,
+    };
+
+    // Different limits for different tweet types
+    const MAX_TWEETS_PER_HOUR = {
+        trade: 10,
+        market_search: 10, // Lower limit for market search tweets
+    };
+
+    if (rateLimit.count >= MAX_TWEETS_PER_HOUR[tweetType]) {
+        elizaLogger.warn(
+            `Tweet rate limit reached for ${tweetType}: ${rateLimit.count} tweets this hour`
+        );
+        return false;
+    }
 
-  // Update rate limit
-  tweetRateCache.set(hourKey, {
-    lastTweet: now,
-    count: rateLimit.count + 1,
-  });
+    // Update rate limit
+    tweetRateCache.set(hourKey, {
+        lastTweet: now,
+        count: rateLimit.count + 1,
+    });
 
-  return true;
+    return true;
 }
 
 // Add new interfaces near the top with other interfaces
 interface TradePerformance {
-  token_address: string;
-  recommender_id: string;
-  buy_price: number;
-  sell_price: number;
-  buy_timeStamp: string;
-  sell_timeStamp: string;
-  buy_amount: number;
-  sell_amount: number;
-  buy_value_usd: number;
-  sell_value_usd: number;
-  buy_market_cap: number;
-  sell_market_cap: number;
-  buy_liquidity: number;
-  sell_liquidity: number;
-  profit_usd: number;
-  profit_percent: number;
-  market_cap_change: number;
-  liquidity_change: number;
-  rapidDump: boolean;
+    token_address: string;
+    recommender_id: string;
+    buy_price: number;
+    sell_price: number;
+    buy_timeStamp: string;
+    sell_timeStamp: string;
+    buy_amount: number;
+    sell_amount: number;
+    buy_value_usd: number;
+    sell_value_usd: number;
+    buy_market_cap: number;
+    sell_market_cap: number;
+    buy_liquidity: number;
+    sell_liquidity: number;
+    profit_usd: number;
+    profit_percent: number;
+    market_cap_change: number;
+    liquidity_change: number;
+    rapidDump: boolean;
 }
 
 interface TradePosition {
-  token_address: string;
-  entry_price: number;
-  size: number;
-  stop_loss: number;
-  take_profit: number;
-  open_timeStamp: string;
-  close_timeStamp?: string;
-  status?: "OPEN" | "CLOSED";
+    token_address: string;
+    entry_price: number;
+    size: number;
+    stop_loss: number;
+    take_profit: number;
+    open_timeStamp: string;
+    close_timeStamp?: string;
+    status?: "OPEN" | "CLOSED";
 }
 
 // Update the analysisParams interface
 interface AnalysisParams extends Record<string, any> {
-  walletBalance: number;
-  tokenAddress: string;
-  price: number;
-  volume: number;
-  marketCap: number;
-  liquidity: number;
-  holderDistribution: string;
-  trustScore: number;
-  dexscreener: any;
-  position?: TradePosition;
-  tradeHistory?: TradePerformance[];
+    walletBalance: number;
+    tokenAddress: string;
+    price: number;
+    volume: number;
+    marketCap: number;
+    liquidity: number;
+    holderDistribution: string;
+    trustScore: number;
+    dexscreener: any;
+    position?: TradePosition;
+    tradeHistory?: TradePerformance[];
 }
 
 // Update the interface to match the SQL parameter order
 interface SellDetailsData {
-  // SET clause parameters in order
-  sell_price: number;
-  sell_timeStamp: string;
-  sell_amount: number;
-  received_sol: number;
-  sell_value_usd: number;
-  profit_usd: number;
-  profit_percent: number;
-  sell_market_cap: number;
-  market_cap_change: number;
-  sell_liquidity: number;
-  liquidity_change: number;
-  rapidDump: boolean;
-  sell_recommender_id: string | null;
+    // SET clause parameters in order
+    sell_price: number;
+    sell_timeStamp: string;
+    sell_amount: number;
+    received_sol: number;
+    sell_value_usd: number;
+    profit_usd: number;
+    profit_percent: number;
+    sell_market_cap: number;
+    market_cap_change: number;
+    sell_liquidity: number;
+    liquidity_change: number;
+    rapidDump: boolean;
+    sell_recommender_id: string | null;
 }
 
 async function updateSellDetails(
-  runtime: IAgentRuntime,
-  tokenAddress: string,
-  recommenderId: string,
-  tradeAmount: number,
-  latestTrade: any,
-  tokenData: any
+    runtime: IAgentRuntime,
+    tokenAddress: string,
+    recommenderId: string,
+    tradeAmount: number,
+    latestTrade: any,
+    tokenData: any
 ) {
-  const trustScoreDb = new TrustScoreDatabase(runtime.databaseAdapter.db);
-
-  const trade = await trustScoreDb.getLatestTradePerformance(
-    tokenAddress,
-    recommenderId,
-    false
-  );
-
-  if (!trade) {
-    elizaLogger.error(
-      `No trade found for token ${tokenAddress} and recommender ${recommenderId}`
-    );
-    throw new Error("No trade found to update");
-  }
-
-  const currentPrice = tokenData.dexScreenerData.pairs[0]?.priceUsd || 0;
-  const marketCap = tokenData.dexScreenerData.pairs[0]?.marketCap || 0;
-  const liquidity = tokenData.dexScreenerData.pairs[0]?.liquidity?.usd || 0;
-
-  const sellValueUsd = tradeAmount * Number(currentPrice);
-  const profitUsd = sellValueUsd - trade.buy_value_usd;
-  const profitPercent = (profitUsd / trade.buy_value_usd) * 100;
-
-  // Create sellDetailsData object matching SQL parameter order
-  const sellDetails: SellDetailsData = {
-    sell_price: Number(currentPrice),
-    sell_timeStamp: new Date().toISOString(),
-    sell_amount: tradeAmount,
-    received_sol: tradeAmount,
-    sell_value_usd: sellValueUsd,
-    profit_usd: profitUsd,
-    profit_percent: profitPercent,
-    sell_market_cap: marketCap,
-    market_cap_change: marketCap - trade.buy_market_cap,
-    sell_liquidity: liquidity,
-    liquidity_change: liquidity - trade.buy_liquidity,
-    rapidDump: false,
-    sell_recommender_id: recommenderId || null,
-  };
-
-  elizaLogger.log("Attempting to update trade performance with data:", {
-    sellDetails,
-    whereClause: {
-      tokenAddress,
-      recommenderId,
-      buyTimeStamp: trade.buy_timeStamp,
-    },
-    isSimulation: false,
-  });
-
-  try {
-    try {
-      // Pass sellDetails first (SET clause), then WHERE clause parameters
-      elizaLogger.log(
-        "Verifying parameters for updateTradePerformanceOnSell:",
-        {
-          sellDetails,
-          tokenAddress,
-          recommenderId,
-          buyTimeStamp: trade.buy_timeStamp,
-          isSimulation: false,
-        }
-      );
-
-      const success = await trustScoreDb.updateTradePerformanceOnSell(
-        tokenAddress, // 1. WHERE token_address = ?
-        recommenderId, // 2. WHERE recommender_id = ?
-        trade.buy_timeStamp, // 3. WHERE buy_timeStamp = ?
-        sellDetails, // 4. SET clause parameters
-        false // 5. isSimulation flag
-      );
-
-      if (!success) {
-        elizaLogger.warn("Trade update returned false", {
-          tokenAddress,
-          recommenderId,
-          buyTimeStamp: trade.buy_timeStamp,
-        });
-      }
+    const trustScoreDb = new TrustScoreDatabase(runtime.databaseAdapter.db);
 
-      elizaLogger.log("Trade performance update completed", {
-        success,
+    const trade = await trustScoreDb.getLatestTradePerformance(
         tokenAddress,
         recommenderId,
-        profitPercent: profitPercent.toFixed(2) + "%",
-        profitUsd: profitUsd.toFixed(4) + " USD",
-      });
-    } catch (dbError) {
-      elizaLogger.error("Database error during trade update:", {
-        error: dbError,
-        query: {
-          sellDetails,
-          whereClause: {
+        false
+    );
+
+    if (!trade) {
+        elizaLogger.error(
+            `No trade found for token ${tokenAddress} and recommender ${recommenderId}`
+        );
+        throw new Error("No trade found to update");
+    }
+
+    const currentPrice = tokenData.dexScreenerData.pairs[0]?.priceUsd || 0;
+    const marketCap = tokenData.dexScreenerData.pairs[0]?.marketCap || 0;
+    const liquidity = tokenData.dexScreenerData.pairs[0]?.liquidity?.usd || 0;
+
+    const sellValueUsd = tradeAmount * Number(currentPrice);
+    const profitUsd = sellValueUsd - trade.buy_value_usd;
+    const profitPercent = (profitUsd / trade.buy_value_usd) * 100;
+
+    // Create sellDetailsData object matching SQL parameter order
+    const sellDetails: SellDetailsData = {
+        sell_price: Number(currentPrice),
+        sell_timeStamp: new Date().toISOString(),
+        sell_amount: tradeAmount,
+        received_sol: tradeAmount,
+        sell_value_usd: sellValueUsd,
+        profit_usd: profitUsd,
+        profit_percent: profitPercent,
+        sell_market_cap: marketCap,
+        market_cap_change: marketCap - trade.buy_market_cap,
+        sell_liquidity: liquidity,
+        liquidity_change: liquidity - trade.buy_liquidity,
+        rapidDump: false,
+        sell_recommender_id: recommenderId || null,
+    };
+
+    elizaLogger.log("Attempting to update trade performance with data:", {
+        sellDetails,
+        whereClause: {
             tokenAddress,
             recommenderId,
             buyTimeStamp: trade.buy_timeStamp,
-          },
         },
-      });
-      throw dbError;
+        isSimulation: false,
+    });
+
+    try {
+        try {
+            // Pass sellDetails first (SET clause), then WHERE clause parameters
+            elizaLogger.log(
+                "Verifying parameters for updateTradePerformanceOnSell:",
+                {
+                    sellDetails,
+                    tokenAddress,
+                    recommenderId,
+                    buyTimeStamp: trade.buy_timeStamp,
+                    isSimulation: false,
+                }
+            );
+
+            const success = await trustScoreDb.updateTradePerformanceOnSell(
+                tokenAddress, // 1. WHERE token_address = ?
+                recommenderId, // 2. WHERE recommender_id = ?
+                trade.buy_timeStamp, // 3. WHERE buy_timeStamp = ?
+                sellDetails, // 4. SET clause parameters
+                false // 5. isSimulation flag
+            );
+
+            if (!success) {
+                elizaLogger.warn("Trade update returned false", {
+                    tokenAddress,
+                    recommenderId,
+                    buyTimeStamp: trade.buy_timeStamp,
+                });
+            }
+
+            elizaLogger.log("Trade performance update completed", {
+                success,
+                tokenAddress,
+                recommenderId,
+                profitPercent: profitPercent.toFixed(2) + "%",
+                profitUsd: profitUsd.toFixed(4) + " USD",
+            });
+        } catch (dbError) {
+            elizaLogger.error("Database error during trade update:", {
+                error: dbError,
+                query: {
+                    sellDetails,
+                    whereClause: {
+                        tokenAddress,
+                        recommenderId,
+                        buyTimeStamp: trade.buy_timeStamp,
+                    },
+                },
+            });
+            throw dbError;
+        }
+    } catch (error) {
+        elizaLogger.error("Failed to update trade performance:", {
+            error,
+            parameters: {
+                sellDetails,
+                whereClause: {
+                    tokenAddress,
+                    recommenderId,
+                    buyTimeStamp: trade.buy_timeStamp,
+                },
+                originalTrade: trade,
+            },
+            errorDetails:
+                error instanceof Error
+                    ? {
+                          message: error.message,
+                          stack: error.stack,
+                          name: error.name,
+                      }
+                    : error,
+        });
+        throw error;
     }
-  } catch (error) {
-    elizaLogger.error("Failed to update trade performance:", {
-      error,
-      parameters: {
+
+    return {
         sellDetails,
-        whereClause: {
-          tokenAddress,
-          recommenderId,
-          buyTimeStamp: trade.buy_timeStamp,
+        currentPrice,
+        profitDetails: {
+            profitUsd,
+            profitPercent,
+            sellValueUsd,
         },
-        originalTrade: trade,
-      },
-      errorDetails:
-        error instanceof Error
-          ? {
-              message: error.message,
-              stack: error.stack,
-              name: error.name,
-            }
-          : error,
-    });
-    throw error;
-  }
-
-  return {
-    sellDetails,
-    currentPrice,
-    profitDetails: {
-      profitUsd,
-      profitPercent,
-      sellValueUsd,
-    },
-  };
+    };
 }
 
 // Update the module declaration to match the new parameter order
 declare module "@elizaos/plugin-trustdb" {
-  interface TrustScoreDatabase {
-    updateTradePerformanceOnSell(
-      tokenAddress: string, // Changed order: tokenAddress first
-      recommenderId: string, // recommenderId second
-      buyTimeStamp: string, // buyTimeStamp third
-      sellDetails: SellDetailsData, // sellDetails fourth
-      isSimulation: boolean // isSimulation fifth
-    ): boolean;
-  }
+    interface TrustScoreDatabase {
+        updateTradePerformanceOnSell(
+            tokenAddress: string, // Changed order: tokenAddress first
+            recommenderId: string, // recommenderId second
+            buyTimeStamp: string, // buyTimeStamp third
+            sellDetails: SellDetailsData, // sellDetails fourth
+            isSimulation: boolean // isSimulation fifth
+        ): boolean;
+    }
 }
 
 async function getChainBalance(
-  connection: Connection,
-  walletAddress: PublicKey,
-  tokenAddress: string
+    connection: Connection,
+    walletAddress: PublicKey,
+    tokenAddress: string
 ): Promise<number> {
-  // Use existing Solana balance fetching logic
-  return await getTokenBalance(
-    connection,
-    walletAddress,
-    new PublicKey(tokenAddress)
-  );
+    // Use existing Solana balance fetching logic
+    return await getTokenBalance(
+        connection,
+        walletAddress,
+        new PublicKey(tokenAddress)
+    );
 }
 
 async function createRabbiTraderPlugin(
-  getSetting: (key: string) => string | undefined,
-  runtime?: IAgentRuntime
+    getSetting: (key: string) => string | undefined,
+    runtime?: IAgentRuntime
 ): Promise<Plugin> {
-  // Define resumeTrading at the start of the function
-  const resumeTrading = async () => {
-    // Load and analyze tokens
-    const tokenAddresses = loadTokenAddresses().filter(
-      (addr) => !addr.startsWith("0x")
-    );
-    elizaLogger.log(`Analyzing ${tokenAddresses.length} Solana tokens...`);
+    // Define resumeTrading at the start of the function
+    const resumeTrading = async () => {
+        // Load and analyze tokens
+        const tokenAddresses = loadTokenAddresses().filter(
+            (addr) => !addr.startsWith("0x")
+        );
+        elizaLogger.log(`Analyzing ${tokenAddresses.length} Solana tokens...`);
+
+        // Analyze regular token list
+        for (const tokenAddress of tokenAddresses) {
+            await analyzeToken(
+                runtime,
+                connection,
+                twitterService,
+                tokenAddress
+            );
+        }
 
-    // Analyze regular token list
-    for (const tokenAddress of tokenAddresses) {
-      await analyzeToken(runtime, connection, twitterService, tokenAddress);
-    }
+        // Add delay between iterations
+        await new Promise((resolve) => setTimeout(resolve, 1200000)); // 20 minutes
+    };
 
-    // Add delay between iterations
-    await new Promise((resolve) => setTimeout(resolve, 1200000)); // 20 minutes
-  };
+    elizaLogger.log("Starting GOAT plugin initialization");
 
-  elizaLogger.log("Starting GOAT plugin initialization");
+    // Move connection initialization to the top
+    const connection = new Connection(
+        runtime?.getSetting("RPC_URL") || "https://api.mainnet-beta.solana.com"
+    );
 
-  // Move connection initialization to the top
-  const connection = new Connection(
-    runtime?.getSetting("RPC_URL") || "https://api.mainnet-beta.solana.com"
-  );
+    const keypair = getWalletKeypair(runtime);
 
-  const keypair = getWalletKeypair(runtime);
+    // Validate required settings
+    const missingSettings: string[] = [];
+    for (const [key, description] of Object.entries(REQUIRED_SETTINGS)) {
+        if (!getSetting(key)) {
+            missingSettings.push(`${key} (${description})`);
+        }
+    }
 
-  // Validate required settings
-  const missingSettings: string[] = [];
-  for (const [key, description] of Object.entries(REQUIRED_SETTINGS)) {
-    if (!getSetting(key)) {
-      missingSettings.push(`${key} (${description})`);
+    if (missingSettings.length > 0) {
+        const errorMsg = `Missing required settings: ${missingSettings.join(", ")}`;
+        elizaLogger.error(errorMsg);
+        throw new Error(errorMsg);
     }
-  }
-
-  if (missingSettings.length > 0) {
-    const errorMsg = `Missing required settings: ${missingSettings.join(", ")}`;
-    elizaLogger.error(errorMsg);
-    throw new Error(errorMsg);
-  }
-
-  elizaLogger.log("Initializing Solana connection...");
-  let walletProvider: ExtendedWalletProvider = {
-    connection,
-    getChain: () => ({ type: "solana" }),
-    getAddress: () => keypair.publicKey.toBase58(),
-    signMessage: async (message: string): Promise<Signature> => {
-      throw new Error("Message signing not implemented for Solana wallet");
-    },
-    balanceOf: async (tokenAddress: string): Promise<ExtendedBalance> => {
-      try {
-        if (tokenAddress.startsWith("0x")) {
-          // Handle Base token balance
-          const baseBalance = await getChainBalance(
-            connection,
-            keypair.publicKey,
-            tokenAddress
-          );
-          return {
-            value: BigInt(baseBalance.toString()),
-            decimals: 18, // Base uses 18 decimals
-            formatted: (baseBalance / 1e18).toString(),
-            symbol: "ETH",
-            name: "Base",
-          };
-        } else {
-          // Existing Solana logic
-          const tokenPublicKey = new PublicKey(tokenAddress);
-          const amount = await getTokenBalance(
-            connection,
-            keypair.publicKey,
-            tokenPublicKey
-          );
-          return {
-            value: BigInt(amount.toString()),
-            decimals: 9,
-            formatted: (amount / 1e9).toString(),
-            symbol: "SOL",
-            name: "Solana",
-          };
-        }
-      } catch (error) {
-        return {
-          value: BigInt(0),
-          decimals: tokenAddress.startsWith("0x") ? 18 : 9,
-          formatted: "0",
-          symbol: tokenAddress.startsWith("0x") ? "ETH" : "SOL",
-          name: tokenAddress.startsWith("0x") ? "Base" : "Solana",
-        };
-      }
-    },
-    getMaxBuyAmount: async (tokenAddress: string) => {
-      try {
-        if (tokenAddress.startsWith("0x")) {
-          // Handle Base chain balance
-          const baseBalance = await getChainBalance(
-            connection,
-            keypair.publicKey,
-            tokenAddress
-          );
-          return (baseBalance * 0.9) / 1e18; // Base uses 18 decimals
-        } else {
-          // Handle Solana balance
-          const balance = await connection.getBalance(keypair.publicKey);
-          return (balance * 0.9) / 1e9; // Solana uses 9 decimals
-        }
-      } catch (error) {
-        elizaLogger.error(
-          `Failed to get max buy amount for ${tokenAddress}:`,
-          error
+
+    elizaLogger.log("Initializing Solana connection...");
+    let walletProvider: ExtendedWalletProvider = {
+        connection,
+        getChain: () => ({ type: "solana" }),
+        getAddress: () => keypair.publicKey.toBase58(),
+        signMessage: async (message: string): Promise<Signature> => {
+            throw new Error(
+                "Message signing not implemented for Solana wallet"
+            );
+        },
+        balanceOf: async (tokenAddress: string): Promise<ExtendedBalance> => {
+            try {
+                if (tokenAddress.startsWith("0x")) {
+                    // Handle Base token balance
+                    const baseBalance = await getChainBalance(
+                        connection,
+                        keypair.publicKey,
+                        tokenAddress
+                    );
+                    return {
+                        value: BigInt(baseBalance.toString()),
+                        decimals: 18, // Base uses 18 decimals
+                        formatted: (baseBalance / 1e18).toString(),
+                        symbol: "ETH",
+                        name: "Base",
+                    };
+                } else {
+                    // Existing Solana logic
+                    const tokenPublicKey = new PublicKey(tokenAddress);
+                    const amount = await getTokenBalance(
+                        connection,
+                        keypair.publicKey,
+                        tokenPublicKey
+                    );
+                    return {
+                        value: BigInt(amount.toString()),
+                        decimals: 9,
+                        formatted: (amount / 1e9).toString(),
+                        symbol: "SOL",
+                        name: "Solana",
+                    };
+                }
+            } catch (error) {
+                return {
+                    value: BigInt(0),
+                    decimals: tokenAddress.startsWith("0x") ? 18 : 9,
+                    formatted: "0",
+                    symbol: tokenAddress.startsWith("0x") ? "ETH" : "SOL",
+                    name: tokenAddress.startsWith("0x") ? "Base" : "Solana",
+                };
+            }
+        },
+        getMaxBuyAmount: async (tokenAddress: string) => {
+            try {
+                if (tokenAddress.startsWith("0x")) {
+                    // Handle Base chain balance
+                    const baseBalance = await getChainBalance(
+                        connection,
+                        keypair.publicKey,
+                        tokenAddress
+                    );
+                    return (baseBalance * 0.9) / 1e18; // Base uses 18 decimals
+                } else {
+                    // Handle Solana balance
+                    const balance = await connection.getBalance(
+                        keypair.publicKey
+                    );
+                    return (balance * 0.9) / 1e9; // Solana uses 9 decimals
+                }
+            } catch (error) {
+                elizaLogger.error(
+                    `Failed to get max buy amount for ${tokenAddress}:`,
+                    error
+                );
+                return 0;
+            }
+        },
+        executeTrade: async (params) => {
+            try {
+                return { success: true };
+            } catch (error) {
+                throw error;
+            }
+        },
+        getFormattedPortfolio: async () => "",
+    };
+
+    elizaLogger.log(
+        "Solana connection and wallet provider initialized successfully"
+    );
+
+    // Initialize Twitter service if enabled
+    let twitterService: TwitterService | undefined;
+    try {
+        elizaLogger.log(
+            "Configuring Twitter service for trade notifications..."
         );
-        return 0;
-      }
-    },
-    executeTrade: async (params) => {
-      try {
-        return { success: true };
-      } catch (error) {
-        throw error;
-      }
-    },
-    getFormattedPortfolio: async () => "",
-  };
-
-  elizaLogger.log(
-    "Solana connection and wallet provider initialized successfully"
-  );
-
-  // Initialize Twitter service if enabled
-  let twitterService: TwitterService | undefined;
-  try {
-    elizaLogger.log("Configuring Twitter service for trade notifications...");
-    const twitterConfig = TwitterConfigSchema.parse({
-      enabled: getSetting("TWITTER_ENABLED") === "true",
-      username: getSetting("TWITTER_USERNAME"),
-      dryRun: false,
-    });
+        const twitterConfig = TwitterConfigSchema.parse({
+            enabled: getSetting("TWITTER_ENABLED") === "true",
+            username: getSetting("TWITTER_USERNAME"),
+            dryRun: false,
+        });
 
-    if (twitterConfig.enabled && runtime) {
-      elizaLogger.log("Starting Twitter client initialization...");
-      const twitterClient = await TwitterClientInterface.start(runtime);
-      twitterService = new TwitterService(twitterClient, twitterConfig);
+        if (twitterConfig.enabled && runtime) {
+            elizaLogger.log("Starting Twitter client initialization...");
+            const twitterClient = await TwitterClientInterface.start(runtime);
+            twitterService = new TwitterService(twitterClient, twitterConfig);
 
-      // Add delay after initialization
-      await new Promise((resolve) => setTimeout(resolve, 5000));
+            // Add delay after initialization
+            await new Promise((resolve) => setTimeout(resolve, 5000));
 
-      elizaLogger.log("Twitter service initialized successfully", {
-        username: twitterConfig.username,
-        dryRun: twitterConfig.dryRun,
-      });
+            elizaLogger.log("Twitter service initialized successfully", {
+                username: twitterConfig.username,
+                dryRun: twitterConfig.dryRun,
+            });
+        }
+    } catch (error) {
+        elizaLogger.error("Failed to initialize Twitter service:", error);
     }
-  } catch (error) {
-    elizaLogger.error("Failed to initialize Twitter service:", error);
-  }
-
-  elizaLogger.log("Initializing Solana plugin components...");
-
-  try {
-    const customActions = actions;
-
-    // Then update the plugin creation
-    const plugin: ExtendedPlugin = {
-      name: "[Rabbi Trader] Onchain Actions with Solana Integration",
-      description: "Autonomous trading integration with AI analysis",
-      evaluators: [trustEvaluator, ...(solanaPlugin.evaluators || [])],
-      providers: [
-        walletProvider,
-        trustScoreProvider,
-        ...(solanaPlugin.providers || []),
-      ],
-      actions: [...customActions, ...(solanaPlugin.actions || [])],
-      services: [],
-      autoStart: true,
-    };
 
-    // Add auto-start trading analysis
-    if (!runtime) return;
+    elizaLogger.log("Initializing Solana plugin components...");
 
-    elizaLogger.log("Starting autonomous trading system...");
-    const analyzeTradeAction = plugin.actions.find(
-      (a) => a.name === "ANALYZE_TRADE"
-    );
+    try {
+        const customActions = actions;
+
+        // Then update the plugin creation
+        const plugin: ExtendedPlugin = {
+            name: "[Rabbi Trader] Onchain Actions with Solana Integration",
+            description: "Autonomous trading integration with AI analysis",
+            evaluators: [trustEvaluator, ...(solanaPlugin.evaluators || [])],
+            providers: [
+                walletProvider,
+                trustScoreProvider,
+                ...(solanaPlugin.providers || []),
+            ],
+            actions: [...customActions, ...(solanaPlugin.actions || [])],
+            services: [],
+            autoStart: true,
+        };
 
-    if (!analyzeTradeAction) return;
+        // Add auto-start trading analysis
+        if (!runtime) return;
 
-    const interval = Number(runtime.getSetting("TRADING_INTERVAL")) || 300000;
+        elizaLogger.log("Starting autonomous trading system...");
+        const analyzeTradeAction = plugin.actions.find(
+            (a) => a.name === "ANALYZE_TRADE"
+        );
 
-    // Then start trading loop if enabled
-    if (!settings.ENABLE_TRADING) return;
+        if (!analyzeTradeAction) return;
 
-    elizaLogger.log("Initializing trading loop...");
-    await resumeTrading();
-    setInterval(resumeTrading, interval);
+        const interval =
+            Number(runtime.getSetting("TRADING_INTERVAL")) || 300000;
 
-    elizaLogger.log("GOAT plugin initialization completed successfully");
-    return plugin;
-  } catch (error) {
-    elizaLogger.error("Failed to initialize plugin components:", error);
-    throw new Error(
-      `Plugin initialization failed: ${error instanceof Error ? error.message : String(error)}`
-    );
-  }
+        // Then start trading loop if enabled
+        if (!settings.ENABLE_TRADING) return;
+
+        elizaLogger.log("Initializing trading loop...");
+        await resumeTrading();
+        setInterval(resumeTrading, interval);
+
+        elizaLogger.log("GOAT plugin initialization completed successfully");
+        return plugin;
+    } catch (error) {
+        elizaLogger.error("Failed to initialize plugin components:", error);
+        throw new Error(
+            `Plugin initialization failed: ${error instanceof Error ? error.message : String(error)}`
+        );
+    }
 }
 
 async function analyzeToken(
-  runtime: IAgentRuntime,
-  connection: Connection,
-  twitterService: TwitterService,
-  tokenAddress: string
+    runtime: IAgentRuntime,
+    connection: Connection,
+    twitterService: TwitterService,
+    tokenAddress: string
 ) {
-  try {
-    // Check cache first
-    const cachedData: CacheEntry | undefined = tokenCache.get(tokenAddress);
-    const now = Date.now();
+    try {
+        // Check cache first
+        const cachedData: CacheEntry | undefined = tokenCache.get(tokenAddress);
+        const now = Date.now();
 
-    // Skip if analyzed within last 20 minutes
-    if (cachedData && now - cachedData.lastAnalysis < 1200000) {
-      elizaLogger.log(
-        `Using cached data for ${tokenAddress}, last analyzed ${Math.floor((now - cachedData.lastAnalysis) / 1000)}s ago`
-      );
-      return;
-    }
+        // Skip if analyzed within last 20 minutes
+        if (cachedData && now - cachedData.lastAnalysis < 1200000) {
+            elizaLogger.log(
+                `Using cached data for ${tokenAddress}, last analyzed ${Math.floor((now - cachedData.lastAnalysis) / 1000)}s ago`
+            );
+            return;
+        }
 
-    elizaLogger.log(`Starting analysis for token: ${tokenAddress}`);
+        elizaLogger.log(`Starting analysis for token: ${tokenAddress}`);
 
-    await new Promise((resolve) => setTimeout(resolve, 2000));
+        await new Promise((resolve) => setTimeout(resolve, 2000));
 
-    if (!validateSolanaAddress(tokenAddress)) {
-      elizaLogger.error(`Invalid token address format: ${tokenAddress}`);
-      return;
-    }
+        if (!validateSolanaAddress(tokenAddress)) {
+            elizaLogger.error(`Invalid token address format: ${tokenAddress}`);
+            return;
+        }
 
-    // Initialize TokenProvider directly with just the token address
-    const tokenProvider = new TokenProvider(tokenAddress);
-
-    // Get processed token data which includes DexScreener data
-    elizaLogger.log(`Fetching token data for ${tokenAddress}`);
-    const tokenData = await tokenProvider.getProcessedTokenData();
-    elizaLogger.log(`Token data fetched for ${tokenAddress}:`, tokenData);
-
-    // Get trust score and cache it
-    const trustProvider = new TrustScoreProvider();
-    const trustEvaluation = await trustProvider.evaluateToken(tokenAddress);
-    const { trustScore } = trustEvaluation;
-
-    // Cache the new data
-    const cacheEntry: CacheEntry = {
-      lastAnalysis: Date.now(),
-      tokenData,
-      trustScore,
-      analysisResult: null, // Will be updated after analysis
-    };
-    tokenCache.set(tokenAddress, cacheEntry);
+        // Initialize TokenProvider directly with just the token address
+        const tokenProvider = new TokenProvider(tokenAddress);
+
+        // Get processed token data which includes DexScreener data
+        elizaLogger.log(`Fetching token data for ${tokenAddress}`);
+        const tokenData = await tokenProvider.getProcessedTokenData();
+        elizaLogger.log(`Token data fetched for ${tokenAddress}:`, tokenData);
+
+        // Get trust score and cache it
+        const trustProvider = new TrustScoreProvider();
+        const trustEvaluation = await trustProvider.evaluateToken(tokenAddress);
+        const { trustScore } = trustEvaluation;
+
+        // Cache the new data
+        const cacheEntry: CacheEntry = {
+            lastAnalysis: Date.now(),
+            tokenData,
+            trustScore,
+            analysisResult: null, // Will be updated after analysis
+        };
+        tokenCache.set(tokenAddress, cacheEntry);
 
-    const walletPublicKey = runtime.getSetting("WALLET_PUBLIC_KEY");
-    if (!walletPublicKey) {
-      elizaLogger.error("No wallet public key configured");
-      return;
-    }
+        const walletPublicKey = runtime.getSetting("WALLET_PUBLIC_KEY");
+        if (!walletPublicKey) {
+            elizaLogger.error("No wallet public key configured");
+            return;
+        }
 
-    const balance = await connection.getBalance(new PublicKey(walletPublicKey));
+        const balance = await connection.getBalance(
+            new PublicKey(walletPublicKey)
+        );
 
-    const walletSolBalance = {
-      formatted: (balance / 1e9).toString(),
-    };
+        const walletSolBalance = {
+            formatted: (balance / 1e9).toString(),
+        };
 
-    // Initialize trustScoreDb
-    const trustScoreDb = new TrustScoreDatabase(runtime.databaseAdapter.db);
+        // Initialize trustScoreDb
+        const trustScoreDb = new TrustScoreDatabase(runtime.databaseAdapter.db);
 
-    // Before creating analysisParams, get the latest trade performance
-    const latestTrade = trustScoreDb.getLatestTradePerformance(
-      tokenAddress,
-      runtime.agentId,
-      false // not simulation
-    );
+        // Before creating analysisParams, get the latest trade performance
+        const latestTrade = trustScoreDb.getLatestTradePerformance(
+            tokenAddress,
+            runtime.agentId,
+            false // not simulation
+        );
 
-    elizaLogger.log(`Latest trade for ${tokenAddress}:`, latestTrade);
-
-    // Before creating analysisParams, get the correct chain balance
-    const walletBalance = await getChainWalletBalance(runtime, tokenAddress);
-
-    const pair = tokenData.dexScreenerData.pairs[0];
-    const analysisParams: AnalysisParams = {
-      walletBalance, // Now using the correct chain's balance
-      tokenAddress,
-      price: Number(pair?.priceUsd || 0),
-      volume: pair?.volume?.h24 || 0,
-      marketCap: pair?.marketCap || 0,
-      liquidity: pair?.liquidity?.usd || 0,
-      holderDistribution: tokenData.holderDistributionTrend,
-      trustScore: trustScore || 0,
-      dexscreener: tokenData.dexScreenerData,
-      position: latestTrade
-        ? {
-            token_address: latestTrade.token_address,
-            entry_price: latestTrade.buy_price,
-            size: latestTrade.buy_amount,
-            stop_loss: latestTrade.buy_price * 0.85, // 15% stop loss
-            take_profit: latestTrade.buy_price * 1.3, // 30% take profit
-            open_timeStamp: latestTrade.buy_timeStamp,
-            status: latestTrade.sell_timeStamp ? "CLOSED" : "OPEN",
-          }
-        : undefined,
-    };
+        elizaLogger.log(`Latest trade for ${tokenAddress}:`, latestTrade);
 
-    // Create initial state first
-    const state: State = await runtime.composeState({
-      userId: runtime.agentId,
-      agentId: runtime.agentId,
-      roomId: runtime.agentId,
-      content: {
-        text: `Initialize state for ${tokenAddress}`,
-        type: "analysis",
-      },
-    });
+        // Before creating analysisParams, get the correct chain balance
+        const walletBalance = await getChainWalletBalance(
+            runtime,
+            tokenAddress
+        );
 
-    // Then create analysis memory using state
-    const analysisMemory: Memory = {
-      userId: state.userId,
-      agentId: runtime.agentId,
-      roomId: state.roomId,
-      content: {
-        text: `Analyze trade for ${tokenAddress}`,
-        type: "analysis",
-      },
-    };
+        const pair = tokenData.dexScreenerData.pairs[0];
+        const analysisParams: AnalysisParams = {
+            walletBalance, // Now using the correct chain's balance
+            tokenAddress,
+            price: Number(pair?.priceUsd || 0),
+            volume: pair?.volume?.h24 || 0,
+            marketCap: pair?.marketCap || 0,
+            liquidity: pair?.liquidity?.usd || 0,
+            holderDistribution: tokenData.holderDistributionTrend,
+            trustScore: trustScore || 0,
+            dexscreener: tokenData.dexScreenerData,
+            position: latestTrade
+                ? {
+                      token_address: latestTrade.token_address,
+                      entry_price: latestTrade.buy_price,
+                      size: latestTrade.buy_amount,
+                      stop_loss: latestTrade.buy_price * 0.85, // 15% stop loss
+                      take_profit: latestTrade.buy_price * 1.3, // 30% take profit
+                      open_timeStamp: latestTrade.buy_timeStamp,
+                      status: latestTrade.sell_timeStamp ? "CLOSED" : "OPEN",
+                  }
+                : undefined,
+        };
 
-    // Update analysis result in cache after completion
-    const analysisResult = await analyzeTradeAction.handler(
-      runtime,
-      analysisMemory,
-      state,
-      analysisParams,
-      async (response) => {
-        if (!response) {
-          elizaLogger.error(`Empty response from analysis for ${tokenAddress}`);
-          return [];
-        }
+        // Create initial state first
+        const state: State = await runtime.composeState({
+            userId: runtime.agentId,
+            agentId: runtime.agentId,
+            roomId: runtime.agentId,
+            content: {
+                text: `Initialize state for ${tokenAddress}`,
+                type: "analysis",
+            },
+        });
 
-        elizaLogger.log(`Analysis result for ${tokenAddress}:`, response);
-        try {
-          // Parse the JSON response from the analysis
-          const result =
-            typeof response.text === "string"
-              ? JSON.parse(response.text)
-              : response.text;
-
-          if (!result) {
-            elizaLogger.error(`Invalid analysis result for ${tokenAddress}`);
-
-            return [];
-          }
-
-          if (result.shouldTrade && result.recommendedAction === "BUY") {
-            await buy({
-              result,
-              runtime,
-              state,
-              tokenAddress,
-              tokenData,
-              twitterService,
-              trustScore,
-            });
-          } else if (result.recommendedAction === "SELL") {
-            await sell({
-              latestTrade,
-              result,
-              runtime,
-              state,
-              tokenAddress,
-              tokenProvider,
-              trustScoreDb,
-              twitterService,
-              trustScore,
-            });
-          } else {
-            elizaLogger.log(
-              `Trade not recommended for ${tokenAddress}:`,
-              result
-            );
-          }
-        } catch (parseError) {}
-        return [];
-      }
-    );
-    cacheEntry.analysisResult = analysisResult;
-    tokenCache.set(tokenAddress, cacheEntry);
-  } catch (tokenError) {
-    elizaLogger.error(`Error processing token ${tokenAddress}:`, {
-      error: tokenError,
-      stack: tokenError instanceof Error ? tokenError.stack : undefined,
-    });
-    await new Promise((resolve) => setTimeout(resolve, 2000));
-  }
+        // Then create analysis memory using state
+        const analysisMemory: Memory = {
+            userId: state.userId,
+            agentId: runtime.agentId,
+            roomId: state.roomId,
+            content: {
+                text: `Analyze trade for ${tokenAddress}`,
+                type: "analysis",
+            },
+        };
+
+        // Update analysis result in cache after completion
+        const analysisResult = await analyzeTradeAction.handler(
+            runtime,
+            analysisMemory,
+            state,
+            analysisParams,
+            async (response) => {
+                if (!response) {
+                    elizaLogger.error(
+                        `Empty response from analysis for ${tokenAddress}`
+                    );
+                    return [];
+                }
+
+                elizaLogger.log(
+                    `Analysis result for ${tokenAddress}:`,
+                    response
+                );
+                try {
+                    // Parse the JSON response from the analysis
+                    const result =
+                        typeof response.text === "string"
+                            ? JSON.parse(response.text)
+                            : response.text;
+
+                    if (!result) {
+                        elizaLogger.error(
+                            `Invalid analysis result for ${tokenAddress}`
+                        );
+
+                        return [];
+                    }
+
+                    if (
+                        result.shouldTrade &&
+                        result.recommendedAction === "BUY"
+                    ) {
+                        await buy({
+                            result,
+                            runtime,
+                            state,
+                            tokenAddress,
+                            tokenData,
+                            twitterService,
+                            trustScore,
+                        });
+                    } else if (result.recommendedAction === "SELL") {
+                        await sell({
+                            latestTrade,
+                            result,
+                            runtime,
+                            state,
+                            tokenAddress,
+                            tokenProvider,
+                            trustScoreDb,
+                            twitterService,
+                            trustScore,
+                        });
+                    } else {
+                        elizaLogger.log(
+                            `Trade not recommended for ${tokenAddress}:`,
+                            result
+                        );
+                    }
+                } catch (parseError) {}
+                return [];
+            }
+        );
+        cacheEntry.analysisResult = analysisResult;
+        tokenCache.set(tokenAddress, cacheEntry);
+    } catch (tokenError) {
+        elizaLogger.error(`Error processing token ${tokenAddress}:`, {
+            error: tokenError,
+            stack: tokenError instanceof Error ? tokenError.stack : undefined,
+        });
+        await new Promise((resolve) => setTimeout(resolve, 2000));
+    }
 }
 
 async function buy({
-  runtime,
-  tokenAddress,
-  state,
-  tokenData,
-  result,
-  twitterService,
-  trustScore,
+    runtime,
+    tokenAddress,
+    state,
+    tokenData,
+    result,
+    twitterService,
+    trustScore,
 }: {
-  runtime: IAgentRuntime;
-  tokenAddress: string;
-  state: State;
-  tokenData: ProcessedTokenData;
-  result: any;
-  twitterService: TwitterService;
-  trustScore: number;
+    runtime: IAgentRuntime;
+    tokenAddress: string;
+    state: State;
+    tokenData: ProcessedTokenData;
+    result: any;
+    twitterService: TwitterService;
+    trustScore: number;
 }) {
-  elizaLogger.log(`Trade recommended for ${tokenAddress}:`, result);
+    elizaLogger.log(`Trade recommended for ${tokenAddress}:`, result);
 
-  // Continue with simulation if analysis recommends trading
-  const simulationService = new SimulationService();
-  const simulation = await simulationService.simulateTrade(
-    tokenAddress,
-    result.suggestedAmount || SAFETY_LIMITS.MINIMUM_TRADE
-  );
+    // Continue with simulation if analysis recommends trading
+    const simulationService = new SimulationService();
+    const simulation = await simulationService.simulateTrade(
+        tokenAddress,
+        result.suggestedAmount || SAFETY_LIMITS.MINIMUM_TRADE
+    );
 
-  if (simulation.recommendedAction === "EXECUTE") {
-    try {
-      // Check wallet balance before trade
-      const currentBalance = await getWalletBalance(runtime);
+    if (simulation.recommendedAction === "EXECUTE") {
+        try {
+            // Check wallet balance before trade
+            const currentBalance = await getWalletBalance(runtime);
 
-      const tradeAmount = Math.min(
-        result.suggestedAmount || SAFETY_LIMITS.MINIMUM_TRADE,
-        currentBalance * 0.95 // Leave some SOL for fees
-      );
+            const tradeAmount = Math.min(
+                result.suggestedAmount || SAFETY_LIMITS.MINIMUM_TRADE,
+                currentBalance * 0.95 // Leave some SOL for fees
+            );
 
-      if (tradeAmount < SAFETY_LIMITS.MINIMUM_TRADE) {
-        elizaLogger.warn(
-          `Insufficient balance for trade: ${currentBalance} SOL`
+            if (tradeAmount < SAFETY_LIMITS.MINIMUM_TRADE) {
+                elizaLogger.warn(
+                    `Insufficient balance for trade: ${currentBalance} SOL`
+                );
+            }
+
+            // Create trade memory object
+            const tradeMemory: Memory = {
+                userId: state.userId,
+                agentId: runtime.agentId,
+                roomId: state.roomId,
+                content: {
+                    text: `Execute trade for ${tokenAddress}`,
+                    tokenAddress,
+                    amount: SAFETY_LIMITS.MINIMUM_TRADE,
+                    action: "BUY",
+                    source: "system",
+                    type: "trade",
+                },
+            };
+
+            // Execute trade using our custom function
+            const tradeResult = await executeTrade(runtime, {
+                tokenAddress,
+                amount: tradeAmount,
+                slippage: tokenAddress.startsWith("0x") ? 0.03 : 0.3, // 3% for Base, 30% for Solana
+                chain: tokenAddress.startsWith("0x") ? "base" : "solana",
+            });
+
+            if (tradeResult.success) {
+                elizaLogger.log(
+                    `Trade executed successfully for ${tokenAddress}:`,
+                    {
+                        signature: tradeResult.signature,
+                        amount: tradeAmount,
+                        memory: tradeMemory,
+                    }
+                );
+
+                // Check rate limit before tweeting
+                if (twitterService && result.recommendedAction === "BUY") {
+                    await tweetTrade(twitterService, {
+                        token:
+                            tokenData.dexScreenerData.pairs[0]?.baseToken
+                                ?.symbol || tokenAddress,
+                        tokenAddress: tokenAddress,
+                        amount: tradeAmount,
+                        trustScore: Number(trustScore) || 0,
+                        riskLevel: result.riskLevel || "MEDIUM",
+                        marketData: {
+                            priceChange24h:
+                                tokenData.dexScreenerData.pairs[0]?.priceChange
+                                    ?.h24 || 0,
+                            volume24h:
+                                tokenData.dexScreenerData.pairs[0]?.volume
+                                    ?.h24 || 0,
+                            liquidity: {
+                                usd:
+                                    tokenData.dexScreenerData.pairs[0]
+                                        ?.liquidity?.usd || 0,
+                            },
+                        },
+                        timestamp: Date.now(),
+                        signature: tradeResult.signature,
+                        hash: tradeResult.hash,
+                        action: "BUY",
+                        price: Number(
+                            tokenData.dexScreenerData.pairs[0]?.priceUsd || 0
+                        ),
+                    });
+                } else {
+                    elizaLogger.log("Skipping tweet due to rate limit");
+                }
+
+                // Record trade using TrustScoreDatabase methods
+                const trustScoreDb = new TrustScoreDatabase(
+                    runtime.databaseAdapter.db
+                );
+
+                try {
+                    // Remove the PublicKey validation for Base addresses
+                    elizaLogger.log(
+                        `Attempting to validate token address: ${tokenAddress}`
+                    );
+                    const formattedAddress = tokenAddress.startsWith("0x")
+                        ? tokenAddress
+                        : new PublicKey(tokenAddress).toBase58(); // Only convert Solana addresses
+                    elizaLogger.log(
+                        `Token address validated successfully: ${formattedAddress}`
+                    );
+
+                    // Create a new recommender ID for this trade
+                    const uuid = uuidv4();
+                    const recommender =
+                        await trustScoreDb.getOrCreateRecommender({
+                            id: uuid,
+                            address: "",
+                            solanaPubkey:
+                                runtime.getSetting("WALLET_PUBLIC_KEY") || "",
+                        });
+                    elizaLogger.log(`Created/retrieved recommender:`, {
+                        recommender,
+                        chainType: tokenAddress.startsWith("0x")
+                            ? "base"
+                            : "solana",
+                    });
+
+                    // Prepare trade data
+                    const tradeData = {
+                        buy_amount: tradeAmount,
+                        is_simulation: false,
+                        token_address: new PublicKey(tokenAddress).toBase58(),
+                        buy_price:
+                            tokenData.dexScreenerData.pairs[0]?.priceUsd || 0,
+                        buy_timeStamp: new Date().toISOString(),
+                        buy_market_cap:
+                            tokenData.dexScreenerData.pairs[0]?.marketCap || 0,
+                        buy_liquidity:
+                            tokenData.dexScreenerData.pairs[0]?.liquidity
+                                ?.usd || 0,
+                        buy_value_usd:
+                            tradeAmount *
+                            Number(
+                                tokenData.dexScreenerData.pairs[0]?.priceUsd ||
+                                    0
+                            ),
+                    };
+                    elizaLogger.log(`Prepared trade data:`, tradeData);
+
+                    // Create trade record directly using trustScoreDb
+                    await trustScoreDb.addTradePerformance(
+                        {
+                            token_address: formattedAddress, // Use the properly formatted address
+                            recommender_id: recommender.id,
+                            buy_price: Number(tradeData.buy_price),
+                            buy_timeStamp: tradeData.buy_timeStamp,
+                            buy_amount: tradeData.buy_amount,
+                            buy_value_usd: tradeData.buy_value_usd,
+                            buy_market_cap: tradeData.buy_market_cap,
+                            buy_liquidity: tradeData.buy_liquidity,
+                            buy_sol: tradeAmount,
+                            last_updated: new Date().toISOString(),
+                            sell_price: 0,
+                            sell_timeStamp: "",
+                            sell_amount: 0,
+                            received_sol: 0,
+                            sell_value_usd: 0,
+                            sell_market_cap: 0,
+                            sell_liquidity: 0,
+                            profit_usd: 0,
+                            profit_percent: 0,
+                            market_cap_change: 0,
+                            liquidity_change: 0,
+                            rapidDump: false,
+                        },
+                        false
+                    );
+
+                    elizaLogger.log(
+                        `Successfully recorded trade performance for ${tokenAddress}`
+                    );
+                } catch (error) {
+                    elizaLogger.error("Failed to record trade performance:", {
+                        error,
+                        tokenAddress,
+                        errorMessage:
+                            error instanceof Error
+                                ? error.message
+                                : String(error),
+                        stack: error instanceof Error ? error.stack : undefined,
+                        errorType: error?.constructor?.name,
+                    });
+                }
+            } else {
+                elizaLogger.error(
+                    `Trade execution failed for ${tokenAddress}:`,
+                    tradeResult.error
+                );
+            }
+        } catch (tradeError) {
+            elizaLogger.error(
+                `Error during trade execution for ${tokenAddress}:`,
+                {
+                    error: tradeError,
+                    stack:
+                        tradeError instanceof Error
+                            ? tradeError.stack
+                            : undefined,
+                }
+            );
+        }
+    } else {
+        elizaLogger.log(
+            `Simulation rejected trade for ${tokenAddress}:`,
+            simulation
         );
-      }
+    }
+}
+
+async function sell({
+    state,
+    runtime,
+    tokenAddress,
+    tokenProvider,
+    twitterService,
+    trustScoreDb,
+    latestTrade,
+    result,
+    trustScore,
+}: {
+    state: State;
+    runtime: IAgentRuntime;
+    tokenAddress: string;
+    tokenProvider: TokenProvider;
+    twitterService: TwitterService;
+    trustScoreDb: TrustScoreDatabase;
+    result: any;
+    latestTrade: TradePerformance;
+    trustScore: number;
+}) {
+    // Get the trade amount from the latest trade
+    const tradeAmount = Number(latestTrade?.buy_amount || 0);
 
-      // Create trade memory object
-      const tradeMemory: Memory = {
+    // Create and save trade memory object for sell
+    const tradeMemory: Memory = {
         userId: state.userId,
         agentId: runtime.agentId,
         roomId: state.roomId,
         content: {
-          text: `Execute trade for ${tokenAddress}`,
-          tokenAddress,
-          amount: SAFETY_LIMITS.MINIMUM_TRADE,
-          action: "BUY",
-          source: "system",
-          type: "trade",
+            text: `Execute sell for ${tokenAddress}`,
+            tokenAddress,
+            amount: tradeAmount,
+            action: "SELL",
+            source: "system",
+            type: "trade",
         },
-      };
+    };
 
-      // Execute trade using our custom function
-      const tradeResult = await executeTrade(runtime, {
+    // Execute sell trade
+    const tradeResult = await executeTrade(runtime, {
         tokenAddress,
         amount: tradeAmount,
-        slippage: tokenAddress.startsWith("0x") ? 0.03 : 0.3, // 3% for Base, 30% for Solana
-        chain: tokenAddress.startsWith("0x") ? "base" : "solana",
-      });
-
-      if (tradeResult.success) {
-        elizaLogger.log(`Trade executed successfully for ${tokenAddress}:`, {
-          signature: tradeResult.signature,
-          amount: tradeAmount,
-          memory: tradeMemory,
-        });
+        slippage: 0.3, //  30% for Solana
+        chain: "solana",
+    });
 
-        // Check rate limit before tweeting
-        if (twitterService && result.recommendedAction === "BUY") {
-          await tweetTrade(twitterService, {
-            token:
-              tokenData.dexScreenerData.pairs[0]?.baseToken?.symbol ||
-              tokenAddress,
-            tokenAddress: tokenAddress,
-            amount: tradeAmount,
-            trustScore: Number(trustScore) || 0,
-            riskLevel: result.riskLevel || "MEDIUM",
-            marketData: {
-              priceChange24h:
-                tokenData.dexScreenerData.pairs[0]?.priceChange?.h24 || 0,
-              volume24h: tokenData.dexScreenerData.pairs[0]?.volume?.h24 || 0,
-              liquidity: {
-                usd: tokenData.dexScreenerData.pairs[0]?.liquidity?.usd || 0,
-              },
-            },
-            timestamp: Date.now(),
+    if (tradeResult.success) {
+        elizaLogger.log(`Sell executed successfully for ${tokenAddress}:`, {
             signature: tradeResult.signature,
-            hash: tradeResult.hash,
-            action: "BUY",
-            price: Number(tokenData.dexScreenerData.pairs[0]?.priceUsd || 0),
-          });
-        } else {
-          elizaLogger.log("Skipping tweet due to rate limit");
-        }
+            amount: tradeAmount,
+        });
 
-        // Record trade using TrustScoreDatabase methods
-        const trustScoreDb = new TrustScoreDatabase(runtime.databaseAdapter.db);
+        // Get token data first
+        const tokenData = await tokenProvider.getProcessedTokenData();
 
-        try {
-          // Remove the PublicKey validation for Base addresses
-          elizaLogger.log(
-            `Attempting to validate token address: ${tokenAddress}`
-          );
-          const formattedAddress = tokenAddress.startsWith("0x")
-            ? tokenAddress
-            : new PublicKey(tokenAddress).toBase58(); // Only convert Solana addresses
-          elizaLogger.log(
-            `Token address validated successfully: ${formattedAddress}`
-          );
-
-          // Create a new recommender ID for this trade
-          const uuid = uuidv4();
-          const recommender = await trustScoreDb.getOrCreateRecommender({
+        // Create recommender
+        const uuid = uuidv4();
+        const recommender = await trustScoreDb.getOrCreateRecommender({
             id: uuid,
-            address: "",
+            address: "", // Empty since we're only handling Solana
             solanaPubkey: runtime.getSetting("WALLET_PUBLIC_KEY") || "",
-          });
-          elizaLogger.log(`Created/retrieved recommender:`, {
-            recommender,
-            chainType: tokenAddress.startsWith("0x") ? "base" : "solana",
-          });
-
-          // Prepare trade data
-          const tradeData = {
-            buy_amount: tradeAmount,
-            is_simulation: false,
-            token_address: new PublicKey(tokenAddress).toBase58(),
-            buy_price: tokenData.dexScreenerData.pairs[0]?.priceUsd || 0,
-            buy_timeStamp: new Date().toISOString(),
-            buy_market_cap: tokenData.dexScreenerData.pairs[0]?.marketCap || 0,
-            buy_liquidity:
-              tokenData.dexScreenerData.pairs[0]?.liquidity?.usd || 0,
-            buy_value_usd:
-              tradeAmount *
-              Number(tokenData.dexScreenerData.pairs[0]?.priceUsd || 0),
-          };
-          elizaLogger.log(`Prepared trade data:`, tradeData);
-
-          // Create trade record directly using trustScoreDb
-          await trustScoreDb.addTradePerformance(
-            {
-              token_address: formattedAddress, // Use the properly formatted address
-              recommender_id: recommender.id,
-              buy_price: Number(tradeData.buy_price),
-              buy_timeStamp: tradeData.buy_timeStamp,
-              buy_amount: tradeData.buy_amount,
-              buy_value_usd: tradeData.buy_value_usd,
-              buy_market_cap: tradeData.buy_market_cap,
-              buy_liquidity: tradeData.buy_liquidity,
-              buy_sol: tradeAmount,
-              last_updated: new Date().toISOString(),
-              sell_price: 0,
-              sell_timeStamp: "",
-              sell_amount: 0,
-              received_sol: 0,
-              sell_value_usd: 0,
-              sell_market_cap: 0,
-              sell_liquidity: 0,
-              profit_usd: 0,
-              profit_percent: 0,
-              market_cap_change: 0,
-              liquidity_change: 0,
-              rapidDump: false,
-            },
-            false
-          );
-
-          elizaLogger.log(
-            `Successfully recorded trade performance for ${tokenAddress}`
-          );
-        } catch (error) {
-          elizaLogger.error("Failed to record trade performance:", {
-            error,
+        });
+
+        // Update sell details and get prices
+        const { sellDetails, currentPrice } = await updateSellDetails(
+            runtime,
             tokenAddress,
-            errorMessage:
-              error instanceof Error ? error.message : String(error),
-            stack: error instanceof Error ? error.stack : undefined,
-            errorType: error?.constructor?.name,
-          });
-        }
-      } else {
-        elizaLogger.error(
-          `Trade execution failed for ${tokenAddress}:`,
-          tradeResult.error
+            recommender.id,
+            tradeAmount,
+            latestTrade,
+            tokenData
         );
-      }
-    } catch (tradeError) {
-      elizaLogger.error(`Error during trade execution for ${tokenAddress}:`, {
-        error: tradeError,
-        stack: tradeError instanceof Error ? tradeError.stack : undefined,
-      });
-    }
-  } else {
-    elizaLogger.log(
-      `Simulation rejected trade for ${tokenAddress}:`,
-      simulation
-    );
-  }
-}
-
-async function sell({
-  state,
-  runtime,
-  tokenAddress,
-  tokenProvider,
-  twitterService,
-  trustScoreDb,
-  latestTrade,
-  result,
-  trustScore,
-}: {
-  state: State;
-  runtime: IAgentRuntime;
-  tokenAddress: string;
-  tokenProvider: TokenProvider;
-  twitterService: TwitterService;
-  trustScoreDb: TrustScoreDatabase;
-  result: any;
-  latestTrade: TradePerformance;
-  trustScore: number;
-}) {
-  // Get the trade amount from the latest trade
-  const tradeAmount = Number(latestTrade?.buy_amount || 0);
-
-  // Create and save trade memory object for sell
-  const tradeMemory: Memory = {
-    userId: state.userId,
-    agentId: runtime.agentId,
-    roomId: state.roomId,
-    content: {
-      text: `Execute sell for ${tokenAddress}`,
-      tokenAddress,
-      amount: tradeAmount,
-      action: "SELL",
-      source: "system",
-      type: "trade",
-    },
-  };
-
-  // Execute sell trade
-  const tradeResult = await executeTrade(runtime, {
-    tokenAddress,
-    amount: tradeAmount,
-    slippage: 0.3, //  30% for Solana
-    chain: "solana",
-  });
-
-  if (tradeResult.success) {
-    elizaLogger.log(`Sell executed successfully for ${tokenAddress}:`, {
-      signature: tradeResult.signature,
-      amount: tradeAmount,
-    });
-
-    // Get token data first
-    const tokenData = await tokenProvider.getProcessedTokenData();
-
-    // Create recommender
-    const uuid = uuidv4();
-    const recommender = await trustScoreDb.getOrCreateRecommender({
-      id: uuid,
-      address: "", // Empty since we're only handling Solana
-      solanaPubkey: runtime.getSetting("WALLET_PUBLIC_KEY") || "",
-    });
 
-    // Update sell details and get prices
-    const { sellDetails, currentPrice } = await updateSellDetails(
-      runtime,
-      tokenAddress,
-      recommender.id,
-      tradeAmount,
-      latestTrade,
-      tokenData
-    );
+        // Post tweet if enabled
+        if (twitterService) {
+            await tweetTrade(twitterService, {
+                token:
+                    tokenData.dexScreenerData.pairs[0]?.baseToken?.symbol ||
+                    tokenAddress,
+                tokenAddress: tokenAddress,
+                amount: tradeAmount,
+                trustScore: Number(trustScore) || 0,
+                riskLevel: result.riskLevel || "MEDIUM",
+                marketData: {
+                    priceChange24h:
+                        tokenData.dexScreenerData.pairs[0]?.priceChange?.h24 ||
+                        0,
+                    volume24h:
+                        tokenData.dexScreenerData.pairs[0]?.volume?.h24 || 0,
+                    liquidity: {
+                        usd:
+                            tokenData.dexScreenerData.pairs[0]?.liquidity
+                                ?.usd || 0,
+                    },
+                },
+                timestamp: Date.now(),
+                signature: tradeResult.signature,
+                hash: tradeResult.hash,
+                action: "SELL",
+                price: Number(currentPrice),
+                profitPercent: `${sellDetails.profit_percent.toFixed(2)}%`,
+                profitUsd: `${sellDetails.profit_usd.toFixed(4)} USD`,
+                reason: `P/L: ${sellDetails.profit_percent.toFixed(2)}%`,
+            });
+        }
 
-    // Post tweet if enabled
-    if (twitterService) {
-      await tweetTrade(twitterService, {
-        token:
-          tokenData.dexScreenerData.pairs[0]?.baseToken?.symbol || tokenAddress,
-        tokenAddress: tokenAddress,
-        amount: tradeAmount,
-        trustScore: Number(trustScore) || 0,
-        riskLevel: result.riskLevel || "MEDIUM",
-        marketData: {
-          priceChange24h:
-            tokenData.dexScreenerData.pairs[0]?.priceChange?.h24 || 0,
-          volume24h: tokenData.dexScreenerData.pairs[0]?.volume?.h24 || 0,
-          liquidity: {
-            usd: tokenData.dexScreenerData.pairs[0]?.liquidity?.usd || 0,
-          },
-        },
-        timestamp: Date.now(),
-        signature: tradeResult.signature,
-        hash: tradeResult.hash,
-        action: "SELL",
-        price: Number(currentPrice),
-        profitPercent: `${sellDetails.profit_percent.toFixed(2)}%`,
-        profitUsd: `${sellDetails.profit_usd.toFixed(4)} USD`,
-        reason: `P/L: ${sellDetails.profit_percent.toFixed(2)}%`,
-      });
+        elizaLogger.log(
+            `Successfully updated sell details for ${tokenAddress}`,
+            {
+                sellPrice: currentPrice,
+                sellAmount: tradeAmount,
+            }
+        );
+    } else {
+        elizaLogger.error(
+            `Sell execution failed for ${tokenAddress}:`,
+            tradeResult.error
+        );
     }
-
-    elizaLogger.log(`Successfully updated sell details for ${tokenAddress}`, {
-      sellPrice: currentPrice,
-      sellAmount: tradeAmount,
-    });
-  } else {
-    elizaLogger.error(
-      `Sell execution failed for ${tokenAddress}:`,
-      tradeResult.error
-    );
-  }
 }
 
 export default createRabbiTraderPlugin;
diff --git a/packages/plugin-rabbi-trader/src/services/simulationService.ts b/packages/plugin-rabbi-trader/src/services/simulationService.ts
index cf23a1c7e42..867b488c3c8 100644
--- a/packages/plugin-rabbi-trader/src/services/simulationService.ts
+++ b/packages/plugin-rabbi-trader/src/services/simulationService.ts
@@ -1,4 +1,4 @@
-import { elizaLogger } from "@ai16z/eliza";
+import { elizaLogger } from "@elizaos/core";
 import { TokenProvider } from "../providers/token";
 import { TrustScoreProvider } from "../providers/trustScoreProvider";
 
@@ -9,19 +9,24 @@ export class SimulationService {
         this.trustScoreProvider = new TrustScoreProvider();
     }
 
-    async simulateTrade(tokenAddress: string, amount: number): Promise<{
+    async simulateTrade(
+        tokenAddress: string,
+        amount: number
+    ): Promise<{
         expectedPrice: number;
         priceImpact: number;
         recommendedAction: "EXECUTE" | "ABORT";
         reason: string;
     }> {
         try {
-            const evaluation = await this.trustScoreProvider.evaluateToken(tokenAddress);
+            const evaluation =
+                await this.trustScoreProvider.evaluateToken(tokenAddress);
             const tokenProvider = new TokenProvider(tokenAddress);
             const tokenData = await tokenProvider.getProcessedTokenData();
 
             // Get liquidity from DexScreener data
-            const liquidity = tokenData.dexScreenerData.pairs[0]?.liquidity?.usd || 0;
+            const liquidity =
+                tokenData.dexScreenerData.pairs[0]?.liquidity?.usd || 0;
             const priceImpact = (amount / liquidity) * 100;
 
             let recommendedAction: "EXECUTE" | "ABORT" = "ABORT";
@@ -36,7 +41,7 @@ export class SimulationService {
                 expectedPrice: tokenData.tradeData.price,
                 priceImpact,
                 recommendedAction,
-                reason
+                reason,
             };
         } catch (error) {
             elizaLogger.error("Trade simulation failed:", error);
diff --git a/packages/plugin-rabbi-trader/src/tokenUtils.ts b/packages/plugin-rabbi-trader/src/tokenUtils.ts
index 703d6c4caf9..0e84ddac6fd 100644
--- a/packages/plugin-rabbi-trader/src/tokenUtils.ts
+++ b/packages/plugin-rabbi-trader/src/tokenUtils.ts
@@ -1,19 +1,19 @@
 import * as fs from "fs";
 import * as path from "path";
-import { elizaLogger } from "@elizaOS/core";
+import { elizaLogger } from "@elizaos/core";
 
 export function loadTokenAddresses(): string[] {
-  try {
-    const filePath = path.resolve(
-      process.cwd(),
-      "../characters/tokens/tokenaddresses.json",
-    );
-    const data = fs.readFileSync(filePath, "utf8");
-    const addresses = JSON.parse(data);
-    elizaLogger.log("Loaded token addresses:", addresses);
-    return addresses;
-  } catch (error) {
-    elizaLogger.error("Failed to load token addresses:", error);
-    throw new Error("Token addresses file not found or invalid");
-  }
+    try {
+        const filePath = path.resolve(
+            process.cwd(),
+            "../characters/tokens/tokenaddresses.json"
+        );
+        const data = fs.readFileSync(filePath, "utf8");
+        const addresses = JSON.parse(data);
+        elizaLogger.log("Loaded token addresses:", addresses);
+        return addresses;
+    } catch (error) {
+        elizaLogger.error("Failed to load token addresses:", error);
+        throw new Error("Token addresses file not found or invalid");
+    }
 }
diff --git a/packages/plugin-rabbi-trader/src/utils.ts b/packages/plugin-rabbi-trader/src/utils.ts
index da1c2126a9a..50d56c58094 100644
--- a/packages/plugin-rabbi-trader/src/utils.ts
+++ b/packages/plugin-rabbi-trader/src/utils.ts
@@ -1,168 +1,168 @@
-import { elizaLogger, IAgentRuntime, settings, State } from "@ai16z/eliza";
+import { elizaLogger, IAgentRuntime, settings, State } from "@elizaos/core";
 import { PublicKey } from "@solana/web3.js";
 import { PROVIDER_CONFIG } from "./config";
-import {
-  ANALYSIS_HISTORY_EXPIRY,
-} from "./constants";
+import { ANALYSIS_HISTORY_EXPIRY } from "./constants";
 
 export function isValidSolanaAddress(address: string): boolean {
-  try {
-
-    // Check if it's a valid Solana public key format
-    new PublicKey(address);
-    return true;
-  } catch {
-    return false;
-  }
+    try {
+        // Check if it's a valid Solana public key format
+        new PublicKey(address);
+        return true;
+    } catch {
+        return false;
+    }
 }
 
 export async function fetchWithRetry(
-  url: string,
-  options: RequestInit = {},
-  chain: "solana" | "base" = "solana",
+    url: string,
+    options: RequestInit = {},
+    chain: "solana" | "base" = "solana"
 ): Promise<any> {
-  let lastError: Error;
-
-  for (let i = 0; i < PROVIDER_CONFIG.MAX_RETRIES; i++) {
-    try {
-      elizaLogger.log(`Attempt ${i + 1} for ${url} with chain ${chain}`);
-
-      // Ensure headers are properly initialized
-      const headers = {
-        Accept: "application/json",
-        "x-chain": chain,
-        "X-API-KEY": settings.BIRDEYE_API_KEY || "",
-        ...options.headers,
-      };
-
+    let lastError: Error;
+
+    for (let i = 0; i < PROVIDER_CONFIG.MAX_RETRIES; i++) {
+        try {
+            elizaLogger.log(`Attempt ${i + 1} for ${url} with chain ${chain}`);
+
+            // Ensure headers are properly initialized
+            const headers = {
+                Accept: "application/json",
+                "x-chain": chain,
+                "X-API-KEY": settings.BIRDEYE_API_KEY || "",
+                ...options.headers,
+            };
+
+            const response = await fetch(url, {
+                ...options,
+                headers,
+            });
+
+            const responseText = await response.text();
+
+            if (!response.ok) {
+                throw new Error(
+                    `HTTP error! status: ${response.status}, message: ${responseText}`
+                );
+            }
+
+            try {
+                return JSON.parse(responseText);
+            } catch (parseError) {
+                throw new Error(
+                    `Failed to parse response: ${responseText}, error: ${parseError.message}`
+                );
+            }
+        } catch (error) {
+            elizaLogger.error(`Attempt ${i + 1} failed:`, {
+                error: error instanceof Error ? error.message : String(error),
+                url,
+                chain,
+                attempt: i + 1,
+            });
+            lastError =
+                error instanceof Error ? error : new Error(String(error));
+
+            if (i < PROVIDER_CONFIG.MAX_RETRIES - 1) {
+                await new Promise((resolve) =>
+                    setTimeout(
+                        resolve,
+                        PROVIDER_CONFIG.RETRY_DELAY * Math.pow(2, i)
+                    )
+                );
+                continue;
+            }
+        }
+    }
 
-      const response = await fetch(url, {
-        ...options,
-        headers,
-      });
+    throw lastError;
+}
 
-      const responseText = await response.text();
+export function decodeBase58(str: string): Uint8Array {
+    const ALPHABET =
+        "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
+    const ALPHABET_MAP = new Map(
+        ALPHABET.split("").map((c, i) => [c, BigInt(i)])
+    );
 
-      if (!response.ok) {
-        throw new Error(
-          `HTTP error! status: ${response.status}, message: ${responseText}`,
-        );
-      }
+    let result = BigInt(0);
+    for (const char of str) {
+        const value = ALPHABET_MAP.get(char);
+        if (value === undefined) throw new Error("Invalid base58 character");
+        result = result * BigInt(58) + value;
+    }
 
-      try {
-        return JSON.parse(responseText);
-      } catch (parseError) {
-        throw new Error(
-          `Failed to parse response: ${responseText}, error: ${parseError.message}`,
-        );
-      }
-    } catch (error) {
-      elizaLogger.error(`Attempt ${i + 1} failed:`, {
-        error: error instanceof Error ? error.message : String(error),
-        url,
-        chain,
-        attempt: i + 1,
-      });
-      lastError = error instanceof Error ? error : new Error(String(error));
-
-      if (i < PROVIDER_CONFIG.MAX_RETRIES - 1) {
-        await new Promise((resolve) =>
-          setTimeout(resolve, PROVIDER_CONFIG.RETRY_DELAY * Math.pow(2, i)),
-        );
-        continue;
-      }
+    const bytes = [];
+    while (result > 0n) {
+        bytes.unshift(Number(result & 0xffn));
+        result = result >> 8n;
     }
-  }
 
-  throw lastError;
-}
+    for (let i = 0; i < str.length && str[i] === "1"; i++) {
+        bytes.unshift(0);
+    }
 
-export function decodeBase58(str: string): Uint8Array {
-  const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
-  const ALPHABET_MAP = new Map(
-    ALPHABET.split("").map((c, i) => [c, BigInt(i)]),
-  );
-
-  let result = BigInt(0);
-  for (const char of str) {
-    const value = ALPHABET_MAP.get(char);
-    if (value === undefined) throw new Error("Invalid base58 character");
-    result = result * BigInt(58) + value;
-  }
-
-  const bytes = [];
-  while (result > 0n) {
-    bytes.unshift(Number(result & 0xffn));
-    result = result >> 8n;
-  }
-
-  for (let i = 0; i < str.length && str[i] === "1"; i++) {
-    bytes.unshift(0);
-  }
-
-  return new Uint8Array(bytes);
+    return new Uint8Array(bytes);
 }
 
-
 interface AnalyzedToken {
-  address: string;
-  timestamp: number;
-  symbol: string;
+    address: string;
+    timestamp: number;
+    symbol: string;
 }
 
 export async function manageAnalyzedTokens(
-  runtime: IAgentRuntime,
-  state: any,
-  newToken?: AnalyzedToken,
+    runtime: IAgentRuntime,
+    state: any,
+    newToken?: AnalyzedToken
 ): Promise<AnalyzedToken[]> {
-  try {
-    const historyKey = "analyzed_tokens_history";
-    let history: AnalyzedToken[] = [];
+    try {
+        const historyKey = "analyzed_tokens_history";
+        let history: AnalyzedToken[] = [];
 
-    if (!state) {
-      state = {};
-    }
+        if (!state) {
+            state = {};
+        }
 
-    if (state[historyKey]) {
-      try {
-        const parsed = JSON.parse(state[historyKey]);
-        if (Array.isArray(parsed)) {
-          history = parsed;
+        if (state[historyKey]) {
+            try {
+                const parsed = JSON.parse(state[historyKey]);
+                if (Array.isArray(parsed)) {
+                    history = parsed;
+                }
+            } catch (e) {
+                elizaLogger.warn("Failed to parse history, resetting", e);
+            }
         }
-      } catch (e) {
-        elizaLogger.warn("Failed to parse history, resetting", e);
-      }
-    }
 
-    const now = Date.now();
-    history = history.filter(
-      (token) =>
-        token &&
-        token.timestamp &&
-        now - token.timestamp < ANALYSIS_HISTORY_EXPIRY,
-    );
+        const now = Date.now();
+        history = history.filter(
+            (token) =>
+                token &&
+                token.timestamp &&
+                now - token.timestamp < ANALYSIS_HISTORY_EXPIRY
+        );
 
-    if (newToken) {
-      history.push(newToken);
-    }
+        if (newToken) {
+            history.push(newToken);
+        }
 
-    // Update state with roomId
-    state = await runtime.updateRecentMessageState({
-      ...state,
-      userId: runtime.agentId,
-      agentId: runtime.agentId,
-      roomId: runtime.agentId,
-      content: {
-        ...state.content,
-        [historyKey]: JSON.stringify(history),
-      },
-    } as State);
-
-    return history;
-  } catch (error) {
-    elizaLogger.error("Failed to manage analyzed tokens history:", {
-      error: error instanceof Error ? error.message : error,
-    });
-    return [];
-  }
+        // Update state with roomId
+        state = await runtime.updateRecentMessageState({
+            ...state,
+            userId: runtime.agentId,
+            agentId: runtime.agentId,
+            roomId: runtime.agentId,
+            content: {
+                ...state.content,
+                [historyKey]: JSON.stringify(history),
+            },
+        } as State);
+
+        return history;
+    } catch (error) {
+        elizaLogger.error("Failed to manage analyzed tokens history:", {
+            error: error instanceof Error ? error.message : error,
+        });
+        return [];
+    }
 }
diff --git a/packages/plugin-rabbi-trader/src/wallet.ts b/packages/plugin-rabbi-trader/src/wallet.ts
index 9235e8ff0ef..326d6b1b7b9 100644
--- a/packages/plugin-rabbi-trader/src/wallet.ts
+++ b/packages/plugin-rabbi-trader/src/wallet.ts
@@ -1,12 +1,7 @@
-import { elizaLogger, IAgentRuntime } from "@elizaOS/core";
-import {
-  Connection,
-  Keypair,
-  VersionedTransaction,
-} from "@solana/web3.js";
+import { elizaLogger, IAgentRuntime } from "@elizaos/core";
+import { Connection, Keypair, VersionedTransaction } from "@solana/web3.js";
 import { decodeBase58 } from "./utils";
-import {  SAFETY_LIMITS } from "./constants";
-
+import { SAFETY_LIMITS } from "./constants";
 
 /**
  * Gets wallet keypair from runtime settings
@@ -15,20 +10,20 @@ import {  SAFETY_LIMITS } from "./constants";
  * @throws Error if private key is missing or invalid
  */
 export function getWalletKeypair(runtime?: IAgentRuntime): Keypair {
-  // Check chain type from token address or configuration
-
-  const privateKeyString = runtime?.getSetting("WALLET_PRIVATE_KEY");
-  if (!privateKeyString) {
-    throw new Error("No wallet private key configured");
-  }
-
-  try {
-    const privateKeyBytes = decodeBase58(privateKeyString);
-    return Keypair.fromSecretKey(privateKeyBytes);
-  } catch (error) {
-    elizaLogger.error("Failed to create wallet keypair:", error);
-    throw error;
-  }
+    // Check chain type from token address or configuration
+
+    const privateKeyString = runtime?.getSetting("WALLET_PRIVATE_KEY");
+    if (!privateKeyString) {
+        throw new Error("No wallet private key configured");
+    }
+
+    try {
+        const privateKeyBytes = decodeBase58(privateKeyString);
+        return Keypair.fromSecretKey(privateKeyBytes);
+    } catch (error) {
+        elizaLogger.error("Failed to create wallet keypair:", error);
+        throw error;
+    }
 }
 
 /**
@@ -37,243 +32,245 @@ export function getWalletKeypair(runtime?: IAgentRuntime): Keypair {
  * @returns Balance in SOL
  */
 export async function getWalletBalance(
-  runtime: IAgentRuntime,
+    runtime: IAgentRuntime
 ): Promise<number> {
-  try {
-
-    // Existing Solana balance logic
-    const walletKeypair = getWalletKeypair(runtime);
-    const walletPubKey = walletKeypair.publicKey;
-    const connection = new Connection(
-      runtime.getSetting("RPC_URL") || "https://api.mainnet-beta.solana.com",
-    );
-
-    const balance = await connection.getBalance(walletPubKey);
-    const solBalance = balance / 1e9;
-
-    elizaLogger.log("Fetched Solana wallet balance:", {
-      address: walletPubKey.toBase58(),
-      lamports: balance,
-      sol: solBalance,
-    });
-
-    return solBalance;
-  } catch (error) {
-    elizaLogger.error("Failed to get wallet balance:", error);
-    return 0;
-  }
+    try {
+        // Existing Solana balance logic
+        const walletKeypair = getWalletKeypair(runtime);
+        const walletPubKey = walletKeypair.publicKey;
+        const connection = new Connection(
+            runtime.getSetting("RPC_URL") ||
+                "https://api.mainnet-beta.solana.com"
+        );
+
+        const balance = await connection.getBalance(walletPubKey);
+        const solBalance = balance / 1e9;
+
+        elizaLogger.log("Fetched Solana wallet balance:", {
+            address: walletPubKey.toBase58(),
+            lamports: balance,
+            sol: solBalance,
+        });
+
+        return solBalance;
+    } catch (error) {
+        elizaLogger.error("Failed to get wallet balance:", error);
+        return 0;
+    }
 }
 
 // Add helper function to get connection
 async function getConnection(runtime: IAgentRuntime): Promise<Connection> {
-  return new Connection(
-    runtime.getSetting("RPC_URL") || "https://api.mainnet-beta.solana.com",
-  );
+    return new Connection(
+        runtime.getSetting("RPC_URL") || "https://api.mainnet-beta.solana.com"
+    );
 }
 
 // Add executeTrade function
 export async function executeTrade(
-  runtime: IAgentRuntime,
-  params: {
-    tokenAddress: string;
-    amount: number;
-    slippage: number;
-    isSell?: boolean;
-    chain?: "base" | "solana";
-  },
-  retryCount = 0,
+    runtime: IAgentRuntime,
+    params: {
+        tokenAddress: string;
+        amount: number;
+        slippage: number;
+        isSell?: boolean;
+        chain?: "base" | "solana";
+    },
+    retryCount = 0
 ): Promise<any> {
-
-  // Existing Solana trade logic remains unchanged
-  try {
-    elizaLogger.log("Executing Solana trade with params:", params);
-
-    const SOL_ADDRESS = "So11111111111111111111111111111111111111112";
-
-    if (!params.isSell && params.amount < SAFETY_LIMITS.MINIMUM_TRADE) {
-      elizaLogger.warn("Trade amount too small:", {
-        amount: params.amount,
-        minimumRequired: SAFETY_LIMITS.MINIMUM_TRADE,
-      });
-      return {
-        success: false,
-        error: "Trade amount too small",
-        details: {
-          amount: params.amount,
-          minimumRequired: SAFETY_LIMITS.MINIMUM_TRADE,
-        },
-      };
+    // Existing Solana trade logic remains unchanged
+    try {
+        elizaLogger.log("Executing Solana trade with params:", params);
+
+        const SOL_ADDRESS = "So11111111111111111111111111111111111111112";
+
+        if (!params.isSell && params.amount < SAFETY_LIMITS.MINIMUM_TRADE) {
+            elizaLogger.warn("Trade amount too small:", {
+                amount: params.amount,
+                minimumRequired: SAFETY_LIMITS.MINIMUM_TRADE,
+            });
+            return {
+                success: false,
+                error: "Trade amount too small",
+                details: {
+                    amount: params.amount,
+                    minimumRequired: SAFETY_LIMITS.MINIMUM_TRADE,
+                },
+            };
+        }
+
+        const walletKeypair = getWalletKeypair(runtime);
+        const connection = await getConnection(runtime);
+
+        // Setup swap parameters
+        const inputTokenCA = params.isSell ? params.tokenAddress : SOL_ADDRESS;
+        const outputTokenCA = params.isSell ? SOL_ADDRESS : params.tokenAddress;
+        const swapAmount = Math.floor(params.amount * 1e9);
+
+        elizaLogger.log("Trade execution details:", {
+            isSell: params.isSell,
+            inputToken: inputTokenCA,
+            outputToken: outputTokenCA,
+            amount: params.amount,
+            slippage: params.slippage,
+        });
+
+        // Get quote
+        const quoteResponse = await fetch(
+            `https://quote-api.jup.ag/v6/quote?inputMint=${inputTokenCA}&outputMint=${outputTokenCA}&amount=${swapAmount}&slippageBps=${Math.floor(params.slippage * 10000)}`
+        );
+
+        if (!quoteResponse.ok) {
+            const error = await quoteResponse.text();
+            elizaLogger.warn("Quote request failed:", {
+                status: quoteResponse.status,
+                error,
+            });
+            return {
+                success: false,
+                error: "Failed to get quote",
+                details: { status: quoteResponse.status, error },
+            };
+        }
+
+        const quoteData = await quoteResponse.json();
+        if (!quoteData || quoteData.error) {
+            elizaLogger.warn("Invalid quote data:", quoteData);
+            return {
+                success: false,
+                error: "Invalid quote data",
+                details: quoteData,
+            };
+        }
+
+        elizaLogger.log("Quote received:", quoteData);
+
+        // Get swap transaction
+        const swapResponse = await fetch("https://quote-api.jup.ag/v6/swap", {
+            method: "POST",
+            headers: { "Content-Type": "application/json" },
+            body: JSON.stringify({
+                quoteResponse: quoteData,
+                userPublicKey: walletKeypair.publicKey.toString(),
+                wrapAndUnwrapSol: true,
+                computeUnitPriceMicroLamports: 2000000,
+                dynamicComputeUnitLimit: true,
+            }),
+        });
+
+        const swapData = await swapResponse.json();
+        if (!swapData?.swapTransaction) {
+            throw new Error("No swap transaction returned");
+        }
+
+        elizaLogger.log("Swap transaction received");
+
+        // Deserialize transaction
+        const transactionBuf = Buffer.from(swapData.swapTransaction, "base64");
+        const tx = VersionedTransaction.deserialize(transactionBuf);
+
+        // Get fresh blockhash and sign transaction
+        const { blockhash, lastValidBlockHeight } =
+            await connection.getLatestBlockhash("finalized");
+        tx.message.recentBlockhash = blockhash;
+        tx.sign([walletKeypair]);
+
+        // Send with confirmation using more lenient settings
+        const signature = await connection.sendTransaction(tx, {
+            skipPreflight: false,
+            maxRetries: 5,
+            preflightCommitment: "processed",
+        });
+
+        elizaLogger.log("Transaction sent:", signature);
+
+        // Wait for confirmation with more lenient settings
+        const confirmation = await connection.confirmTransaction(
+            {
+                signature,
+                blockhash,
+                lastValidBlockHeight,
+            },
+            "processed"
+        ); // Use 'processed' instead of default 'finalized'
+
+        if (confirmation.value.err) {
+            throw new Error(`Transaction failed: ${confirmation.value.err}`);
+        }
+
+        // Add additional verification
+        const status = await connection.getSignatureStatus(signature);
+        if (status.value?.err) {
+            throw new Error(
+                `Transaction verification failed: ${status.value.err}`
+            );
+        }
+
+        elizaLogger.log("Solana trade executed successfully:", {
+            signature,
+            explorer: `https://solscan.io/tx/${signature}`,
+        });
+
+        return {
+            success: true,
+            signature,
+            confirmation,
+            explorer: `https://solscan.io/tx/${signature}`,
+        };
+    } catch (error) {
+        // Handle blockhash errors with retry and longer timeout
+        if (
+            (error.message?.includes("Blockhash not found") ||
+                error.message?.includes("block height exceeded")) &&
+            retryCount < 3
+        ) {
+            elizaLogger.warn(
+                `Transaction error, retrying (${retryCount + 1}/3)...`
+            );
+            await new Promise((resolve) => setTimeout(resolve, 5000)); // Longer delay between retries
+            return executeTrade(runtime, params, retryCount + 1);
+        }
+
+        elizaLogger.error("Trade execution failed:", {
+            error: error instanceof Error ? error.message : error,
+            stack: error instanceof Error ? error.stack : undefined,
+            params,
+            retryCount,
+        });
+
+        return {
+            success: false,
+            error: error.message || error,
+            params,
+            stack: error instanceof Error ? error.stack : undefined,
+        };
     }
-
-    const walletKeypair = getWalletKeypair(runtime);
-    const connection = await getConnection(runtime);
-
-    // Setup swap parameters
-    const inputTokenCA = params.isSell ? params.tokenAddress : SOL_ADDRESS;
-    const outputTokenCA = params.isSell ? SOL_ADDRESS : params.tokenAddress;
-    const swapAmount = Math.floor(params.amount * 1e9);
-
-    elizaLogger.log("Trade execution details:", {
-      isSell: params.isSell,
-      inputToken: inputTokenCA,
-      outputToken: outputTokenCA,
-      amount: params.amount,
-      slippage: params.slippage,
-    });
-
-    // Get quote
-    const quoteResponse = await fetch(
-      `https://quote-api.jup.ag/v6/quote?inputMint=${inputTokenCA}&outputMint=${outputTokenCA}&amount=${swapAmount}&slippageBps=${Math.floor(params.slippage * 10000)}`,
-    );
-
-    if (!quoteResponse.ok) {
-      const error = await quoteResponse.text();
-      elizaLogger.warn("Quote request failed:", {
-        status: quoteResponse.status,
-        error,
-      });
-      return {
-        success: false,
-        error: "Failed to get quote",
-        details: { status: quoteResponse.status, error },
-      };
-    }
-
-    const quoteData = await quoteResponse.json();
-    if (!quoteData || quoteData.error) {
-      elizaLogger.warn("Invalid quote data:", quoteData);
-      return {
-        success: false,
-        error: "Invalid quote data",
-        details: quoteData,
-      };
-    }
-
-    elizaLogger.log("Quote received:", quoteData);
-
-    // Get swap transaction
-    const swapResponse = await fetch("https://quote-api.jup.ag/v6/swap", {
-      method: "POST",
-      headers: { "Content-Type": "application/json" },
-      body: JSON.stringify({
-        quoteResponse: quoteData,
-        userPublicKey: walletKeypair.publicKey.toString(),
-        wrapAndUnwrapSol: true,
-        computeUnitPriceMicroLamports: 2000000,
-        dynamicComputeUnitLimit: true,
-      }),
-    });
-
-    const swapData = await swapResponse.json();
-    if (!swapData?.swapTransaction) {
-      throw new Error("No swap transaction returned");
-    }
-
-    elizaLogger.log("Swap transaction received");
-
-    // Deserialize transaction
-    const transactionBuf = Buffer.from(swapData.swapTransaction, "base64");
-    const tx = VersionedTransaction.deserialize(transactionBuf);
-
-    // Get fresh blockhash and sign transaction
-    const { blockhash, lastValidBlockHeight } =
-      await connection.getLatestBlockhash("finalized");
-    tx.message.recentBlockhash = blockhash;
-    tx.sign([walletKeypair]);
-
-    // Send with confirmation using more lenient settings
-    const signature = await connection.sendTransaction(tx, {
-      skipPreflight: false,
-      maxRetries: 5,
-      preflightCommitment: "processed",
-    });
-
-    elizaLogger.log("Transaction sent:", signature);
-
-    // Wait for confirmation with more lenient settings
-    const confirmation = await connection.confirmTransaction(
-      {
-        signature,
-        blockhash,
-        lastValidBlockHeight,
-      },
-      "processed",
-    ); // Use 'processed' instead of default 'finalized'
-
-    if (confirmation.value.err) {
-      throw new Error(`Transaction failed: ${confirmation.value.err}`);
-    }
-
-    // Add additional verification
-    const status = await connection.getSignatureStatus(signature);
-    if (status.value?.err) {
-      throw new Error(`Transaction verification failed: ${status.value.err}`);
-    }
-
-    elizaLogger.log("Solana trade executed successfully:", {
-      signature,
-      explorer: `https://solscan.io/tx/${signature}`,
-    });
-
-    return {
-      success: true,
-      signature,
-      confirmation,
-      explorer: `https://solscan.io/tx/${signature}`,
-    };
-  } catch (error) {
-    // Handle blockhash errors with retry and longer timeout
-    if (
-      (error.message?.includes("Blockhash not found") ||
-        error.message?.includes("block height exceeded")) &&
-      retryCount < 3
-    ) {
-      elizaLogger.warn(`Transaction error, retrying (${retryCount + 1}/3)...`);
-      await new Promise((resolve) => setTimeout(resolve, 5000)); // Longer delay between retries
-      return executeTrade(runtime, params, retryCount + 1);
-    }
-
-    elizaLogger.error("Trade execution failed:", {
-      error: error instanceof Error ? error.message : error,
-      stack: error instanceof Error ? error.stack : undefined,
-      params,
-      retryCount,
-    });
-
-    return {
-      success: false,
-      error: error.message || error,
-      params,
-      stack: error instanceof Error ? error.stack : undefined,
-    };
-  }
 }
 
-
 export async function getChainWalletBalance(
-  runtime: IAgentRuntime,
-  tokenAddress: string,
+    runtime: IAgentRuntime,
+    tokenAddress: string
 ): Promise<number> {
-     // Get Solana balance
+    // Get Solana balance
     return await getWalletBalance(runtime);
-  }
+}
 
 // Add this helper function at the top level
 export async function simulateTransaction(
-  client: any,
-  tx: any,
+    client: any,
+    tx: any
 ): Promise<string> {
-  try {
-    const result = await client.call({
-      account: client.account,
-      to: tx.to,
-      data: tx.data,
-      value: tx.value,
-      gas: tx.gas,
-      gasPrice: tx.gasPrice,
-    });
-    return result;
-  } catch (error) {
-    return `Simulation failed: ${error.message}`;
-  }
+    try {
+        const result = await client.call({
+            account: client.account,
+            to: tx.to,
+            data: tx.data,
+            value: tx.value,
+            gas: tx.gas,
+            gasPrice: tx.gasPrice,
+        });
+        return result;
+    } catch (error) {
+        return `Simulation failed: ${error.message}`;
+    }
 }
diff --git a/packages/plugin-solana/src/index.ts b/packages/plugin-solana/src/index.ts
index b207ed260ba..ecfe801ef32 100644
--- a/packages/plugin-solana/src/index.ts
+++ b/packages/plugin-solana/src/index.ts
@@ -15,8 +15,9 @@ import { trustScoreProvider } from "./providers/trustScoreProvider.ts";
 import { trustEvaluator } from "./evaluators/trust.ts";
 import { TokenProvider } from "./providers/token.ts";
 import { WalletProvider } from "./providers/wallet.ts";
+import { getTokenBalance, getTokenBalances } from "./providers/tokenUtils.ts";
 
-export { TokenProvider, WalletProvider };
+export { TokenProvider, WalletProvider, getTokenBalance, getTokenBalances };
 
 export const solanaPlugin: Plugin = {
     name: "solana",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 382a8d5df46..b456169188b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1290,7 +1290,7 @@ importers:
         specifier: 8.3.5
         version: 8.3.5(@swc/core@1.10.6(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.7.0)
 
-  packages/plugin-coinprice:
+  packages/plugin-coinmarketcap:
     dependencies:
       '@elizaos/core':
         specifier: workspace:*
@@ -1306,7 +1306,7 @@ importers:
         specifier: ^8.3.5
         version: 8.3.5(@swc/core@1.10.6(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.7.0)
 
-  packages/plugin-coinmarketcap:
+  packages/plugin-coinprice:
     dependencies:
       '@elizaos/core':
         specifier: workspace:*
@@ -1320,7 +1320,7 @@ importers:
     devDependencies:
       tsup:
         specifier: ^8.3.5
-        version: 8.3.5(@swc/core@1.10.4(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.6.3)(yaml@2.7.0)
+        version: 8.3.5(@swc/core@1.10.6(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.7.0)
 
   packages/plugin-conflux:
     dependencies:
@@ -2019,6 +2019,57 @@ importers:
         specifier: ^3.22.4
         version: 3.23.8
 
+  packages/plugin-rabbi-trader:
+    dependencies:
+      '@elizaos/client-twitter':
+        specifier: workspace:*
+        version: link:../client-twitter
+      '@elizaos/core':
+        specifier: workspace:*
+        version: link:../core
+      '@elizaos/plugin-solana':
+        specifier: workspace:*
+        version: link:../plugin-solana
+      '@elizaos/plugin-trustdb':
+        specifier: workspace:*
+        version: link:../plugin-trustdb
+      '@goat-sdk/core':
+        specifier: 0.3.8
+        version: 0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10)
+      '@goat-sdk/plugin-coingecko':
+        specifier: 0.1.4
+        version: 0.1.4(@goat-sdk/core@0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8))
+      '@goat-sdk/plugin-erc20':
+        specifier: 0.1.7
+        version: 0.1.7(@goat-sdk/core@0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8))
+      '@goat-sdk/wallet-viem':
+        specifier: 0.1.3
+        version: 0.1.3(@goat-sdk/core@0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8))
+      '@solana/web3.js':
+        specifier: ^1.87.6
+        version: 1.95.8(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)
+      bignumber:
+        specifier: 1.1.0
+        version: 1.1.0
+      bignumber.js:
+        specifier: 9.1.2
+        version: 9.1.2
+      node-cache:
+        specifier: ^5.1.2
+        version: 5.1.2
+      tsup:
+        specifier: 8.3.5
+        version: 8.3.5(@swc/core@1.10.6(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.2)(yaml@2.7.0)
+      whatwg-url:
+        specifier: 7.1.0
+        version: 7.1.0
+      ws:
+        specifier: ^8.0.0
+        version: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
+      zod:
+        specifier: 3.23.8
+        version: 3.23.8
+
   packages/plugin-solana:
     dependencies:
       '@coral-xyz/anchor':
@@ -2488,8 +2539,8 @@ packages:
     peerDependencies:
       zod: ^3.0.0
 
-  '@ai-sdk/openai@1.0.14':
-    resolution: {integrity: sha512-uyOkQNtYsHr4qyV7y0rmMAtdW4LTJoThYo1qXcvQa30RDh/MyvLEOjKYX181Siyp8LcTqYvwf6Tt+eckdVTTug==}
+  '@ai-sdk/openai@1.0.15':
+    resolution: {integrity: sha512-acX2crxBrkyfIlTtJGGX/YD/ck6L+LpPdaYQqGiahacHX07yn1nUE1jlnNLmTnDFoMwgxJXXt/wI16LC3ybYZg==}
     engines: {node: '>=18'}
     peerDependencies:
       zod: ^3.0.0
@@ -5446,9 +5497,26 @@ packages:
       '@goat-sdk/core': 0.4.0
       ai: 4.0.3
 
+  '@goat-sdk/core@0.3.8':
+    resolution: {integrity: sha512-1H8Cziyjj3bN78M4GETGN8+/fAQhtTPqMowSyAgIZtC/MGWvf41H2SR0FNba/xhfCOALhb0UfhGOsXCswvM5iA==}
+    engines: {node: '>=20.12.2 <21', npm: please-use-pnpm, pnpm: '>=9', yarn: please-use-pnpm}
+
   '@goat-sdk/core@0.4.0':
     resolution: {integrity: sha512-x7TVQ+3IS8bS+44O+ZkbS2R6IDXO0dOcRNWe5psU8Aqrb7/48Fe1ILN2Pif0sv34y1WkPYPlqoPINl/TiatIVQ==}
 
+  '@goat-sdk/plugin-coingecko@0.1.4':
+    resolution: {integrity: sha512-i85v/SeCXB7/fcqZKc0hV68/3FrUAHJSL4N5AUp5OPauzV5kq4Ecn0WjeDZEHX8iCEEY1NZSZ47yweDckAhjhA==}
+    peerDependencies:
+      '@goat-sdk/core': 0.3.14
+      viem: 2.21.58
+
+  '@goat-sdk/plugin-erc20@0.1.7':
+    resolution: {integrity: sha512-UDd6pXIBmpCWW7QIFxM5rJPta4tWqkys8P1sAt1kqabAndx+GaczhNUPwSdV1MH77BNtcyGZ6+HoeirskiV//Q==}
+    engines: {node: '>=20.12.2 <21', npm: please-use-pnpm, pnpm: '>=9', yarn: please-use-pnpm}
+    peerDependencies:
+      '@goat-sdk/core': 0.3.8
+      viem: 2.21.58
+
   '@goat-sdk/plugin-erc20@0.2.2':
     resolution: {integrity: sha512-uobj8A2GRAHAU8PNY9Be0iA8p+311zRDIRKHRQX0uooCWD4CxD6iMj99Q4RvBl8Es+Kc7JMQPRoZzMLawJUSJw==}
     peerDependencies:
@@ -5466,6 +5534,13 @@ packages:
     peerDependencies:
       '@goat-sdk/core': 0.4.0
 
+  '@goat-sdk/wallet-viem@0.1.3':
+    resolution: {integrity: sha512-2uofsH/dVmeJk/4V2/tJ1rDk6/ZFQlthUO50tg366hjq0vjINJXMQqYGwSLnv5Z3PMmdfPCSd5xikFEfA+1ZZw==}
+    engines: {node: '>=20.12.2 <21', npm: please-use-pnpm, pnpm: '>=9', yarn: please-use-pnpm}
+    peerDependencies:
+      '@goat-sdk/core': 0.3.4
+      viem: 2.21.58
+
   '@goat-sdk/wallet-viem@0.2.0':
     resolution: {integrity: sha512-x9FTUg9/ZhJyx8tQMAuIGmoFfRkmyDge78yvd9CTK6SQTiYQ/Hio7rAmHjLE95lElXb6EumZu7R0IlX3m/SGSw==}
     peerDependencies:
@@ -5816,8 +5891,8 @@ packages:
     peerDependencies:
       '@langchain/core': '>=0.2.31 <0.4.0'
 
-  '@langchain/langgraph-sdk@0.0.33':
-    resolution: {integrity: sha512-l/hRbI6roLzplBXy2VyDUwqY1TkK7RcjPmrMUuVdvCCH4LTwLfIXh/G1kHatNiN7VUTskw0FkfBbgq6gtj0ang==}
+  '@langchain/langgraph-sdk@0.0.34':
+    resolution: {integrity: sha512-Pjnuz2fDK/Ud11bld2dhqA2hLQ9png3fHWfITfxm3plBCtdpFWmOMH4mbHcmgCSTlZXVQv1rIpctPI3E/4sp5A==}
 
   '@langchain/langgraph@0.2.39':
     resolution: {integrity: sha512-zoQT5LViPlB5hRS7RNwixcAonUBAHcW+IzVkGR/4vcKoE49z5rPBdZsWjJ6b1YIV1K2bdSDJWl5KSEHilvnR1Q==}
@@ -8440,8 +8515,8 @@ packages:
     resolution: {integrity: sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==}
     engines: {node: '>=18.0.0'}
 
-  '@smithy/util-waiter@4.0.0':
-    resolution: {integrity: sha512-C8dSfGmZH0ecrmnJOw4aDXJ47krihnUtee8eDZ2fA+28wTjD4TVM3L/bBQYnBBlDVWcYzldLV7loPRsPc1kERg==}
+  '@smithy/util-waiter@4.0.1':
+    resolution: {integrity: sha512-PiLI5OMSDOw0IyA+lB8Ta0CIgaJuIyXE97Khvrk1G1ab71WbMTruzLKP9j3nS6QJScGirkUVN9sTOhZHU8q3OQ==}
     engines: {node: '>=18.0.0'}
 
   '@solana-developers/helpers@2.5.6':
@@ -13245,8 +13320,8 @@ packages:
     resolution: {integrity: sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA==}
     engines: {node: '>=18'}
 
-  flash-sdk@2.25.0:
-    resolution: {integrity: sha512-n7SUVztt/E3s0i6Nfh/tuRi9IEe8kYLyIhyFGuNmaddducSvsqllGkC15xJjZV9petC/YDnAqF+y/CoSJ7aKIg==}
+  flash-sdk@2.25.1:
+    resolution: {integrity: sha512-n9hGhJ1uMpMw7xUVZ6cqaGpbGgcLZqyh0jMlXWcqT2mPfLtVL16n2bSEOCmik/rx9jSizixCG9l9cKpeVSi4zg==}
 
   flat-cache@3.2.0:
     resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==}
@@ -16687,8 +16762,8 @@ packages:
       zod:
         optional: true
 
-  openai@4.77.3:
-    resolution: {integrity: sha512-wLDy4+KWHz31HRFMW2+9KQuVuT2QWhs0z94w1Gm1h2Ut9vIHr9/rHZggbykZEfyiaJRVgw8ZS9K6AylDWzvPYw==}
+  openai@4.77.4:
+    resolution: {integrity: sha512-rShjKsZ/HXm1cSxXt6iFeZxiCohrVShawt0aRRQmbb+z/EXcH4OouyQZP1ShyZMb63LJajpl8aGw3DzEi8Wh9Q==}
     hasBin: true
     peerDependencies:
       zod: ^3.23.8
@@ -21643,7 +21718,7 @@ snapshots:
       '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8)
       zod: 3.23.8
 
-  '@ai-sdk/openai@1.0.14(zod@3.24.1)':
+  '@ai-sdk/openai@1.0.15(zod@3.24.1)':
     dependencies:
       '@ai-sdk/provider': 1.0.4
       '@ai-sdk/provider-utils': 2.0.6(zod@3.24.1)
@@ -22236,7 +22311,7 @@ snapshots:
       '@smithy/util-retry': 4.0.0
       '@smithy/util-stream': 4.0.0
       '@smithy/util-utf8': 4.0.0
-      '@smithy/util-waiter': 4.0.0
+      '@smithy/util-waiter': 4.0.1
       tslib: 2.8.1
     transitivePeerDependencies:
       - aws-crt
@@ -26398,11 +26473,35 @@ snapshots:
       ai: 4.0.30(react@18.3.1)(zod@3.23.8)
       zod: 3.23.8
 
+  '@goat-sdk/core@0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10)':
+    dependencies:
+      '@solana/web3.js': 1.95.5(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)
+      abitype: 1.0.8(typescript@5.7.2)(zod@3.23.8)
+      viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8)
+      zod: 3.23.8
+    transitivePeerDependencies:
+      - bufferutil
+      - encoding
+      - typescript
+      - utf-8-validate
+
   '@goat-sdk/core@0.4.0':
     dependencies:
       reflect-metadata: 0.2.2
       zod: 3.23.8
 
+  '@goat-sdk/plugin-coingecko@0.1.4(@goat-sdk/core@0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8))':
+    dependencies:
+      '@goat-sdk/core': 0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10)
+      viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8)
+      zod: 3.23.8
+
+  '@goat-sdk/plugin-erc20@0.1.7(@goat-sdk/core@0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8))':
+    dependencies:
+      '@goat-sdk/core': 0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10)
+      viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8)
+      zod: 3.23.8
+
   '@goat-sdk/plugin-erc20@0.2.2(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8))':
     dependencies:
       '@goat-sdk/core': 0.4.0
@@ -26436,6 +26535,11 @@ snapshots:
       - typescript
       - utf-8-validate
 
+  '@goat-sdk/wallet-viem@0.1.3(@goat-sdk/core@0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8))':
+    dependencies:
+      '@goat-sdk/core': 0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.2)(utf-8-validate@5.0.10)
+      viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8)
+
   '@goat-sdk/wallet-viem@0.2.0(@goat-sdk/wallet-evm@0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)(zod@3.23.8))':
     dependencies:
       '@goat-sdk/wallet-evm': 0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.2)(utf-8-validate@5.0.10)
@@ -26924,14 +27028,14 @@ snapshots:
     transitivePeerDependencies:
       - openai
 
-  '@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))':
+  '@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))':
     dependencies:
       '@cfworker/json-schema': 4.1.0
       ansi-styles: 5.2.0
       camelcase: 6.3.0
       decamelize: 1.2.0
       js-tiktoken: 1.0.15
-      langsmith: 0.2.14(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))
+      langsmith: 0.2.14(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))
       mustache: 4.2.0
       p-queue: 6.6.2
       p-retry: 4.6.2
@@ -26952,33 +27056,33 @@ snapshots:
       - encoding
     optional: true
 
-  '@langchain/groq@0.1.2(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)':
+  '@langchain/groq@0.1.2(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)':
     dependencies:
-      '@langchain/core': 0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))
-      '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
+      '@langchain/core': 0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))
+      '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
       groq-sdk: 0.5.0(encoding@0.1.13)
       zod: 3.23.8
       zod-to-json-schema: 3.24.1(zod@3.23.8)
     transitivePeerDependencies:
       - encoding
 
-  '@langchain/langgraph-checkpoint@0.0.13(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))':
+  '@langchain/langgraph-checkpoint@0.0.13(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))':
     dependencies:
-      '@langchain/core': 0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))
+      '@langchain/core': 0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))
       uuid: 10.0.0
 
-  '@langchain/langgraph-sdk@0.0.33':
+  '@langchain/langgraph-sdk@0.0.34':
     dependencies:
       '@types/json-schema': 7.0.15
       p-queue: 6.6.2
       p-retry: 4.6.2
       uuid: 9.0.1
 
-  '@langchain/langgraph@0.2.39(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))':
+  '@langchain/langgraph@0.2.39(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))':
     dependencies:
-      '@langchain/core': 0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))
-      '@langchain/langgraph-checkpoint': 0.0.13(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))
-      '@langchain/langgraph-sdk': 0.0.33
+      '@langchain/core': 0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))
+      '@langchain/langgraph-checkpoint': 0.0.13(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))
+      '@langchain/langgraph-sdk': 0.0.34
       uuid: 10.0.0
       zod: 3.23.8
 
@@ -26986,17 +27090,17 @@ snapshots:
     dependencies:
       '@langchain/core': 0.3.27(openai@4.73.0(encoding@0.1.13)(zod@3.23.8))
       js-tiktoken: 1.0.15
-      openai: 4.77.3(encoding@0.1.13)(zod@3.23.8)
+      openai: 4.77.4(encoding@0.1.13)(zod@3.23.8)
       zod: 3.23.8
       zod-to-json-schema: 3.24.1(zod@3.23.8)
     transitivePeerDependencies:
       - encoding
 
-  '@langchain/openai@0.3.16(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)':
+  '@langchain/openai@0.3.16(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)':
     dependencies:
-      '@langchain/core': 0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))
+      '@langchain/core': 0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))
       js-tiktoken: 1.0.15
-      openai: 4.77.3(encoding@0.1.13)(zod@3.23.8)
+      openai: 4.77.4(encoding@0.1.13)(zod@3.23.8)
       zod: 3.23.8
       zod-to-json-schema: 3.24.1(zod@3.23.8)
     transitivePeerDependencies:
@@ -27007,9 +27111,9 @@ snapshots:
       '@langchain/core': 0.3.27(openai@4.73.0(encoding@0.1.13)(zod@3.23.8))
       js-tiktoken: 1.0.15
 
-  '@langchain/textsplitters@0.1.0(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))':
+  '@langchain/textsplitters@0.1.0(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))':
     dependencies:
-      '@langchain/core': 0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))
+      '@langchain/core': 0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))
       js-tiktoken: 1.0.15
 
   '@leichtgewicht/ip-codec@2.0.5': {}
@@ -30920,7 +31024,7 @@ snapshots:
       '@smithy/util-buffer-from': 4.0.0
       tslib: 2.8.1
 
-  '@smithy/util-waiter@4.0.0':
+  '@smithy/util-waiter@4.0.1':
     dependencies:
       '@smithy/abort-controller': 4.0.0
       '@smithy/types': 4.0.0
@@ -31384,7 +31488,7 @@ snapshots:
     dependencies:
       '@babel/runtime': 7.26.0
       '@noble/curves': 1.8.0
-      '@noble/hashes': 1.5.0
+      '@noble/hashes': 1.7.0
       '@solana/buffer-layout': 4.0.1
       agentkeepalive: 4.6.0
       bigint-buffer: 1.1.5
@@ -37814,7 +37918,7 @@ snapshots:
       semver-regex: 4.0.5
       super-regex: 1.0.0
 
-  flash-sdk@2.25.0(@swc/core@1.10.6(@swc/helpers@0.5.15))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10):
+  flash-sdk@2.25.1(@swc/core@1.10.6(@swc/helpers@0.5.15))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10):
     dependencies:
       '@coral-xyz/anchor': 0.27.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)
       '@pythnetwork/client': 2.22.0(@solana/web3.js@1.95.8(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)
@@ -40544,15 +40648,15 @@ snapshots:
       inherits: 2.0.4
       stream-splicer: 2.0.1
 
-  langchain@0.3.10(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13))(axios@1.7.9)(encoding@0.1.13)(handlebars@4.7.8)(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)):
+  langchain@0.3.10(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13))(axios@1.7.9)(encoding@0.1.13)(handlebars@4.7.8)(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)):
     dependencies:
-      '@langchain/core': 0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))
-      '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
-      '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))
+      '@langchain/core': 0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))
+      '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
+      '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))
       js-tiktoken: 1.0.15
       js-yaml: 4.1.0
       jsonpointer: 5.0.1
-      langsmith: 0.2.14(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))
+      langsmith: 0.2.14(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))
       openapi-types: 12.1.3
       p-retry: 4.6.2
       uuid: 10.0.0
@@ -40560,7 +40664,7 @@ snapshots:
       zod: 3.23.8
       zod-to-json-schema: 3.24.1(zod@3.23.8)
     optionalDependencies:
-      '@langchain/groq': 0.1.2(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
+      '@langchain/groq': 0.1.2(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
       axios: 1.7.9(debug@4.4.0)
       handlebars: 4.7.8
     transitivePeerDependencies:
@@ -40609,7 +40713,7 @@ snapshots:
     optionalDependencies:
       openai: 4.73.0(encoding@0.1.13)(zod@3.23.8)
 
-  langsmith@0.2.14(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)):
+  langsmith@0.2.14(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)):
     dependencies:
       '@types/uuid': 10.0.0
       commander: 10.0.1
@@ -40618,7 +40722,7 @@ snapshots:
       semver: 7.6.3
       uuid: 10.0.0
     optionalDependencies:
-      openai: 4.77.3(encoding@0.1.13)(zod@3.24.1)
+      openai: 4.77.4(encoding@0.1.13)(zod@3.24.1)
 
   latest-version@7.0.0:
     dependencies:
@@ -42731,7 +42835,7 @@ snapshots:
     transitivePeerDependencies:
       - encoding
 
-  openai@4.77.3(encoding@0.1.13)(zod@3.23.8):
+  openai@4.77.4(encoding@0.1.13)(zod@3.23.8):
     dependencies:
       '@types/node': 18.19.70
       '@types/node-fetch': 2.6.12
@@ -42745,7 +42849,7 @@ snapshots:
     transitivePeerDependencies:
       - encoding
 
-  openai@4.77.3(encoding@0.1.13)(zod@3.24.1):
+  openai@4.77.4(encoding@0.1.13)(zod@3.24.1):
     dependencies:
       '@types/node': 18.19.70
       '@types/node-fetch': 2.6.12
@@ -45729,14 +45833,14 @@ snapshots:
 
   solana-agent-kit@1.3.7(@noble/hashes@1.7.0)(@swc/core@1.10.6(@swc/helpers@0.5.15))(axios@1.7.9)(borsh@2.0.0)(buffer@6.0.3)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(handlebars@4.7.8)(jiti@2.4.2)(react@18.3.1)(sodium-native@3.4.1)(typescript@5.7.2)(utf-8-validate@5.0.10):
     dependencies:
-      '@ai-sdk/openai': 1.0.14(zod@3.24.1)
+      '@ai-sdk/openai': 1.0.15(zod@3.24.1)
       '@bonfida/spl-name-service': 3.0.7(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)
       '@cks-systems/manifest-sdk': 0.1.59(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(jiti@2.4.2)(typescript@5.7.2)(utf-8-validate@5.0.10)
       '@coral-xyz/anchor': 0.29.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)
-      '@langchain/core': 0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))
-      '@langchain/groq': 0.1.2(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
-      '@langchain/langgraph': 0.2.39(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))
-      '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
+      '@langchain/core': 0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))
+      '@langchain/groq': 0.1.2(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
+      '@langchain/langgraph': 0.2.39(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))
+      '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)
       '@lightprotocol/compressed-token': 0.17.1(@lightprotocol/stateless.js@0.17.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)
       '@lightprotocol/stateless.js': 0.17.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)
       '@metaplex-foundation/mpl-core': 1.1.1(@metaplex-foundation/umi@0.9.2)(@noble/hashes@1.7.0)
@@ -45760,10 +45864,10 @@ snapshots:
       chai: 5.1.2
       decimal.js: 10.4.3
       dotenv: 16.4.7
-      flash-sdk: 2.25.0(@swc/core@1.10.6(@swc/helpers@0.5.15))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)
+      flash-sdk: 2.25.1(@swc/core@1.10.6(@swc/helpers@0.5.15))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)
       form-data: 4.0.1
-      langchain: 0.3.10(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.27(openai@4.77.3(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13))(axios@1.7.9)(encoding@0.1.13)(handlebars@4.7.8)(openai@4.77.3(encoding@0.1.13)(zod@3.24.1))
-      openai: 4.77.3(encoding@0.1.13)(zod@3.24.1)
+      langchain: 0.3.10(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.27(openai@4.77.4(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13))(axios@1.7.9)(encoding@0.1.13)(handlebars@4.7.8)(openai@4.77.4(encoding@0.1.13)(zod@3.24.1))
+      openai: 4.77.4(encoding@0.1.13)(zod@3.24.1)
       typedoc: 0.27.6(typescript@5.7.2)
       zod: 3.24.1
     transitivePeerDependencies:
@@ -47606,25 +47710,6 @@ snapshots:
       '@types/unist': 3.0.3
       vfile-message: 4.0.2
 
-  viem@2.21.58(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.23.8):
-    dependencies:
-      '@noble/curves': 1.7.0
-      '@noble/hashes': 1.6.1
-      '@scure/bip32': 1.6.0
-      '@scure/bip39': 1.5.0
-      abitype: 1.0.7(typescript@5.6.3)(zod@3.23.8)
-      isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))
-      ox: 0.4.4(typescript@5.6.3)(zod@3.23.8)
-      webauthn-p256: 0.0.10
-      ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)
-    optionalDependencies:
-      typescript: 5.6.3
-    transitivePeerDependencies:
-      - bufferutil
-      - utf-8-validate
-      - zod
-
-  vite-node@2.1.4(@types/node@22.10.5)(terser@5.37.0):
   viem@2.21.58(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.24.1):
     dependencies:
       '@noble/curves': 1.7.0

From b2abd16f6bc54e7de4401ac9f23bc1943cf99b2a Mon Sep 17 00:00:00 2001
From: Shakker Nerd <shakkerdroid@gmail.com>
Date: Wed, 8 Jan 2025 18:07:11 +0000
Subject: [PATCH 3/3] chore: fix build on plugin rabbi trader

---
 packages/plugin-rabbi-trader/package.json | 14 +++++++-------
 pnpm-lock.yaml                            |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/packages/plugin-rabbi-trader/package.json b/packages/plugin-rabbi-trader/package.json
index 69e8c7a736d..4b73dacae6a 100644
--- a/packages/plugin-rabbi-trader/package.json
+++ b/packages/plugin-rabbi-trader/package.json
@@ -6,18 +6,18 @@
     "types": "dist/index.d.ts",
     "dependencies": {
         "@elizaos/core": "workspace:*",
-        "@elizaos/client-twitter":"workspace:*",
-        "@elizaos/plugin-solana":"workspace:*",
-	"@elizaos/plugin-trustdb":"workspace:*",
+        "@elizaos/client-twitter": "workspace:*",
+        "@elizaos/plugin-solana": "workspace:*",
+        "@elizaos/plugin-trustdb": "workspace:*",
         "@solana/web3.js": "^1.87.6",
-        "zod":"3.23.8",
+        "zod": "3.23.8",
         "@goat-sdk/core": "0.3.8",
         "@goat-sdk/plugin-erc20": "0.1.7",
         "@goat-sdk/wallet-viem": "0.1.3",
-	    "node-cache": "^5.1.2",
-       	"bignumber": "1.1.0",
+        "node-cache": "^5.1.2",
+        "bignumber": "1.1.0",
         "bignumber.js": "9.1.2",
-        "@goat-sdk/plugin-coingecko":"0.1.4",
+        "@goat-sdk/plugin-coingecko": "0.1.4",
         "tsup": "8.3.5",
         "ws": "^8.0.0"
     },
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b456169188b..5e43a7474a0 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -37706,7 +37706,7 @@ snapshots:
 
   extract-zip@2.0.1:
     dependencies:
-      debug: 4.3.4
+      debug: 4.4.0(supports-color@8.1.1)
       get-stream: 5.2.0
       yauzl: 2.10.0
     optionalDependencies: