diff --git a/.env.example b/.env.example index d491d9f050..a9364c2427 100644 --- a/.env.example +++ b/.env.example @@ -100,32 +100,32 @@ MEDIUM_HYPERBOLIC_MODEL= # Default: meta-llama/Meta-Llama-3.1-70B-Instruc LARGE_HYPERBOLIC_MODEL= # Default: meta-llama/Meta-Llama-3.1-405-Instruct # Infera Configuration -INFERA_API_KEY= # visit api.infera.org/docs to obtain an API key under /signup_user -INFERA_MODEL= # Default: llama3.2:latest -INFERA_SERVER_URL= # Default: https://api.infera.org/ -SMALL_INFERA_MODEL= #Recommended: llama3.2:latest -MEDIUM_INFERA_MODEL= #Recommended: mistral-nemo:latest -LARGE_INFERA_MODEL= #Recommended: mistral-small:latest - -# Venice Configuration -VENICE_API_KEY= # generate from venice settings -SMALL_VENICE_MODEL= # Default: llama-3.3-70b -MEDIUM_VENICE_MODEL= # Default: llama-3.3-70b -LARGE_VENICE_MODEL= # Default: llama-3.1-405b -IMAGE_VENICE_MODEL= # Default: fluently-xl - -# Nineteen.ai Configuration -NINETEEN_AI_API_KEY= # Get a free api key from https://nineteen.ai/app/api -SMALL_NINETEEN_AI_MODEL= # Default: unsloth/Llama-3.2-3B-Instruct -MEDIUM_NINETEEN_AI_MODEL= # Default: unsloth/Meta-Llama-3.1-8B-Instruct -LARGE_NINETEEN_AI_MODEL= # Default: hugging-quants/Meta-Llama-3.1-70B-Instruct-AWQ-INT4 -IMAGE_NINETEEN_AI_MODE= # Default: dataautogpt3/ProteusV0.4-Lightning - -# Akash Chat API Configuration docs: https://chatapi.akash.network/documentation -AKASH_CHAT_API_KEY= # Get from https://chatapi.akash.network/ -SMALL_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-2-3B-Instruct -MEDIUM_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-3-70B-Instruct -LARGE_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-1-405B-Instruct-FP8 + INFERA_API_KEY= # visit api.infera.org/docs to obtain an API key under /signup_user + INFERA_MODEL= # Default: llama3.2:latest + INFERA_SERVER_URL= # Default: https://api.infera.org/ + SMALL_INFERA_MODEL= #Recommended: llama3.2:latest + MEDIUM_INFERA_MODEL= #Recommended: mistral-nemo:latest + LARGE_INFERA_MODEL= #Recommended: mistral-small:latest + + # Venice Configuration + VENICE_API_KEY= # generate from venice settings + SMALL_VENICE_MODEL= # Default: llama-3.3-70b + MEDIUM_VENICE_MODEL= # Default: llama-3.3-70b + LARGE_VENICE_MODEL= # Default: llama-3.1-405b + IMAGE_VENICE_MODEL= # Default: fluently-xl + + # Nineteen.ai Configuration + NINETEEN_AI_API_KEY= # Get a free api key from https://nineteen.ai/app/api + SMALL_NINETEEN_AI_MODEL= # Default: unsloth/Llama-3.2-3B-Instruct + MEDIUM_NINETEEN_AI_MODEL= # Default: unsloth/Meta-Llama-3.1-8B-Instruct + LARGE_NINETEEN_AI_MODEL= # Default: hugging-quants/Meta-Llama-3.1-70B-Instruct-AWQ-INT4 + IMAGE_NINETEEN_AI_MODE= # Default: dataautogpt3/ProteusV0.4-Lightning + + # Akash Chat API Configuration docs: https://chatapi.akash.network/documentation + AKASH_CHAT_API_KEY= # Get from https://chatapi.akash.network/ + SMALL_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-2-3B-Instruct + MEDIUM_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-3-70B-Instruct + LARGE_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-1-405B-Instruct-FP8 # Livepeer configuration LIVEPEER_GATEWAY_URL= # Free inference gateways and docs: https://livepeer-eliza.com/ @@ -184,6 +184,12 @@ MEDIUM_GOOGLE_MODEL= # Default: gemini-1.5-flash-latest LARGE_GOOGLE_MODEL= # Default: gemini-1.5-pro-latest EMBEDDING_GOOGLE_MODEL= # Default: text-embedding-004 +# Mistral Configuration +MISTRAL_MODEL= +SMALL_MISTRAL_MODEL= # Default: mistral-small-latest +MEDIUM_MISTRAL_MODEL= # Default: mistral-large-latest +LARGE_MISTRAL_MODEL= # Default: mistral-large-latest + # Groq Configuration GROQ_API_KEY= # Starts with gsk_ SMALL_GROQ_MODEL= # Default: llama-3.1-8b-instant @@ -232,6 +238,13 @@ MEDIUM_VOLENGINE_MODEL= # Default: doubao-pro-128k LARGE_VOLENGINE_MODEL= # Default: doubao-pro-256k VOLENGINE_EMBEDDING_MODEL= # Default: doubao-embedding +# DeepSeek Configuration +DEEPSEEK_API_URL= # Default: https://api.deepseek.com +SMALL_DEEPSEEK_MODEL= # Default: deepseek-chat +MEDIUM_DEEPSEEK_MODEL= # Default: deepseek-chat +LARGE_DEEPSEEK_MODEL= # Default: deepseek-chat + + # fal.ai Configuration FAL_API_KEY= FAL_AI_LORA_PATH= @@ -306,6 +319,10 @@ STARKNET_ADDRESS= STARKNET_PRIVATE_KEY= STARKNET_RPC_URL= +# Lens Network Configuration +LENS_ADDRESS= +LENS_PRIVATE_KEY= + # Coinbase COINBASE_COMMERCE_KEY= # From Coinbase developer portal COINBASE_API_KEY= # From Coinbase developer portal @@ -359,6 +376,12 @@ FLOW_ENDPOINT_URL= # Default: https://mainnet.onflow.org INTERNET_COMPUTER_PRIVATE_KEY= INTERNET_COMPUTER_ADDRESS= + +#Cloudflare AI Gateway +CLOUDFLARE_GW_ENABLED= # Set to true to enable Cloudflare AI Gateway +CLOUDFLARE_AI_ACCOUNT_ID= # Cloudflare AI Account ID - found in the Cloudflare Dashboard under AI Gateway +CLOUDFLARE_AI_GATEWAY_ID= # Cloudflare AI Gateway ID - found in the Cloudflare Dashboard under AI Gateway + # Aptos APTOS_PRIVATE_KEY= # Aptos private key APTOS_NETWORK= # Must be one of mainnet, testnet @@ -477,6 +500,56 @@ TAVILY_API_KEY= VERIFIABLE_INFERENCE_ENABLED=false # Set to false to disable verifiable inference VERIFIABLE_INFERENCE_PROVIDER=opacity # Options: opacity + # Autonome Configuration AUTONOME_JWT_TOKEN= AUTONOME_RPC=https://wizard-bff-rpc.alt.technology/v1/bff/aaa/apps + +#################################### +#### Akash Network Configuration #### +#################################### +AKASH_ENV=mainnet +AKASH_NET=https://raw.githubusercontent.com/ovrclk/net/master/mainnet +RPC_ENDPOINT=https://rpc.akashnet.net:443 +AKASH_GAS_PRICES=0.025uakt +AKASH_GAS_ADJUSTMENT=1.5 +AKASH_KEYRING_BACKEND=os +AKASH_FROM=default +AKASH_FEES=20000uakt +AKASH_DEPOSIT=500000uakt +AKASH_MNEMONIC= +AKASH_WALLET_ADDRESS= +# Akash Pricing API +AKASH_PRICING_API_URL=https://console-api.akash.network/v1/pricing +# Default values # 1 CPU = 1000 1GB = 1000000000 1GB = 1000000000 +AKASH_DEFAULT_CPU=1000 +AKASH_DEFAULT_MEMORY=1000000000 +AKASH_DEFAULT_STORAGE=1000000000 +AKASH_SDL=example.sdl.yml +# Close deployment +# Close all deployments = closeAll +# Close a single deployment = dseq and add the value in AKASH_CLOSE_DSEQ +AKASH_CLOSE_DEP=closeAll +AKASH_CLOSE_DSEQ=19729929 +# Provider Info we added one to check you will have to pass this into the action +AKASH_PROVIDER_INFO=akash1ccktptfkvdc67msasmesuy5m7gpc76z75kukpz +# Deployment Status +# AKASH_DEP_STATUS = dseq or param_passed when you are building you wil pass the dseq dinamically to test you +# you can pass the dseq using AKASH_DEP_DSEQ 19729929 is an example of a dseq we test while build. +AKASH_DEP_STATUS=dseq +AKASH_DEP_DSEQ=19729929 +# Gas Estimation Options: close, create, or update +# qseq is required when operation is "close" 19729929 is an example of a dseq we test while build. +AKASH_GAS_OPERATION=close +AKASH_GAS_DSEQ=19729929 +# Manifest +# Values: "auto" | "manual" | "validate_only" Default: "auto" +AKASH_MANIFEST_MODE=auto +# Default: Will use the SDL directory +AKASH_MANIFEST_PATH= +# Values: "strict" | "lenient" | "none" - Default: "strict" +AKASH_MANIFEST_VALIDATION_LEVEL=strict + +# Quai Network Ecosystem +QUAI_PRIVATE_KEY= +QUAI_RPC_URL=https://rpc.quai.network diff --git a/.github/workflows/integrationTests.yaml b/.github/workflows/integrationTests.yaml index 0dcef61c06..b21aac7b55 100644 --- a/.github/workflows/integrationTests.yaml +++ b/.github/workflows/integrationTests.yaml @@ -3,7 +3,7 @@ on: push: branches: - "*" - pull_request_target: + pull_request: branches: - "*" @@ -33,12 +33,9 @@ jobs: - name: Build packages run: pnpm build - - name: Check for API key - run: | - if [ -z "$OPENAI_API_KEY" ]; then - echo "Error: OPENAI_API_KEY is not set." - exit 1 - fi - - name: Run integration tests - run: pnpm run integrationTests + env: + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + COINBASE_COMMERCE_KEY: ${{ secrets.COINBASE_COMMERCE_KEY }} + run: | + pnpm run integrationTests diff --git a/README.md b/README.md index 8a6db86caf..9c4949c026 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ git clone https://github.com/elizaos/eliza.git # Checkout the latest release # This project iterates fast, so we recommend checking out the latest release git checkout $(git describe --tags --abbrev=0) +# If the above doesn't checkout the latest release, this should work: +# git checkout $(git describe --tags `git rev-list --tags --max-count=1`) ``` ### Start Eliza with Gitpod diff --git a/agent/package.json b/agent/package.json index f0d4d86dbb..c52b837a8b 100644 --- a/agent/package.json +++ b/agent/package.json @@ -18,6 +18,7 @@ "exec": "node --enable-source-maps --loader ts-node/esm src/index.ts" }, "dependencies": { + "@elizaos/adapter-supabase": "workspace:*", "@elizaos/adapter-postgres": "workspace:*", "@elizaos/adapter-redis": "workspace:*", "@elizaos/adapter-sqlite": "workspace:*", @@ -34,7 +35,6 @@ "@elizaos/plugin-0g": "workspace:*", "@elizaos/plugin-abstract": "workspace:*", "@elizaos/plugin-aptos": "workspace:*", - "@elizaos/plugin-coingecko": "workspace:*", "@elizaos/plugin-coinmarketcap": "workspace:*", "@elizaos/plugin-coingecko": "workspace:*", "@elizaos/plugin-binance": "workspace:*", @@ -50,10 +50,12 @@ "@elizaos/plugin-gitbook": "workspace:*", "@elizaos/plugin-story": "workspace:*", "@elizaos/plugin-goat": "workspace:*", + "@elizaos/plugin-lensNetwork": "workspace:*", "@elizaos/plugin-icp": "workspace:*", "@elizaos/plugin-image-generation": "workspace:*", "@elizaos/plugin-movement": "workspace:*", - "@elizaos/plugin-nft-generation": "workspace:*", + "@elizaos/plugin-massa": "workspace:*", + "@elizaos/plugin-nft-generation": "workspace:*", "@elizaos/plugin-node": "workspace:*", "@elizaos/plugin-solana": "workspace:*", "@elizaos/plugin-solana-agentkit": "workspace:*", @@ -71,6 +73,7 @@ "@elizaos/plugin-near": "workspace:*", "@elizaos/plugin-zksync-era": "workspace:*", "@elizaos/plugin-twitter": "workspace:*", + "@elizaos/plugin-primus": "workspace:*", "@elizaos/plugin-cronoszkevm": "workspace:*", "@elizaos/plugin-3d-generation": "workspace:*", "@elizaos/plugin-fuel": "workspace:*", @@ -86,6 +89,9 @@ "@elizaos/plugin-arthera": "workspace:*", "@elizaos/plugin-allora": "workspace:*", "@elizaos/plugin-opacity": "workspace:*", + "@elizaos/plugin-hyperliquid": "workspace:*", + "@elizaos/plugin-akash": "workspace:*", + "@elizaos/plugin-quai": "workspace:*", "readline": "1.3.0", "ws": "8.18.0", "yargs": "17.7.2" @@ -97,4 +103,4 @@ "ts-node": "10.9.2", "tsup": "8.3.5" } -} \ No newline at end of file +} diff --git a/agent/src/index.ts b/agent/src/index.ts index c612afa92b..57501c2c13 100644 --- a/agent/src/index.ts +++ b/agent/src/index.ts @@ -2,6 +2,7 @@ import { PGLiteDatabaseAdapter } from "@elizaos/adapter-pglite"; import { PostgresDatabaseAdapter } from "@elizaos/adapter-postgres"; import { RedisClient } from "@elizaos/adapter-redis"; import { SqliteDatabaseAdapter } from "@elizaos/adapter-sqlite"; +import { SupabaseDatabaseAdapter } from "@elizaos/adapter-supabase"; import { AutoClientInterface } from "@elizaos/client-auto"; import { DiscordClientInterface } from "@elizaos/client-discord"; import { FarcasterAgentClient } from "@elizaos/client-farcaster"; @@ -10,6 +11,9 @@ import { SlackClientInterface } from "@elizaos/client-slack"; import { TelegramClientInterface } from "@elizaos/client-telegram"; import { TwitterClientInterface } from "@elizaos/client-twitter"; // import { ReclaimAdapter } from "@elizaos/plugin-reclaim"; +import { DirectClient } from "@elizaos/client-direct"; +import { PrimusAdapter } from "@elizaos/plugin-primus"; + import { AgentRuntime, CacheManager, @@ -63,6 +67,7 @@ import { flowPlugin } from "@elizaos/plugin-flow"; import { fuelPlugin } from "@elizaos/plugin-fuel"; import { genLayerPlugin } from "@elizaos/plugin-genlayer"; import { imageGenerationPlugin } from "@elizaos/plugin-image-generation"; +import { lensPlugin } from "@elizaos/plugin-lensNetwork"; import { multiversxPlugin } from "@elizaos/plugin-multiversx"; import { nearPlugin } from "@elizaos/plugin-near"; import { nftGenerationPlugin } from "@elizaos/plugin-nft-generation"; @@ -80,22 +85,24 @@ import { teeMarlinPlugin } from "@elizaos/plugin-tee-marlin"; import { tonPlugin } from "@elizaos/plugin-ton"; import { webSearchPlugin } from "@elizaos/plugin-web-search"; -import { coingeckoPlugin } from "@elizaos/plugin-coingecko"; import { giphyPlugin } from "@elizaos/plugin-giphy"; import { letzAIPlugin } from "@elizaos/plugin-letzai"; import { thirdwebPlugin } from "@elizaos/plugin-thirdweb"; - +import { hyperliquidPlugin } from "@elizaos/plugin-hyperliquid"; import { zksyncEraPlugin } from "@elizaos/plugin-zksync-era"; import { OpacityAdapter } from "@elizaos/plugin-opacity"; import { openWeatherPlugin } from "@elizaos/plugin-open-weather"; import { stargazePlugin } from "@elizaos/plugin-stargaze"; +import { akashPlugin } from "@elizaos/plugin-akash"; +import { quaiPlugin } from "@elizaos/plugin-quai"; import Database from "better-sqlite3"; import fs from "fs"; import net from "net"; import path from "path"; import { fileURLToPath } from "url"; import yargs from "yargs"; +import {dominosPlugin} from "@elizaos/plugin-dominos"; const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file const __dirname = path.dirname(__filename); // get the name of the directory @@ -142,6 +149,61 @@ function tryLoadFile(filePath: string): string | null { return null; } } +function mergeCharacters(base: Character, child: Character): Character { + const mergeObjects = (baseObj: any, childObj: any) => { + const result: any = {}; + const keys = new Set([...Object.keys(baseObj || {}), ...Object.keys(childObj || {})]); + keys.forEach(key => { + if (typeof baseObj[key] === 'object' && typeof childObj[key] === 'object' && !Array.isArray(baseObj[key]) && !Array.isArray(childObj[key])) { + result[key] = mergeObjects(baseObj[key], childObj[key]); + } else if (Array.isArray(baseObj[key]) || Array.isArray(childObj[key])) { + result[key] = [...(baseObj[key] || []), ...(childObj[key] || [])]; + } else { + result[key] = childObj[key] !== undefined ? childObj[key] : baseObj[key]; + } + }); + return result; + }; + return mergeObjects(base, child); +} +async function loadCharacter(filePath: string): Promise { + const content = tryLoadFile(filePath); + if (!content) { + throw new Error(`Character file not found: ${filePath}`); + } + let character = JSON.parse(content); + validateCharacterConfig(character); + + // .id isn't really valid + const characterId = character.id || character.name; + const characterPrefix = `CHARACTER.${characterId.toUpperCase().replace(/ /g, "_")}.`; + const characterSettings = Object.entries(process.env) + .filter(([key]) => key.startsWith(characterPrefix)) + .reduce((settings, [key, value]) => { + const settingKey = key.slice(characterPrefix.length); + return { ...settings, [settingKey]: value }; + }, {}); + if (Object.keys(characterSettings).length > 0) { + character.settings = character.settings || {}; + character.settings.secrets = { + ...characterSettings, + ...character.settings.secrets, + }; + } + // Handle plugins + character.plugins = await handlePluginImporting( + character.plugins + ); + if (character.extends) { + elizaLogger.info(`Merging ${character.name} character with parent characters`); + for (const extendPath of character.extends) { + const baseCharacter = await loadCharacter(path.resolve(path.dirname(filePath), extendPath)); + character = mergeCharacters(baseCharacter, character); + elizaLogger.info(`Merged ${character.name} with ${baseCharacter.name}`); + } + } + return character; +} export async function loadCharacters( charactersArg: string @@ -205,32 +267,7 @@ export async function loadCharacters( } try { - const character = JSON.parse(content); - validateCharacterConfig(character); - - // .id isn't really valid - const characterId = character.id || character.name; - const characterPrefix = `CHARACTER.${characterId.toUpperCase().replace(/ /g, "_")}.`; - - const characterSettings = Object.entries(process.env) - .filter(([key]) => key.startsWith(characterPrefix)) - .reduce((settings, [key, value]) => { - const settingKey = key.slice(characterPrefix.length); - return { ...settings, [settingKey]: value }; - }, {}); - - if (Object.keys(characterSettings).length > 0) { - character.settings = character.settings || {}; - character.settings.secrets = { - ...characterSettings, - ...character.settings.secrets, - }; - } - - // Handle plugins - character.plugins = await handlePluginImporting( - character.plugins - ); + const character: Character = await loadCharacter(resolvedPath); loadedCharacters.push(character); elizaLogger.info( @@ -397,6 +434,11 @@ export function getTokenForProvider( character.settings?.secrets?.GOOGLE_GENERATIVE_AI_API_KEY || settings.GOOGLE_GENERATIVE_AI_API_KEY ); + case ModelProviderName.MISTRAL: + return ( + character.settings?.secrets?.MISTRAL_API_KEY || + settings.MISTRAL_API_KEY + ); case ModelProviderName.LETZAI: return ( character.settings?.secrets?.LETZAI_API_KEY || @@ -415,7 +457,24 @@ export function getTokenForProvider( } function initializeDatabase(dataDir: string) { - if (process.env.POSTGRES_URL) { + if (process.env.SUPABASE_URL && process.env.SUPABASE_ANON_KEY) { + elizaLogger.info("Initializing Supabase connection..."); + const db = new SupabaseDatabaseAdapter( + process.env.SUPABASE_URL, + process.env.SUPABASE_ANON_KEY + ); + + // Test the connection + db.init() + .then(() => { + elizaLogger.success("Successfully connected to Supabase database"); + }) + .catch((error) => { + elizaLogger.error("Failed to connect to Supabase:", error); + }); + + return db; + } else if (process.env.POSTGRES_URL) { elizaLogger.info("Initializing PostgreSQL connection..."); const db = new PostgresDatabaseAdapter({ connectionString: process.env.POSTGRES_URL, @@ -425,9 +484,7 @@ function initializeDatabase(dataDir: string) { // Test the connection db.init() .then(() => { - elizaLogger.success( - "Successfully connected to PostgreSQL database" - ); + elizaLogger.success("Successfully connected to PostgreSQL database"); }) .catch((error) => { elizaLogger.error("Failed to connect to PostgreSQL:", error); @@ -442,10 +499,19 @@ function initializeDatabase(dataDir: string) { }); return db; } else { - const filePath = - process.env.SQLITE_FILE ?? path.resolve(dataDir, "db.sqlite"); - // ":memory:"; + const filePath = process.env.SQLITE_FILE ?? path.resolve(dataDir, "db.sqlite"); + elizaLogger.info(`Initializing SQLite database at ${filePath}...`); const db = new SqliteDatabaseAdapter(new Database(filePath)); + + // Test the connection + db.init() + .then(() => { + elizaLogger.success("Successfully connected to SQLite database"); + }) + .catch((error) => { + elizaLogger.error("Failed to connect to SQLite:", error); + }); + return db; } } @@ -615,6 +681,19 @@ export async function createAgent( elizaLogger.log("modelProvider", character.modelProvider); elizaLogger.log("token", token); } + if ( + process.env.PRIMUS_APP_ID && + process.env.PRIMUS_APP_SECRET && + process.env.VERIFIABLE_INFERENCE_ENABLED === "true"){ + verifiableInferenceAdapter = new PrimusAdapter({ + appId: process.env.PRIMUS_APP_ID, + appSecret: process.env.PRIMUS_APP_SECRET, + attMode: "proxytls", + modelProvider: character.modelProvider, + token, + }); + elizaLogger.log("Verifiable inference primus adapter initialized"); + } return new AgentRuntime({ databaseAdapter: db, @@ -702,8 +781,8 @@ export async function createAgent( goatPlugin, getSecret(character, "COINGECKO_API_KEY") || getSecret(character, "COINGECKO_PRO_API_KEY") - ? coingeckoPlugin - : null, + ? coingeckoPlugin + : null, getSecret(character, "EVM_PROVIDER_URL") ? goatPlugin : null, getSecret(character, "ABSTRACT_PRIVATE_KEY") ? abstractPlugin @@ -716,6 +795,10 @@ export async function createAgent( getSecret(character, "FLOW_PRIVATE_KEY") ? flowPlugin : null, + getSecret(character, "LENS_ADDRESS") && + getSecret(character, "LENS_PRIVATE_KEY") + ? lensPlugin + : null, getSecret(character, "APTOS_PRIVATE_KEY") ? aptosPlugin : null, getSecret(character, "MVX_PRIVATE_KEY") ? multiversxPlugin : null, getSecret(character, "ZKSYNC_PRIVATE_KEY") ? zksyncEraPlugin : null, @@ -753,6 +836,19 @@ export async function createAgent( ? artheraPlugin : null, getSecret(character, "ALLORA_API_KEY") ? alloraPlugin : null, + getSecret(character, "HYPERLIQUID_PRIVATE_KEY") + ? hyperliquidPlugin + : null, + getSecret(character, "HYPERLIQUID_TESTNET") + ? hyperliquidPlugin + : null, + getSecret(character, "AKASH_MNEMONIC") && + getSecret(character, "AKASH_WALLET_ADDRESS") + ? akashPlugin + : null, + getSecret(character, "QUAI_PRIVATE_KEY") + ? quaiPlugin + : null, ].filter(Boolean), providers: [], actions: [], diff --git a/docs/README.md b/docs/README.md index d1c4e34503..ef4760ed1b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -176,7 +176,7 @@ To create new tests, add a `.test.ts` file adjacent to the code you're testing. ## Docs Updates -Please make sure to vetify if the documentation provided is correct. In order to do so, please run the docs service. +Please make sure to verify if the documentation provided is correct. In order to do so, please run the docs service. ```console docker compose -f docker-compose-docs.yaml up --build diff --git a/docs/README_PT.md b/docs/README_PT.md new file mode 100644 index 0000000000..4a6b24211b --- /dev/null +++ b/docs/README_PT.md @@ -0,0 +1,191 @@ +# Eliza - framework de simulação Multi-agentes + +# https://github.com/elizaOS/eliza + +# Visite https://eliza.builders para suporte + +## 🌍 README Traduções + +[中文说明](README_CN.md) | [Deutsch](README_DE.md) | [Français](README_FR.md) | [ไทย](README_TH.md) | [Español](README_ES.md) | [Português](README_PT.md) + +# dev branch + +Eliza Banner + +_Como visto dando funcionamento em [@DegenSpartanAI](https://x.com/degenspartanai) e [@MarcAIndreessen](https://x.com/pmairca)_ + +- Framework Multi-agente de simulação +- Adicione quantos personagens únicos quiser com o [characterfile](https://github.com/lalalune/characterfile/) +- Conectores completos para Discord e Twitter, com suporte para canais de voz no Discord +- Memória RAG completa para conversas e documentos +- Pode ler links e PDFs, transcrever áudios e vídeos, resumir conversas e muito mais +- Altamente extensível - crie suas próprias ações e clientes para ampliar as capacidades do Eliza +- Suporte para modelos de código aberto e locais (configuração padrão com Nous Hermes Llama 3.1B) +- Suporte ao OpenAI para inferência em nuvem em dispositivos com configurações leves +- Modo "Perguntar ao Claude" para chamadas a Claude em consultas mais complexas +- 100% Typescript + +# Iniciando + +**Pré-requisitos (OBRIGATÓRIO):** + +- [Node.js 23+](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) +- [pnpm](https://pnpm.io/installation) + +### Edite o arquivo .env + +- Copie .env.example para .env e preencha com valores apropriados +- Edite as variáveis de ambiente do TWITTER para adicionar o nome de usuário e a senha do seu bot + +### Edite o arquivo de personagem (character file) + +- Verifique o arquivo `src/core/defaultCharacter.ts` - você pode modificá-lo +- Você também pode carregar personagens com o comando `pnpm start --characters="path/to/your/character.json"` e executar vários bots ao mesmo tempo. + +Após configurar o arquivo .env e o arquivo de personagem (character file), você pode iniciar o bot com o seguinte comando: + +``` +pnpm i +pnpm start +``` + +# Personalizando Eliza + +### Adicionando ações personalizadas + +Para evitar conflitos no diretório principal, recomendamos adicionar ações personalizadas a um diretório chamado `custom_actions` e, em seguida, incluí-las no arquivo `elizaConfig.yaml`. Consulte o arquivo `elizaConfig.example.yaml` para um exemplo. + +## Rodando com diferentes modelos + +### Rode com Llama + +Você pode executar modelos Llama 70B ou 405B configurando a variável de ambiente `XAI_MODEL` para `meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo` ou `meta-llama/Meta-Llama-3.1-405B-Instruct` + +### Rode com Grok + +Você pode executar modelos Grok configurando a variável de ambiente `XAI_MODEL` para `grok-beta`. + +### Rode com OpenAI + +Você pode executar modelos OpenAI configurando a variável de ambiente para `gpt-4-mini` or `gpt-4o` + +## Requisitos Adicionais + +Você pode precisar instalar o Sharp. Se aparecer um erro ao iniciar, tente instalá-lo com o seguinte comando: + +``` +pnpm install --include=optional sharp +``` + +# Configuração do Ambiente + +Você precisará adicionar variáveis de ambiente ao seu arquivo .env para conectar a diversas plataformas: + +``` +# Variaveis de ambiente obrigatorias +DISCORD_APPLICATION_ID= +DISCORD_API_TOKEN= # Bot token +OPENAI_API_KEY=sk-* # OpenAI API key, começando com sk- +ELEVENLABS_XI_API_KEY= # API key da elevenlabs + +# Configuracoes ELEVENLABS +ELEVENLABS_MODEL_ID=eleven_multilingual_v2 +ELEVENLABS_VOICE_ID=21m00Tcm4TlvDq8ikWAM +ELEVENLABS_VOICE_STABILITY=0.5 +ELEVENLABS_VOICE_SIMILARITY_BOOST=0.9 +ELEVENLABS_VOICE_STYLE=0.66 +ELEVENLABS_VOICE_USE_SPEAKER_BOOST=false +ELEVENLABS_OPTIMIZE_STREAMING_LATENCY=4 +ELEVENLABS_OUTPUT_FORMAT=pcm_16000 + +TWITTER_DRY_RUN=false +TWITTER_USERNAME= # Usuário da conta +TWITTER_PASSWORD= # Senha da conta +TWITTER_EMAIL= # Email da conta + +X_SERVER_URL= +XAI_API_KEY= +XAI_MODEL= + + +# Para perguntas ao Claude +ANTHROPIC_API_KEY= + +WALLET_SECRET_KEY=EXAMPLE_WALLET_SECRET_KEY +WALLET_PUBLIC_KEY=EXAMPLE_WALLET_PUBLIC_KEY + +BIRDEYE_API_KEY= + +SOL_ADDRESS=So11111111111111111111111111111111111111112 +SLIPPAGE=1 +RPC_URL=https://api.mainnet-beta.solana.com +HELIUS_API_KEY= + + +## Telegram +TELEGRAM_BOT_TOKEN= + +TOGETHER_API_KEY= +``` + +# Configuração de Inferência Local + +### Configuração CUDA + +Se você tiver uma GPU NVIDIA, pode instalar o CUDA para acelerar significativamente a inferência local. + +``` +pnpm install +npx --no node-llama-cpp source download --gpu cuda +``` + +Certifique-se de que você instalou o CUDA Toolkit, incluindo o cuDNN e cuBLAS. + +### Rodando localmente + +Add XAI_MODEL e defina-o para uma das opções mencionadas em [Run with +Llama](#run-with-llama) - você pode deixar X_SERVER_URL e XAI_API_KEY em branco, +pois o modelo será baixado do Hugging Face e consultado localmente. + +# Clientes + +## Discord Bot + +Para ajuda com a configuração do seu bot no Discord, consulte aqui: https://discordjs.guide/preparations/setting-up-a-bot-application.html + +# Desenvolvimento + +## Testando + +Para executar a suíte de testes: + +```bash +pnpm test # Executar os testes uma vez +pnpm test:watch # Executar os testes no modo de observação/monitoramento (watch mode) +``` + +Para testes específicos de banco de dados: + +```bash +pnpm test:sqlite # Rode testes com SQLite +pnpm test:sqljs # Rode testes com SQL.js +``` + +Os testes são escritos usando o Jest e podem ser encontrados nos arquivos. O ambiente de teste está configurado para: + +- Carregar variáveis de ambiente do arquivo `.env.test` +- Usar um tempo limite de 2 minutos para testes de longa duração +- Suportar módulos ESM +- Executar os testes em sequência (--runInBand) + +Para criar novos testes, adicione um arquivo `.test.ts` ao lado do código que você está testando. + +## Atualizações da Documentação + +Por favor, verifique se a documentação fornecida está correta. Para fazer isso, execute o serviço de documentação (docs) abaixo. + +```console +docker compose -f docker-compose-docs.yaml up --build +``` + +O servidor do Docusaurus será iniciado e você poderá verificar a documentação localmente em https://localhost:3000/eliza. diff --git a/docs/api/classes/DatabaseAdapter.md b/docs/api/classes/DatabaseAdapter.md index 65f8186e76..46cf221d27 100644 --- a/docs/api/classes/DatabaseAdapter.md +++ b/docs/api/classes/DatabaseAdapter.md @@ -194,7 +194,7 @@ Retrieves memories based on the specified parameters. • **params** -An object containing parameters for the memory retrieval. +An object containing parameters for memory retrieval. • **params.agentId**: \`$\{string\}-$\{string\}-$\{string\}-$\{string\}-$\{string\}\` @@ -300,7 +300,7 @@ An object containing parameters for the embedding retrieval. `Promise`\<`object`[]\> -A Promise that resolves to an array of objects containing embeddings and levenshtein scores. +A Promise that resolves to an array of objects containing embeddings and Levenshtein scores. #### Implementation of diff --git a/docs/api/functions/composeContext.md b/docs/api/functions/composeContext.md index 86ed7bb61a..055bdb28c0 100644 --- a/docs/api/functions/composeContext.md +++ b/docs/api/functions/composeContext.md @@ -20,7 +20,7 @@ The parameters for composing the context. • **params.state**: [`State`](../interfaces/State.md) -The state object containing values to replace the placeholders in the template. +The state object contains values to replace the placeholders in the template. • **params.template**: `string` | `Function` diff --git a/docs/api/functions/configureSettings.md b/docs/api/functions/configureSettings.md index 97e013f435..876d1dc54c 100644 --- a/docs/api/functions/configureSettings.md +++ b/docs/api/functions/configureSettings.md @@ -10,7 +10,7 @@ Configures environment settings for browser usage • **settings**: `Settings` -Object containing environment variables +The object containing environment variables ## Returns diff --git a/docs/api/functions/splitChunks.md b/docs/api/functions/splitChunks.md index b066d0777f..4e9f5745dd 100644 --- a/docs/api/functions/splitChunks.md +++ b/docs/api/functions/splitChunks.md @@ -24,7 +24,7 @@ Number of characters to overlap between chunks (default: 100) `Promise`\<`string`[]\> -Promise resolving to array of text chunks with bleed sections +Promise resolving to an array of text chunks with bleed sections ## Defined in diff --git a/docs/api/interfaces/ActionExample.md b/docs/api/interfaces/ActionExample.md index f084d8ab5d..40f694afa1 100644 --- a/docs/api/interfaces/ActionExample.md +++ b/docs/api/interfaces/ActionExample.md @@ -2,7 +2,7 @@ # Interface: ActionExample -Example content with associated user for demonstration purposes +Example content with the associated user for demonstration purposes ## Properties diff --git a/docs/api/interfaces/ConversationExample.md b/docs/api/interfaces/ConversationExample.md index c7d2107307..3043585468 100644 --- a/docs/api/interfaces/ConversationExample.md +++ b/docs/api/interfaces/ConversationExample.md @@ -10,7 +10,7 @@ Example conversation content with user ID > **userId**: \`$\{string\}-$\{string\}-$\{string\}-$\{string\}-$\{string\}\` -UUID of user in conversation +UUID of the user in conversation #### Defined in diff --git a/docs/docs/advanced/fine-tuning.md b/docs/docs/advanced/fine-tuning.md index 7822e9010f..2a3220ddac 100644 --- a/docs/docs/advanced/fine-tuning.md +++ b/docs/docs/advanced/fine-tuning.md @@ -22,6 +22,7 @@ enum ModelProviderName { LLAMACLOUD, LLAMALOCAL, GOOGLE, + MISTRAL, REDPILL, OPENROUTER, HEURIST, diff --git a/docs/docs/core/actions.md b/docs/docs/core/actions.md index 529ff18ea3..0f710e0c90 100644 --- a/docs/docs/core/actions.md +++ b/docs/docs/core/actions.md @@ -179,7 +179,7 @@ const continueAction: Action = { name: "CONTINUE", similes: ["ELABORATE", "KEEP_TALKING"], description: - "Used when the message requires a follow-up. Don't use when conversation is finished.", + "Used when the message requires a follow-up. Don't use when the conversation is finished.", validate: async (runtime, message) => { // Validation logic return true; diff --git a/docs/docs/core/characterfile.md b/docs/docs/core/characterfile.md index f9ca0648fc..8b5a278f45 100644 --- a/docs/docs/core/characterfile.md +++ b/docs/docs/core/characterfile.md @@ -140,7 +140,7 @@ Array used for Retrieval Augmented Generation (RAG), containing facts or referen #### `messageExamples` -Sample conversations for establishing interaction patterns, helps establish the character's conversational style. +Sample conversations for establishing interaction patterns, help establish the character's conversational style. ```json "messageExamples": [ @@ -191,7 +191,7 @@ The `style` object defines behavior patterns across contexts: ### Adjectives Array - Words that describe the character's traits and personality -- Used for generating responses with consistent tone +- Used for generating responses with a consistent tone - Can be used in "Mad Libs" style content generation ### Settings Configuration diff --git a/docs/docs/core/evaluators.md b/docs/docs/core/evaluators.md index 7811e9d953..43cfb96caa 100644 --- a/docs/docs/core/evaluators.md +++ b/docs/docs/core/evaluators.md @@ -119,7 +119,7 @@ interface Objective { ### Handler Implementation - Use runtime services appropriately -- Store results in correct memory manager +- Store results in the correct memory manager - Handle errors gracefully - Maintain state consistency diff --git a/docs/docs/faq.md b/docs/docs/faq.md index 5e0baea566..0f26446fe2 100644 --- a/docs/docs/faq.md +++ b/docs/docs/faq.md @@ -68,4 +68,4 @@ There are several ways to contribute to the Eliza project: - **Participate in community discussions**: Share your memecoin insights, propose new ideas, and engage with other community members. - **Contribute to the development of the Eliza platform**: https://github.com/orgs/elizaos/projects/1/views/3 -- **Help build the Eliza ecosystem**: Create applicatoins / tools, resources, and memes. Give feedback, and spread the word +- **Help build the Eliza ecosystem**: Create applications / tools, resources, and memes. Give feedback, and spread the word diff --git a/docs/docs/guides/configuration.md b/docs/docs/guides/configuration.md index b260a4d807..a87d61046c 100644 --- a/docs/docs/guides/configuration.md +++ b/docs/docs/guides/configuration.md @@ -71,6 +71,59 @@ HEURIST_API_KEY= # Livepeer Settings LIVEPEER_GATEWAY_URL= ``` + +### Cloudflare AI Gateway Integration + +Eliza supports routing API calls through [Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/), which provides several benefits: + +- Detailed analytics and monitoring of message traffic and response times +- Cost optimization through request caching and usage tracking across providers +- Improved latency through Cloudflare's global network +- Comprehensive visibility into message content and token usage +- Cost analysis and comparison between different AI providers +- Usage patterns and trends visualization +- Request/response logging for debugging and optimization + +To enable Cloudflare AI Gateway: + +```bash +# Cloudflare AI Gateway Settings +CLOUDFLARE_GW_ENABLED=true +CLOUDFLARE_AI_ACCOUNT_ID=your-account-id +CLOUDFLARE_AI_GATEWAY_ID=your-gateway-id +``` + +Supported providers through Cloudflare AI Gateway: +- OpenAI +- Anthropic +- Groq + +When enabled, Eliza will automatically route requests through your Cloudflare AI Gateway endpoint. The gateway URL is constructed in the format: +``` +https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}/${provider} +``` + +If the gateway configuration is incomplete or disabled, Eliza will fall back to direct API calls. + +```bash +# Cloudflare AI Gateway Settings +CLOUDFLARE_GW_ENABLED=true +CLOUDFLARE_AI_ACCOUNT_ID=your-account-id +CLOUDFLARE_AI_GATEWAY_ID=your-gateway-id +``` + +Supported providers through Cloudflare AI Gateway: +- OpenAI +- Anthropic +- Groq + +When enabled, Eliza will automatically route requests through your Cloudflare AI Gateway endpoint. The gateway URL is constructed in the format: +``` +https://gateway.ai.cloudflare.com/v1/${accountId}/${gatewayId}/${provider} +``` + +If the gateway configuration is incomplete or disabled, Eliza will fall back to direct API calls. + ### Image Generation Configure image generation in your character file: diff --git a/packages/adapter-postgres/src/__tests__/vector-extension.test.ts b/packages/adapter-postgres/src/__tests__/vector-extension.test.ts index 7ced587371..a22c51c79f 100644 --- a/packages/adapter-postgres/src/__tests__/vector-extension.test.ts +++ b/packages/adapter-postgres/src/__tests__/vector-extension.test.ts @@ -3,7 +3,7 @@ import pg from 'pg'; import fs from 'fs'; import path from 'path'; import { describe, test, expect, beforeEach, afterEach, vi, beforeAll } from 'vitest'; -import { DatabaseAdapter, elizaLogger, type Memory, type Content, EmbeddingProvider } from '@elizaos/core'; +import { elizaLogger, type Memory, type Content } from '@elizaos/core'; // Increase test timeout vi.setConfig({ testTimeout: 15000 }); @@ -41,7 +41,7 @@ vi.mock('@elizaos/core', () => ({ const parseVectorString = (vectorStr: string): number[] => { if (!vectorStr) return []; // Remove brackets and split by comma - return vectorStr.replace(/[\[\]]/g, '').split(',').map(Number); + return vectorStr.replace(/[[\]]/g, '').split(',').map(Number); }; describe('PostgresDatabaseAdapter - Vector Extension Validation', () => { @@ -111,7 +111,7 @@ describe('PostgresDatabaseAdapter - Vector Extension Validation', () => { user: 'postgres', password: 'postgres' }); - + const setupClient = await setupPool.connect(); try { await cleanDatabase(setupClient); @@ -133,13 +133,13 @@ describe('PostgresDatabaseAdapter - Vector Extension Validation', () => { user: 'postgres', password: 'postgres' }); - + testClient = await testPool.connect(); elizaLogger.debug('Database connection established'); - + await cleanDatabase(testClient); elizaLogger.debug('Database cleaned'); - + adapter = new PostgresDatabaseAdapter({ host: 'localhost', port: 5433, @@ -254,7 +254,7 @@ describe('PostgresDatabaseAdapter - Vector Extension Validation', () => { elizaLogger.debug('Attempting initialization with error...'); await expect(adapter.init()).rejects.toThrow('Schema read error'); elizaLogger.success('Error thrown as expected'); - + // Verify no tables were created elizaLogger.debug('Verifying rollback...'); const { rows } = await testClient.query(` @@ -277,19 +277,19 @@ describe('PostgresDatabaseAdapter - Vector Extension Validation', () => { describe('Memory Operations with Vector', () => { const TEST_UUID = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'; const TEST_TABLE = 'test_memories'; - + beforeEach(async () => { elizaLogger.info('Setting up memory operations test...'); try { // Ensure clean state and proper initialization await adapter.init(); - + // Verify vector extension and search path await testClient.query(` SET search_path TO public, extensions; SELECT set_config('app.use_openai_embedding', 'true', false); `); - + // Create necessary account and room first await testClient.query('BEGIN'); try { @@ -298,19 +298,19 @@ describe('PostgresDatabaseAdapter - Vector Extension Validation', () => { VALUES ($1, 'test@test.com') ON CONFLICT (id) DO NOTHING `, [TEST_UUID]); - + await testClient.query(` INSERT INTO rooms (id) VALUES ($1) ON CONFLICT (id) DO NOTHING `, [TEST_UUID]); - + await testClient.query('COMMIT'); } catch (error) { await testClient.query('ROLLBACK'); throw error; } - + } catch (error) { elizaLogger.error('Memory operations setup failed:', { error: error instanceof Error ? error.message : String(error) @@ -324,7 +324,7 @@ describe('PostgresDatabaseAdapter - Vector Extension Validation', () => { const content: Content = { text: 'test content' }; - + const memory: Memory = { id: TEST_UUID, content, @@ -383,7 +383,7 @@ describe('PostgresDatabaseAdapter - Vector Extension Validation', () => { await testClient.query('ROLLBACK'); throw error; } - + // Act const results = await adapter.searchMemoriesByEmbedding(embedding, { tableName: TEST_TABLE, @@ -405,7 +405,7 @@ describe('PostgresDatabaseAdapter - Vector Extension Validation', () => { const content: Content = { text: 'test content' }; - + const memory: Memory = { id: TEST_UUID, content, @@ -430,4 +430,4 @@ describe('PostgresDatabaseAdapter - Vector Extension Validation', () => { } }, { timeout: 30000 }); // Increased timeout for retry attempts }); -}); \ No newline at end of file +}); \ No newline at end of file diff --git a/packages/adapter-postgres/src/index.ts b/packages/adapter-postgres/src/index.ts index efbca97a91..2a774b53f2 100644 --- a/packages/adapter-postgres/src/index.ts +++ b/packages/adapter-postgres/src/index.ts @@ -329,6 +329,7 @@ export class PostgresDatabaseAdapter roomIds: UUID[]; agentId?: UUID; tableName: string; + limit?: number; }): Promise { return this.withDatabase(async () => { if (params.roomIds.length === 0) return []; @@ -344,6 +345,13 @@ export class PostgresDatabaseAdapter queryParams = [...queryParams, params.agentId]; } + // Add sorting, and conditionally add LIMIT if provided + query += ` ORDER BY "createdAt" DESC`; + if (params.limit) { + query += ` LIMIT $${queryParams.length + 1}`; + queryParams.push(params.limit.toString()); + } + const { rows } = await this.pool.query(query, queryParams); return rows.map((row) => ({ ...row, diff --git a/packages/adapter-sqljs/src/index.ts b/packages/adapter-sqljs/src/index.ts index db27215e10..6df3c93f03 100644 --- a/packages/adapter-sqljs/src/index.ts +++ b/packages/adapter-sqljs/src/index.ts @@ -859,7 +859,7 @@ export class SqlJsDatabaseAdapter return JSON.parse(cachedResult); } - let sql = ` + const sql = ` WITH vector_scores AS ( SELECT id, 1 / (1 + vec_distance_L2(embedding, ?)) as vector_score diff --git a/packages/adapter-supabase/seed.sql b/packages/adapter-supabase/seed.sql index 063c5fbe53..4385fa4786 100644 --- a/packages/adapter-supabase/seed.sql +++ b/packages/adapter-supabase/seed.sql @@ -1,3 +1,3 @@ -INSERT INTO public.accounts (id, name, email, avatarUrl, details) VALUES ('00000000-0000-0000-0000-000000000000', 'Default Agent', 'default@agent.com', '', '{}'); -INSERT INTO public.rooms (id) VALUES ('00000000-0000-0000-0000-000000000000'); -INSERT INTO public.participants (userId, roomId) VALUES ('00000000-0000-0000-0000-000000000000', '00000000-0000-0000-0000-000000000000'); +INSERT INTO public.accounts (id, name, email, "avatarUrl", details) VALUES ('00000000-0000-0000-0000-000000000000', 'Default Agent', 'default@agent.com', '', '{}'); +INSERT INTO public.rooms (id, "createdAt") VALUES ('00000000-0000-0000-0000-000000000000', NOW()); +INSERT INTO public.participants (id, "createdAt", "userId", "roomId", "userState", last_messsage_read) VALUES ('00000000-0000-0000-0000-000000000000', NOW(), 'Default Agent', '00000000-0000-0000-0000-000000000000', NULL, NULL); diff --git a/packages/adapter-supabase/src/index.ts b/packages/adapter-supabase/src/index.ts index 9c8d643f61..3800b845c9 100644 --- a/packages/adapter-supabase/src/index.ts +++ b/packages/adapter-supabase/src/index.ts @@ -20,12 +20,12 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { .from("rooms") .select("id") .eq("id", roomId) - .single(); + .maybeSingle(); if (error) { - throw new Error(`Error getting room: ${error.message}`); + elizaLogger.error(`Error getting room: ${error.message}`); + return null; } - return data ? (data.id as UUID) : null; } @@ -56,7 +56,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { .single(); if (error) { - console.error("Error getting participant user state:", error); + elizaLogger.error("Error getting participant user state:", error); return null; } @@ -75,7 +75,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { .eq("userId", userId); if (error) { - console.error("Error setting participant user state:", error); + elizaLogger.error("Error setting participant user state:", error); throw new Error("Failed to set participant user state"); } } @@ -127,7 +127,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { const { data, error } = await query; if (error) { - console.error("Error retrieving memories by room IDs:", error); + elizaLogger.error("Error retrieving memories by room IDs:", error); return []; } @@ -155,7 +155,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { .from("accounts") .upsert([account]); if (error) { - console.error(error.message); + elizaLogger.error(error.message); return false; } return true; @@ -175,7 +175,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { .eq("id", params.roomId); if (response.error) { - console.error("Error!" + response.error); + elizaLogger.error("Error!" + response.error); return []; } const { data } = response; @@ -194,7 +194,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { ) .flat(); } catch (error) { - console.error("error", error); + elizaLogger.error("error", error); throw error; } } @@ -267,7 +267,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { }); if (error) { - console.error("Error inserting log:", error); + elizaLogger.error("Error inserting log:", error); throw new Error(error.message); } } @@ -357,7 +357,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { .single(); if (error) { - console.error("Error retrieving memory by ID:", error); + elizaLogger.error("Error retrieving memory by ID:", error); return null; } @@ -571,7 +571,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { .insert({ userId: userId, roomId: roomId }); if (error) { - console.error(`Error adding participant: ${error.message}`); + elizaLogger.error(`Error adding participant: ${error.message}`); return false; } return true; @@ -585,7 +585,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { .eq("roomId", roomId); if (error) { - console.error(`Error removing participant: ${error.message}`); + elizaLogger.error(`Error removing participant: ${error.message}`); return false; } return true; @@ -695,7 +695,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { .single(); if (error) { - console.error('Error fetching cache:', error); + elizaLogger.error('Error fetching cache:', error); return undefined; } @@ -717,7 +717,7 @@ export class SupabaseDatabaseAdapter extends DatabaseAdapter { }); if (error) { - console.error('Error setting cache:', error); + elizaLogger.error('Error setting cache:', error); return false; } diff --git a/packages/client-direct/src/api.ts b/packages/client-direct/src/api.ts index 2780831c24..0a16059233 100644 --- a/packages/client-direct/src/api.ts +++ b/packages/client-direct/src/api.ts @@ -56,7 +56,7 @@ export function createApiRouter( return; } - let character = agent?.character; + const character = agent?.character; if (character?.settings?.secrets) { delete character.settings.secrets; } diff --git a/packages/client-direct/src/index.ts b/packages/client-direct/src/index.ts index d98bc6a661..86f3593b54 100644 --- a/packages/client-direct/src/index.ts +++ b/packages/client-direct/src/index.ts @@ -373,14 +373,12 @@ export class DirectClient { // hyperfi specific parameters let nearby = []; - let messages = []; let availableEmotes = []; if (body.nearby) { nearby = body.nearby; } if (body.messages) { - messages = body.messages; // loop on the messages and record the memories // might want to do this in parallel for (const msg of body.messages) { @@ -502,10 +500,17 @@ export class DirectClient { schema: hyperfiOutSchema, }); + if (!response) { + res.status(500).send( + "No response from generateMessageResponse" + ); + return; + } + let hfOut; try { hfOut = hyperfiOutSchema.parse(response.object); - } catch (e) { + } catch { elizaLogger.error( "cant serialize response", response.object @@ -515,7 +520,7 @@ export class DirectClient { } // do this in the background - const rememberThis = new Promise(async (resolve) => { + new Promise((resolve) => { const contentObj: Content = { text: hfOut.say, }; @@ -545,45 +550,38 @@ export class DirectClient { content: contentObj, }; - await runtime.messageManager.createMemory(responseMessage); // 18.2ms - - if (!response) { - res.status(500).send( - "No response from generateMessageResponse" - ); - return; - } - - let message = null as Content | null; - - const messageId = stringToUuid(Date.now().toString()); - const memory: Memory = { - id: messageId, - agentId: runtime.agentId, - userId, - roomId, - content, - createdAt: Date.now(), - }; - - // run evaluators (generally can be done in parallel with processActions) - // can an evaluator modify memory? it could but currently doesn't - await runtime.evaluate(memory, state); // 0.5s - - // only need to call if responseMessage.content.action is set - if (contentObj.action) { - // pass memory (query) to any actions to call - const _result = await runtime.processActions( - memory, - [responseMessage], - state, - async (newMessages) => { - message = newMessages; - return [memory]; + runtime.messageManager.createMemory(responseMessage).then(() => { + const messageId = stringToUuid(Date.now().toString()); + const memory: Memory = { + id: messageId, + agentId: runtime.agentId, + userId, + roomId, + content, + createdAt: Date.now(), + }; + + // run evaluators (generally can be done in parallel with processActions) + // can an evaluator modify memory? it could but currently doesn't + runtime.evaluate(memory, state).then(() => { + // only need to call if responseMessage.content.action is set + if (contentObj.action) { + // pass memory (query) to any actions to call + runtime.processActions( + memory, + [responseMessage], + state, + async (_newMessages) => { + // FIXME: this is supposed override what the LLM said/decided + // but the promise doesn't make this possible + //message = newMessages; + return [memory]; + } + ); // 0.674s } - ); // 0.674s - } - resolve(true); + resolve(true); + }); + }); }); res.json({ response: hfOut }); } diff --git a/packages/client-discord/src/actions/joinvoice.ts b/packages/client-discord/src/actions/joinvoice.ts index dbfa556482..71c879712a 100644 --- a/packages/client-discord/src/actions/joinvoice.ts +++ b/packages/client-discord/src/actions/joinvoice.ts @@ -8,6 +8,8 @@ import { IAgentRuntime, Memory, State, + generateText, + ModelClass, } from "@elizaos/core"; import { Channel, @@ -17,6 +19,7 @@ import { Guild, GuildMember, } from "discord.js"; +import { joinVoiceChannel } from "@discordjs/voice"; export default { name: "JOIN_VOICE", @@ -66,12 +69,7 @@ export default { return false; } - const client = state.discordClient as Client; - - // Check if the client is connected to any voice channel - const isConnectedToVoice = client.voice.adapters.size === 0; - - return isConnectedToVoice; + return true; }, description: "Join a voice channel to participate in voice chat.", handler: async ( @@ -115,31 +113,30 @@ export default { ); }); - if (!state.voiceManager) { - state.voiceManager = new VoiceManager({ - client: state.discordClient, - runtime: runtime, - }); - } - if (targetChannel) { - state.voiceManager.joinVoiceChannel({ + joinVoiceChannel({ channelId: targetChannel.id, guildId: (discordMessage as DiscordMessage).guild?.id as string, adapterCreator: (client.guilds.cache.get(id) as Guild) .voiceAdapterCreator, + selfDeaf: false, + selfMute: false, + group: client.user.id, }); return true; } else { const member = (discordMessage as DiscordMessage) .member as GuildMember; if (member?.voice?.channel) { - state.voiceManager.joinVoiceChannel({ + joinVoiceChannel({ channelId: member.voice.channel.id, guildId: (discordMessage as DiscordMessage).guild ?.id as string, adapterCreator: (client.guilds.cache.get(id) as Guild) .voiceAdapterCreator, + selfDeaf: false, + selfMute: false, + group: client.user.id, }); return true; } @@ -204,12 +201,15 @@ You should only respond with the name of the voice channel or none, no commentar }); if (targetChannel) { - state.voiceManager.joinVoiceChannel({ + joinVoiceChannel({ channelId: targetChannel.id, guildId: (discordMessage as DiscordMessage).guild ?.id as string, adapterCreator: (client.guilds.cache.get(id) as Guild) .voiceAdapterCreator, + selfDeaf: false, + selfMute: false, + group: client.user.id, }); return true; } diff --git a/packages/client-slack/src/actions/chat_with_attachments.ts b/packages/client-slack/src/actions/chat_with_attachments.ts index e059cc47b4..b40353020d 100644 --- a/packages/client-slack/src/actions/chat_with_attachments.ts +++ b/packages/client-slack/src/actions/chat_with_attachments.ts @@ -5,7 +5,6 @@ import { parseJSONObjectFromText, getModelSettings, } from "@elizaos/core"; -import { models } from "@elizaos/core"; import { Action, ActionExample, diff --git a/packages/client-slack/src/actions/summarize_conversation.ts b/packages/client-slack/src/actions/summarize_conversation.ts index b487757cad..1464952122 100644 --- a/packages/client-slack/src/actions/summarize_conversation.ts +++ b/packages/client-slack/src/actions/summarize_conversation.ts @@ -6,7 +6,6 @@ import { parseJSONObjectFromText, getModelSettings, } from "@elizaos/core"; -import { models } from "@elizaos/core"; import { getActorDetails } from "@elizaos/core"; import { Action, diff --git a/packages/client-twitter/src/interactions.ts b/packages/client-twitter/src/interactions.ts index ebc9ca9e64..d076668200 100644 --- a/packages/client-twitter/src/interactions.ts +++ b/packages/client-twitter/src/interactions.ts @@ -14,6 +14,8 @@ import { stringToUuid, elizaLogger, getEmbeddingZeroVector, + IImageDescriptionService, + ServiceType } from "@elizaos/core"; import { ClientBase } from "./base"; import { buildConversationThread, sendTweet, wait } from "./utils.ts"; @@ -43,6 +45,8 @@ Recent interactions between {{agentName}} and other users: Current Post: {{currentPost}} +Here is the descriptions of images in the Current post. +{{imageDescriptions}} Thread of Tweets You Are Replying To: {{formattedConversation}} @@ -53,6 +57,8 @@ Thread of Tweets You Are Replying To: Here is the current post text again. Remember to include an action if the current post text includes a prompt that asks for one of the available actions mentioned above (does not need to be exact) {{currentPost}} +Here is the descriptions of images in the Current post. +{{imageDescriptions}} ` + messageCompletionFooter; export const twitterShouldRespondTemplate = (targetUsersStr: string) => @@ -342,11 +348,34 @@ export class TwitterInteractionClient { elizaLogger.debug("formattedConversation: ", formattedConversation); + let imageDescriptionsArray = []; + try{ + elizaLogger.debug('Getting images'); + for (const photo of tweet.photos) { + elizaLogger.debug(photo.url); + const description = await this.runtime + .getService( + ServiceType.IMAGE_DESCRIPTION + ) + .describeImage(photo.url); + imageDescriptionsArray.push(description); + } + } catch (error) { + // Handle the error + elizaLogger.error("Error Occured during describing image: ", error); +} + + + + let state = await this.runtime.composeState(message, { twitterClient: this.client.twitterClient, twitterUserName: this.client.twitterConfig.TWITTER_USERNAME, currentPost, formattedConversation, + imageDescriptions: imageDescriptionsArray.length > 0 + ? `\nImages in Tweet:\n${imageDescriptionsArray.map((desc, i) => + `Image ${i + 1}: Title: ${desc.title}\nDescription: ${desc.description}`).join("\n\n")}`:"" }); // check if the tweet exists, save if it doesn't @@ -413,7 +442,6 @@ export class TwitterInteractionClient { this.runtime.character?.templates?.messageHandlerTemplate || twitterMessageHandlerTemplate, }); - elizaLogger.debug("Interactions prompt:\n" + context); const response = await generateMessageResponse({ @@ -624,4 +652,4 @@ export class TwitterInteractionClient { return thread; } -} +} \ No newline at end of file diff --git a/packages/client-twitter/src/plugins/SttTtsSpacesPlugin.ts b/packages/client-twitter/src/plugins/SttTtsSpacesPlugin.ts index ade6084eb6..b23a25d79c 100644 --- a/packages/client-twitter/src/plugins/SttTtsSpacesPlugin.ts +++ b/packages/client-twitter/src/plugins/SttTtsSpacesPlugin.ts @@ -67,7 +67,7 @@ export class SttTtsPlugin implements Plugin { private ttsQueue: string[] = []; private isSpeaking = false; - onAttach(space: Space) { + onAttach(_space: Space) { elizaLogger.log("[SttTtsPlugin] onAttach => space was attached"); } diff --git a/packages/client-twitter/src/post.ts b/packages/client-twitter/src/post.ts index e0aff4b3a6..93d8993025 100644 --- a/packages/client-twitter/src/post.ts +++ b/packages/client-twitter/src/post.ts @@ -8,6 +8,7 @@ import { stringToUuid, TemplateType, UUID, + truncateToCompleteSentence, } from "@elizaos/core"; import { elizaLogger } from "@elizaos/core"; import { ClientBase } from "./base.ts"; @@ -77,40 +78,6 @@ Tweet: # Respond with qualifying action tags only. Default to NO action unless extremely confident of relevance.` + postActionResponseFooter; -/** - * Truncate text to fit within the Twitter character limit, ensuring it ends at a complete sentence. - */ -function truncateToCompleteSentence( - text: string, - maxTweetLength: number -): string { - if (text.length <= maxTweetLength) { - return text; - } - - // Attempt to truncate at the last period within the limit - const lastPeriodIndex = text.lastIndexOf(".", maxTweetLength - 1); - if (lastPeriodIndex !== -1) { - const truncatedAtPeriod = text.slice(0, lastPeriodIndex + 1).trim(); - if (truncatedAtPeriod.length > 0) { - return truncatedAtPeriod; - } - } - - // If no period, truncate to the nearest whitespace within the limit - const lastSpaceIndex = text.lastIndexOf(" ", maxTweetLength - 1); - if (lastSpaceIndex !== -1) { - const truncatedAtSpace = text.slice(0, lastSpaceIndex).trim(); - if (truncatedAtSpace.length > 0) { - return truncatedAtSpace + "..."; - } - } - - // Fallback: Hard truncate and add ellipsis - const hardTruncated = text.slice(0, maxTweetLength - 3).trim(); - return hardTruncated + "..."; -} - interface PendingTweet { cleanedContent: string; roomId: UUID; @@ -399,7 +366,6 @@ export class TwitterPostClient { async handleNoteTweet( client: ClientBase, - runtime: IAgentRuntime, content: string, tweetId?: string ) { @@ -465,11 +431,7 @@ export class TwitterPostClient { let result; if (cleanedContent.length > DEFAULT_MAX_TWEET_LENGTH) { - result = await this.handleNoteTweet( - client, - runtime, - cleanedContent - ); + result = await this.handleNoteTweet(client, cleanedContent); } else { result = await this.sendStandardTweet(client, cleanedContent); } @@ -1204,7 +1166,6 @@ export class TwitterPostClient { if (replyText.length > DEFAULT_MAX_TWEET_LENGTH) { result = await this.handleNoteTweet( this.client, - this.runtime, replyText, tweet.id ); diff --git a/packages/client-twitter/src/utils.ts b/packages/client-twitter/src/utils.ts index d11ed5b534..a728694453 100644 --- a/packages/client-twitter/src/utils.ts +++ b/packages/client-twitter/src/utils.ts @@ -345,7 +345,7 @@ function extractUrls(paragraph: string): { function splitSentencesAndWords(text: string, maxLength: number): string[] { // Split by periods, question marks and exclamation marks // Note that URLs in text have been replaced with `<>` and won't be split by dots - const sentences = text.match(/[^\.!\?]+[\.!\?]+|[^\.!\?]+$/g) || [text]; + const sentences = text.match(/[^.!?]+[.!?]+|[^.!?]+$/g) || [text]; const chunks: string[] = []; let currentChunk = ""; diff --git a/packages/core/package.json b/packages/core/package.json index 3a1b74388f..ccea2942a4 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -69,6 +69,7 @@ "@ai-sdk/google": "0.0.55", "@ai-sdk/google-vertex": "0.0.43", "@ai-sdk/groq": "0.0.3", + "@ai-sdk/mistral": "^1.0.8", "@ai-sdk/openai": "1.0.5", "@anthropic-ai/sdk": "0.30.1", "@fal-ai/client": "1.2.0", diff --git a/packages/core/src/database.ts b/packages/core/src/database.ts index 310c44c32a..322341a8cf 100644 --- a/packages/core/src/database.ts +++ b/packages/core/src/database.ts @@ -95,6 +95,7 @@ export abstract class DatabaseAdapter implements IDatabaseAdapter { agentId: UUID; roomIds: UUID[]; tableName: string; + limit?: number; }): Promise; abstract getMemoryById(id: UUID): Promise; diff --git a/packages/core/src/defaultCharacter.ts b/packages/core/src/defaultCharacter.ts index e4a81b07e2..8faaa64f2b 100644 --- a/packages/core/src/defaultCharacter.ts +++ b/packages/core/src/defaultCharacter.ts @@ -527,4 +527,5 @@ export const defaultCharacter: Character = { "meticulous", "provocative", ], + extends: [], }; diff --git a/packages/core/src/environment.ts b/packages/core/src/environment.ts index ed7edf3bf2..4bbe5fcb91 100644 --- a/packages/core/src/environment.ts +++ b/packages/core/src/environment.ts @@ -135,6 +135,7 @@ export const CharacterSchema = z.object({ prompt: z.string().optional(), }) .optional(), + extends: z.array(z.string()).optional(), }); // Type inference diff --git a/packages/core/src/generation.ts b/packages/core/src/generation.ts index c835b993be..e2248b584c 100644 --- a/packages/core/src/generation.ts +++ b/packages/core/src/generation.ts @@ -1,5 +1,6 @@ import { createAnthropic } from "@ai-sdk/anthropic"; import { createGoogleGenerativeAI } from "@ai-sdk/google"; +import { createMistral } from "@ai-sdk/mistral"; import { createGroq } from "@ai-sdk/groq"; import { createOpenAI } from "@ai-sdk/openai"; import { RecursiveCharacterTextSplitter } from "langchain/text_splitter"; @@ -45,7 +46,7 @@ import { IVerifiableInferenceAdapter, VerifiableInferenceOptions, VerifiableInferenceResult, - VerifiableInferenceProvider, + //VerifiableInferenceProvider, TelemetrySettings, TokenizerType, } from "./types.ts"; @@ -163,6 +164,50 @@ async function truncateTiktoken( } } +/** + * Gets the Cloudflare Gateway base URL for a specific provider if enabled + * @param runtime The runtime environment + * @param provider The model provider name + * @returns The Cloudflare Gateway base URL if enabled, undefined otherwise + */ +function getCloudflareGatewayBaseURL(runtime: IAgentRuntime, provider: string): string | undefined { + const isCloudflareEnabled = runtime.getSetting("CLOUDFLARE_GW_ENABLED") === "true"; + const cloudflareAccountId = runtime.getSetting("CLOUDFLARE_AI_ACCOUNT_ID"); + const cloudflareGatewayId = runtime.getSetting("CLOUDFLARE_AI_GATEWAY_ID"); + + elizaLogger.debug("Cloudflare Gateway Configuration:", { + isEnabled: isCloudflareEnabled, + hasAccountId: !!cloudflareAccountId, + hasGatewayId: !!cloudflareGatewayId, + provider: provider + }); + + if (!isCloudflareEnabled) { + elizaLogger.debug("Cloudflare Gateway is not enabled"); + return undefined; + } + + if (!cloudflareAccountId) { + elizaLogger.warn("Cloudflare Gateway is enabled but CLOUDFLARE_AI_ACCOUNT_ID is not set"); + return undefined; + } + + if (!cloudflareGatewayId) { + elizaLogger.warn("Cloudflare Gateway is enabled but CLOUDFLARE_AI_GATEWAY_ID is not set"); + return undefined; + } + + const baseURL = `https://gateway.ai.cloudflare.com/v1/${cloudflareAccountId}/${cloudflareGatewayId}/${provider.toLowerCase()}`; + elizaLogger.info("Using Cloudflare Gateway:", { + provider, + baseURL, + accountId: cloudflareAccountId, + gatewayId: cloudflareGatewayId + }); + + return baseURL; +} + /** * Send a message to the model for a text generateText - receive a string back and parse how you'd like * @param opts - The options for the generateText request. @@ -242,6 +287,16 @@ export async function generateText({ } const provider = runtime.modelProvider; + elizaLogger.debug("Provider settings:", { + provider, + hasRuntime: !!runtime, + runtimeSettings: { + CLOUDFLARE_GW_ENABLED: runtime.getSetting("CLOUDFLARE_GW_ENABLED"), + CLOUDFLARE_AI_ACCOUNT_ID: runtime.getSetting("CLOUDFLARE_AI_ACCOUNT_ID"), + CLOUDFLARE_AI_GATEWAY_ID: runtime.getSetting("CLOUDFLARE_AI_GATEWAY_ID") + } + }); + const endpoint = runtime.character.modelEndpointOverride || getEndpoint(provider); const modelSettings = getModelSettings(runtime.modelProvider, modelClass); @@ -356,13 +411,17 @@ export async function generateText({ case ModelProviderName.LLAMACLOUD: case ModelProviderName.NANOGPT: case ModelProviderName.HYPERBOLIC: + case ModelProviderName.TOGETHER: case ModelProviderName.NINETEEN_AI: case ModelProviderName.TOGETHER: case ModelProviderName.AKASH_CHAT_API: { - elizaLogger.debug("Initializing OpenAI model."); + elizaLogger.debug("Initializing OpenAI model with Cloudflare check"); + const baseURL = getCloudflareGatewayBaseURL(runtime, 'openai') || endpoint; + + //elizaLogger.debug("OpenAI baseURL result:", { baseURL }); const openai = createOpenAI({ apiKey, - baseURL: endpoint, + baseURL, fetch: runtime.fetch, }); @@ -430,10 +489,7 @@ export async function generateText({ const { text: openaiResponse } = await aiGenerateText({ model: openai.languageModel(model), prompt: context, - system: - runtime.character.system ?? - settings.SYSTEM_PROMPT ?? - undefined, + system: runtime.character.system ?? settings.SYSTEM_PROMPT ?? undefined, temperature: temperature, maxTokens: max_response_length, frequencyPenalty: frequency_penalty, @@ -473,14 +529,33 @@ export async function generateText({ break; } - case ModelProviderName.ANTHROPIC: { - elizaLogger.debug("Initializing Anthropic model."); + case ModelProviderName.MISTRAL: { + const mistral = createMistral(); - const anthropic = createAnthropic({ - apiKey, - fetch: runtime.fetch, + const { text: mistralResponse } = await aiGenerateText({ + model: mistral(model), + prompt: context, + system: + runtime.character.system ?? + settings.SYSTEM_PROMPT ?? + undefined, + temperature: temperature, + maxTokens: max_response_length, + frequencyPenalty: frequency_penalty, + presencePenalty: presence_penalty, }); + response = mistralResponse; + elizaLogger.debug("Received response from Mistral model."); + break; + } + + case ModelProviderName.ANTHROPIC: { + elizaLogger.debug("Initializing Anthropic model with Cloudflare check"); + const baseURL = getCloudflareGatewayBaseURL(runtime, 'anthropic') || "https://api.anthropic.com/v1"; + elizaLogger.debug("Anthropic baseURL result:", { baseURL }); + + const anthropic = createAnthropic({ apiKey, baseURL, fetch: runtime.fetch }); const { text: anthropicResponse } = await aiGenerateText({ model: anthropic.languageModel(model), prompt: context, @@ -568,26 +643,30 @@ export async function generateText({ } case ModelProviderName.GROQ: { - const groq = createGroq({ apiKey, fetch: runtime.fetch }); + elizaLogger.debug("Initializing Groq model with Cloudflare check"); + const baseURL = getCloudflareGatewayBaseURL(runtime, 'groq'); + elizaLogger.debug("Groq baseURL result:", { baseURL }); + const groq = createGroq({ apiKey, fetch: runtime.fetch, baseURL }); const { text: groqResponse } = await aiGenerateText({ model: groq.languageModel(model), prompt: context, - temperature: temperature, + temperature, system: runtime.character.system ?? settings.SYSTEM_PROMPT ?? undefined, - tools: tools, + tools, onStepFinish: onStepFinish, - maxSteps: maxSteps, + maxSteps, maxTokens: max_response_length, frequencyPenalty: frequency_penalty, presencePenalty: presence_penalty, - experimental_telemetry: experimental_telemetry, + experimental_telemetry, }); response = groqResponse; + elizaLogger.debug("Received response from Groq model."); break; } @@ -887,6 +966,37 @@ export async function generateText({ break; } + case ModelProviderName.DEEPSEEK: { + elizaLogger.debug("Initializing Deepseek model."); + const serverUrl = models[provider].endpoint; + const deepseek = createOpenAI({ + apiKey, + baseURL: serverUrl, + fetch: runtime.fetch, + }); + + const { text: deepseekResponse } = await aiGenerateText({ + model: deepseek.languageModel(model), + prompt: context, + temperature: temperature, + system: + runtime.character.system ?? + settings.SYSTEM_PROMPT ?? + undefined, + tools: tools, + onStepFinish: onStepFinish, + maxSteps: maxSteps, + maxTokens: max_response_length, + frequencyPenalty: frequency_penalty, + presencePenalty: presence_penalty, + experimental_telemetry: experimental_telemetry, + }); + + response = deepseekResponse; + elizaLogger.debug("Received response from Deepseek model."); + break; + } + default: { const errorMessage = `Unsupported provider: ${provider}`; elizaLogger.error(errorMessage); @@ -1777,9 +1887,9 @@ export async function handleProvider( runtime, context, modelClass, - verifiableInference, - verifiableInferenceAdapter, - verifiableInferenceOptions, + //verifiableInference, + //verifiableInferenceAdapter, + //verifiableInferenceOptions, } = options; switch (provider) { case ModelProviderName.OPENAI: @@ -1806,12 +1916,16 @@ export async function handleProvider( }); case ModelProviderName.GOOGLE: return await handleGoogle(options); + case ModelProviderName.MISTRAL: + return await handleMistral(options); case ModelProviderName.REDPILL: return await handleRedPill(options); case ModelProviderName.OPENROUTER: return await handleOpenRouter(options); case ModelProviderName.OLLAMA: return await handleOllama(options); + case ModelProviderName.DEEPSEEK: + return await handleDeepSeek(options); default: { const errorMessage = `Unsupported provider: ${provider}`; elizaLogger.error(errorMessage); @@ -1833,8 +1947,10 @@ async function handleOpenAI({ schemaDescription, mode = "json", modelOptions, + provider, + runtime, }: ProviderOptions): Promise> { - const baseURL = models.openai.endpoint || undefined; + const baseURL = getCloudflareGatewayBaseURL(runtime, 'openai') || models.openai.endpoint; const openai = createOpenAI({ apiKey, baseURL }); return await aiGenerateObject({ model: openai.languageModel(model), @@ -1860,8 +1976,13 @@ async function handleAnthropic({ schemaDescription, mode = "json", modelOptions, + runtime, }: ProviderOptions): Promise> { - const anthropic = createAnthropic({ apiKey }); + elizaLogger.debug("Handling Anthropic request with Cloudflare check"); + const baseURL = getCloudflareGatewayBaseURL(runtime, 'anthropic'); + elizaLogger.debug("Anthropic handleAnthropic baseURL:", { baseURL }); + + const anthropic = createAnthropic({ apiKey, baseURL }); return await aiGenerateObject({ model: anthropic.languageModel(model), schema, @@ -1912,8 +2033,13 @@ async function handleGroq({ schemaDescription, mode = "json", modelOptions, + runtime, }: ProviderOptions): Promise> { - const groq = createGroq({ apiKey }); + elizaLogger.debug("Handling Groq request with Cloudflare check"); + const baseURL = getCloudflareGatewayBaseURL(runtime, 'groq'); + elizaLogger.debug("Groq handleGroq baseURL:", { baseURL }); + + const groq = createGroq({ apiKey, baseURL }); return await aiGenerateObject({ model: groq.languageModel(model), schema, @@ -1950,6 +2076,31 @@ async function handleGoogle({ }); } +/** + * Handles object generation for Mistral models. + * + * @param {ProviderOptions} options - Options specific to Mistral. + * @returns {Promise>} - A promise that resolves to generated objects. + */ +async function handleMistral({ + model, + schema, + schemaName, + schemaDescription, + mode, + modelOptions, +}: ProviderOptions): Promise> { + const mistral = createMistral(); + return await aiGenerateObject({ + model: mistral(model), + schema, + schemaName, + schemaDescription, + mode, + ...modelOptions, + }); +} + /** * Handles object generation for Redpill models. * @@ -2034,6 +2185,32 @@ async function handleOllama({ }); } +/** + * Handles object generation for DeepSeek models. + * + * @param {ProviderOptions} options - Options specific to DeepSeek. + * @returns {Promise>} - A promise that resolves to generated objects. + */ +async function handleDeepSeek({ + model, + apiKey, + schema, + schemaName, + schemaDescription, + mode, + modelOptions, +}: ProviderOptions): Promise> { + const openai = createOpenAI({ apiKey, baseURL: models.deepseek.endpoint }); + return await aiGenerateObject({ + model: openai.languageModel(model), + schema, + schemaName, + schemaDescription, + mode, + ...modelOptions, + }); +} + // Add type definition for Together AI response interface TogetherAIImageResponse { data: Array<{ diff --git a/packages/core/src/memory.ts b/packages/core/src/memory.ts index 112352766f..698c1c6337 100644 --- a/packages/core/src/memory.ts +++ b/packages/core/src/memory.ts @@ -189,11 +189,12 @@ export class MemoryManager implements IMemoryManager { ); } - async getMemoriesByRoomIds(params: { roomIds: UUID[] }): Promise { + async getMemoriesByRoomIds(params: { roomIds: UUID[], limit?: number; }): Promise { return await this.runtime.databaseAdapter.getMemoriesByRoomIds({ tableName: this.tableName, agentId: this.runtime.agentId, roomIds: params.roomIds, + limit: params.limit }); } diff --git a/packages/core/src/models.ts b/packages/core/src/models.ts index 663aaa518a..c562fe69e5 100644 --- a/packages/core/src/models.ts +++ b/packages/core/src/models.ts @@ -378,6 +378,46 @@ export const models: Models = { }, }, }, + [ModelProviderName.MISTRAL]: { + model: { + [ModelClass.SMALL]: { + name: + settings.SMALL_MISTRAL_MODEL || + settings.MISTRAL_MODEL || + "mistral-small-latest", + stop: [], + maxInputTokens: 128000, + maxOutputTokens: 8192, + frequency_penalty: 0.4, + presence_penalty: 0.4, + temperature: 0.7, + }, + [ModelClass.MEDIUM]: { + name: + settings.MEDIUM_MISTRAL_MODEL || + settings.MISTRAL_MODEL || + "mistral-large-latest", + stop: [], + maxInputTokens: 128000, + maxOutputTokens: 8192, + frequency_penalty: 0.4, + presence_penalty: 0.4, + temperature: 0.7, + }, + [ModelClass.LARGE]: { + name: + settings.LARGE_MISTRAL_MODEL || + settings.MISTRAL_MODEL || + "mistral-large-latest", + stop: [], + maxInputTokens: 128000, + maxOutputTokens: 8192, + frequency_penalty: 0.4, + presence_penalty: 0.4, + temperature: 0.7, + }, + }, + }, [ModelProviderName.REDPILL]: { endpoint: "https://api.red-pill.ai/v1", // Available models: https://docs.red-pill.ai/get-started/supported-models @@ -926,6 +966,38 @@ export const models: Models = { }, }, }, + [ModelProviderName.DEEPSEEK]: { + endpoint: settings.DEEPSEEK_API_URL || "https://api.deepseek.com", + model: { + [ModelClass.SMALL]: { + name: settings.SMALL_DEEPSEEK_MODEL || "deepseek-chat", + stop: [], + maxInputTokens: 128000, + maxOutputTokens: 8192, + frequency_penalty: 0.0, + presence_penalty: 0.0, + temperature: 0.7, + }, + [ModelClass.MEDIUM]: { + name: settings.MEDIUM_DEEPSEEK_MODEL || "deepseek-chat", + stop: [], + maxInputTokens: 128000, + maxOutputTokens: 8192, + frequency_penalty: 0.0, + presence_penalty: 0.0, + temperature: 0.7, + }, + [ModelClass.LARGE]: { + name: settings.LARGE_DEEPSEEK_MODEL || "deepseek-chat", + stop: [], + maxInputTokens: 128000, + maxOutputTokens: 8192, + frequency_penalty: 0.0, + presence_penalty: 0.0, + temperature: 0.7, + }, + }, + }, }; export function getModelSettings( diff --git a/packages/core/src/parsing.ts b/packages/core/src/parsing.ts index 107ce8ea0b..331cd30a13 100644 --- a/packages/core/src/parsing.ts +++ b/packages/core/src/parsing.ts @@ -205,3 +205,37 @@ export const parseActionResponseFromText = ( return { actions }; }; + +/** + * Truncate text to fit within the character limit, ensuring it ends at a complete sentence. + */ +export function truncateToCompleteSentence( + text: string, + maxLength: number +): string { + if (text.length <= maxLength) { + return text; + } + + // Attempt to truncate at the last period within the limit + const lastPeriodIndex = text.lastIndexOf(".", maxLength - 1); + if (lastPeriodIndex !== -1) { + const truncatedAtPeriod = text.slice(0, lastPeriodIndex + 1).trim(); + if (truncatedAtPeriod.length > 0) { + return truncatedAtPeriod; + } + } + + // If no period, truncate to the nearest whitespace within the limit + const lastSpaceIndex = text.lastIndexOf(" ", maxLength - 1); + if (lastSpaceIndex !== -1) { + const truncatedAtSpace = text.slice(0, lastSpaceIndex).trim(); + if (truncatedAtSpace.length > 0) { + return truncatedAtSpace + "..."; + } + } + + // Fallback: Hard truncate and add ellipsis + const hardTruncated = text.slice(0, maxLength - 3).trim(); + return hardTruncated + "..."; +} diff --git a/packages/core/src/ragknowledge.ts b/packages/core/src/ragknowledge.ts index 0856cea67a..5c91309703 100644 --- a/packages/core/src/ragknowledge.ts +++ b/packages/core/src/ragknowledge.ts @@ -299,14 +299,14 @@ export class RAGKnowledgeManager implements IRAGKnowledgeManager { }; const startTime = Date.now(); - let content = file.content; + const content = file.content; try { const fileSizeKB = (new TextEncoder().encode(content)).length / 1024; elizaLogger.info(`[File Progress] Starting ${file.path} (${fileSizeKB.toFixed(2)} KB)`); // Step 1: Preprocessing - const preprocessStart = Date.now(); + //const preprocessStart = Date.now(); const processedContent = this.preprocess(content); timeMarker('Preprocessing'); diff --git a/packages/core/src/runtime.ts b/packages/core/src/runtime.ts index a3f4062a72..bb33b78796 100644 --- a/packages/core/src/runtime.ts +++ b/packages/core/src/runtime.ts @@ -34,8 +34,8 @@ import { IRAGKnowledgeManager, IMemoryManager, KnowledgeItem, - RAGKnowledgeItem, - Media, + //RAGKnowledgeItem, + //Media, ModelClass, ModelProviderName, Plugin, @@ -546,10 +546,7 @@ export class AgentRuntime implements IAgentRuntime { agentId: this.agentId }); - let content: string; - - content = await readFile(filePath, 'utf8'); - + const content: string = await readFile(filePath, 'utf8'); if (!content) { hasError = true; continue; @@ -1102,21 +1099,11 @@ Text: ${attachment.text} ]); // Check the existing memories in the database - const existingMemories = - await this.messageManager.getMemoriesByRoomIds({ + return this.messageManager.getMemoriesByRoomIds({ // filter out the current room id from rooms roomIds: rooms.filter((room) => room !== roomId), + limit: 20 }); - - // Sort messages by timestamp in descending order - existingMemories.sort( - (a, b) => - (b?.createdAt ?? Date.now()) - (a?.createdAt ?? Date.now()) - ); - - // Take the most recent messages - const recentInteractionsData = existingMemories.slice(0, 20); - return recentInteractionsData; }; const recentInteractions = diff --git a/packages/core/src/tests/uuid.test.ts b/packages/core/src/tests/uuid.test.ts new file mode 100644 index 0000000000..5a09d78eb6 --- /dev/null +++ b/packages/core/src/tests/uuid.test.ts @@ -0,0 +1,108 @@ +import { beforeEach, describe, expect, it } from "vitest"; +import { stringToUuid } from "../uuid"; +import type { UUID } from "../types"; + +describe("UUID Module", () => { + // Helper function to generate test strings + const generateTestString = (): string => + Math.random().toString(36).substring(7); + + // Test data setup + let testString: string; + let testNumber: number; + + beforeEach(() => { + testString = generateTestString(); + testNumber = Math.floor(Math.random() * 1000); + }); + + describe("stringToUuid", () => { + it("should generate a valid UUID matching the standard format", () => { + const result = stringToUuid(testString) as UUID; + expect(result).toMatch( + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i + ); + }); + + it("should generate consistent UUIDs for identical inputs", () => { + const input = testString; + const uuid1 = stringToUuid(input) as UUID; + const uuid2 = stringToUuid(input) as UUID; + expect(uuid1).toBe(uuid2); + }); + + it("should generate unique UUIDs for different inputs", () => { + const input1 = testString; + const input2 = generateTestString(); + const uuid1 = stringToUuid(input1) as UUID; + const uuid2 = stringToUuid(input2) as UUID; + expect(uuid1).not.toBe(uuid2); + }); + + describe("input handling", () => { + it("should convert number inputs to strings correctly", () => { + const numberUuid = stringToUuid(testNumber) as UUID; + const stringUuid = stringToUuid(testNumber.toString()) as UUID; + expect(numberUuid).toBe(stringUuid); + }); + + it("should throw TypeError for invalid input types", () => { + expect(() => stringToUuid(undefined as any)).toThrow(TypeError); + expect(() => stringToUuid(null as any)).toThrow(TypeError); + expect(() => stringToUuid({} as any)).toThrow(TypeError); + }); + + it("should handle empty string input", () => { + const result = stringToUuid("") as UUID; + expect(result).toMatch( + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i + ); + }); + + it("should handle Unicode characters and emojis consistently", () => { + const unicodeInput = "Hello 世界! 🌍"; + const result1 = stringToUuid(unicodeInput) as UUID; + const result2 = stringToUuid(unicodeInput) as UUID; + expect(result1).toBe(result2); + expect(result1).toMatch( + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i + ); + }); + }); + + describe("UUID version and variant bits", () => { + it("should set correct version bits (version 5)", () => { + const uuid = stringToUuid(testString) as UUID; + const versionChar = uuid.split("-")[2][0]; + expect(versionChar).toBe("5"); + }); + + it("should set correct variant bits (RFC4122)", () => { + const uuid = stringToUuid(testString) as UUID; + const variantByte = parseInt( + uuid.split("-")[3].slice(0, 2), + 16 + ); + expect(variantByte >= 0x80 && variantByte <= 0xbf).toBe(true); + }); + }); + + describe("encoding handling", () => { + it("should handle URL-unsafe characters", () => { + const urlUnsafeInput = "test?query=value¶m=123"; + const result = stringToUuid(urlUnsafeInput) as UUID; + expect(result).toMatch( + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i + ); + }); + + it("should handle very long inputs", () => { + const longInput = "a".repeat(1000); + const result = stringToUuid(longInput) as UUID; + expect(result).toMatch( + /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i + ); + }); + }); + }); +}); diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 708e4ec8e5..2c958c6993 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -210,6 +210,7 @@ export type Models = { [ModelProviderName.TOGETHER]: Model; [ModelProviderName.LLAMALOCAL]: Model; [ModelProviderName.GOOGLE]: Model; + [ModelProviderName.MISTRAL]: Model; [ModelProviderName.CLAUDE_VERTEX]: Model; [ModelProviderName.REDPILL]: Model; [ModelProviderName.OPENROUTER]: Model; @@ -226,6 +227,7 @@ export type Models = { [ModelProviderName.NINETEEN_AI]: Model; [ModelProviderName.AKASH_CHAT_API]: Model; [ModelProviderName.LIVEPEER]: Model; + [ModelProviderName.DEEPSEEK]: Model; [ModelProviderName.INFERA]: Model; }; @@ -242,6 +244,7 @@ export enum ModelProviderName { TOGETHER = "together", LLAMALOCAL = "llama_local", GOOGLE = "google", + MISTRAL = "mistral", CLAUDE_VERTEX = "claude_vertex", REDPILL = "redpill", OPENROUTER = "openrouter", @@ -258,8 +261,8 @@ export enum ModelProviderName { NINETEEN_AI = "nineteen_ai", AKASH_CHAT_API = "akash_chat_api", LIVEPEER = "livepeer", - LETZAI = "letzai", - INFERA = "infera", + DEEPSEEK="deepseek", + INFERA="infera" } /** @@ -644,6 +647,7 @@ export enum Clients { LENS = "lens", AUTO = "auto", SLACK = "slack", + GITHUB = "github", } export interface IAgentConfig { @@ -868,6 +872,8 @@ export type Character = { nft?: { prompt: string; }; + /**Optinal Parent characters to inherit information from */ + extends?: string[]; }; /** @@ -906,6 +912,7 @@ export interface IDatabaseAdapter { tableName: string; agentId: UUID; roomIds: UUID[]; + limit?: number; }): Promise; getCachedEmbeddings(params: { @@ -1079,7 +1086,7 @@ export interface IMemoryManager { ): Promise<{ embedding: number[]; levenshtein_score: number }[]>; getMemoryById(id: UUID): Promise; - getMemoriesByRoomIds(params: { roomIds: UUID[] }): Promise; + getMemoriesByRoomIds(params: { roomIds: UUID[], limit?: number }): Promise; searchMemoriesByEmbedding( embedding: number[], opts: { @@ -1473,7 +1480,9 @@ export interface ISlackService extends Service { * Available verifiable inference providers */ export enum VerifiableInferenceProvider { + RECLAIM = "reclaim", OPACITY = "opacity", + PRIMUS = "primus", } /** diff --git a/packages/plugin-akash/.eslintrc.js b/packages/plugin-akash/.eslintrc.js new file mode 100644 index 0000000000..e476cac57e --- /dev/null +++ b/packages/plugin-akash/.eslintrc.js @@ -0,0 +1,29 @@ +module.exports = { + root: true, + parser: '@typescript-eslint/parser', + parserOptions: { + project: './tsconfig.json', + tsconfigRootDir: __dirname, + ecmaVersion: 2020, + sourceType: 'module', + }, + plugins: ['@typescript-eslint'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:@typescript-eslint/recommended-requiring-type-checking', + ], + rules: { + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/no-unused-vars': ['error', { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + ignoreRestSiblings: true, + }], + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-non-null-assertion': 'warn', + 'no-console': ['error', { allow: ['warn', 'error'] }], + }, + ignorePatterns: ['dist/', 'node_modules/', '*.js', '*.mjs', '*.cjs'], +}; \ No newline at end of file diff --git a/packages/plugin-akash/.npmignore b/packages/plugin-akash/.npmignore new file mode 100644 index 0000000000..078562ecea --- /dev/null +++ b/packages/plugin-akash/.npmignore @@ -0,0 +1,6 @@ +* + +!dist/** +!package.json +!readme.md +!tsup.config.ts \ No newline at end of file diff --git a/packages/plugin-akash/assets/akash.jpg b/packages/plugin-akash/assets/akash.jpg new file mode 100644 index 0000000000..dd08e0e570 Binary files /dev/null and b/packages/plugin-akash/assets/akash.jpg differ diff --git a/packages/plugin-akash/eslint.config.mjs b/packages/plugin-akash/eslint.config.mjs new file mode 100644 index 0000000000..92fe5bbebe --- /dev/null +++ b/packages/plugin-akash/eslint.config.mjs @@ -0,0 +1,3 @@ +import eslintGlobalConfig from "../../eslint.config.mjs"; + +export default [...eslintGlobalConfig]; diff --git a/packages/plugin-akash/jest.config.js b/packages/plugin-akash/jest.config.js new file mode 100644 index 0000000000..a8331cee2f --- /dev/null +++ b/packages/plugin-akash/jest.config.js @@ -0,0 +1,31 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + roots: ['/test'], + testMatch: [ + "**/__tests__/**/*.+(ts|tsx|js)", + "**/?(*.)+(spec|test).+(ts|tsx|js)" + ], + transform: { + "^.+\\.(ts|tsx)$": "ts-jest" + }, + moduleNameMapper: { + '^@/(.*)$': '/src/$1' + }, + setupFilesAfterEnv: ['/test/setup/jest.setup.ts'], + globals: { + 'ts-jest': { + tsconfig: 'tsconfig.json' + } + }, + testTimeout: 30000, + verbose: true, + collectCoverage: true, + coverageDirectory: "coverage", + coverageReporters: ["text", "lcov"], + coveragePathIgnorePatterns: [ + "/node_modules/", + "/test/fixtures/", + "/test/setup/" + ] +}; \ No newline at end of file diff --git a/packages/plugin-akash/package.json b/packages/plugin-akash/package.json new file mode 100644 index 0000000000..6c2bbab527 --- /dev/null +++ b/packages/plugin-akash/package.json @@ -0,0 +1,51 @@ +{ + "name": "@elizaos/plugin-akash", + "version": "0.1.0", + "description": "Akash Network Plugin for Eliza", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "type": "module", + "scripts": { + "build": "tsup", + "dev": "tsup --watch", + "clean": "rm -rf dist", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "test": "vitest", + "test:watch": "vitest watch", + "test:coverage": "vitest run --coverage", + "test:ui": "vitest --ui" + }, + "dependencies": { + "@akashnetwork/akash-api": "^1.4.0", + "@akashnetwork/akashjs": "0.10.1", + "@cosmjs/proto-signing": "^0.31.3", + "@cosmjs/stargate": "0.31.3", + "@elizaos/core": "workspace:*", + "axios": "^1.7.9", + "dotenv": "^16.4.1", + "jsrsasign": "^11.1.0", + "node-fetch": "^2.7.0", + "zod": "^3.22.4", + "@types/js-yaml": "^4.0.9" + }, + "devDependencies": { + "@types/dotenv": "^8.2.0", + "@types/jest": "^29.5.11", + "@types/js-yaml": "^4.0.9", + "@types/node": "^20.10.5", + "@typescript-eslint/eslint-plugin": "^6.15.0", + "@typescript-eslint/parser": "^6.15.0", + "@vitest/coverage-v8": "^0.34.6", + "@vitest/ui": "^0.34.6", + "eslint": "^8.56.0", + "tsup": "^8.0.1", + "typescript": "^5.3.3", + "vite": "^5.0.10", + "vite-tsconfig-paths": "^4.2.2", + "vitest": "^0.34.6" + }, + "peerDependencies": { + "@elizaos/core": "workspace:*" + } +} diff --git a/packages/plugin-akash/readme.md b/packages/plugin-akash/readme.md new file mode 100644 index 0000000000..081f353f26 --- /dev/null +++ b/packages/plugin-akash/readme.md @@ -0,0 +1,133 @@ +# Akash Network Plugin for Eliza + +A powerful plugin for interacting with the Akash Network, enabling deployment management and cloud compute operations through Eliza. + +## Table of Contents +- [Installation](#installation) +- [Configuration](#configuration) +- [Directory Structure](#directory-structure) +- [Available Actions](#available-actions) + +## Installation + +```bash +pnpm add @elizaos/plugin-akash +``` + +## Configuration + +### Environment Variables +Create a `.env` file in your project root with the following configuration: + +```env +# Network Configuration +AKASH_ENV=mainnet +AKASH_NET=https://raw.githubusercontent.com/ovrclk/net/master/mainnet +RPC_ENDPOINT=https://rpc.akashnet.net:443 + +# Transaction Settings +AKASH_GAS_PRICES=0.025uakt +AKASH_GAS_ADJUSTMENT=1.5 +AKASH_KEYRING_BACKEND=os +AKASH_FROM=default +AKASH_FEES=20000uakt + +# Authentication +AKASH_MNEMONIC=your_12_word_mnemonic_here + +# Manifest Settings +AKASH_MANIFEST_MODE=auto # Options: auto, validate_only +AKASH_MANIFEST_VALIDATION_LEVEL=strict # Options: strict, basic, none +AKASH_MANIFEST_PATH=/path/to/manifests # Optional: Path to save generated manifests + +# Deployment Settings +AKASH_DEPOSIT=5000000uakt # Default deployment deposit +AKASH_SDL=deployment.yml # Default SDL file name +``` + +**Important Notes:** +- `AKASH_MNEMONIC`: Your 12-word wallet mnemonic phrase (required) +- `AKASH_MANIFEST_MODE`: Controls manifest generation behavior +- `AKASH_MANIFEST_VALIDATION_LEVEL`: Sets SDL validation strictness +- `AKASH_DEPOSIT`: Default deposit amount for deployments + +⚠️ Never commit your `.env` file with real credentials to version control! + + +#### SDL (Stack Definition Language) +``` +src/sdl/example.sdl.yml +``` +Place your SDL configuration files here. The plugin looks for SDL files in this directory by default. + +#### Certificates +``` +src/.certificates/ +``` +SSL certificates for secure provider communication are stored here. + +## Available Actions + +| Action | Description | Parameters | +|---------------------|------------------------------------------------|---------------------------------------------| +| CREATE_DEPLOYMENT | Create a new deployment | `sdl`, `sdlFile`, `deposit` | +| CLOSE_DEPLOYMENT | Close an existing deployment | `dseq`, `owner` | +| GET_PROVIDER_INFO | Get provider information | `provider` | +| GET_DEPLOYMENT_STATUS| Check deployment status | `dseq`, `owner` | +| GET_GPU_PRICING | Get GPU pricing comparison | `cpu`, `memory`, `storage` | +| GET_MANIFEST | Generate deployment manifest | `sdl`, `sdlFile` | +| GET_PROVIDERS_LIST | List available providers | `filter: { active, hasGPU, region }` | + + +Each action returns a structured response with: +```typescript +{ + text: string; // Human-readable response + content: { + success: boolean; // Operation success status + data?: any; // Action-specific data + error?: { // Present only on failure + code: string; + message: string; + }; + metadata: { // Operation metadata + timestamp: string; + source: string; + action: string; + version: string; + actionId: string; + } + } +} +``` + +## Error Handling + +The plugin includes comprehensive error handling with specific error codes: + +- `VALIDATION_SDL_FAILED`: SDL validation errors +- `WALLET_NOT_INITIALIZED`: Wallet setup issues +- `DEPLOYMENT_CREATION_FAILED`: Deployment failures +- `API_REQUEST_FAILED`: Network/API issues +- `MANIFEST_PARSING_FAILED`: Manifest generation errors +- `PROVIDER_FILTER_ERROR`: Provider filtering issues + +## Development + +### Running Tests +```bash +pnpm test +``` + +### Building +```bash +pnpm run build +``` + +## License + +This project is licensed under the MIT License - see the LICENSE file for details. + +## Support + +For support and questions, please open an issue in the repository or contact the maintainers. diff --git a/packages/plugin-akash/src/actions/closeDeployment.ts b/packages/plugin-akash/src/actions/closeDeployment.ts new file mode 100644 index 0000000000..ee50e0067d --- /dev/null +++ b/packages/plugin-akash/src/actions/closeDeployment.ts @@ -0,0 +1,521 @@ +import { Action, elizaLogger } from "@elizaos/core"; +import { IAgentRuntime, Memory, State, HandlerCallback, Content, ActionExample } from "@elizaos/core"; +import { DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing"; +import { SigningStargateClient } from "@cosmjs/stargate"; +import { getAkashTypeRegistry, getTypeUrl } from "@akashnetwork/akashjs/build/stargate"; +import { MsgCloseDeployment } from "@akashnetwork/akash-api/akash/deployment/v1beta3"; +import { validateAkashConfig } from "../environment"; +import { fetchDeployments } from "./getDeploymentApi"; +import { AkashError, AkashErrorCode } from "../error/error"; +// import { getCertificatePath } from "../utils/paths"; +import { isPluginLoaded } from "../runtime_inspect"; + +interface CloseDeploymentContent extends Content { + dseq?: string; + closeAll?: boolean; +} + +// Certificate file path +// const CERTIFICATE_PATH = getCertificatePath(import.meta.url); + +// Initialize wallet and client +async function initializeClient(runtime: IAgentRuntime) { + elizaLogger.info("=== Initializing Client for Deployment Closure ==="); + const config = await validateAkashConfig(runtime); + + if (!config.AKASH_MNEMONIC) { + throw new AkashError( + "AKASH_MNEMONIC is required for closing deployments", + AkashErrorCode.WALLET_NOT_INITIALIZED + ); + } + + elizaLogger.debug("Initializing wallet", { + rpcEndpoint: config.RPC_ENDPOINT, + chainId: config.AKASH_CHAIN_ID, + version: config.AKASH_VERSION, + hasMnemonic: !!config.AKASH_MNEMONIC + }); + + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(config.AKASH_MNEMONIC, { + prefix: "akash" + }); + + const [account] = await wallet.getAccounts(); + elizaLogger.debug("Wallet initialized successfully", { + address: account.address, + prefix: "akash" + }); + + // Initialize registry and client + const myRegistry = new Registry(getAkashTypeRegistry()); + const client = await SigningStargateClient.connectWithSigner( + config.AKASH_NODE || "https://rpc.akash.forbole.com:443", + wallet, + { registry: myRegistry } + ); + + elizaLogger.info("Client initialization complete", { + nodeUrl: config.AKASH_NODE || "https://rpc.akash.forbole.com:443", + address: account.address + }); + + return { client, account, wallet }; +} + +// Verify deployment status before closing +async function verifyDeploymentStatus(runtime: IAgentRuntime, dseq: string): Promise { + elizaLogger.info("Verifying deployment status", { dseq }); + + try { + const deployments = await fetchDeployments(runtime, undefined, 0, 100); + const deployment = deployments.results.find(d => d.dseq === dseq); + + if (!deployment) { + throw new AkashError( + `Deployment not found with DSEQ: ${dseq}`, + AkashErrorCode.DEPLOYMENT_NOT_FOUND + ); + } + + if (deployment.status.toLowerCase() !== 'active') { + throw new AkashError( + `Deployment ${dseq} is not active (current status: ${deployment.status})`, + AkashErrorCode.DEPLOYMENT_CLOSE_FAILED + ); + } + + return true; + } catch (error) { + if (error instanceof AkashError) { + throw error; + } + throw new AkashError( + `Failed to verify deployment status: ${error instanceof Error ? error.message : String(error)}`, + AkashErrorCode.DEPLOYMENT_NOT_FOUND + ); + } +} + +// Close a single deployment by DSEQ +async function closeSingleDeployment( + runtime: IAgentRuntime, + dseq: string +): Promise { + elizaLogger.info("Closing single deployment", { dseq }); + + try { + // Verify deployment exists and is active + await verifyDeploymentStatus(runtime, dseq); + + const { client, account } = await initializeClient(runtime); + + // Create close deployment message + const message = MsgCloseDeployment.fromPartial({ + id: { + dseq: dseq, + owner: account.address + } + }); + + const msgAny = { + typeUrl: getTypeUrl(MsgCloseDeployment), + value: message + }; + + // Set fee + const fee = { + amount: [{ denom: "uakt", amount: "20000" }], + gas: "800000" + }; + + // Send transaction + elizaLogger.info("Sending close deployment transaction", { dseq }); + const result = await client.signAndBroadcast( + account.address, + [msgAny], + fee, + `close deployment ${dseq}` + ); + + if (result.code !== 0) { + throw new AkashError( + `Transaction failed: ${result.rawLog}`, + AkashErrorCode.DEPLOYMENT_CLOSE_FAILED, + { rawLog: result.rawLog } + ); + } + + elizaLogger.info("Deployment closed successfully", { + dseq, + transactionHash: result.transactionHash + }); + + return true; + } catch (error) { + elizaLogger.error("Failed to close deployment", { + dseq, + error: error instanceof Error ? error.message : String(error), + code: error instanceof AkashError ? error.code : AkashErrorCode.DEPLOYMENT_CLOSE_FAILED, + stack: error instanceof Error ? error.stack : undefined + }); + throw error; + } +} + +// Close all active deployments +async function closeAllDeployments( + runtime: IAgentRuntime +): Promise<{ success: string[], failed: string[] }> { + elizaLogger.info("Closing all active deployments"); + + try { + // Fetch active deployments + const deployments = await fetchDeployments(runtime, undefined, 0, 100); + const activeDeployments = deployments.results.filter(d => + d.status.toLowerCase() === 'active' + ); + + if (activeDeployments.length === 0) { + elizaLogger.info("No active deployments found to close"); + return { success: [], failed: [] }; + } + + elizaLogger.info("Found active deployments to close", { + count: activeDeployments.length, + dseqs: activeDeployments.map(d => d.dseq) + }); + + // Close each deployment + const results = { success: [] as string[], failed: [] as string[] }; + for (const deployment of activeDeployments) { + try { + await closeSingleDeployment(runtime, deployment.dseq); + results.success.push(deployment.dseq); + } catch (error) { + elizaLogger.error("Failed to close deployment", { + dseq: deployment.dseq, + error: error instanceof Error ? error.message : String(error), + code: error instanceof AkashError ? error.code : AkashErrorCode.DEPLOYMENT_CLOSE_FAILED + }); + results.failed.push(deployment.dseq); + } + } + + elizaLogger.info("Finished closing deployments", results); + return results; + } catch (error) { + elizaLogger.error("Failed to close deployments", { + error: error instanceof Error ? error.message : String(error), + code: error instanceof AkashError ? error.code : AkashErrorCode.DEPLOYMENT_CLOSE_FAILED, + stack: error instanceof Error ? error.stack : undefined + }); + throw error; + } +} + +export const closeDeploymentAction: Action = { + name: "CLOSE_DEPLOYMENT", + similes: ["CLOSE_AKASH_DEPLOYMENT", "STOP_DEPLOYMENT", "TERMINATE_DEPLOYMENT"], + description: "Close an active deployment on the Akash Network", + examples: [[ + { + user: "user", + content: { + text: "Close deployment with DSEQ 123456", + dseq: "123456" + } as CloseDeploymentContent + } as ActionExample, + { + user: "assistant", + content: { + text: "Closing deployment with DSEQ 123456..." + } as CloseDeploymentContent + } as ActionExample + ], [ + { + user: "user", + content: { + text: "Close all active deployments", + closeAll: true + } as CloseDeploymentContent + } as ActionExample, + { + user: "assistant", + content: { + text: "Closing all active deployments..." + } as CloseDeploymentContent + } as ActionExample + ]], + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + elizaLogger.debug("=== Starting Close Deployment Validation ==="); + elizaLogger.debug("Validating close deployment request", { message }); + + // Check if plugin is properly loaded + if (!isPluginLoaded(runtime, "akash")) { + elizaLogger.error("Akash plugin not properly loaded during validation"); + return false; + } + + try { + const params = message.content as Partial; + const config = await validateAkashConfig(runtime); + elizaLogger.debug("Validating parameters", { params }); + + // If no parameters provided, use environment defaults + if (!params.dseq && !params.closeAll) { + if (config.AKASH_CLOSE_DEP === "closeAll") { + params.closeAll = true; + } else if (config.AKASH_CLOSE_DEP === "dseq" && config.AKASH_CLOSE_DSEQ) { + params.dseq = config.AKASH_CLOSE_DSEQ; + } else { + throw new AkashError( + "Either dseq or closeAll parameter is required", + AkashErrorCode.VALIDATION_PARAMETER_MISSING, + { parameters: ["dseq", "closeAll"] } + ); + } + } + + if (params.dseq && params.closeAll) { + throw new AkashError( + "Cannot specify both dseq and closeAll parameters", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameters: ["dseq", "closeAll"] } + ); + } + + if (params.dseq && !/^\d+$/.test(params.dseq)) { + throw new AkashError( + "DSEQ must be a numeric string", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "dseq", value: params.dseq } + ); + } + + elizaLogger.debug("Validation completed successfully"); + return true; + } catch (error) { + elizaLogger.error("Close deployment validation failed", { + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : String(error) + }); + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State | undefined, + _options: { [key: string]: unknown } = {}, + callback?: HandlerCallback + ): Promise => { + const actionId = Date.now().toString(); + elizaLogger.info("=== Starting Close Deployment Request ===", { + actionId, + messageId: message.id, + userId: message.userId + }); + + try { + const config = await validateAkashConfig(runtime); + const params = message.content as Partial; + + // If no parameters provided, use environment defaults + if (!params.dseq && !params.closeAll) { + if (config.AKASH_CLOSE_DEP === "closeAll") { + params.closeAll = true; + } else if (config.AKASH_CLOSE_DEP === "dseq" && config.AKASH_CLOSE_DSEQ) { + params.dseq = config.AKASH_CLOSE_DSEQ; + } else { + if (callback) { + elizaLogger.info("=== Preparing error callback response ===", { + actionId, + hasCallback: true, + errorType: 'AkashError' + }); + + const errorResponse = { + text: "Either DSEQ or closeAll parameter is required", + content: { + success: false, + error: { + code: AkashErrorCode.VALIDATION_PARAMETER_MISSING, + message: "Either dseq or closeAll parameter is required" + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'closeDeployment', + version: '1.0.0', + actionId + } + } + }; + + callback(errorResponse); + } + return false; + } + } + + if (params.closeAll) { + const results = await closeAllDeployments(runtime); + + if (callback) { + elizaLogger.info("=== Preparing callback response for bulk closure ===", { + hasCallback: true, + actionId, + successCount: results.success.length, + failedCount: results.failed.length + }); + + const callbackResponse = { + text: `Deployment Closure Results:\n\nSuccessfully closed: ${results.success.length} deployments${ + results.success.length > 0 ? `\nDSEQs: ${results.success.join(', ')}` : '' + }${ + results.failed.length > 0 ? `\n\nFailed to close: ${results.failed.length} deployments\nDSEQs: ${results.failed.join(', ')}` : '' + }`, + content: { + success: results.failed.length === 0, + data: { + successful: results.success, + failed: results.failed, + totalClosed: results.success.length, + totalFailed: results.failed.length + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'closeDeployment', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing callback with response ===", { + actionId, + responseText: callbackResponse.text, + hasContent: !!callbackResponse.content, + contentKeys: Object.keys(callbackResponse.content), + metadata: callbackResponse.content.metadata + }); + + callback(callbackResponse); + + elizaLogger.info("=== Callback executed successfully ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + return results.failed.length === 0; + + } else if (params.dseq) { + const success = await closeSingleDeployment(runtime, params.dseq); + + if (callback) { + elizaLogger.info("=== Preparing callback response for single closure ===", { + hasCallback: true, + actionId, + dseq: params.dseq, + success + }); + + const callbackResponse = { + text: success ? + `Successfully closed deployment DSEQ: ${params.dseq}` : + `Failed to close deployment DSEQ: ${params.dseq}`, + content: { + success, + data: { + dseq: params.dseq + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'closeDeployment', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing callback with response ===", { + actionId, + responseText: callbackResponse.text, + hasContent: !!callbackResponse.content, + contentKeys: Object.keys(callbackResponse.content), + metadata: callbackResponse.content.metadata + }); + + callback(callbackResponse); + + elizaLogger.info("=== Callback executed successfully ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + return success; + } + + return false; + + } catch (error) { + elizaLogger.error("Close deployment request failed", { + error: error instanceof Error ? error.message : String(error), + code: error instanceof AkashError ? error.code : AkashErrorCode.DEPLOYMENT_CLOSE_FAILED, + actionId + }); + + if (callback) { + elizaLogger.info("=== Preparing error callback response ===", { + actionId, + hasCallback: true, + errorType: error instanceof AkashError ? 'AkashError' : 'Error' + }); + + const errorResponse = { + text: `Failed to close deployment: ${error instanceof Error ? error.message : String(error)}`, + content: { + success: false, + error: { + code: error instanceof AkashError ? error.code : AkashErrorCode.DEPLOYMENT_CLOSE_FAILED, + message: error instanceof Error ? error.message : String(error) + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'closeDeployment', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing error callback ===", { + actionId, + responseText: errorResponse.text, + hasContent: !!errorResponse.content, + contentKeys: Object.keys(errorResponse.content) + }); + + callback(errorResponse); + + elizaLogger.info("=== Error callback executed ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + + return false; + } + } +}; + +export default closeDeploymentAction; \ No newline at end of file diff --git a/packages/plugin-akash/src/actions/createCertificate.ts b/packages/plugin-akash/src/actions/createCertificate.ts new file mode 100644 index 0000000000..67058e2d16 --- /dev/null +++ b/packages/plugin-akash/src/actions/createCertificate.ts @@ -0,0 +1,456 @@ +import { Action, elizaLogger } from "@elizaos/core"; +import { IAgentRuntime, Memory, State, HandlerCallback, Content, ActionExample } from "@elizaos/core"; +import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; +import { SigningStargateClient } from "@cosmjs/stargate"; +import * as cert from "@akashnetwork/akashjs/build/certificates"; +import { certificateManager } from "@akashnetwork/akashjs/build/certificates/certificate-manager"; +import { CertificatePem } from "@akashnetwork/akashjs/build/certificates/certificate-manager/CertificateManager"; +import { getAkashTypeRegistry } from "@akashnetwork/akashjs/build/stargate"; +import { validateAkashConfig } from "../environment"; +import { AkashError, AkashErrorCode, withRetry } from "../error/error"; +import * as fs from 'fs'; +import * as path from 'path'; +import { Registry } from "@cosmjs/proto-signing"; +import type { SigningStargateClient as AkashSigningStargateClient } from "@akashnetwork/akashjs/node_modules/@cosmjs/stargate"; +import { getCertificatePath } from "../utils/paths"; + +interface CreateCertificateContent extends Content { + overwrite?: boolean; +} + +// Certificate file path +const CERTIFICATE_PATH = getCertificatePath(import.meta.url); + +// Save certificate to file +async function saveCertificate(certificate: CertificatePem): Promise { + elizaLogger.debug("Saving certificate to file", { path: CERTIFICATE_PATH }); + try { + // Ensure directory exists + const dir = path.dirname(CERTIFICATE_PATH); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + const json = JSON.stringify(certificate); + fs.writeFileSync(CERTIFICATE_PATH, json); + elizaLogger.debug("Certificate saved successfully"); + } catch (error) { + elizaLogger.error("Failed to save certificate", { + error: error instanceof Error ? error.message : String(error), + path: CERTIFICATE_PATH + }); + throw new AkashError( + "Failed to save certificate", + AkashErrorCode.FILE_WRITE_ERROR, + { path: CERTIFICATE_PATH, error } + ); + } +} + +// Load certificate from file +function loadCertificate(): CertificatePem { + elizaLogger.debug("Loading certificate from file", { path: CERTIFICATE_PATH }); + try { + if (!fs.existsSync(CERTIFICATE_PATH)) { + throw new AkashError( + "Certificate file not found", + AkashErrorCode.CERTIFICATE_NOT_FOUND, + { path: CERTIFICATE_PATH } + ); + } + const json = fs.readFileSync(CERTIFICATE_PATH, "utf8"); + const certificate = JSON.parse(json); + elizaLogger.debug("Certificate loaded successfully", { + hasCert: !!certificate.cert, + hasPrivateKey: !!certificate.privateKey, + hasPublicKey: !!certificate.publicKey + }); + return certificate; + } catch (error) { + elizaLogger.error("Failed to load certificate", { + error: error instanceof Error ? error.message : String(error), + path: CERTIFICATE_PATH + }); + if (error instanceof AkashError) { + throw error; + } + throw new AkashError( + "Failed to load certificate", + AkashErrorCode.FILE_READ_ERROR, + { path: CERTIFICATE_PATH, error } + ); + } +} + +// Initialize wallet with proper error handling +async function initializeWallet(mnemonic: string): Promise { + elizaLogger.debug("=== Initializing Wallet ===", { + mnemonicLength: mnemonic.split(' ').length, + hasMnemonic: !!mnemonic, + mnemonicFirstWord: mnemonic.split(' ')[0] + }); + + // Validate mnemonic format + const words = mnemonic.trim().split(/\s+/); + if (words.length !== 12 && words.length !== 24) { + const error = `Invalid mnemonic length: got ${words.length} words, expected 12 or 24 words`; + elizaLogger.error("Mnemonic validation failed", { + error, + wordCount: words.length, + expectedCounts: [12, 24], + mnemonicPreview: words.slice(0, 3).join(' ') + '...' + }); + throw new AkashError( + error, + AkashErrorCode.WALLET_INITIALIZATION_FAILED, + { + wordCount: words.length, + expectedCounts: [12, 24] + } + ); + } + + try { + elizaLogger.debug("Creating wallet with mnemonic", { + wordCount: words.length, + mnemonicPreview: words.slice(0, 3).join(' ') + '...' + }); + + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { + prefix: "akash" + }); + const accounts = await wallet.getAccounts(); + + elizaLogger.debug("Wallet initialized successfully", { + accountCount: accounts.length, + firstAccountAddress: accounts[0]?.address, + addressPrefix: accounts[0]?.address?.substring(0, 6) + }); + + if (!accounts.length) { + throw new AkashError( + "No accounts found in wallet", + AkashErrorCode.WALLET_INITIALIZATION_FAILED + ); + } + + return wallet; + } catch (error) { + elizaLogger.error("Wallet initialization failed", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + mnemonicLength: words.length, + mnemonicPreview: words.slice(0, 3).join(' ') + '...' + }); + + if (error instanceof AkashError) { + throw error; + } + + throw new AkashError( + `Failed to initialize wallet: ${error instanceof Error ? error.message : String(error)}`, + AkashErrorCode.WALLET_INITIALIZATION_FAILED, + { + mnemonicLength: words.length, + error: error instanceof Error ? error.message : String(error) + } + ); + } +} + +// Setup client with proper error handling and fallback RPC endpoints +async function setupClient(wallet: DirectSecp256k1HdWallet, rpcEndpoint: string): Promise { + // Try alternative RPC endpoints if the main one fails + const rpcEndpoints = [ + rpcEndpoint, + "https://rpc.akashnet.net:443", + "https://akash-rpc.polkachu.com:443", + "https://akash-rpc.europlots.com:443" + ]; + + elizaLogger.info("=== Setting up Stargate Client ===", { + primaryRpcEndpoint: rpcEndpoint, + allEndpoints: rpcEndpoints, + walletType: wallet.constructor.name + }); + + let lastError: Error | undefined; + for (const endpoint of rpcEndpoints) { + try { + elizaLogger.debug("Attempting to connect to RPC endpoint", { + endpoint, + attempt: rpcEndpoints.indexOf(endpoint) + 1, + totalEndpoints: rpcEndpoints.length + }); + + const registry = new Registry(getAkashTypeRegistry()); + elizaLogger.debug("Registry created for endpoint", { + endpoint, + registryType: registry.constructor.name + }); + + const client = await SigningStargateClient.connectWithSigner( + endpoint, + wallet, + { registry } + ); + + elizaLogger.debug("Client setup completed successfully", { + endpoint, + clientType: client.constructor.name + }); + + return client; + } catch (error) { + lastError = error as Error; + elizaLogger.warn("Failed to connect to RPC endpoint", { + endpoint, + error: error instanceof Error ? error.message : String(error), + remainingEndpoints: rpcEndpoints.slice(rpcEndpoints.indexOf(endpoint) + 1).length + }); + } + } + + throw new AkashError( + `Failed to connect to any RPC endpoint: ${lastError?.message}`, + AkashErrorCode.CLIENT_SETUP_FAILED, + { lastError } + ); +} + +export const createCertificateAction: Action = { + name: "CREATE_CERTIFICATE", + similes: ["GENERATE_CERTIFICATE", "SETUP_CERTIFICATE", "INIT_CERTIFICATE"], + description: "Create or load Akash certificate for provider interactions", + examples: [[ + { + user: "user", + content: { + text: "Create a new certificate", + overwrite: true + } as CreateCertificateContent + } as ActionExample, + { + user: "assistant", + content: { + text: "Creating new certificate..." + } as CreateCertificateContent + } as ActionExample + ]], + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + elizaLogger.debug("=== Starting Certificate Validation ==="); + try { + const params = message.content as Partial; + + // Validate Akash configuration + await validateAkashConfig(runtime); + + // If overwrite is specified, it must be a boolean + if (params.overwrite !== undefined && typeof params.overwrite !== 'boolean') { + throw new AkashError( + "Overwrite parameter must be a boolean", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "overwrite", value: params.overwrite } + ); + } + + elizaLogger.debug("Certificate validation completed successfully"); + return true; + } catch (error) { + elizaLogger.error("Certificate validation failed", { + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : String(error) + }); + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State | undefined, + options: { callback?: HandlerCallback } = {} + ): Promise => { + const actionId = Date.now().toString(); + elizaLogger.info("=== Starting Certificate Creation/Loading ===", { actionId }); + + try { + // First validate the parameters + if (!await createCertificateAction.validate(runtime, message)) { + const error = new AkashError( + "Invalid parameters provided", + AkashErrorCode.VALIDATION_PARAMETER_INVALID + ); + if (options.callback) { + options.callback({ + text: `Failed to validate parameters: ${error.message}`, + error: error.message, + content: { + success: false, + error: { + code: error.code, + message: error.message + } + } + }); + } + return false; + } + + const params = message.content as Partial; + const config = await validateAkashConfig(runtime); + + try { + // Check if certificate exists and overwrite is not true + if (fs.existsSync(CERTIFICATE_PATH) && !params.overwrite) { + elizaLogger.info("Loading existing certificate"); + const certificate = loadCertificate(); + + if (options.callback) { + options.callback({ + text: "Loaded existing certificate", + content: { + success: true, + certificate: { + hasCert: !!certificate.cert, + hasPrivateKey: !!certificate.privateKey, + hasPublicKey: !!certificate.publicKey + } + } + }); + } + return true; + } + + // Initialize wallet + elizaLogger.info("Initializing wallet for certificate creation"); + const wallet = await initializeWallet(config.AKASH_MNEMONIC); + const accounts = await wallet.getAccounts(); + const address = accounts[0].address; + elizaLogger.debug("Wallet initialized", { + address, + accountCount: accounts.length + }); + + // Setup client + elizaLogger.debug("Setting up Stargate client"); + const client = await setupClient(wallet, config.RPC_ENDPOINT); + elizaLogger.debug("Client setup completed"); + + // Generate new certificate + elizaLogger.info("Generating new certificate"); + const certificate = certificateManager.generatePEM(address); + elizaLogger.debug("Certificate generated", { + hasCert: !!certificate.cert, + hasPrivateKey: !!certificate.privateKey, + hasPublicKey: !!certificate.publicKey + }); + + // Broadcast certificate + elizaLogger.info("Broadcasting certificate to network"); + const result = await withRetry(async () => { + return await cert.broadcastCertificate( + certificate, + address, + client as unknown as AkashSigningStargateClient + ); + }); + + if (result.code !== 0) { + throw new AkashError( + `Could not create certificate: ${result.rawLog}`, + AkashErrorCode.CERTIFICATE_CREATION_FAILED, + { rawLog: result.rawLog } + ); + } + + elizaLogger.info("Certificate broadcast successful", { + code: result.code, + txHash: result.transactionHash, + height: result.height, + gasUsed: result.gasUsed + }); + + // Save certificate + await saveCertificate(certificate); + elizaLogger.info("Certificate saved to file", { path: CERTIFICATE_PATH }); + + if (options.callback) { + options.callback({ + text: "Certificate created and saved successfully", + content: { + success: true, + certificate: { + hasCert: !!certificate.cert, + hasPrivateKey: !!certificate.privateKey, + hasPublicKey: !!certificate.publicKey + }, + transaction: { + hash: result.transactionHash, + height: result.height, + gasUsed: result.gasUsed + } + } + }); + } + + return true; + } catch (error) { + elizaLogger.error("Failed to create/load certificate", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined + }); + + if (options.callback) { + options.callback({ + text: `Failed to create/load certificate: ${error instanceof Error ? error.message : String(error)}`, + error: error instanceof Error ? error.message : String(error), + content: { + success: false, + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : { + code: AkashErrorCode.CERTIFICATE_CREATION_FAILED, + message: String(error) + } + } + }); + } + return false; + } + } catch (error) { + elizaLogger.error("Certificate operation failed", { + error: error instanceof Error ? error.message : String(error), + code: error instanceof AkashError ? error.code : AkashErrorCode.CERTIFICATE_CREATION_FAILED, + actionId + }); + + if (options.callback) { + options.callback({ + text: `Certificate operation failed: ${error instanceof Error ? error.message : String(error)}`, + error: error instanceof Error ? error.message : String(error), + content: { + success: false, + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : { + code: AkashErrorCode.CERTIFICATE_CREATION_FAILED, + message: String(error) + } + } + }); + } + + return false; + } + } +}; + +export default createCertificateAction; diff --git a/packages/plugin-akash/src/actions/createDeployment.ts b/packages/plugin-akash/src/actions/createDeployment.ts new file mode 100644 index 0000000000..d64c5a6ebc --- /dev/null +++ b/packages/plugin-akash/src/actions/createDeployment.ts @@ -0,0 +1,1471 @@ +import { Action, elizaLogger } from "@elizaos/core"; +import { IAgentRuntime, Memory, State, HandlerCallback, Content, ActionExample } from "@elizaos/core"; +import { MsgCreateDeployment } from "@akashnetwork/akash-api/akash/deployment/v1beta3"; +import { QueryClientImpl as QueryProviderClient, QueryProviderRequest } from "@akashnetwork/akash-api/akash/provider/v1beta3"; +import { QueryBidsRequest, QueryClientImpl as QueryMarketClient, MsgCreateLease, BidID } from "@akashnetwork/akash-api/akash/market/v1beta4"; +import * as cert from "@akashnetwork/akashjs/build/certificates"; +import { getRpc } from "@akashnetwork/akashjs/build/rpc"; +import { SDL } from "@akashnetwork/akashjs/build/sdl"; +import { getAkashTypeRegistry } from "@akashnetwork/akashjs/build/stargate"; +import { CertificatePem } from "@akashnetwork/akashjs/build/certificates/certificate-manager/CertificateManager"; +import { certificateManager } from "@akashnetwork/akashjs/build/certificates/certificate-manager"; +import { DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing"; +import { SigningStargateClient } from "@cosmjs/stargate"; +import { validateAkashConfig } from "../environment"; +import { AkashError, AkashErrorCode, withRetry } from "../error/error"; +import * as fs from 'fs'; +import * as path from 'path'; +import { getCertificatePath, getDefaultSDLPath } from "../utils/paths"; +// import { fileURLToPath } from 'url'; +import { inspectRuntime, isPluginLoaded } from "../runtime_inspect"; +import https from 'node:https'; +import axios from 'axios'; + +interface CreateDeploymentContent extends Content { + sdl?: string; + sdlFile?: string; + deposit?: string; +} + +// Certificate file path +const CERTIFICATE_PATH = getCertificatePath(import.meta.url); + +// Save certificate to file +function saveCertificate(certificate: CertificatePem) { + elizaLogger.debug("Saving certificate to file", { path: CERTIFICATE_PATH }); + try { + // Ensure directory exists + const dir = path.dirname(CERTIFICATE_PATH); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + const json = JSON.stringify(certificate); + fs.writeFileSync(CERTIFICATE_PATH, json); + elizaLogger.debug("Certificate saved successfully"); + } catch (error) { + elizaLogger.error("Failed to save certificate", { + error: error instanceof Error ? error.message : String(error), + path: CERTIFICATE_PATH + }); + throw error; + } +} + +// Load certificate from file +function loadCertificate(path: string): CertificatePem { + elizaLogger.debug("Loading certificate from file", { path }); + try { + const json = fs.readFileSync(path, "utf8"); + const certificate = JSON.parse(json); + elizaLogger.debug("Certificate loaded successfully", { + hasCert: !!certificate.cert, + hasPrivateKey: !!certificate.privateKey, + hasPublicKey: !!certificate.publicKey + }); + return certificate; + } catch (error) { + elizaLogger.error("Failed to load certificate", { + error: error instanceof Error ? error.message : String(error), + path + }); + throw error; + } +} + +const DEFAULT_SDL_PATH = (() => { + const currentFileUrl = import.meta.url; + // elizaLogger.info("=== Starting SDL Path Resolution in createDeployment ===", { + // currentFileUrl, + // cwd: process.cwd(), + // importMetaUrl: import.meta.url + // }); + + // Use the utility function from paths.ts instead of manual resolution + const sdlPath = getDefaultSDLPath(currentFileUrl); + + // Only log if file doesn't exist + if (!fs.existsSync(sdlPath)) { + elizaLogger.warn("Default SDL path not found", { + sdlPath, + exists: false + }); + } + + return sdlPath; +})(); + +const validateDeposit = (deposit: string): boolean => { + const pattern = /^\d+uakt$/; + return pattern.test(deposit); +}; + +const loadSDLFromFile = (filePath: string): string => { + // elizaLogger.info("=== Loading SDL File ===", { + // requestedPath: filePath, + // resolvedPath: path.resolve(filePath), + // defaultSdlPath: DEFAULT_SDL_PATH, + // cwd: process.cwd(), + // exists: fs.existsSync(filePath), + // defaultExists: fs.existsSync(DEFAULT_SDL_PATH) + // }); + + try { + // If path doesn't contain plugin-akash and it's not the default path, adjust it + if (!filePath.includes('plugin-akash') && filePath !== DEFAULT_SDL_PATH) { + const adjustedPath = path.join(path.dirname(DEFAULT_SDL_PATH), path.basename(filePath)); + // elizaLogger.info("Adjusting SDL path", { + // originalPath: filePath, + // adjustedPath, + // exists: fs.existsSync(adjustedPath), + // dirExists: fs.existsSync(path.dirname(adjustedPath)), + // dirContents: fs.existsSync(path.dirname(adjustedPath)) ? fs.readdirSync(path.dirname(adjustedPath)) : [] + // }); + filePath = adjustedPath; + } + + // Try multiple possible locations + const possiblePaths = [ + filePath, + path.join(process.cwd(), filePath), + path.join(process.cwd(), 'packages', 'plugin-akash', filePath), + path.join(process.cwd(), 'packages', 'plugin-akash', 'src', filePath), + path.join(path.dirname(DEFAULT_SDL_PATH), filePath) + ]; + + // elizaLogger.info("Attempting to load SDL from possible paths", { + // possiblePaths, + // existsMap: possiblePaths.map(p => ({ path: p, exists: fs.existsSync(p) })) + // }); + + for (const tryPath of possiblePaths) { + if (fs.existsSync(tryPath)) { + const content = fs.readFileSync(tryPath, "utf8"); + elizaLogger.info("SDL file loaded successfully from", { + path: tryPath + }); + return content; + } + } + + // If we get here, none of the paths worked + throw new Error(`SDL file not found in any of the possible locations`); + } catch (error) { + elizaLogger.error("Failed to read SDL file", { + filePath, + error: error instanceof Error ? error.message : String(error) + }); + throw new AkashError( + `Failed to read SDL file: ${error instanceof Error ? error.message : String(error)}`, + AkashErrorCode.VALIDATION_SDL_FAILED, + { filePath } + ); + } +}; + +// Preserved for future use +/* const formatErrorMessage = (error: unknown): string => { + if (error instanceof AkashError) { + if (error.code === AkashErrorCode.WALLET_NOT_INITIALIZED) { + return "Akash wallet not initialized"; + } + if (error.code === AkashErrorCode.DEPLOYMENT_CREATION_FAILED) { + return `Transaction failed: ${error.details?.rawLog || 'Unknown error'}`; + } + if (error.code === AkashErrorCode.MANIFEST_PARSING_FAILED) { + return "Failed to parse SDL"; + } + if (error.code === AkashErrorCode.VALIDATION_PARAMETER_MISSING) { + return `${error.message}`; + } + if (error.code === AkashErrorCode.VALIDATION_SDL_FAILED) { + return `Failed to parse SDL: ${error.details?.error || error.message}`; + } + if (error.code === AkashErrorCode.VALIDATION_PARAMETER_INVALID) { + return `Invalid deposit format. Must be in format: uakt`; + } + return error.message; + } + + const message = error instanceof Error ? error.message : String(error); + if (message.toLowerCase().includes("insufficient funds")) { + return "Insufficient funds"; + } + if (message.toLowerCase().includes("invalid deposit")) { + return "Invalid deposit amount"; + } + if (message.toLowerCase().includes("cannot read properties")) { + return "Failed to parse SDL: Invalid format"; + } + return message; +}; */ + +async function initializeWallet(mnemonic: string) { + elizaLogger.debug("=== Initializing Wallet ===", { + mnemonicLength: mnemonic.split(' ').length, + hasMnemonic: !!mnemonic, + mnemonicFirstWord: mnemonic.split(' ')[0] + }); + + // Validate mnemonic format + const words = mnemonic.trim().split(/\s+/); + if (words.length !== 12 && words.length !== 24) { + const error = `Invalid mnemonic length: got ${words.length} words, expected 12 or 24 words`; + elizaLogger.error("Mnemonic validation failed", { + error, + wordCount: words.length, + expectedCounts: [12, 24], + mnemonicPreview: words.slice(0, 3).join(' ') + '...' + }); + throw new AkashError( + error, + AkashErrorCode.WALLET_INITIALIZATION_FAILED, + { + wordCount: words.length, + expectedCounts: [12, 24] + } + ); + } + + try { + elizaLogger.debug("Creating wallet with mnemonic", { + wordCount: words.length, + mnemonicPreview: words.slice(0, 3).join(' ') + '...' + }); + + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { + prefix: "akash" + }); + const accounts = await wallet.getAccounts(); + + elizaLogger.debug("Wallet initialized successfully", { + accountCount: accounts.length, + firstAccountAddress: accounts[0]?.address, + addressPrefix: accounts[0]?.address?.substring(0, 6) + }); + + if (!accounts.length) { + throw new AkashError( + "No accounts found in wallet", + AkashErrorCode.WALLET_INITIALIZATION_FAILED + ); + } + + return wallet; + } catch (error) { + elizaLogger.error("Wallet initialization failed", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + mnemonicLength: words.length, + mnemonicPreview: words.slice(0, 3).join(' ') + '...' + }); + + // Provide more specific error messages + const errorMessage = error instanceof Error ? error.message : String(error); + if (errorMessage.includes("Invalid mnemonic")) { + throw new AkashError( + "Invalid mnemonic format: The mnemonic phrase contains invalid words or is malformed", + AkashErrorCode.WALLET_INITIALIZATION_FAILED, + { + mnemonicLength: words.length, + error: errorMessage + } + ); + } + + throw new AkashError( + `Failed to initialize wallet: ${errorMessage}`, + AkashErrorCode.WALLET_INITIALIZATION_FAILED, + { + mnemonicLength: words.length, + error: errorMessage + } + ); + } +} + +async function setupClient(wallet: DirectSecp256k1HdWallet, rpcEndpoint: string) { + // Try alternative RPC endpoints if the main one fails + const rpcEndpoints = [ + "https://akash-rpc.europlots.com:443", // New endpoint first + rpcEndpoint, + "https://rpc.akashnet.net:443", + "https://rpc.akash.forbole.com:443", + "https://rpc-akash.ecostake.com:443", + "https://akash-rpc.polkachu.com:443", + "https://akash.c29r3.xyz:443/rpc" + ]; + + elizaLogger.info("=== Setting up Stargate Client ===", { + primaryRpcEndpoint: rpcEndpoint, + allEndpoints: rpcEndpoints, + walletType: wallet.constructor.name, + preferredEndpoint: rpcEndpoints[0] + }); + + let lastError: Error | undefined; + for (const endpoint of rpcEndpoints) { + try { + elizaLogger.debug("Attempting to connect to RPC endpoint", { + endpoint, + attempt: rpcEndpoints.indexOf(endpoint) + 1, + totalEndpoints: rpcEndpoints.length + }); + + const registry = new Registry(getAkashTypeRegistry()); + elizaLogger.debug("Registry created for endpoint", { + endpoint, + registryType: registry.constructor.name + }); + + const client = await SigningStargateClient.connectWithSigner( + endpoint, + wallet, + { registry } + ); + + // Check if client is connected by attempting to get the height + try { + const height = await client.getHeight(); + elizaLogger.info("Stargate client setup successful", { + endpoint, + height, + clientType: client.constructor.name, + attempt: rpcEndpoints.indexOf(endpoint) + 1 + }); + return client; + } catch (heightError) { + elizaLogger.error("Failed to get chain height", { + endpoint, + attempt: rpcEndpoints.indexOf(endpoint) + 1, + error: heightError instanceof Error ? heightError.message : String(heightError) + }); + lastError = heightError instanceof Error ? heightError : new Error(String(heightError)); + continue; + } + } catch (error) { + elizaLogger.error("Failed to connect to RPC endpoint", { + endpoint, + attempt: rpcEndpoints.indexOf(endpoint) + 1, + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined + }); + lastError = error instanceof Error ? error : new Error(String(error)); + continue; + } + } + + // If we get here, all endpoints failed + elizaLogger.error("All RPC endpoints failed", { + endpoints: rpcEndpoints, + lastError: lastError?.message, + totalAttempts: rpcEndpoints.length + }); + throw new AkashError( + `Failed to setup client: ${lastError?.message}`, + AkashErrorCode.CLIENT_SETUP_FAILED, + { rpcEndpoint: rpcEndpoints.join(", ") } + ); +} + +async function fetchBid(dseq: number, owner: string, rpcEndpoint: string) { + elizaLogger.info("=== Starting Bid Fetch Process ===", { + dseq, + owner, + ownerPrefix: owner.substring(0, 6) + }); + + const maxRetries = 3; + let lastError: Error | undefined; + + for (let retry = 0; retry < maxRetries; retry++) { + try { + elizaLogger.debug("Connecting to RPC for bid fetch", { + rpcEndpoint, + attempt: retry + 1, + maxRetries + }); + + const rpc = await getRpc(rpcEndpoint); + elizaLogger.debug("RPC connection established", { + rpcType: rpc.constructor.name, + attempt: retry + 1 + }); + + const client = new QueryMarketClient(rpc); + const request = QueryBidsRequest.fromPartial({ + filters: { + owner: owner, + dseq: dseq + } + }); + + const startTime = Date.now(); + const timeout = 1000 * 60 * 5; // 5 minutes timeout + elizaLogger.debug("Starting bid polling loop", { + timeout: "5 minutes", + pollInterval: "5 seconds", + attempt: retry + 1 + }); + + while (Date.now() - startTime < timeout) { + const elapsedTime = Math.round((Date.now() - startTime) / 1000); + elizaLogger.debug("Polling for bids", { + dseq, + owner: owner.substring(0, 6), + elapsedSeconds: elapsedTime, + remainingSeconds: Math.round(timeout/1000 - elapsedTime), + attempt: retry + 1 + }); + + try { + await new Promise(resolve => setTimeout(resolve, 5000)); + const bids = await client.Bids(request); + + if (bids.bids.length > 0 && bids.bids[0].bid !== undefined) { + elizaLogger.info("Bid found successfully", { + dseq, + owner: owner.substring(0, 6), + bidCount: bids.bids.length, + elapsedSeconds: elapsedTime, + attempt: retry + 1 + }); + elizaLogger.debug("Bid details", { + bid: bids.bids[0].bid, + provider: bids.bids[0].bid?.bidId?.provider + }); + return bids.bids[0].bid; + } + } catch (pollError) { + // Log but continue polling if it's a temporary error + elizaLogger.warn("Temporary error during bid polling", { + error: pollError instanceof Error ? pollError.message : String(pollError), + dseq, + attempt: retry + 1, + willRetry: true + }); + continue; + } + } + + elizaLogger.error("Bid fetch timeout", { + dseq, + owner: owner.substring(0, 6), + timeout: "5 minutes", + attempt: retry + 1 + }); + throw new AkashError( + `Could not fetch bid for deployment ${dseq}. Timeout reached.`, + AkashErrorCode.BID_FETCH_TIMEOUT, + { dseq, owner } + ); + } catch (error) { + lastError = error instanceof Error ? error : new Error(String(error)); + elizaLogger.error("Error during bid fetch", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + dseq, + owner: owner.substring(0, 6), + attempt: retry + 1, + hasMoreRetries: retry < maxRetries - 1 + }); + + if (retry < maxRetries - 1) { + // Wait before retrying (exponential backoff) + const delay = Math.pow(2, retry) * 1000; + elizaLogger.info("Retrying bid fetch after delay", { + delay, + nextAttempt: retry + 2, + maxRetries + }); + await new Promise(resolve => setTimeout(resolve, delay)); + continue; + } + } + } + + // If we get here, all retries failed + elizaLogger.error("All bid fetch attempts failed", { + dseq, + owner: owner.substring(0, 6), + attempts: maxRetries, + finalError: lastError?.message + }); + throw lastError || new Error("Failed to fetch bid after all retries"); +} + +async function createLease(deployment: any, wallet: DirectSecp256k1HdWallet, client: SigningStargateClient, rpcEndpoint: string): Promise { + const { dseq, owner } = deployment.id; + elizaLogger.info("Starting lease creation", { dseq, owner }); + + try { + elizaLogger.debug("Fetching bid for lease creation"); + const bid = await fetchBid(dseq, owner, rpcEndpoint); + const accounts = await wallet.getAccounts(); + + if (bid.bidId === undefined) { + elizaLogger.error("Invalid bid - missing bidId", { dseq, owner }); + throw new AkashError("Bid ID is undefined", AkashErrorCode.INVALID_BID); + } + + elizaLogger.debug("Creating lease message", { + dseq, + owner, + bidId: bid.bidId + }); + + const lease = { + bidId: bid.bidId + }; + + const fee = { + amount: [{ denom: "uakt", amount: "50000" }], + gas: "2000000" + }; + + const msg = { + typeUrl: `/${MsgCreateLease.$type}`, + value: MsgCreateLease.fromPartial(lease) + }; + + elizaLogger.info("Broadcasting lease creation transaction"); + const tx = await client.signAndBroadcast(accounts[0].address, [msg], fee, "create lease"); + + if (tx.code !== 0) { + elizaLogger.error("Lease creation failed", { + dseq, + owner, + code: tx.code, + rawLog: tx.rawLog + }); + throw new AkashError( + `Could not create lease: ${tx.rawLog}`, + AkashErrorCode.LEASE_CREATION_FAILED, + { rawLog: tx.rawLog } + ); + } + + elizaLogger.info("Lease created successfully", { + dseq, + owner, + txHash: tx.transactionHash + }); + + return { + id: BidID.toJSON(bid.bidId) + }; + } catch (error) { + elizaLogger.error("Error during lease creation", { + error, + dseq, + owner + }); + throw error; + } +} + +interface LeaseStatus { + services: Record; +} + +async function queryLeaseStatus(lease: any, providerUri: string, certificate: CertificatePem): Promise { + const id = lease.id; + elizaLogger.info("Querying lease status", { + dseq: id?.dseq, + gseq: id?.gseq, + oseq: id?.oseq, + providerUri + }); + + if (id === undefined) { + elizaLogger.error("Invalid lease - missing ID"); + throw new AkashError("Lease ID is undefined", AkashErrorCode.INVALID_LEASE); + } + + const leasePath = `/lease/${id.dseq}/${id.gseq}/${id.oseq}/status`; + elizaLogger.debug("Setting up request", { + providerUri, + leasePath, + hasCert: !!certificate.cert, + hasKey: !!certificate.privateKey + }); + + const MAX_RETRIES = 3; + const INITIAL_RETRY_DELAY = 3000; + let retryCount = 0; + + while (retryCount < MAX_RETRIES) { + try { + const url = new URL(providerUri); + const fullUrl = `${url.protocol}//${url.hostname}${url.port ? ':' + url.port : ''}${leasePath}`; + + elizaLogger.debug("Making request", { + url: fullUrl, + method: 'GET', + hasCertificate: !!certificate, + retryCount + }); + + const agent = new https.Agent({ + cert: certificate.cert, + key: certificate.privateKey, + rejectUnauthorized: false, + keepAlive: false, + timeout: 10000 + }); + + try { + const response = await fetch(fullUrl, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + // @ts-expect-error - TypeScript's fetch types don't include Node's agent support, but it exists at runtime + agent, + signal: AbortSignal.timeout(10000) + }); + + if (response.status !== 200) { + elizaLogger.warn("Non-OK response from lease status query", { + statusCode: response.status, + statusText: response.statusText, + dseq: id.dseq, + url: fullUrl, + retryCount + }); + + if (response.status === 404) { + elizaLogger.debug("Deployment not ready yet (404)", { + dseq: id.dseq, + retryCount + }); + return undefined; + } + throw new Error(`Could not query lease status: ${response.status}`); + } + + const data = await response.json() as LeaseStatus; + elizaLogger.debug("Lease status received", { + dseq: id.dseq, + dataLength: JSON.stringify(data).length, + hasServices: !!data.services, + serviceCount: Object.keys(data.services || {}).length + }); + return data; + } finally { + agent.destroy(); + } + } catch (error) { + elizaLogger.warn("Error during lease status query", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + dseq: id.dseq, + providerUri, + retryCount + }); + + if (retryCount < MAX_RETRIES - 1) { + const delay = INITIAL_RETRY_DELAY * Math.pow(2, retryCount); + elizaLogger.debug("Retrying after error", { + delay, + nextRetry: retryCount + 1, + maxRetries: MAX_RETRIES + }); + await new Promise(r => setTimeout(r, delay)); + retryCount++; + continue; + } + + // On final retry, if it's a network error or 404, return undefined + if (error instanceof Error && + ((error as any).code === 'ECONNABORTED' || + (error as any).code === 'ETIMEDOUT' || + ((error as any).response && (error as any).response.status === 404))) { + elizaLogger.info("Returning undefined after max retries", { + dseq: id.dseq, + error: error.message + }); + return undefined; + } + + throw error; + } + } + + elizaLogger.info("Max retries reached, returning undefined", { + dseq: id.dseq, + maxRetries: MAX_RETRIES + }); + return undefined; +} + +async function sendManifest(sdl: SDL, lease: any, certificate: CertificatePem, rpcEndpoint: string) { + elizaLogger.info("Starting manifest send process"); + if (lease.id === undefined) { + elizaLogger.error("Invalid lease - missing ID"); + throw new AkashError("Lease ID is undefined", AkashErrorCode.INVALID_LEASE); + } + + try { + const { dseq, provider } = lease.id; + elizaLogger.debug("Getting provider info", { provider }); + + const rpc = await getRpc(rpcEndpoint); + const client = new QueryProviderClient(rpc); + const request = QueryProviderRequest.fromPartial({ + owner: provider + }); + + const tx = await client.Provider(request); + + if (tx.provider === undefined) { + elizaLogger.error("Provider not found", { provider }); + throw new AkashError( + `Could not find provider ${provider}`, + AkashErrorCode.PROVIDER_NOT_FOUND + ); + } + + const providerInfo = tx.provider; + elizaLogger.debug("Provider info retrieved", { + provider, + hostUri: providerInfo.hostUri + }); + + const manifest = sdl.manifestSortedJSON(); + const path = `/deployment/${dseq}/manifest`; + + elizaLogger.info("Sending manifest to provider", { + dseq, + provider, + manifestLength: manifest.length + }); + + const uri = new URL(providerInfo.hostUri); + + const httpsAgent = new https.Agent({ + cert: certificate.cert, + key: certificate.privateKey, + rejectUnauthorized: false, + keepAlive: false, + timeout: 10000 + }); + + try { + const fullUrl = `${uri.protocol}//${uri.hostname}${uri.port ? ':' + uri.port : ''}${path}`; + elizaLogger.debug("Making manifest request", { + url: fullUrl, + method: 'PUT', + manifestLength: manifest.length + }); + + const response = await axios.put(fullUrl, manifest, { + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + httpsAgent, + timeout: 10000, + validateStatus: null // Don't throw on any status code + }); + + if (response.status !== 200) { + elizaLogger.error("Failed to send manifest", { + statusCode: response.status, + statusText: response.statusText, + dseq + }); + throw new Error(`Failed to send manifest: ${response.status} ${response.statusText}`); + } + + elizaLogger.info("Manifest sent successfully", { dseq }); + } finally { + httpsAgent.destroy(); + } + + // Wait for deployment to start + elizaLogger.info("Waiting for deployment to start", { dseq }); + const startTime = Date.now(); + const timeout = 1000 * 60 * 10; // 10 minutes timeout + let consecutiveErrors = 0; + const MAX_CONSECUTIVE_ERRORS = 5; + + while (Date.now() - startTime < timeout) { + const elapsedTime = Math.round((Date.now() - startTime) / 1000); + elizaLogger.debug("Checking deployment status", { + dseq, + elapsedTime: `${elapsedTime}s`, + remainingTime: `${Math.round(timeout/1000 - elapsedTime)}s`, + consecutiveErrors + }); + + try { + const status = await queryLeaseStatus(lease, providerInfo.hostUri, certificate); + + if (status === undefined) { + consecutiveErrors++; + elizaLogger.debug("Status check returned undefined", { + dseq, + consecutiveErrors, + maxConsecutiveErrors: MAX_CONSECUTIVE_ERRORS + }); + + if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) { + elizaLogger.warn("Too many consecutive undefined status responses", { + dseq, + consecutiveErrors + }); + // Don't throw, just continue waiting + consecutiveErrors = 0; + } + + await new Promise(resolve => setTimeout(resolve, 3000)); + continue; + } + + // Reset error counter on successful status check + consecutiveErrors = 0; + + for (const [name, service] of Object.entries<{ uris?: string[] }>(status.services)) { + if (service.uris) { + const rawUrl = service.uris[0]; + // Ensure URL has protocol + const serviceUrl = rawUrl.startsWith('http') ? rawUrl : `http://${rawUrl}`; + elizaLogger.info("Service is available", { + name, + rawUrl, + serviceUrl, + dseq + }); + return serviceUrl; + } + } + } catch (error) { + consecutiveErrors++; + const errorMessage = error instanceof Error ? error.message : String(error); + elizaLogger.warn("Error checking deployment status", { + error: errorMessage, + dseq, + consecutiveErrors, + maxConsecutiveErrors: MAX_CONSECUTIVE_ERRORS + }); + + if (consecutiveErrors >= MAX_CONSECUTIVE_ERRORS) { + elizaLogger.error("Too many consecutive errors checking deployment status", { + dseq, + consecutiveErrors, + error: errorMessage + }); + throw new AkashError( + "Too many consecutive errors checking deployment status", + AkashErrorCode.DEPLOYMENT_START_TIMEOUT, + { dseq, error: errorMessage } + ); + } + } + + await new Promise(resolve => setTimeout(resolve, 3000)); + } + + elizaLogger.error("Deployment start timeout", { + dseq, + timeout: "10 minutes" + }); + throw new AkashError( + "Could not start deployment. Timeout reached.", + AkashErrorCode.DEPLOYMENT_START_TIMEOUT + ); + } catch (error) { + elizaLogger.error("Error during manifest send process", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + dseq: lease.id.dseq + }); + throw error; + } +} + +async function loadOrCreateCertificate(wallet: DirectSecp256k1HdWallet, client: SigningStargateClient): Promise { + elizaLogger.info("=== Starting Certificate Creation/Loading Process ==="); + try { + const accounts = await wallet.getAccounts(); + const address = accounts[0].address; + elizaLogger.debug("Got wallet address for certificate", { + address, + addressLength: address.length, + addressPrefix: address.substring(0, 6) + }); + + // Check if certificate exists + if (fs.existsSync(CERTIFICATE_PATH)) { + elizaLogger.info("Found existing certificate file", { path: CERTIFICATE_PATH }); + const cert = loadCertificate(CERTIFICATE_PATH); + elizaLogger.debug("Loaded existing certificate", { + hasCert: !!cert.cert, + hasPrivateKey: !!cert.privateKey, + hasPublicKey: !!cert.publicKey, + certLength: cert.cert?.length, + privateKeyLength: cert.privateKey?.length, + publicKeyLength: cert.publicKey?.length + }); + return cert; + } + + // Create new certificate exactly like the example + elizaLogger.info("No existing certificate found, creating new one", { address }); + const certificate = certificateManager.generatePEM(address); + elizaLogger.debug("Certificate generated", { + hasCert: !!certificate.cert, + hasPrivateKey: !!certificate.privateKey, + hasPublicKey: !!certificate.publicKey, + certLength: certificate.cert?.length, + privateKeyLength: certificate.privateKey?.length, + publicKeyLength: certificate.publicKey?.length + }); + + // Broadcast certificate + elizaLogger.info("Broadcasting certificate to network", { + address, + certLength: certificate.cert?.length, + publicKeyLength: certificate.publicKey?.length + }); + + const result = await cert.broadcastCertificate( + certificate, + address, + client as any + ).catch(error => { + elizaLogger.error("Certificate broadcast failed", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + address, + certLength: certificate.cert?.length + }); + throw error; + }); + + if (result.code !== 0) { + const error = `Could not create certificate: ${result.rawLog}`; + elizaLogger.error("Certificate broadcast returned error code", { + code: result.code, + rawLog: result.rawLog, + address, + txHash: result.transactionHash + }); + throw new AkashError( + error, + AkashErrorCode.CERTIFICATE_CREATION_FAILED, + { rawLog: result.rawLog } + ); + } + + elizaLogger.info("Certificate broadcast successful", { + code: result.code, + txHash: result.transactionHash, + height: result.height, + gasUsed: result.gasUsed + }); + + // Save certificate + saveCertificate(certificate); + elizaLogger.info("Certificate saved to file", { path: CERTIFICATE_PATH }); + + elizaLogger.info("Certificate process completed successfully", { + hasCert: !!certificate.cert, + hasPrivateKey: !!certificate.privateKey, + hasPublicKey: !!certificate.publicKey, + path: CERTIFICATE_PATH + }); + + return certificate; + } catch (error) { + elizaLogger.error("Certificate creation/broadcast process failed", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + path: CERTIFICATE_PATH + }); + throw error; + } +} + +async function parseSDL(sdlContent: string): Promise { + try { + // Clean up SDL content by taking only the part after the YAML document separator + const yamlSeparatorIndex = sdlContent.indexOf('---'); + if (yamlSeparatorIndex === -1) { + throw new Error("No YAML document separator (---) found in SDL"); + } + + // Extract only the actual YAML content + const cleanSDL = sdlContent.substring(yamlSeparatorIndex); + + elizaLogger.info("Starting SDL parsing process", { + originalLength: sdlContent.length, + cleanLength: cleanSDL.length, + yamlSeparatorIndex, + cleanContent: cleanSDL.substring(0, 200) + '...', + firstLine: cleanSDL.split('\n')[0], + lastLine: cleanSDL.split('\n').slice(-1)[0], + lineCount: cleanSDL.split('\n').length, + hasVersion: cleanSDL.includes('version: "2.0"'), + hasServices: cleanSDL.includes('services:'), + hasProfiles: cleanSDL.includes('profiles:'), + hasDeployment: cleanSDL.includes('deployment:'), + charCodes: cleanSDL.substring(0, 50).split('').map(c => c.charCodeAt(0)) + }); + + // Try to parse SDL with clean content - exactly like the example + const parsedSDL = SDL.fromString(cleanSDL, "beta3"); + elizaLogger.debug("Initial SDL parsing successful", { + hasVersion: !!parsedSDL.version, + hasServices: !!parsedSDL.services, + hasProfiles: !!parsedSDL.profiles, + hasDeployment: !!parsedSDL.deployments, + serviceCount: Object.keys(parsedSDL.services || {}).length, + profileCount: Object.keys(parsedSDL.profiles || {}).length + }); + + // Get groups and version like the example + const groups = parsedSDL.groups(); + const version = await parsedSDL.manifestVersion(); + + elizaLogger.info("SDL validation completed", { + groupCount: groups.length, + version, + groups: JSON.stringify(groups) + }); + + return parsedSDL; + } catch (error) { + elizaLogger.error("Failed to parse SDL", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + sdlContent: sdlContent.substring(0, 200) + '...', + sdlLength: sdlContent.length + }); + throw error; + } +} + +export const createDeploymentAction: Action = { + name: "CREATE_DEPLOYMENT", + similes: ["DEPLOY", "START_DEPLOYMENT", "LAUNCH"], + description: "Create a new deployment on Akash Network", + examples: [[ + { + user: "user", + content: { + text: "Deploy SDL on Akash Network", + sdl: "version: \"2.0\"\n\nservices:\n web:\n image: nginx\n expose:\n - port: 80\n as: 80\n to:\n - global: true" + } as CreateDeploymentContent + } as ActionExample + ]], + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + elizaLogger.debug("=== Starting Deployment Validation ==="); + elizaLogger.debug("Validating deployment request", { message }); + + // Check if plugin is properly loaded + if (!isPluginLoaded(runtime, "akash")) { + elizaLogger.error("Akash plugin not properly loaded during validation"); + return false; + } + + try { + const params = message.content as Partial; + elizaLogger.debug("Checking SDL content", { params }); + + // Get SDL content either from direct string, specified file, or default file + let sdlContent: string; + if (params.sdl) { + sdlContent = params.sdl; + } else if (params.sdlFile) { + sdlContent = loadSDLFromFile(params.sdlFile); + } else { + sdlContent = loadSDLFromFile(DEFAULT_SDL_PATH); + } + + if (params.deposit && !validateDeposit(params.deposit)) { + throw new AkashError( + "Invalid deposit format", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "deposit", value: params.deposit } + ); + } + + elizaLogger.debug("Validating SDL format"); + try { + // Clean up SDL content by taking only the part after the YAML document separator + const yamlSeparatorIndex = sdlContent.indexOf('---'); + if (yamlSeparatorIndex === -1) { + throw new Error("No YAML document separator (---) found in SDL"); + } + + // Extract only the actual YAML content + const cleanSDL = sdlContent.substring(yamlSeparatorIndex); + + // Use exact same approach as example for validation + const sdl = SDL.fromString(cleanSDL, "beta3"); + await sdl.manifestVersion(); // Verify we can get the version + elizaLogger.debug("SDL format validation successful", { + groups: sdl.groups(), + groupCount: sdl.groups().length + }); + } catch (sdlError) { + elizaLogger.error("SDL format validation failed", { error: sdlError }); + throw new AkashError( + `Invalid SDL format: ${sdlError instanceof Error ? sdlError.message : String(sdlError)}`, + AkashErrorCode.VALIDATION_SDL_FAILED, + { sdl: sdlContent } + ); + } + + elizaLogger.debug("Validation completed successfully"); + return true; + } catch (error) { + elizaLogger.error("Deployment validation failed", { + error: error instanceof AkashError ? { + category: error.category, + code: error.code, + message: error.message, + details: error.details + } : String(error) + }); + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State | undefined, + _options: { [key: string]: unknown; } = {}, + callback?: HandlerCallback + ): Promise => { + const actionId = Date.now().toString(); + elizaLogger.info("=== Starting Deployment Creation ===", { + actionId, + messageId: message.id, + userId: message.userId + }); + + // Inspect runtime to verify plugin and action registration + inspectRuntime(runtime); + + try { + elizaLogger.debug("=== Validating Akash Configuration ==="); + const config = await validateAkashConfig(runtime); + elizaLogger.debug("Configuration validated successfully", { + rpcEndpoint: config.RPC_ENDPOINT, + chainId: config.AKASH_CHAIN_ID, + version: config.AKASH_VERSION, + hasMnemonic: !!config.AKASH_MNEMONIC + }); + + const params = message.content as CreateDeploymentContent; + elizaLogger.debug("=== Processing Deployment Parameters ===", { + hasSDL: !!params.sdl, + hasSDLFile: !!params.sdlFile, + hasDeposit: !!params.deposit + }); + + // Get SDL content either from direct string, specified file, or default file + let sdlContent: string; + let sdlSource: string; + if (params.sdl) { + sdlContent = params.sdl; + sdlSource = 'direct'; + } else if (params.sdlFile) { + sdlContent = loadSDLFromFile(params.sdlFile); + sdlSource = 'file'; + } else { + sdlContent = loadSDLFromFile(DEFAULT_SDL_PATH); + sdlSource = 'default'; + } + elizaLogger.debug("SDL content loaded", { + source: sdlSource, + contentLength: sdlContent.length + }); + + if (params.deposit && !validateDeposit(params.deposit)) { + elizaLogger.error("Invalid deposit format", { + deposit: params.deposit + }); + throw new AkashError( + "Invalid deposit format", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "deposit", value: params.deposit } + ); + } + + // Initialize wallet from mnemonic + elizaLogger.info("=== Initializing Wallet and Client ==="); + const wallet = await initializeWallet(config.AKASH_MNEMONIC); + const accounts = await wallet.getAccounts(); + const address = accounts[0].address; + elizaLogger.debug("Wallet initialized", { + address, + accountCount: accounts.length + }); + + // Setup client + elizaLogger.debug("Setting up Stargate client"); + const client = await setupClient(wallet, config.RPC_ENDPOINT); + elizaLogger.debug("Client setup completed", { + rpcEndpoint: config.RPC_ENDPOINT + }); + + // Load or create certificate + elizaLogger.info("=== Setting up Certificate ==="); + const certificate = await loadOrCreateCertificate(wallet, client); + elizaLogger.debug("Certificate setup completed", { + hasCert: !!certificate.cert, + hasPrivateKey: !!certificate.privateKey, + hasPublicKey: !!certificate.publicKey + }); + + // Parse SDL + elizaLogger.info("=== Parsing SDL Configuration ==="); + let sdl: SDL; + try { + sdl = await parseSDL(sdlContent); + elizaLogger.debug("SDL parsed successfully", { + groupCount: sdl.groups().length, + groups: sdl.groups(), + version: await sdl.manifestVersion() + }); + } catch (sdlError) { + elizaLogger.error("SDL parsing failed", { + error: sdlError instanceof Error ? sdlError.message : String(sdlError), + sdlContent + }); + throw new AkashError( + `SDL parsing failed: ${sdlError instanceof Error ? sdlError.message : String(sdlError)}`, + AkashErrorCode.MANIFEST_PARSING_FAILED, + { + sdl: sdlContent, + actionId + } + ); + } + + elizaLogger.info("=== Creating Deployment Message ==="); + const blockHeight = await client.getHeight(); + elizaLogger.debug("Current block height", { blockHeight }); + + const deployment = { + id: { + owner: address, + dseq: blockHeight + }, + groups: sdl.groups(), + deposit: { + denom: "uakt", + amount: params.deposit?.replace("uakt", "") || config.AKASH_DEPOSIT.replace("uakt", "") + }, + version: await sdl.manifestVersion(), + depositor: address + }; + + elizaLogger.debug("Deployment object created", { + owner: deployment.id.owner, + dseq: deployment.id.dseq, + groupCount: deployment.groups.length, + groups: deployment.groups, + deposit: deployment.deposit, + version: deployment.version + }); + + const msg = { + typeUrl: "/akash.deployment.v1beta3.MsgCreateDeployment", + value: MsgCreateDeployment.fromPartial(deployment) + }; + + // Broadcast transaction with retry for network issues + elizaLogger.info("=== Broadcasting Deployment Transaction ===", { + owner: address, + dseq: blockHeight, + deposit: params.deposit || config.AKASH_DEPOSIT, + groups: deployment.groups + }); + + const result = await withRetry(async () => { + elizaLogger.debug("Attempting to sign and broadcast transaction", { + attempt: 'current', + fees: config.AKASH_DEPOSIT, + gas: "800000", + groups: deployment.groups + }); + + const txResult = await client.signAndBroadcast( + address, + [msg], + { + amount: [{ denom: "uakt", amount: config.AKASH_DEPOSIT.replace("uakt", "") }], + gas: "800000", + } + ); + + elizaLogger.debug("Transaction broadcast result", { + code: txResult.code, + height: txResult.height, + transactionHash: txResult.transactionHash, + gasUsed: txResult.gasUsed, + gasWanted: txResult.gasWanted, + rawLog: txResult.rawLog + }); + + if (txResult.code !== 0) { + elizaLogger.error("Transaction failed", { + code: txResult.code, + rawLog: txResult.rawLog, + groups: deployment.groups + }); + throw new AkashError( + `Transaction failed: ${txResult.rawLog}`, + AkashErrorCode.DEPLOYMENT_CREATION_FAILED, + { + rawLog: txResult.rawLog, + dseq: blockHeight, + owner: address, + actionId, + groups: deployment.groups + } + ); + } + + return txResult; + }); + + elizaLogger.info("=== Deployment Created Successfully ===", { + txHash: result.transactionHash, + owner: address, + dseq: blockHeight, + actionId, + height: result.height, + gasUsed: result.gasUsed + }); + + // Create lease + elizaLogger.debug("=== Creating Lease ==="); + const lease = await createLease(deployment, wallet, client, config.RPC_ENDPOINT); + elizaLogger.debug("Lease created", { + leaseId: lease.id, + dseq: deployment.id.dseq + }); + + // Send manifest + elizaLogger.debug("=== Sending Manifest ==="); + const serviceUrl = await sendManifest(sdl, lease, certificate, config.RPC_ENDPOINT); + elizaLogger.debug("Manifest sent successfully", { + serviceUrl + }); + + if (callback) { + elizaLogger.info("=== Preparing callback response for deployment creation ===", { + hasCallback: true, + actionId, + dseq: String(blockHeight) + }); + + const callbackResponse = { + text: `Deployment created and started successfully\nDSEQ: ${blockHeight}\nOwner: ${address}\nTx Hash: ${result.transactionHash}\nService URL: ${serviceUrl}`, + content: { + success: true, + data: { + txHash: result.transactionHash, + owner: address, + dseq: String(blockHeight), + serviceUrl + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'createDeployment', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing callback with response ===", { + actionId, + responseText: callbackResponse.text, + hasContent: !!callbackResponse.content, + contentKeys: Object.keys(callbackResponse.content), + metadata: callbackResponse.content.metadata + }); + + callback(callbackResponse); + + elizaLogger.info("=== Callback executed successfully ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + + elizaLogger.info("=== Deployment Process Completed Successfully ===", { + actionId, + txHash: result.transactionHash, + dseq: blockHeight + }); + + return true; + } catch (error) { + elizaLogger.error("=== Deployment Creation Failed ===", { + error: error instanceof AkashError ? { + category: error.category, + code: error.code, + message: error.message, + details: error.details + } : String(error), + actionId, + stack: error instanceof Error ? error.stack : undefined + }); + + if (callback) { + elizaLogger.info("=== Preparing error callback response ===", { + actionId, + hasCallback: true, + errorType: error instanceof AkashError ? 'AkashError' : 'Error' + }); + + const errorResponse = { + text: "Failed to create deployment", + content: { + success: false, + error: { + code: error instanceof AkashError ? error.code : AkashErrorCode.DEPLOYMENT_CREATION_FAILED, + message: error instanceof Error ? error.message : String(error) + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'createDeployment', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing error callback ===", { + actionId, + responseText: errorResponse.text, + hasContent: !!errorResponse.content, + contentKeys: Object.keys(errorResponse.content) + }); + + callback(errorResponse); + + elizaLogger.info("=== Error callback executed successfully ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + + return false; + } + }, +}; + +export default createDeploymentAction; \ No newline at end of file diff --git a/packages/plugin-akash/src/actions/estimateGas.ts b/packages/plugin-akash/src/actions/estimateGas.ts new file mode 100644 index 0000000000..e83ccc8fa5 --- /dev/null +++ b/packages/plugin-akash/src/actions/estimateGas.ts @@ -0,0 +1,354 @@ +import { Action, elizaLogger } from "@elizaos/core"; +import { IAgentRuntime, Memory, State, HandlerCallback, Content, ActionExample } from "@elizaos/core"; +import { DirectSecp256k1HdWallet, Registry, EncodeObject } from "@cosmjs/proto-signing"; +import { SigningStargateClient } from "@cosmjs/stargate"; +import { MsgCloseDeployment } from "@akashnetwork/akash-api/akash/deployment/v1beta3"; +import { getAkashTypeRegistry, getTypeUrl } from "@akashnetwork/akashjs/build/stargate"; +import { validateAkashConfig } from "../environment"; +import { AkashError, AkashErrorCode } from "../error/error"; +import { encodingForModel } from "js-tiktoken"; + +interface AkashMessage { + typeUrl: string; + value: { + id?: { + owner: string; + dseq: string; + }; + [key: string]: unknown; + }; +} + +interface EstimateGasContent extends Content { + text: string; + dseq?: string; + operation: "close" | "create" | "update"; + message?: EncodeObject; +} + +function getTotalTokensFromString(str: string): number { + try { + const encoding = encodingForModel("gpt-3.5-turbo"); + return encoding.encode(str).length; + } catch (error) { + elizaLogger.warn("Failed to count tokens", { error }); + return 0; + } +} + +export const estimateGas: Action = { + name: "ESTIMATE_GAS", + similes: ["CALCULATE_GAS", "GET_GAS_ESTIMATE", "CHECK_GAS"], + description: "Estimate gas for a transaction on Akash Network", + examples: [[ + { + user: "user", + content: { + text: "Can you estimate gas for closing deployment with DSEQ 123456?", + operation: "close" + } as EstimateGasContent + } as ActionExample + ]], + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + elizaLogger.debug("Validating gas estimation request", { message }); + try { + const params = message.content as Partial; + const config = await validateAkashConfig(runtime); + + // Extract DSEQ from text if present + if (params.text && !params.dseq) { + const dseqMatch = params.text.match(/dseq\s*(?::|=|\s)\s*(\d+)/i) || + params.text.match(/deployment\s+(?:number|sequence|#)?\s*(\d+)/i) || + params.text.match(/(\d{6,})/); // Matches standalone numbers of 6+ digits + if (dseqMatch) { + params.dseq = dseqMatch[1]; + elizaLogger.debug("Extracted DSEQ from text", { + text: params.text, + extractedDseq: params.dseq + }); + } + } + + // If no operation provided, check environment configuration + if (!params.operation) { + if (config.AKASH_GAS_OPERATION) { + params.operation = config.AKASH_GAS_OPERATION as "close" | "create" | "update"; + elizaLogger.info("Using operation from environment", { operation: params.operation }); + } else { + throw new AkashError( + "Operation type is required (close, create, or update)", + AkashErrorCode.VALIDATION_PARAMETER_MISSING, + { parameter: "operation" } + ); + } + } + + // For close operations, check DSEQ from various sources + if (params.operation === "close") { + if (!params.dseq) { + if (config.AKASH_GAS_DSEQ) { + params.dseq = config.AKASH_GAS_DSEQ; + elizaLogger.info("Using DSEQ from environment", { dseq: params.dseq }); + } else { + throw new AkashError( + "Deployment sequence (dseq) is required for close operation", + AkashErrorCode.VALIDATION_PARAMETER_MISSING, + { parameter: "dseq" } + ); + } + } + } + + // For create/update operations, check message + if ((params.operation === "create" || params.operation === "update") && !params.message) { + throw new AkashError( + "Message is required for create/update operations", + AkashErrorCode.VALIDATION_PARAMETER_MISSING, + { parameter: "message" } + ); + } + + return true; + } catch (error) { + elizaLogger.error("Gas estimation validation failed", { + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : String(error) + }); + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State | undefined, + options: { [key: string]: unknown } = {}, + callback?: HandlerCallback + ): Promise => { + const actionId = Date.now().toString(); + elizaLogger.info("Starting gas estimation", { actionId }); + + elizaLogger.debug("=== Handler Parameters ===", { + hasRuntime: !!runtime, + hasMessage: !!message, + hasState: !!state, + hasOptions: !!options, + hasCallback: !!callback, + actionId + }); + + try { + const config = await validateAkashConfig(runtime); + const params = message.content as Partial; + + // Initialize wallet and get address + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(config.AKASH_MNEMONIC, { prefix: "akash" }); + const [account] = await wallet.getAccounts(); + + // Initialize client with Akash registry + const myRegistry = new Registry(getAkashTypeRegistry()); + const client = await SigningStargateClient.connectWithSigner( + config.RPC_ENDPOINT, + wallet, + { registry: myRegistry } + ); + + let msg: EncodeObject; + switch (params.operation) { + case "close": + msg = { + typeUrl: getTypeUrl(MsgCloseDeployment), + value: MsgCloseDeployment.fromPartial({ + id: { + owner: account.address, + dseq: params.dseq + } + }) + }; + break; + case "create": + case "update": + if (!params.message) { + if (callback) { + callback({ + text: `Message is required for ${params.operation} operations.`, + content: { + success: false, + error: { + code: AkashErrorCode.VALIDATION_PARAMETER_MISSING, + message: "Missing message", + help: `Please provide a message object for the ${params.operation} operation.` + } + } + }); + } + return false; + } + msg = params.message; + break; + default: + if (callback) { + callback({ + text: `Invalid operation type: ${params.operation}. Must be one of: close, create, or update.`, + content: { + success: false, + error: { + code: AkashErrorCode.VALIDATION_PARAMETER_INVALID, + message: "Invalid operation", + help: "Specify a valid operation type: 'close', 'create', or 'update'." + } + } + }); + } + return false; + } + + // Estimate gas + elizaLogger.info("Estimating gas for operation", { + operation: params.operation, + dseq: params.dseq, + owner: account.address + }); + + const gasEstimate = await client.simulate( + account.address, + [msg], + `Estimate gas for ${params.operation} operation` + ); + + elizaLogger.info("Gas estimation completed", { + gasEstimate, + operation: params.operation, + dseq: params.dseq, + owner: account.address, + actionId + }); + + if (callback) { + elizaLogger.info("=== Preparing callback response for gas estimation ===", { + hasCallback: true, + actionId, + operation: params.operation, + dseq: params.dseq + }); + + const operationText = params.operation === "close" ? `closing deployment ${params.dseq}` : params.operation; + const estimateData = { + gasEstimate, + operation: params.operation, + dseq: params.dseq, + owner: account.address, + message: msg + }; + + let responseText = `I've estimated the gas for ${operationText}:\n`; + responseText += `• Gas Required: ${gasEstimate} units\n`; + responseText += `• Operation: ${params.operation}\n`; + if (params.dseq) { + responseText += `• DSEQ: ${params.dseq}\n`; + } + responseText += `• Owner: ${account.address}`; + + const response = { + text: responseText, + content: { + success: true, + data: estimateData, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'estimateGas', + version: '1.0.0', + actionId, + tokenCount: getTotalTokensFromString(responseText) + } + } + }; + + elizaLogger.info("=== Executing callback with response ===", { + actionId, + responseText: response.text, + hasContent: !!response.content, + contentKeys: Object.keys(response.content), + metadata: response.content.metadata + }); + + callback(response); + + elizaLogger.info("=== Callback executed successfully ===", { + actionId, + timestamp: new Date().toISOString() + }); + } else { + elizaLogger.warn("=== No callback provided for gas estimation ===", { + actionId, + operation: params.operation, + dseq: params.dseq + }); + } + + return true; + } catch (error) { + elizaLogger.error("Gas estimation failed", { + error: error instanceof Error ? error.message : String(error), + actionId + }); + + if (callback) { + elizaLogger.info("=== Preparing error callback response ===", { + actionId, + hasCallback: true, + errorType: error instanceof AkashError ? 'AkashError' : 'Error' + }); + + const errorResponse = { + code: error instanceof AkashError ? error.code : AkashErrorCode.API_ERROR, + message: error instanceof Error ? error.message : String(error), + details: error instanceof AkashError ? error.details : undefined + }; + + const response = { + text: `Failed to estimate gas: ${errorResponse.message}`, + content: { + success: false, + error: errorResponse, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'estimateGas', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing error callback ===", { + actionId, + errorResponse, + hasContent: !!response.content, + contentKeys: Object.keys(response.content) + }); + + callback(response); + + elizaLogger.info("=== Error callback executed ===", { + actionId, + timestamp: new Date().toISOString() + }); + } else { + elizaLogger.warn("=== No callback provided for error handling ===", { + actionId, + errorMessage: error instanceof Error ? error.message : String(error) + }); + } + + return false; + } + } +}; + +export default estimateGas; \ No newline at end of file diff --git a/packages/plugin-akash/src/actions/getDeploymentApi.ts b/packages/plugin-akash/src/actions/getDeploymentApi.ts new file mode 100644 index 0000000000..417a9fc508 --- /dev/null +++ b/packages/plugin-akash/src/actions/getDeploymentApi.ts @@ -0,0 +1,499 @@ +import { Action, elizaLogger } from "@elizaos/core"; +import { IAgentRuntime, Memory, State, HandlerCallback, Content, ActionExample } from "@elizaos/core"; +import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; +import { validateAkashConfig } from "../environment"; +import { AkashError, AkashErrorCode } from "../error/error"; +import * as fs from 'fs'; +import * as path from 'path'; +import { getDeploymentsPath } from "../utils/paths"; + +export interface DeploymentInfo { + owner: string; + dseq: string; + status: string; + createdHeight: number; + cpuUnits: number; + gpuUnits: number; + memoryQuantity: number; + storageQuantity: number; +} + +export interface DeploymentListResponse { + count: number; + results: DeploymentInfo[]; +} + +interface GetDeploymentsContent extends Content { + status?: 'active' | 'closed'; + skip?: number; + limit?: number; +} + +async function sleep(ms: number) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +async function fetchWithRetry(url: string, options: RequestInit, retries = 3, delay = 1000): Promise { + for (let i = 0; i < retries; i++) { + try { + const response = await fetch(url, options); + if (response.ok) { + return response; + } + + const error = await response.text(); + elizaLogger.warn(`API request failed (attempt ${i + 1}/${retries})`, { + status: response.status, + error + }); + + if (i < retries - 1) { + await sleep(delay * Math.pow(2, i)); // Exponential backoff + continue; + } + + throw new AkashError( + `API request failed after ${retries} attempts: ${response.status} - ${error}`, + AkashErrorCode.API_ERROR + ); + } catch (error) { + if (i === retries - 1) { + throw error; + } + elizaLogger.warn(`API request error (attempt ${i + 1}/${retries})`, { + error: error instanceof Error ? error.message : String(error) + }); + await sleep(delay * Math.pow(2, i)); + } + } + throw new AkashError( + `Failed to fetch after ${retries} retries`, + AkashErrorCode.API_ERROR + ); +} + +export async function initializeWallet(runtime: IAgentRuntime): Promise<{wallet: DirectSecp256k1HdWallet | null, address: string}> { + try { + // Validate configuration and get mnemonic + const config = await validateAkashConfig(runtime); + + elizaLogger.info("Initializing wallet with config", { + hasMnemonic: !!config.AKASH_MNEMONIC, + hasWalletAddress: !!config.AKASH_WALLET_ADDRESS + }); + + // First try to get the wallet address directly + if (config.AKASH_WALLET_ADDRESS) { + elizaLogger.info("Using provided wallet address", { + address: config.AKASH_WALLET_ADDRESS + }); + return { + wallet: null, + address: config.AKASH_WALLET_ADDRESS + }; + } + + // If no wallet address, create wallet from mnemonic + if (!config.AKASH_MNEMONIC) { + throw new AkashError( + "Neither AKASH_WALLET_ADDRESS nor AKASH_MNEMONIC provided", + AkashErrorCode.WALLET_NOT_INITIALIZED + ); + } + + try { + elizaLogger.info("Creating wallet from mnemonic"); + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(config.AKASH_MNEMONIC, { + prefix: "akash" + }); + + // Get account address + const accounts = await wallet.getAccounts(); + const address = accounts[0].address; + + elizaLogger.info("Wallet initialized from mnemonic", { + address, + accountCount: accounts.length + }); + + return { wallet, address }; + } catch (error) { + throw new AkashError( + `Failed to initialize wallet: ${error instanceof Error ? error.message : String(error)}`, + AkashErrorCode.WALLET_NOT_INITIALIZED, + { originalError: error instanceof Error ? error.message : String(error) } + ); + } + } catch (error) { + // Ensure all errors are properly wrapped as AkashError + if (error instanceof AkashError) { + throw error; + } + throw new AkashError( + `Failed to initialize wallet: ${error instanceof Error ? error.message : String(error)}`, + AkashErrorCode.WALLET_NOT_INITIALIZED, + { originalError: error instanceof Error ? error.message : String(error) } + ); + } +} + +export async function fetchDeployments( + runtime: IAgentRuntime, + status?: 'active' | 'closed', + skip = 0, + limit = 10 +): Promise { + elizaLogger.info("Initializing deployment fetch", { + status: status || 'all', + skip, + limit + }); + + try { + // Initialize wallet and get address + const { address } = await initializeWallet(runtime); + + if (!address) { + throw new AkashError( + "Failed to get wallet address", + AkashErrorCode.WALLET_NOT_INITIALIZED + ); + } + + elizaLogger.info("Fetching deployments from API", { + address, + status: status || 'all', + skip, + limit + }); + + // Map status for API compatibility + const apiStatus = status; + + // Don't include status in URL if not specified + const params = new URLSearchParams(); + if (apiStatus) { + params.append('status', apiStatus); + } + params.append('reverseSorting', 'true'); + const url = `https://console-api.akash.network/v1/addresses/${address}/deployments/${skip}/${limit}?${params.toString()}`; + elizaLogger.debug("Making API request", { url }); + + const response = await fetchWithRetry(url, { + headers: { + 'accept': 'application/json' + } + }); + + const data = await response.json() as DeploymentListResponse; + elizaLogger.info("Deployments fetched successfully", { + count: data.count, + resultCount: data.results.length, + status: status || 'all' + }); + + // Keep status as-is from API + data.results = data.results.map(deployment => ({ + ...deployment, + status: deployment.status.toLowerCase() + })); + + // Save deployments to files, organized by their actual status + const deploymentDir = getDeploymentsPath(import.meta.url); + elizaLogger.info("Using deployments directory", { deploymentDir }); + + // Create base deployments directory if it doesn't exist + if (!fs.existsSync(deploymentDir)) { + elizaLogger.info("Creating deployments directory", { deploymentDir }); + fs.mkdirSync(deploymentDir, { recursive: true }); + } + + // Group deployments by status + const deploymentsByStatus = data.results.reduce((acc, deployment) => { + const status = deployment.status.toLowerCase(); + if (!acc[status]) { + acc[status] = []; + } + acc[status].push(deployment); + return acc; + }, {} as Record); + + // Save deployments by status + for (const [status, deployments] of Object.entries(deploymentsByStatus)) { + const statusDir = path.join(deploymentDir, status); + elizaLogger.info("Processing status directory", { statusDir, status, deploymentCount: deployments.length }); + + // Ensure status directory exists + if (!fs.existsSync(statusDir)) { + elizaLogger.info("Creating status directory", { statusDir }); + fs.mkdirSync(statusDir, { recursive: true }); + } + + // Save all deployments for this status in parallel + await Promise.all(deployments.map(async (deployment) => { + const filePath = path.join(statusDir, `${deployment.dseq}.json`); + elizaLogger.debug("Saving deployment file", { filePath, dseq: deployment.dseq }); + await saveDeploymentInfo(deployment, filePath); + })); + } + + return data; + } catch (error) { + elizaLogger.error("Failed to fetch deployments", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined + }); + throw error; + } +} + +export async function saveDeploymentInfo(deploymentInfo: DeploymentInfo, filePath: string): Promise { + elizaLogger.info("Saving deployment info", { + dseq: deploymentInfo.dseq, + owner: deploymentInfo.owner, + filePath + }); + + try { + // Ensure directory exists + const dir = path.dirname(filePath); + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } + + // Save deployment info + fs.writeFileSync(filePath, JSON.stringify(deploymentInfo, null, 2), 'utf8'); + elizaLogger.debug("Deployment info saved successfully"); + } catch (error) { + elizaLogger.error("Failed to save deployment info", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + filePath + }); + throw error; + } +} + +export async function loadDeploymentInfo(filePath: string): Promise { + elizaLogger.info("Loading deployment info", { filePath }); + + try { + if (!fs.existsSync(filePath)) { + throw new AkashError( + `Deployment info file not found: ${filePath}`, + AkashErrorCode.FILE_NOT_FOUND + ); + } + + const data = fs.readFileSync(filePath, 'utf8'); + const deploymentInfo = JSON.parse(data) as DeploymentInfo; + elizaLogger.debug("Deployment info loaded successfully", { + dseq: deploymentInfo.dseq, + owner: deploymentInfo.owner + }); + + return deploymentInfo; + } catch (error) { + elizaLogger.error("Failed to load deployment info", { + error: error instanceof Error ? error.message : String(error), + stack: error instanceof Error ? error.stack : undefined, + filePath + }); + throw error; + } +} + +export const getDeploymentApiAction: Action = { + name: "GET_DEPLOYMENTS", + similes: ["LIST_DEPLOYMENTS", "FETCH_DEPLOYMENTS", "SHOW_DEPLOYMENTS"], + description: "Fetch deployments from Akash Network", + examples: [[ + { + user: "user", + content: { + text: "Get all deployments", + } as GetDeploymentsContent + } as ActionExample, + { + user: "assistant", + content: { + text: "Fetching all deployments..." + } as GetDeploymentsContent + } as ActionExample + ], [ + { + user: "user", + content: { + text: "Get active deployments", + status: "active" + } as GetDeploymentsContent + } as ActionExample, + { + user: "assistant", + content: { + text: "Fetching active deployments..." + } as GetDeploymentsContent + } as ActionExample + ]], + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + elizaLogger.debug("Validating get deployments request", { message }); + try { + const params = message.content as Partial; + + if (params.status && !['active', 'closed'].includes(params.status)) { + throw new AkashError( + "Status must be either 'active' or 'closed'", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "status", value: params.status } + ); + } + + if (params.skip !== undefined && (typeof params.skip !== 'number' || params.skip < 0)) { + throw new AkashError( + "Skip must be a non-negative number", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "skip", value: params.skip } + ); + } + + if (params.limit !== undefined && (typeof params.limit !== 'number' || params.limit <= 0)) { + throw new AkashError( + "Limit must be a positive number", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "limit", value: params.limit } + ); + } + + return true; + } catch (error) { + elizaLogger.error("Get deployments validation failed", { + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : String(error) + }); + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State | undefined, + _options: { [key: string]: unknown } = {}, + callback?: HandlerCallback + ): Promise => { + const actionId = Date.now().toString(); + elizaLogger.info("Starting deployment API request", { actionId }); + + try { + // const config = await validateAkashConfig(runtime); + const params = message.content as Partial; + + // Fetch deployments + const deployments = await fetchDeployments( + runtime, + params.status, + params.skip, + params.limit + ); + + if (callback) { + elizaLogger.info("=== Preparing callback response for deployments ===", { + hasCallback: true, + actionId, + deploymentCount: deployments.count + }); + + const callbackResponse = { + text: `Found ${deployments.count} deployment${deployments.count !== 1 ? 's' : ''}${params.status ? ` with status: ${params.status}` : ''}\n\nDeployments:\n${deployments.results.map(dep => + `- DSEQ: ${dep.dseq}\n Status: ${dep.status}\n CPU: ${dep.cpuUnits} units\n Memory: ${dep.memoryQuantity} units\n Storage: ${dep.storageQuantity} units` + ).join('\n\n')}`, + content: { + success: true, + data: { + deployments: deployments.results, + total: deployments.count, + status: params.status || 'all' + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getDeploymentApi', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing callback with response ===", { + actionId, + responseText: callbackResponse.text, + hasContent: !!callbackResponse.content, + contentKeys: Object.keys(callbackResponse.content), + metadata: callbackResponse.content.metadata + }); + + callback(callbackResponse); + + elizaLogger.info("=== Callback executed successfully ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + + return true; + } catch (error) { + elizaLogger.error("Get deployments request failed", { + error: error instanceof Error ? error.message : String(error), + actionId + }); + + if (callback) { + elizaLogger.info("=== Preparing error callback response ===", { + actionId, + hasCallback: true, + errorType: error instanceof AkashError ? 'AkashError' : 'Error' + }); + + const errorResponse = { + text: `Failed to get deployments: ${error instanceof Error ? error.message : String(error)}`, + content: { + success: false, + error: { + code: error instanceof AkashError ? error.code : AkashErrorCode.API_ERROR, + message: error instanceof Error ? error.message : String(error) + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getDeploymentApi', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing error callback ===", { + actionId, + responseText: errorResponse.text, + hasContent: !!errorResponse.content, + contentKeys: Object.keys(errorResponse.content) + }); + + callback(errorResponse); + + elizaLogger.info("=== Error callback executed ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + + return false; + } + } +}; + +export default getDeploymentApiAction; \ No newline at end of file diff --git a/packages/plugin-akash/src/actions/getDeploymentStatus.ts b/packages/plugin-akash/src/actions/getDeploymentStatus.ts new file mode 100644 index 0000000000..98a90dccf9 --- /dev/null +++ b/packages/plugin-akash/src/actions/getDeploymentStatus.ts @@ -0,0 +1,493 @@ +import { Action, elizaLogger } from "@elizaos/core"; +import { IAgentRuntime, Memory, State, HandlerCallback, Content, ActionExample } from "@elizaos/core"; +import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; +import { QueryDeploymentRequest, QueryClientImpl as DeploymentQueryClient } from "@akashnetwork/akash-api/akash/deployment/v1beta3"; +import { getRpc } from "@akashnetwork/akashjs/build/rpc"; +import { validateAkashConfig } from "../environment"; +import { AkashError, AkashErrorCode } from "../error/error"; + +interface GetDeploymentStatusContent extends Content { + text: string; + dseq?: string; +} + +interface DeploymentGroup { + groupId?: { + owner: string; + dseq: string; + gseq: number; + }; + state: string; + resources: Array<{ + resources: { + cpu: { + units: { + val: string; + }; + }; + memory: { + quantity: { + val: string; + }; + }; + storage: Array<{ + quantity: { + val: string; + }; + }>; + }; + count: number; + price: { + denom: string; + amount: string; + }; + }>; +} + +interface DeploymentResponse { + deploymentId?: { + owner: string; + dseq: string; + }; + state: string; + version: string; + createdAt: string; + escrowAccount?: { + balance?: { + denom: string; + amount: string; + }; + }; + groups?: DeploymentGroup[]; +} + +enum DeploymentState { + UNKNOWN = 0, + ACTIVE = 1, + CLOSED = 2, + INSUFFICIENT_FUNDS = 3, +} + +export const getDeploymentStatusAction: Action = { + name: "GET_DEPLOYMENT_STATUS", + similes: ["CHECK_DEPLOYMENT", "DEPLOYMENT_STATUS", "DEPLOYMENT_STATE", "CHECK DSEQ"], + description: "Get the current status of a deployment on Akash Network", + examples: [[ + { + user: "user", + content: { + text: "Can you check the deployment status of the DSEQ 123456?", + } as GetDeploymentStatusContent + } as ActionExample + ]], + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + elizaLogger.debug("Validating get deployment status request", { message }); + try { + const params = message.content as Partial; + const config = await validateAkashConfig(runtime); + + // Extract DSEQ from text if present + if (params.text && !params.dseq) { + // Pattern to match DSEQ followed by numbers + const dseqMatch = params.text.match(/(?:DSEQ|dseq)\s*(\d+)/i); + if (dseqMatch) { + params.dseq = dseqMatch[1]; + elizaLogger.debug("Extracted DSEQ from text", { + text: params.text, + extractedDseq: params.dseq + }); + } + } + + // If no dseq provided, check environment configuration + if (!params.dseq) { + if (config.AKASH_DEP_STATUS === "dseq" && config.AKASH_DEP_DSEQ) { + params.dseq = config.AKASH_DEP_DSEQ; + } else if (config.AKASH_DEP_STATUS === "param_passed") { + elizaLogger.info("DSEQ parameter is required when AKASH_DEP_STATUS is set to param_passed", { + current_status: config.AKASH_DEP_STATUS + }); + return true; // Allow validation to pass, we'll handle the missing parameter in the handler + } else { + elizaLogger.info("No DSEQ provided and no valid environment configuration found", { + dep_status: config.AKASH_DEP_STATUS, + dep_dseq: config.AKASH_DEP_DSEQ + }); + return true; // Allow validation to pass, we'll handle the missing configuration in the handler + } + } + + // If dseq is provided, validate its format + if (params.dseq && !/^\d+$/.test(params.dseq)) { + throw new AkashError( + "Invalid DSEQ format. Must be a numeric string", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "dseq", value: params.dseq } + ); + } + + return true; + } catch (error) { + elizaLogger.error("Get deployment status validation failed", { + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : String(error) + }); + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State | undefined, + _options: { [key: string]: unknown } = {}, + callback?: HandlerCallback + ): Promise => { + const actionId = Date.now().toString(); + elizaLogger.info("Starting deployment status request", { actionId }); + + try { + const config = await validateAkashConfig(runtime); + const params = message.content as Partial; + let dseqSource = "parameter"; // Track where the DSEQ came from + + // Handle missing dseq parameter based on environment configuration + if (!params.dseq) { + if (config.AKASH_DEP_STATUS === "dseq") { + if (config.AKASH_DEP_DSEQ) { + params.dseq = config.AKASH_DEP_DSEQ; + dseqSource = "environment"; + } else { + if (callback) { + callback({ + text: "AKASH_DEP_DSEQ is not set in your environment. Please set a valid deployment sequence number.", + content: { + success: false, + error: { + code: AkashErrorCode.VALIDATION_PARAMETER_MISSING, + message: "Missing AKASH_DEP_DSEQ", + help: "When AKASH_DEP_STATUS is set to 'dseq', you must also set AKASH_DEP_DSEQ in your .env file." + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getDeploymentStatus', + version: '1.0.0', + actionId + } + } + }); + } + return false; + } + } else if (config.AKASH_DEP_STATUS === "param_passed") { + if (callback) { + callback({ + text: "DSEQ parameter is required. Please provide a deployment sequence number.", + content: { + success: false, + error: { + code: AkashErrorCode.VALIDATION_PARAMETER_MISSING, + message: "Missing required parameter: dseq", + help: "You need to provide a deployment sequence number (dseq) to check its status." + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getDeploymentStatus', + version: '1.0.0', + actionId + } + } + }); + } + return false; + } else { + if (callback) { + callback({ + text: "No deployment configuration found. Please set AKASH_DEP_STATUS and AKASH_DEP_DSEQ in your environment or provide a dseq parameter.", + content: { + success: false, + error: { + code: AkashErrorCode.VALIDATION_PARAMETER_MISSING, + message: "Missing configuration", + help: "Set AKASH_DEP_STATUS='dseq' and AKASH_DEP_DSEQ in your .env file, or set AKASH_DEP_STATUS='param_passed' and provide dseq parameter in your request." + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getDeploymentStatus', + version: '1.0.0', + actionId + } + } + }); + } + return false; + } + } + + // Initialize wallet from mnemonic + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(config.AKASH_MNEMONIC, { prefix: "akash" }); + const [account] = await wallet.getAccounts(); + + // Initialize query client + const queryClient = new DeploymentQueryClient(await getRpc(config.RPC_ENDPOINT)); + + // Query deployment + elizaLogger.info("Querying deployment status", { + dseq: params.dseq, + owner: account.address + }); + + try { + const request = QueryDeploymentRequest.fromPartial({ + id: { + owner: account.address, + dseq: params.dseq + } + }); + + const response = await queryClient.Deployment(request); + + if (!response.deployment) { + // Different messages based on DSEQ source + if (dseqSource === "environment") { + if (callback) { + callback({ + text: "The deployment sequence number in your environment configuration was not found. Please check AKASH_DEP_DSEQ value.", + content: { + success: false, + error: { + code: AkashErrorCode.DEPLOYMENT_NOT_FOUND, + message: "Invalid AKASH_DEP_DSEQ", + help: "Update AKASH_DEP_DSEQ in your .env file with a valid deployment sequence number, or switch to AKASH_DEP_STATUS='param_passed' to provide DSEQ as a parameter.", + current_dseq: params.dseq + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getDeploymentStatus', + version: '1.0.0', + actionId + } + } + }); + } + } else { + throw new AkashError( + "Deployment not found", + AkashErrorCode.DEPLOYMENT_NOT_FOUND, + { + dseq: params.dseq, + owner: account.address, + actionId + } + ); + } + return false; + } + + // Format deployment status + const deployment = response.deployment as unknown as DeploymentResponse; + const status = { + owner: deployment.deploymentId?.owner, + dseq: deployment.deploymentId?.dseq, + state: deployment.state, + version: deployment.version, + createdAt: deployment.createdAt, + balance: deployment.escrowAccount?.balance, + groups: deployment.groups?.map((group: DeploymentGroup) => ({ + groupId: group.groupId, + state: group.state, + resources: group.resources + })) + }; + + elizaLogger.info("Deployment status retrieved successfully", { + dseq: params.dseq, + state: status.state, + owner: status.owner, + actionId + }); + + if (callback) { + // Convert numeric state to readable string + const stateString = DeploymentState[status.state as keyof typeof DeploymentState] || 'UNKNOWN'; + + const formattedBalance = deployment.escrowAccount?.balance + ? `${deployment.escrowAccount.balance.amount}${deployment.escrowAccount.balance.denom}` + : 'No balance information'; + + elizaLogger.info("=== Preparing callback response for deployment status ===", { + hasCallback: true, + actionId, + dseq: params.dseq + }); + + const callbackResponse = { + text: `Deployment ${params.dseq} Status:\nState: ${stateString}\nBalance: ${formattedBalance}\nCreated At: ${status.createdAt}`, + content: { + success: true, + data: { + deployment: status, + queryResponse: response.deployment + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getDeploymentStatus', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing callback with response ===", { + actionId, + responseText: callbackResponse.text, + hasContent: !!callbackResponse.content, + contentKeys: Object.keys(callbackResponse.content), + metadata: callbackResponse.content.metadata + }); + + callback(callbackResponse); + + elizaLogger.info("=== Callback executed successfully ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + + return true; + } catch (queryError) { + // Handle query errors differently based on DSEQ source + if (dseqSource === "environment") { + elizaLogger.warn("Failed to query deployment from environment configuration", { + dseq: params.dseq, + error: queryError instanceof Error ? queryError.message : String(queryError) + }); + if (callback) { + callback({ + text: "Could not find deployment with the configured DSEQ. Please check your environment settings.", + content: { + success: false, + error: { + code: AkashErrorCode.API_ERROR, + message: "Invalid AKASH_DEP_DSEQ configuration", + help: "Verify that AKASH_DEP_DSEQ contains a valid deployment sequence number, or switch to AKASH_DEP_STATUS='param_passed' to provide DSEQ as a parameter.", + current_dseq: params.dseq + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getDeploymentStatus', + version: '1.0.0', + actionId + } + } + }); + } + } else { + elizaLogger.error("Failed to query deployment", { + error: queryError instanceof Error ? queryError.message : String(queryError), + actionId + }); + if (callback) { + elizaLogger.info("=== Preparing error callback response ===", { + actionId, + hasCallback: true, + errorType: queryError instanceof AkashError ? 'AkashError' : 'Error' + }); + + const errorResponse = { + text: `Failed to get deployment status: ${queryError instanceof Error ? queryError.message : String(queryError)}`, + content: { + success: false, + error: { + code: queryError instanceof AkashError ? queryError.code : AkashErrorCode.API_ERROR, + message: queryError instanceof Error ? queryError.message : String(queryError) + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getDeploymentStatus', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing error callback ===", { + actionId, + responseText: errorResponse.text, + hasContent: !!errorResponse.content, + contentKeys: Object.keys(errorResponse.content) + }); + + callback(errorResponse); + + elizaLogger.info("=== Error callback executed ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + } + return false; + } + } catch (error) { + elizaLogger.error("Get deployment status request failed", { + error: error instanceof Error ? error.message : String(error), + actionId + }); + + if (callback) { + elizaLogger.info("=== Preparing error callback response ===", { + actionId, + hasCallback: true, + errorType: error instanceof AkashError ? 'AkashError' : 'Error' + }); + + const errorResponse = { + text: `Failed to get deployment status: ${error instanceof Error ? error.message : String(error)}`, + content: { + success: false, + error: { + code: error instanceof AkashError ? error.code : AkashErrorCode.API_ERROR, + message: error instanceof Error ? error.message : String(error) + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getDeploymentStatus', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing error callback ===", { + actionId, + responseText: errorResponse.text, + hasContent: !!errorResponse.content, + contentKeys: Object.keys(errorResponse.content) + }); + + callback(errorResponse); + + elizaLogger.info("=== Error callback executed ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + + return false; + } + } +}; + +export default getDeploymentStatusAction; \ No newline at end of file diff --git a/packages/plugin-akash/src/actions/getGPUPricing.ts b/packages/plugin-akash/src/actions/getGPUPricing.ts new file mode 100644 index 0000000000..35e407f00f --- /dev/null +++ b/packages/plugin-akash/src/actions/getGPUPricing.ts @@ -0,0 +1,225 @@ +import { Action, elizaLogger } from "@elizaos/core"; +import { IAgentRuntime, Memory, State, HandlerCallback, Content, ActionExample } from "@elizaos/core"; +import { getConfig } from "../environment"; + +interface GetGPUPricingContent extends Content { + cpu?: number; // CPU units in millicores (e.g., 1000 = 1 CPU) + memory?: number; // Memory in bytes (e.g., 1000000000 = 1GB) + storage?: number; // Storage in bytes (e.g., 1000000000 = 1GB) +} + +interface PricingResponse { + spec: { + cpu: number; + memory: number; + storage: number; + }; + akash: number; + aws: number; + gcp: number; + azure: number; +} + +// Get configuration with defaults +const config = getConfig(process.env.AKASH_ENV); +const PRICING_API_URL = config.AKASH_PRICING_API_URL; +const DEFAULT_CPU = parseInt(config.AKASH_DEFAULT_CPU || "1000"); +const DEFAULT_MEMORY = parseInt(config.AKASH_DEFAULT_MEMORY || "1000000000"); +const DEFAULT_STORAGE = parseInt(config.AKASH_DEFAULT_STORAGE || "1000000000"); + +// Custom error class for GPU pricing errors +class GPUPricingError extends Error { + constructor(message: string, public code: string) { + super(message); + this.name = 'GPUPricingError'; + } +} + +export const getGPUPricingAction: Action = { + name: "GET_GPU_PRICING", + similes: ["GET_PRICING", "COMPARE_PRICES", "CHECK_PRICING"], + description: "Get GPU pricing comparison between Akash and major cloud providers", + examples: [[ + { + user: "user", + content: { + text: "Get GPU pricing for 2 CPUs, 2GB memory, and 10GB storage", + cpu: 2000, + memory: 2000000000, + storage: 10000000000 + } as GetGPUPricingContent + } as ActionExample + ], [ + { + user: "user", + content: { + text: "Compare GPU prices across providers" + } as GetGPUPricingContent + } as ActionExample + ]], + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + elizaLogger.debug("Validating GPU pricing request", { message }); + try { + const params = message.content as Partial; + + // Validate CPU if provided + if (params.cpu !== undefined && (isNaN(params.cpu) || params.cpu <= 0)) { + throw new GPUPricingError("CPU units must be a positive number", "INVALID_CPU"); + } + + // Validate memory if provided + if (params.memory !== undefined && (isNaN(params.memory) || params.memory <= 0)) { + throw new GPUPricingError("Memory must be a positive number", "INVALID_MEMORY"); + } + + // Validate storage if provided + if (params.storage !== undefined && (isNaN(params.storage) || params.storage <= 0)) { + throw new GPUPricingError("Storage must be a positive number", "INVALID_STORAGE"); + } + + return true; + } catch (error) { + elizaLogger.error("GPU pricing validation failed", { + error: error instanceof GPUPricingError ? { + code: error.code, + message: error.message + } : String(error) + }); + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State | undefined, + _options: { [key: string]: unknown; } = {}, + callback?: HandlerCallback + ): Promise => { + const actionId = Date.now().toString(); + elizaLogger.info("Starting GPU pricing request", { actionId }); + + try { + const params = message.content as GetGPUPricingContent; + + // Use provided values or defaults + const requestBody = { + cpu: params.cpu || DEFAULT_CPU, + memory: params.memory || DEFAULT_MEMORY, + storage: params.storage || DEFAULT_STORAGE + }; + + elizaLogger.info("Fetching pricing information", { + specs: requestBody, + apiUrl: PRICING_API_URL + }); + + // Make API request using fetch + const response = await fetch(PRICING_API_URL, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Accept': 'application/json' + }, + body: JSON.stringify(requestBody) + }); + + if (!response.ok) { + throw new GPUPricingError( + `API request failed with status ${response.status}: ${response.statusText}`, + "API_ERROR" + ); + } + + const data = await response.json() as PricingResponse; + + // Calculate savings percentages + const savings = { + vs_aws: ((data.aws - data.akash) / data.aws * 100).toFixed(2), + vs_gcp: ((data.gcp - data.akash) / data.gcp * 100).toFixed(2), + vs_azure: ((data.azure - data.akash) / data.azure * 100).toFixed(2) + }; + + elizaLogger.info("Pricing information retrieved successfully", { + specs: data.spec, + pricing: { + akash: data.akash, + aws: data.aws, + gcp: data.gcp, + azure: data.azure + }, + savings + }); + + if (callback) { + const callbackResponse = { + text: `GPU Pricing Comparison\nAkash: $${data.akash}\nAWS: $${data.aws} (${savings.vs_aws}% savings)\nGCP: $${data.gcp} (${savings.vs_gcp}% savings)\nAzure: $${data.azure} (${savings.vs_azure}% savings)`, + content: { + success: true, + data: { + specs: { + cpu: data.spec.cpu, + memory: data.spec.memory, + storage: data.spec.storage + }, + pricing: { + akash: data.akash, + aws: data.aws, + gcp: data.gcp, + azure: data.azure + }, + savings: { + vs_aws: `${savings.vs_aws}%`, + vs_gcp: `${savings.vs_gcp}%`, + vs_azure: `${savings.vs_azure}%` + } + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getGPUPricing', + version: '1.0.0', + actionId + } + } + }; + + callback(callbackResponse); + } + + return true; + } catch (error) { + elizaLogger.error("GPU pricing request failed", { + error: error instanceof Error ? error.message : String(error), + actionId + }); + + if (callback) { + const errorResponse = { + text: "Failed to get GPU pricing information", + content: { + success: false, + error: { + code: error instanceof GPUPricingError ? error.code : 'UNKNOWN_ERROR', + message: error instanceof Error ? error.message : String(error) + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getGPUPricing', + version: '1.0.0', + actionId + } + } + }; + + callback(errorResponse); + } + + return false; + } + } +}; + +export default getGPUPricingAction; diff --git a/packages/plugin-akash/src/actions/getManifest.ts b/packages/plugin-akash/src/actions/getManifest.ts new file mode 100644 index 0000000000..5d6e116f9e --- /dev/null +++ b/packages/plugin-akash/src/actions/getManifest.ts @@ -0,0 +1,361 @@ +import { Action, elizaLogger } from "@elizaos/core"; +import { IAgentRuntime, Memory, State, HandlerCallback, Content, ActionExample } from "@elizaos/core"; +import { SDL } from "@akashnetwork/akashjs/build/sdl"; +import { validateAkashConfig } from "../environment"; +import { AkashError, AkashErrorCode } from "../error/error"; +import * as fs from 'fs'; +import * as path from 'path'; +import yaml from 'js-yaml'; +// import { getAkashTypeRegistry } from "@akashnetwork/akashjs/build/stargate"; +import { getDefaultSDLPath } from "../utils/paths"; + +interface GetManifestContent extends Content { + sdl?: string; + sdlFile?: string; +} + +// elizaLogger.info("Default SDL path initialized", { DEFAULT_SDL_PATH }); +// elizaLogger.info("Loading SDL from file", { filePath }); +// elizaLogger.info("Resolved SDL file path", { resolvedPath }); +// elizaLogger.error("SDL file not found", { resolvedPath }); +// elizaLogger.info("SDL file loaded successfully", { content }); +// elizaLogger.error("Failed to read SDL file", { error }); +// elizaLogger.error("SDL validation failed", { error }); +// elizaLogger.info("Using provided SDL content"); +// elizaLogger.info("Loading SDL from file", { path: params.sdlFile }); +// elizaLogger.info("Loading default SDL", { path: DEFAULT_SDL_PATH }); +// elizaLogger.debug("Parsing SDL content and generating manifest"); + +const DEFAULT_SDL_PATH = (() => { + const currentFileUrl = import.meta.url; + const sdlPath = getDefaultSDLPath(currentFileUrl); + + // Only log if file doesn't exist + if (!fs.existsSync(sdlPath)) { + elizaLogger.warn("Default SDL path not found", { + sdlPath, + exists: false + }); + } + + return sdlPath; +})(); + +const loadSDLFromFile = (filePath: string): string => { + try { + // If path doesn't contain plugin-akash and it's not the default path, adjust it + if (!filePath.includes('plugin-akash') && filePath !== DEFAULT_SDL_PATH) { + const adjustedPath = path.join(path.dirname(DEFAULT_SDL_PATH), path.basename(filePath)); + filePath = adjustedPath; + } + + // Try multiple possible locations + const possiblePaths = [ + filePath, + path.join(process.cwd(), filePath), + path.join(process.cwd(), 'packages', 'plugin-akash', filePath), + path.join(process.cwd(), 'packages', 'plugin-akash', 'src', filePath), + path.join(path.dirname(DEFAULT_SDL_PATH), filePath) + ]; + + for (const tryPath of possiblePaths) { + if (fs.existsSync(tryPath)) { + const content = fs.readFileSync(tryPath, "utf8"); + elizaLogger.info("SDL file loaded successfully from", { + path: tryPath + }); + return content; + } + } + + // If we get here, none of the paths worked + throw new AkashError( + `SDL file not found in any of the possible locations`, + AkashErrorCode.VALIDATION_SDL_FAILED, + { + filePath, + triedPaths: possiblePaths + } + ); + } catch (error) { + elizaLogger.error("Failed to read SDL file", { + filePath, + error: error instanceof Error ? error.message : String(error) + }); + throw new AkashError( + `Failed to read SDL file: ${error instanceof Error ? error.message : String(error)}`, + AkashErrorCode.VALIDATION_SDL_FAILED, + { filePath } + ); + } +}; + +const validateSDL = (sdlContent: string, validationLevel: string = "strict"): boolean => { + try { + // First try to parse as YAML + const parsed = yaml.load(sdlContent); + if (!parsed || typeof parsed !== 'object') { + throw new Error('Invalid SDL format: not a valid YAML object'); + } + + if (validationLevel === "none") { + // elizaLogger.debug("Skipping SDL validation (validation level: none)"); + return true; + } + + // Required sections based on validation level + const requiredSections = ['version', 'services']; + const sectionsToCheck = validationLevel === "strict" ? + [...requiredSections, 'profiles', 'deployment'] : + requiredSections; + + for (const section of sectionsToCheck) { + if (!(section in parsed)) { + throw new Error(`Invalid SDL format: missing required section '${section}'`); + } + } + + // elizaLogger.debug("SDL validation successful", { + // validationLevel, + // checkedSections: sectionsToCheck + // }); + return true; + } catch (error) { + elizaLogger.error("SDL validation failed", { + error: error instanceof Error ? error.message : String(error), + validationLevel + }); + return false; + } +}; + +export const getManifestAction: Action = { + name: "GET_MANIFEST", + similes: ["LOAD_MANIFEST", "READ_MANIFEST", "PARSE_MANIFEST"], + description: "Load and validate SDL to generate a manifest for Akash deployments", + examples: [[ + { + user: "user", + content: { + text: "Get manifest from SDL file", + sdlFile: "deployment.yml" + } as GetManifestContent + } as ActionExample + ]], + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + elizaLogger.debug("Validating manifest request", { message }); + try { + const params = message.content as Partial; + const config = await validateAkashConfig(runtime); + + // Either SDL content or file path must be provided + if (!params.sdl && !params.sdlFile && !config.AKASH_SDL) { + throw new AkashError( + "Either SDL content, file path, or AKASH_SDL environment variable must be provided", + AkashErrorCode.VALIDATION_PARAMETER_MISSING, + { parameters: ["sdl", "sdlFile", "AKASH_SDL"] } + ); + } + + // If SDL content is provided, validate it + if (params.sdl) { + const validationLevel = config.AKASH_MANIFEST_VALIDATION_LEVEL || "strict"; + if (!validateSDL(params.sdl, validationLevel)) { + throw new AkashError( + "Invalid SDL format", + AkashErrorCode.VALIDATION_SDL_FAILED + ); + } + } + + return true; + } catch (error) { + elizaLogger.error("Manifest validation failed", { + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : String(error) + }); + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State | undefined, + _options: { [key: string]: unknown; } = {}, + callback?: HandlerCallback + ): Promise => { + const actionId = Date.now().toString(); + elizaLogger.info("Starting manifest operation", { actionId }); + + try { + const config = await validateAkashConfig(runtime); + const params = message.content as Partial; + + let sdlContent: string; + try { + // Load SDL content based on priority: params.sdl > params.sdlFile > config.AKASH_SDL + if (params.sdl) { + sdlContent = params.sdl; + elizaLogger.info("Using provided SDL content"); + } else if (params.sdlFile) { + sdlContent = loadSDLFromFile(params.sdlFile); + elizaLogger.info("Loaded SDL from file", { path: params.sdlFile }); + } else { + const sdlPath = config.AKASH_SDL || DEFAULT_SDL_PATH; + sdlContent = loadSDLFromFile(sdlPath); + elizaLogger.info("Using SDL from environment", { path: sdlPath }); + } + + // Validate based on environment settings + const validationLevel = config.AKASH_MANIFEST_VALIDATION_LEVEL || "strict"; + const isValid = validateSDL(sdlContent, validationLevel); + + if (!isValid) { + throw new AkashError( + "SDL validation failed", + AkashErrorCode.VALIDATION_SDL_FAILED + ); + } + + // Check manifest mode + const manifestMode = config.AKASH_MANIFEST_MODE || "auto"; + if (manifestMode === "validate_only") { + elizaLogger.info("Validation successful (validate_only mode)"); + if (callback) { + const callbackResponse = { + text: "SDL validation successful", + content: { + success: true, + data: { + validationLevel, + mode: manifestMode + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getManifest', + version: '1.0.0', + actionId + } + } + }; + callback(callbackResponse); + } + return true; + } + + // Generate manifest + const sdl = new SDL(yaml.load(sdlContent) as any); + const manifest = sdl.manifest(); + + // Save manifest if path is specified + if (config.AKASH_MANIFEST_PATH) { + const manifestPath = path.join( + config.AKASH_MANIFEST_PATH, + `manifest-${Date.now()}.yaml` + ); + fs.writeFileSync(manifestPath, yaml.dump(manifest), 'utf8'); + elizaLogger.info("Manifest saved", { path: manifestPath }); + } + + if (callback) { + const callbackResponse = { + text: "Manifest generated successfully", + content: { + success: true, + data: { + manifest, + settings: { + mode: manifestMode, + validationLevel, + outputPath: config.AKASH_MANIFEST_PATH + } + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getManifest', + version: '1.0.0', + actionId + } + } + }; + callback(callbackResponse); + } + + return true; + } catch (error) { + const formattedError = error instanceof Error ? error.message : String(error); + elizaLogger.error("Manifest operation failed", { + error: formattedError, + settings: { + mode: config.AKASH_MANIFEST_MODE || "auto", + validationLevel: config.AKASH_MANIFEST_VALIDATION_LEVEL || "strict", + outputPath: config.AKASH_MANIFEST_PATH + } + }); + + if (callback) { + const errorResponse = { + text: "Failed to process manifest", + content: { + success: false, + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : { + code: AkashErrorCode.MANIFEST_PARSING_FAILED, + message: formattedError + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getManifest', + version: '1.0.0', + actionId + } + } + }; + callback(errorResponse); + } + return false; + } + } catch (error) { + elizaLogger.error("Manifest operation failed", { + error: error instanceof Error ? error.message : String(error), + actionId + }); + + if (callback) { + const errorResponse = { + text: "Manifest operation failed", + content: { + success: false, + error: { + code: AkashErrorCode.MANIFEST_PARSING_FAILED, + message: error instanceof Error ? error.message : String(error) + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getManifest', + version: '1.0.0', + actionId + } + } + }; + callback(errorResponse); + } + + return false; + } + } +}; + +export default getManifestAction; diff --git a/packages/plugin-akash/src/actions/getProviderInfo.ts b/packages/plugin-akash/src/actions/getProviderInfo.ts new file mode 100644 index 0000000000..0203a4a62f --- /dev/null +++ b/packages/plugin-akash/src/actions/getProviderInfo.ts @@ -0,0 +1,369 @@ +import { Action, elizaLogger } from "@elizaos/core"; +import { IAgentRuntime, Memory, State, HandlerCallback, Content, ActionExample } from "@elizaos/core"; +import { QueryProviderRequest, QueryClientImpl as ProviderQueryClient } from "@akashnetwork/akash-api/akash/provider/v1beta3"; +import { getRpc } from "@akashnetwork/akashjs/build/rpc"; +import { AkashError, AkashErrorCode } from "../error/error"; +import { validateAkashConfig } from "../environment"; + +interface GetProviderInfoContent extends Content { + text: string; + provider?: string; +} + +interface ProviderResponse { + provider?: { + owner: string; + hostUri: string; + attributes: Array<{ + key: string; + value: string; + }>; + info?: { + email: string; + website: string; + capabilities: string[]; + }; + status?: ProviderStatus; + }; +} + +interface ProviderStatus { + cluster?: { + nodes: Array<{ + name: string; + capacity: { + cpu: string; + memory: string; + storage: string; + }; + allocatable: { + cpu: string; + memory: string; + storage: string; + }; + }>; + }; + leases?: { + active: number; + pending: number; + available: number; + }; +} + +const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + +export const getProviderInfoAction: Action = { + name: "GET_PROVIDER_INFO", + similes: ["CHECK_PROVIDER", "PROVIDER_INFO", "PROVIDER_STATUS", "CHECK PROVIDER"], + description: "Get detailed information about a provider on Akash Network", + examples: [[ + { + user: "user", + content: { + text: "Can you check the provider info for akash1ccktptfkvdc67msasmesuy5m7gpc76z75kukpz?", + } as GetProviderInfoContent + } as ActionExample + ]], + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + elizaLogger.debug("Validating get provider info request", { message }); + try { + const params = message.content as Partial; + const config = await validateAkashConfig(runtime); + + // Extract provider address from text if present + if (params.text && !params.provider) { + // Pattern to match akash1 followed by address characters + const providerMatch = params.text.match(/akash1[a-zA-Z0-9]{38}/); + if (providerMatch) { + params.provider = providerMatch[0]; + elizaLogger.debug("Extracted provider address from text", { + text: params.text, + extractedProvider: params.provider + }); + } + } + + // If still no provider specified, use environment default + if (!params.provider && config.AKASH_PROVIDER_INFO) { + params.provider = config.AKASH_PROVIDER_INFO; + } + + if (!params.provider) { + throw new AkashError( + "Provider address is required", + AkashErrorCode.VALIDATION_PARAMETER_MISSING, + { parameter: "provider" } + ); + } + + // Validate provider address format + if (!params.provider.startsWith("akash1")) { + throw new AkashError( + "Invalid provider address format. Must start with 'akash1'", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "provider", value: params.provider } + ); + } + + return true; + } catch (error) { + elizaLogger.error("Get provider info validation failed", { + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : String(error) + }); + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State | undefined, + options: { [key: string]: unknown } = {}, + callback?: HandlerCallback + ): Promise => { + const actionId = Date.now().toString(); + elizaLogger.info("Starting provider info request", { actionId }); + + elizaLogger.debug("=== Handler Parameters ===", { + hasRuntime: !!runtime, + hasMessage: !!message, + hasState: !!state, + hasOptions: !!options, + hasCallback: !!callback, + actionId + }); + + try { + const config = await validateAkashConfig(runtime); + const params = message.content as Partial; + + // If no provider specified, use environment default + if (!params.provider && config.AKASH_PROVIDER_INFO) { + params.provider = config.AKASH_PROVIDER_INFO; + } + + if (!params.provider) { + throw new AkashError( + "Provider address is required", + AkashErrorCode.VALIDATION_PARAMETER_MISSING, + { parameter: "provider" } + ); + } + + // Query provider information + elizaLogger.info("Querying provider information", { + provider: params.provider, + actionId + }); + + const queryClient = new ProviderQueryClient(await getRpc(config.RPC_ENDPOINT)); + const request = QueryProviderRequest.fromPartial({ + owner: params.provider + }); + + try { + const response = await queryClient.Provider(request) as ProviderResponse; + + if (!response.provider) { + throw new AkashError( + "Failed to query provider: Provider not found", + AkashErrorCode.PROVIDER_NOT_FOUND, + { + provider: params.provider, + actionId + } + ); + } + + // Add a delay before querying status + await sleep(2000); // 2 second delay + + // Query provider status from their API + elizaLogger.info("Querying provider status", { + hostUri: response.provider.hostUri, + actionId + }); + + const hostUri = response.provider.hostUri.replace(/^https?:\/\//, ''); + elizaLogger.debug("Making provider status request", { url: `https://${hostUri}/status` }); + + try { + const statusResponse = await fetch(`https://${hostUri}/status`, { + headers: { + 'Accept': 'application/json' + }, + signal: AbortSignal.timeout(5000) + }); + + if (!statusResponse.ok) { + elizaLogger.debug("Provider status not available", { + status: statusResponse.status, + provider: params.provider, + hostUri: response.provider.hostUri, + actionId + }); + } else { + const statusData = await statusResponse.json(); + response.provider.status = statusData; + } + } catch (statusError) { + elizaLogger.debug("Provider status fetch failed", { + error: statusError instanceof Error ? statusError.message : String(statusError), + provider: params.provider, + hostUri: response.provider.hostUri, + actionId + }); + } + + // Format provider information + const info = { + owner: response.provider.owner, + hostUri: response.provider.hostUri, + attributes: response.provider.attributes, + info: response.provider.info, + status: response.provider.status ? { + nodes: response.provider.status.cluster?.nodes.map(node => ({ + name: node.name, + capacity: node.capacity, + allocatable: node.allocatable + })), + leases: response.provider.status.leases + } : undefined + }; + + elizaLogger.info("Provider information retrieved successfully", { + provider: params.provider, + hostUri: response.provider.hostUri, + hasStatus: !!response.provider.status, + actionId + }); + + if (callback) { + elizaLogger.info("=== Preparing callback response for provider info ===", { + hasCallback: true, + actionId, + provider: params.provider + }); + + const callbackResponse = { + text: `Provider ${params.provider} information:\nHost URI: ${info.hostUri}\nOwner: ${info.owner}${info.info ? `\nEmail: ${info.info.email}\nWebsite: ${info.info.website}` : ''}\nAttributes: ${info.attributes.map(attr => `${attr.key}: ${attr.value}`).join(', ')}`, + content: { + success: true, + data: { + provider: info, + queryResponse: response.provider + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getProviderInfo', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing callback with response ===", { + actionId, + responseText: callbackResponse.text, + hasContent: !!callbackResponse.content, + contentKeys: Object.keys(callbackResponse.content), + metadata: callbackResponse.content.metadata + }); + + callback(callbackResponse); + + elizaLogger.info("=== Callback executed successfully ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + + return true; + } catch (queryError) { + // Handle specific error cases + const errorMessage = queryError instanceof Error ? queryError.message : String(queryError); + + if (errorMessage.toLowerCase().includes("invalid address")) { + throw new AkashError( + "Failed to query provider: Invalid address format", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { + provider: params.provider, + error: errorMessage, + actionId + } + ); + } + + // For all other query errors, treat as provider not found + throw new AkashError( + "Failed to query provider: Provider not found or not accessible", + AkashErrorCode.PROVIDER_NOT_FOUND, + { + provider: params.provider, + error: errorMessage, + actionId + } + ); + } + } catch (error) { + elizaLogger.error("Get provider info request failed", { + error: error instanceof Error ? error.message : String(error), + actionId + }); + + if (callback) { + elizaLogger.info("=== Preparing error callback response ===", { + actionId, + hasCallback: true, + errorType: error instanceof AkashError ? 'AkashError' : 'Error' + }); + + const errorResponse = { + code: error instanceof AkashError ? error.code : AkashErrorCode.API_ERROR, + message: error instanceof Error ? error.message : String(error), + details: error instanceof AkashError ? error.details : undefined + }; + + const response = { + text: `Failed to get provider information: ${errorResponse.message}`, + content: { + success: false, + error: errorResponse, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getProviderInfo', + version: '1.0.0', + actionId + } + } + }; + + elizaLogger.info("=== Executing error callback ===", { + actionId, + errorResponse, + hasContent: !!response.content, + contentKeys: Object.keys(response.content) + }); + + callback(response); + + elizaLogger.info("=== Error callback executed ===", { + actionId, + timestamp: new Date().toISOString() + }); + } + + return false; + } + } +}; + +export default getProviderInfoAction; \ No newline at end of file diff --git a/packages/plugin-akash/src/actions/getProvidersList.ts b/packages/plugin-akash/src/actions/getProvidersList.ts new file mode 100644 index 0000000000..52e3c0fe91 --- /dev/null +++ b/packages/plugin-akash/src/actions/getProvidersList.ts @@ -0,0 +1,333 @@ +import { Action, elizaLogger } from "@elizaos/core"; +import { IAgentRuntime, Memory, State, HandlerCallback, Content, ActionExample } from "@elizaos/core"; +import { AkashError, AkashErrorCode } from "../error/error"; +import { validateAkashConfig } from "../environment"; + +interface GetProvidersListContent extends Content { + filter?: { + active?: boolean; + hasGPU?: boolean; + region?: string; + }; +} + +interface ProviderAttributes { + key: string; + value: string; +} + +interface ProviderInfo { + owner: string; + hostUri: string; + attributes: ProviderAttributes[]; + active: boolean; + uptime: number; + leaseCount: number; + info?: { + email?: string; + website?: string; + capabilities?: string[]; + }; + status?: { + available: boolean; + error?: string; + lastCheckTime: string; + resources?: { + cpu: { + total: number; + available: number; + }; + memory: { + total: number; + available: number; + }; + storage: { + total: number; + available: number; + }; + }; + }; +} + +const API_BASE_URL = "https://console-api.akash.network/v1"; + +async function fetchProviders(): Promise { + try { + const response = await fetch(`${API_BASE_URL}/providers`, { + headers: { + 'Accept': 'application/json' + } + }); + + if (!response.ok) { + throw new AkashError( + "Failed to fetch providers list: Invalid response from API", + AkashErrorCode.API_RESPONSE_INVALID, + { + status: response.status, + statusText: response.statusText + } + ); + } + + const data = await response.json(); + return data; + } catch (error) { + if (error instanceof AkashError) { + throw error; + } + throw new AkashError( + `Failed to fetch providers list: ${error instanceof Error ? error.message : String(error)}`, + AkashErrorCode.API_REQUEST_FAILED, + { + error: error instanceof Error ? error.message : String(error) + } + ); + } +} + +function filterProviders(providers: ProviderInfo[], filter?: GetProvidersListContent['filter']): ProviderInfo[] { + if (!filter) return providers; + + try { + let filtered = [...providers]; + + if (filter.active !== undefined) { + filtered = filtered.filter(p => { + const isActive = p.active && p.status?.available !== false; + return isActive === filter.active; + }); + } + + if (filter.hasGPU) { + filtered = filtered.filter(p => + p.attributes.some(attr => + attr.key.toLowerCase().includes('gpu') && + attr.value.toLowerCase() !== 'false' && + attr.value !== '0' + ) + ); + } + + if (filter.region) { + const regionFilter = filter.region.toLowerCase(); + filtered = filtered.filter(p => + p.attributes.some(attr => + attr.key.toLowerCase() === 'region' && + attr.value.toLowerCase().includes(regionFilter) + ) + ); + } + + return filtered; + } catch (error) { + throw new AkashError( + "Failed to apply provider filters", + AkashErrorCode.PROVIDER_FILTER_ERROR, + { filter, error: error instanceof Error ? error.message : String(error) } + ); + } +} + +export const getProvidersListAction: Action = { + name: "GET_PROVIDERS_LIST", + similes: ["LIST_PROVIDERS", "FETCH_PROVIDERS", "GET_ALL_PROVIDERS"], + description: "Get a list of all available providers on the Akash Network with their details and status", + examples: [[ + { + user: "user", + content: { + text: "Get a list of all active providers" + } as GetProvidersListContent + } as ActionExample, + { + user: "assistant", + content: { + text: "Fetching list of active Akash providers...", + filter: { + active: true + } + } as GetProvidersListContent + } as ActionExample + ], [ + { + user: "user", + content: { + text: "Show me all GPU providers in the US region", + filter: { + hasGPU: true, + region: "us" + } + } as GetProvidersListContent + } as ActionExample + ]], + + validate: async (runtime: IAgentRuntime, message: Memory): Promise => { + elizaLogger.debug("Validating get providers list request", { message }); + try { + const params = message.content as Partial; + + // Validate filter parameters if provided + if (params.filter) { + if (params.filter.region && typeof params.filter.region !== 'string') { + throw new AkashError( + "Region filter must be a string", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "filter.region" } + ); + } + + if (params.filter.active !== undefined && typeof params.filter.active !== 'boolean') { + throw new AkashError( + "Active filter must be a boolean", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "filter.active" } + ); + } + + if (params.filter.hasGPU !== undefined && typeof params.filter.hasGPU !== 'boolean') { + throw new AkashError( + "HasGPU filter must be a boolean", + AkashErrorCode.VALIDATION_PARAMETER_INVALID, + { parameter: "filter.hasGPU" } + ); + } + } + + return true; + } catch (error) { + elizaLogger.error("Get providers list validation failed", { + error: error instanceof AkashError ? { + code: error.code, + message: error.message, + details: error.details + } : String(error) + }); + return false; + } + }, + + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State | undefined, + _options: { [key: string]: unknown; } = {}, + callback?: HandlerCallback + ): Promise => { + const actionId = Date.now().toString(); + elizaLogger.info("Starting providers list request", { actionId }); + + try { + await validateAkashConfig(runtime); + const params = message.content as GetProvidersListContent; + + elizaLogger.info("Fetching providers list", { + filter: params.filter, + actionId + }); + + // Fetch providers + const allProviders = await fetchProviders(); + + // Apply filters + const filteredProviders = filterProviders(allProviders, params.filter); + + elizaLogger.info("Providers list retrieved successfully", { + totalProviders: allProviders.length, + filteredProviders: filteredProviders.length, + filter: params.filter, + actionId + }); + + if (callback) { + const callbackResponse = { + text: `Retrieved ${filteredProviders.length} providers${params.filter ? ' (filtered)' : ''} from total ${allProviders.length}`, + content: { + success: true, + data: { + summary: { + total: allProviders.length, + filtered: filteredProviders.length, + activeCount: filteredProviders.filter(p => p.active && p.status?.available !== false).length, + gpuCount: filteredProviders.filter(p => + p.attributes.some(attr => + attr.key.toLowerCase().includes('gpu') && + attr.value.toLowerCase() !== 'false' && + attr.value !== '0' + ) + ).length + }, + providers: filteredProviders.map(p => ({ + owner: p.owner, + hostUri: p.hostUri, + active: p.active && p.status?.available !== false, + uptime: p.uptime, + leaseCount: p.leaseCount, + attributes: p.attributes, + info: { + ...p.info, + capabilities: p.info?.capabilities || [], + region: p.attributes.find(a => a.key.toLowerCase() === 'region')?.value || 'unknown' + }, + resources: p.status?.resources || { + cpu: { total: 0, available: 0 }, + memory: { total: 0, available: 0 }, + storage: { total: 0, available: 0 } + }, + status: { + available: p.status?.available || false, + lastCheckTime: p.status?.lastCheckTime || new Date().toISOString(), + error: p.status?.error + } + })) + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getProvidersList', + version: '1.0.0', + actionId, + filters: params.filter || {} + } + } + }; + + callback(callbackResponse); + } + + return true; + } catch (error) { + elizaLogger.error("Get providers list request failed", { + error: error instanceof Error ? error.message : String(error), + code: error instanceof AkashError ? error.code : undefined, + actionId + }); + + if (callback) { + const errorResponse = { + text: "Failed to get providers list", + content: { + success: false, + error: { + code: error instanceof AkashError ? error.code : AkashErrorCode.API_REQUEST_FAILED, + message: error instanceof Error ? error.message : String(error) + }, + metadata: { + timestamp: new Date().toISOString(), + source: 'akash-plugin', + action: 'getProvidersList', + version: '1.0.0', + actionId + } + } + }; + + callback(errorResponse); + } + + return false; + } + } +}; +export default getProvidersListAction; + diff --git a/packages/plugin-akash/src/environment.ts b/packages/plugin-akash/src/environment.ts new file mode 100644 index 0000000000..12a8332b08 --- /dev/null +++ b/packages/plugin-akash/src/environment.ts @@ -0,0 +1,259 @@ +import { IAgentRuntime, elizaLogger } from "@elizaos/core"; +import { z } from "zod"; + +// Add ENV variable at the top +let ENV: string = "mainnet"; + +// Log environment information +elizaLogger.info("Environment sources", { + shellVars: Object.keys(process.env).filter(key => key.startsWith('AKASH_')), +}); + +export const akashEnvSchema = z.object({ + AKASH_MNEMONIC: z.string() + .min(1, "Wallet mnemonic is required") + .refine( + (mnemonic) => { + const words = mnemonic.trim().split(/\s+/); + return words.length === 12 || words.length === 24; + }, + { + message: "Mnemonic must be 12 or 24 words", + path: ["AKASH_MNEMONIC"] + } + ), + AKASH_WALLET_ADDRESS: z.string() + .min(1, "Wallet address is required") + .regex(/^akash[a-zA-Z0-9]{39}$/, "Invalid Akash wallet address format") + .optional(), + AKASH_NET: z.string().min(1, "Network configuration URL is required"), + AKASH_VERSION: z.string().min(1, "Akash version is required"), + AKASH_CHAIN_ID: z.string().min(1, "Chain ID is required"), + AKASH_NODE: z.string().min(1, "Node URL is required"), + RPC_ENDPOINT: z.string().min(1, "RPC endpoint is required"), + AKASH_GAS_PRICES: z.string().min(1, "Gas prices are required"), + AKASH_GAS_ADJUSTMENT: z.string().min(1, "Gas adjustment is required"), + AKASH_KEYRING_BACKEND: z.string().min(1, "Keyring backend is required"), + AKASH_FROM: z.string().min(1, "Key name is required"), + AKASH_FEES: z.string().min(1, "Transaction fees are required"), + AKASH_DEPOSIT: z.string().min(1, "Deposit is required be careful with the value not too low generally around 500000uakt"), + AKASH_PRICING_API_URL: z.string().optional(), + AKASH_DEFAULT_CPU: z.string().optional(), + AKASH_DEFAULT_MEMORY: z.string().optional(), + AKASH_DEFAULT_STORAGE: z.string().optional(), + AKASH_SDL: z.string().optional(), + AKASH_CLOSE_DEP: z.string().optional(), + AKASH_CLOSE_DSEQ: z.string().optional(), + AKASH_PROVIDER_INFO: z.string().optional(), + AKASH_DEP_STATUS: z.string().optional(), + AKASH_DEP_DSEQ: z.string().optional(), + AKASH_GAS_OPERATION: z.string().optional(), + AKASH_GAS_DSEQ: z.string().optional(), + // Manifest Configuration + AKASH_MANIFEST_MODE: z.string() + .optional() + .refine( + (mode) => !mode || ["auto", "manual", "validate_only"].includes(mode), + { + message: "AKASH_MANIFEST_MODE must be one of: auto, manual, validate_only" + } + ), + AKASH_MANIFEST_PATH: z.string() + .optional(), + AKASH_MANIFEST_VALIDATION_LEVEL: z.string() + .optional() + .refine( + (level) => !level || ["strict", "lenient", "none"].includes(level), + { + message: "AKASH_MANIFEST_VALIDATION_LEVEL must be one of: strict, lenient, none" + } + ), +}); + +export type AkashConfig = z.infer; + +export function getConfig( + env: string | undefined | null = ENV || + process.env.AKASH_ENV +) { + ENV = env || "mainnet"; + switch (env) { + case "mainnet": + return { + AKASH_NET: "https://raw.githubusercontent.com/ovrclk/net/master/mainnet", + RPC_ENDPOINT: "https://rpc.akashnet.net:443", + AKASH_GAS_PRICES: "0.025uakt", + AKASH_GAS_ADJUSTMENT: "1.5", + AKASH_KEYRING_BACKEND: "os", + AKASH_FROM: "default", + AKASH_FEES: "20000uakt", + AKASH_WALLET_ADDRESS: process.env.AKASH_WALLET_ADDRESS || "", + AKASH_PRICING_API_URL: process.env.AKASH_PRICING_API_URL || "https://console-api.akash.network/v1/pricing", + AKASH_DEFAULT_CPU: process.env.AKASH_DEFAULT_CPU || "1000", + AKASH_DEFAULT_MEMORY: process.env.AKASH_DEFAULT_MEMORY || "1000000000", + AKASH_DEFAULT_STORAGE: process.env.AKASH_DEFAULT_STORAGE || "1000000000", + AKASH_SDL: process.env.AKASH_SDL || "example.sdl.yml", + AKASH_CLOSE_DEP: process.env.AKASH_CLOSE_DEP || "closeAll", + AKASH_CLOSE_DSEQ: process.env.AKASH_CLOSE_DSEQ || "", + AKASH_PROVIDER_INFO: process.env.AKASH_PROVIDER_INFO || "", + AKASH_DEP_STATUS: process.env.AKASH_DEP_STATUS || "param_passed", + AKASH_DEP_DSEQ: process.env.AKASH_DEP_DSEQ || "", + AKASH_GAS_OPERATION: process.env.AKASH_GAS_OPERATION || "close", + AKASH_GAS_DSEQ: process.env.AKASH_GAS_DSEQ || "", + AKASH_MANIFEST_MODE: process.env.AKASH_MANIFEST_MODE || "auto", + AKASH_MANIFEST_PATH: process.env.AKASH_MANIFEST_PATH || "", + AKASH_MANIFEST_VALIDATION_LEVEL: process.env.AKASH_MANIFEST_VALIDATION_LEVEL || "strict", + AKASH_DEPOSIT: process.env.AKASH_DEPOSIT || "500000uakt" + }; + case "testnet": + return { + AKASH_NET: "https://raw.githubusercontent.com/ovrclk/net/master/testnet", + RPC_ENDPOINT: "https://rpc.sandbox-01.aksh.pw", + AKASH_GAS_PRICES: "0.025uakt", + AKASH_GAS_ADJUSTMENT: "1.5", + AKASH_KEYRING_BACKEND: "test", + AKASH_FROM: "default", + AKASH_FEES: "20000uakt", + AKASH_WALLET_ADDRESS: process.env.AKASH_WALLET_ADDRESS || "", + AKASH_PRICING_API_URL: process.env.AKASH_PRICING_API_URL || "https://console-api.akash.network/v1/pricing", + AKASH_DEFAULT_CPU: process.env.AKASH_DEFAULT_CPU || "1000", + AKASH_DEFAULT_MEMORY: process.env.AKASH_DEFAULT_MEMORY || "1000000000", + AKASH_DEFAULT_STORAGE: process.env.AKASH_DEFAULT_STORAGE || "1000000000", + AKASH_SDL: process.env.AKASH_SDL || "example.sdl.yml", + AKASH_CLOSE_DEP: process.env.AKASH_CLOSE_DEP || "closeAll", + AKASH_CLOSE_DSEQ: process.env.AKASH_CLOSE_DSEQ || "", + AKASH_PROVIDER_INFO: process.env.AKASH_PROVIDER_INFO || "", + AKASH_DEP_STATUS: process.env.AKASH_DEP_STATUS || "param_passed", + AKASH_DEP_DSEQ: process.env.AKASH_DEP_DSEQ || "", + AKASH_GAS_OPERATION: process.env.AKASH_GAS_OPERATION || "close", + AKASH_GAS_DSEQ: process.env.AKASH_GAS_DSEQ || "", + AKASH_MANIFEST_MODE: process.env.AKASH_MANIFEST_MODE || "auto", + AKASH_MANIFEST_PATH: process.env.AKASH_MANIFEST_PATH || "", + AKASH_MANIFEST_VALIDATION_LEVEL: process.env.AKASH_MANIFEST_VALIDATION_LEVEL || "strict", + AKASH_DEPOSIT: process.env.AKASH_DEPOSIT || "500000uakt" + }; + default: + return { + AKASH_NET: "https://raw.githubusercontent.com/ovrclk/net/master/mainnet", + RPC_ENDPOINT: "https://rpc.akashnet.net:443", + AKASH_GAS_PRICES: "0.025uakt", + AKASH_GAS_ADJUSTMENT: "1.5", + AKASH_KEYRING_BACKEND: "os", + AKASH_FROM: "default", + AKASH_FEES: "20000uakt", + AKASH_WALLET_ADDRESS: process.env.AKASH_WALLET_ADDRESS || "", + AKASH_PRICING_API_URL: process.env.AKASH_PRICING_API_URL || "https://console-api.akash.network/v1/pricing", + AKASH_DEFAULT_CPU: process.env.AKASH_DEFAULT_CPU || "1000", + AKASH_DEFAULT_MEMORY: process.env.AKASH_DEFAULT_MEMORY || "1000000000", + AKASH_DEFAULT_STORAGE: process.env.AKASH_DEFAULT_STORAGE || "1000000000", + AKASH_SDL: process.env.AKASH_SDL || "example.sdl.yml", + AKASH_CLOSE_DEP: process.env.AKASH_CLOSE_DEP || "closeAll", + AKASH_CLOSE_DSEQ: process.env.AKASH_CLOSE_DSEQ || "", + AKASH_PROVIDER_INFO: process.env.AKASH_PROVIDER_INFO || "", + AKASH_DEP_STATUS: process.env.AKASH_DEP_STATUS || "param_passed", + AKASH_DEP_DSEQ: process.env.AKASH_DEP_DSEQ || "", + AKASH_GAS_OPERATION: process.env.AKASH_GAS_OPERATION || "close", + AKASH_GAS_DSEQ: process.env.AKASH_GAS_DSEQ || "", + AKASH_MANIFEST_MODE: process.env.AKASH_MANIFEST_MODE || "auto", + AKASH_MANIFEST_PATH: process.env.AKASH_MANIFEST_PATH || "", + AKASH_MANIFEST_VALIDATION_LEVEL: process.env.AKASH_MANIFEST_VALIDATION_LEVEL || "strict", + AKASH_DEPOSIT: process.env.AKASH_DEPOSIT || "500000uakt" + }; + } +} + +export async function validateAkashConfig( + runtime: IAgentRuntime +): Promise { + try { + // Log environment information + // elizaLogger.info("Environment configuration details", { + // shellMnemonic: process.env.AKASH_MNEMONIC, + // runtimeMnemonic: runtime.getSetting("AKASH_MNEMONIC"), + // envVars: { + // fromShell: Object.keys(process.env).filter(key => key.startsWith('AKASH_')), + // fromRuntime: Object.keys(runtime) + // .filter(key => typeof runtime.getSetting === 'function' && runtime.getSetting(key)) + // .filter(key => key.startsWith('AKASH_')) + // } + // }); + + const envConfig = getConfig( + runtime.getSetting("AKASH_ENV") ?? undefined + ); + + // Fetch dynamic values from the network configuration + const akashNet = process.env.AKASH_NET || runtime.getSetting("AKASH_NET") || envConfig.AKASH_NET; + const version = await fetch(`${akashNet}/version.txt`).then(res => res.text()); + const chainId = await fetch(`${akashNet}/chain-id.txt`).then(res => res.text()); + const node = await fetch(`${akashNet}/rpc-nodes.txt`).then(res => res.text().then(text => text.split('\n')[0])); + + // Prioritize shell environment variables over runtime settings + const mnemonic = process.env.AKASH_MNEMONIC || runtime.getSetting("AKASH_MNEMONIC"); + + // elizaLogger.debug("SDL configuration", { + // fromShell: process.env.AKASH_SDL, + // fromRuntime: runtime.getSetting("AKASH_SDL"), + // fromConfig: envConfig.AKASH_SDL + // }); + + if (!mnemonic) { + throw new Error( + "AKASH_MNEMONIC not found in environment variables or runtime settings.\n" + + "Please ensure AKASH_MNEMONIC is set in your shell environment or runtime settings" + ); + } + + // Clean the mnemonic string - handle quotes and whitespace + const cleanMnemonic = mnemonic + .trim() + .replace(/^["']|["']$/g, '') // Remove surrounding quotes + .replace(/\n/g, ' ') + .replace(/\r/g, ' ') + .replace(/\s+/g, ' '); + + const mnemonicWords = cleanMnemonic.split(' ').filter(word => word.length > 0); + + if (mnemonicWords.length !== 12 && mnemonicWords.length !== 24) { + throw new Error( + `Invalid AKASH_MNEMONIC length: got ${mnemonicWords.length} words, expected 12 or 24 words.\n` + + `Words found: ${mnemonicWords.join(', ')}` + ); + } + + const config = { + AKASH_MNEMONIC: cleanMnemonic, + AKASH_NET: akashNet, + AKASH_VERSION: version, + AKASH_CHAIN_ID: chainId, + AKASH_NODE: node, + RPC_ENDPOINT: process.env.RPC_ENDPOINT || runtime.getSetting("RPC_ENDPOINT") || envConfig.RPC_ENDPOINT, + AKASH_GAS_PRICES: process.env.AKASH_GAS_PRICES || runtime.getSetting("AKASH_GAS_PRICES") || envConfig.AKASH_GAS_PRICES, + AKASH_GAS_ADJUSTMENT: process.env.AKASH_GAS_ADJUSTMENT || runtime.getSetting("AKASH_GAS_ADJUSTMENT") || envConfig.AKASH_GAS_ADJUSTMENT, + AKASH_KEYRING_BACKEND: process.env.AKASH_KEYRING_BACKEND || runtime.getSetting("AKASH_KEYRING_BACKEND") || envConfig.AKASH_KEYRING_BACKEND, + AKASH_FROM: process.env.AKASH_FROM || runtime.getSetting("AKASH_FROM") || envConfig.AKASH_FROM, + AKASH_FEES: process.env.AKASH_FEES || runtime.getSetting("AKASH_FEES") || envConfig.AKASH_FEES, + AKASH_PRICING_API_URL: process.env.AKASH_PRICING_API_URL || runtime.getSetting("AKASH_PRICING_API_URL") || envConfig.AKASH_PRICING_API_URL, + AKASH_DEFAULT_CPU: process.env.AKASH_DEFAULT_CPU || runtime.getSetting("AKASH_DEFAULT_CPU") || envConfig.AKASH_DEFAULT_CPU, + AKASH_DEFAULT_MEMORY: process.env.AKASH_DEFAULT_MEMORY || runtime.getSetting("AKASH_DEFAULT_MEMORY") || envConfig.AKASH_DEFAULT_MEMORY, + AKASH_DEFAULT_STORAGE: process.env.AKASH_DEFAULT_STORAGE || runtime.getSetting("AKASH_DEFAULT_STORAGE") || envConfig.AKASH_DEFAULT_STORAGE, + AKASH_SDL: process.env.AKASH_SDL || runtime.getSetting("AKASH_SDL") || envConfig.AKASH_SDL, + AKASH_CLOSE_DEP: process.env.AKASH_CLOSE_DEP || runtime.getSetting("AKASH_CLOSE_DEP") || envConfig.AKASH_CLOSE_DEP, + AKASH_CLOSE_DSEQ: process.env.AKASH_CLOSE_DSEQ || runtime.getSetting("AKASH_CLOSE_DSEQ") || envConfig.AKASH_CLOSE_DSEQ, + AKASH_PROVIDER_INFO: process.env.AKASH_PROVIDER_INFO || runtime.getSetting("AKASH_PROVIDER_INFO") || envConfig.AKASH_PROVIDER_INFO, + AKASH_DEP_STATUS: process.env.AKASH_DEP_STATUS || runtime.getSetting("AKASH_DEP_STATUS") || envConfig.AKASH_DEP_STATUS, + AKASH_DEP_DSEQ: process.env.AKASH_DEP_DSEQ || runtime.getSetting("AKASH_DEP_DSEQ") || envConfig.AKASH_DEP_DSEQ, + AKASH_GAS_OPERATION: process.env.AKASH_GAS_OPERATION || runtime.getSetting("AKASH_GAS_OPERATION") || envConfig.AKASH_GAS_OPERATION, + AKASH_GAS_DSEQ: process.env.AKASH_GAS_DSEQ || runtime.getSetting("AKASH_GAS_DSEQ") || envConfig.AKASH_GAS_DSEQ, + AKASH_MANIFEST_MODE: process.env.AKASH_MANIFEST_MODE || runtime.getSetting("AKASH_MANIFEST_MODE") || envConfig.AKASH_MANIFEST_MODE, + AKASH_MANIFEST_PATH: process.env.AKASH_MANIFEST_PATH || runtime.getSetting("AKASH_MANIFEST_PATH") || envConfig.AKASH_MANIFEST_PATH, + AKASH_MANIFEST_VALIDATION_LEVEL: process.env.AKASH_MANIFEST_VALIDATION_LEVEL || runtime.getSetting("AKASH_MANIFEST_VALIDATION_LEVEL") || envConfig.AKASH_MANIFEST_VALIDATION_LEVEL, + AKASH_DEPOSIT: process.env.AKASH_DEPOSIT || runtime.getSetting("AKASH_DEPOSIT") || envConfig.AKASH_DEPOSIT + }; + + return akashEnvSchema.parse(config); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + throw new Error(`Failed to validate Akash configuration: ${errorMessage}`); + } +} diff --git a/packages/plugin-akash/src/error/error.ts b/packages/plugin-akash/src/error/error.ts new file mode 100644 index 0000000000..fb6d56416b --- /dev/null +++ b/packages/plugin-akash/src/error/error.ts @@ -0,0 +1,125 @@ + +export enum AkashErrorCategory { + WALLET = 'WALLET', + DEPLOYMENT = 'DEPLOYMENT', + LEASE = 'LEASE', + PROVIDER = 'PROVIDER', + MANIFEST = 'MANIFEST', + NETWORK = 'NETWORK', + TRANSACTION = 'TRANSACTION', + VALIDATION = 'VALIDATION', + SDK = 'SDK', + API = 'API', + FILE = 'FILE' +} + +export enum AkashErrorCode { + // Wallet Errors (1000-1999) + WALLET_NOT_INITIALIZED = 1000, + WALLET_CONNECTION_FAILED = 1001, + WALLET_INSUFFICIENT_FUNDS = 1002, + WALLET_UNAUTHORIZED = 1003, + WALLET_SIGNATURE_FAILED = 1004, + WALLET_MESSAGE_INVALID = 1005, + WALLET_INITIALIZATION_FAILED = "WALLET_INITIALIZATION_FAILED", + CLIENT_SETUP_FAILED = "CLIENT_SETUP_FAILED", + + // Certificate Errors (1500-1599) + CERTIFICATE_CREATION_FAILED = 1500, + CERTIFICATE_BROADCAST_FAILED = 1501, + CERTIFICATE_NOT_FOUND = 1502, + + // Deployment Errors (2000-2999) + DEPLOYMENT_NOT_FOUND = 2000, + DEPLOYMENT_CREATION_FAILED = 2001, + DEPLOYMENT_UPDATE_FAILED = 2002, + DEPLOYMENT_CLOSE_FAILED = 2003, + DEPLOYMENT_START_TIMEOUT = 2004, + + // Lease Errors (3000-3999) + LEASE_NOT_FOUND = 3000, + LEASE_CREATION_FAILED = 3001, + LEASE_CLOSE_FAILED = 3002, + LEASE_INVALID_STATE = 3003, + LEASE_BID_NOT_FOUND = 3004, + LEASE_QUERY_FAILED = 3005, + LEASE_STATUS_ERROR = 3006, + LEASE_VALIDATION_FAILED = 3007, + INVALID_LEASE = 3008, + + // Provider Errors (4000-4999) + PROVIDER_NOT_FOUND = 4000, + PROVIDER_UNREACHABLE = 4001, + PROVIDER_RESPONSE_ERROR = 4002, + PROVIDER_LIST_ERROR = 4003, + PROVIDER_FILTER_ERROR = 4004, + + // Manifest Errors (5000-5999) + MANIFEST_INVALID = 5000, + MANIFEST_PARSING_FAILED = 5001, + MANIFEST_DEPLOYMENT_FAILED = 5002, + MANIFEST_VALIDATION_FAILED = 5003, + + // Bid Errors (6000-6999) + BID_FETCH_TIMEOUT = 6000, + INVALID_BID = 6001, + + // SDL Errors (7000-7999) + SDL_PARSING_FAILED = 7000, + + // Validation Errors (8000-8999) + VALIDATION_PARAMETER_MISSING = 8000, + VALIDATION_PARAMETER_INVALID = 8001, + VALIDATION_STATE_INVALID = 8002, + VALIDATION_SDL_FAILED = 8003, + VALIDATION_CONFIG_INVALID = 8004, + + // Generic Errors (9000-9999) + INSUFFICIENT_FUNDS = 9000, + + // API Errors (10000-10999) + API_ERROR = 10000, + API_RESPONSE_INVALID = 10001, + API_REQUEST_FAILED = 10002, + API_TIMEOUT = 10003, + + // File System Errors (11000-11999) + FILE_NOT_FOUND = 11000, + FILE_READ_ERROR = 11001, + FILE_WRITE_ERROR = 11002, + FILE_PERMISSION_ERROR = 11003, + + // Network Errors (12000-12999) + RPC_CONNECTION_FAILED = 12000 +} + +export class AkashError extends Error { + constructor( + message: string, + public code: AkashErrorCode, + public details?: Record, + public category: string = "akash" + ) { + super(message); + this.name = "AkashError"; + } +} + +export async function withRetry( + fn: () => Promise, + maxRetries: number = 3, + delay: number = 1000 +): Promise { + let lastError: Error | undefined; + for (let i = 0; i < maxRetries; i++) { + try { + return await fn(); + } catch (error) { + lastError = error as Error; + if (i < maxRetries - 1) { + await new Promise(resolve => setTimeout(resolve, delay * Math.pow(2, i))); + } + } + } + throw lastError; +} diff --git a/packages/plugin-akash/src/index.ts b/packages/plugin-akash/src/index.ts new file mode 100644 index 0000000000..ffa07f75f6 --- /dev/null +++ b/packages/plugin-akash/src/index.ts @@ -0,0 +1,68 @@ +import { Plugin} from "@elizaos/core"; +import { createDeploymentAction } from "./actions/createDeployment"; +import { closeDeploymentAction } from "./actions/closeDeployment"; +import { getProviderInfoAction } from "./actions/getProviderInfo"; +import { getDeploymentStatusAction } from "./actions/getDeploymentStatus"; +import { estimateGas } from "./actions/estimateGas"; +import { getDeploymentApiAction } from "./actions/getDeploymentApi"; +import { getGPUPricingAction } from "./actions/getGPUPricing"; +import { getManifestAction } from "./actions/getManifest"; +import { getProvidersListAction } from "./actions/getProvidersList"; + +const actions = [ + createDeploymentAction, + closeDeploymentAction, + getProviderInfoAction, + getDeploymentStatusAction, + estimateGas, + getDeploymentApiAction, + getGPUPricingAction, + getManifestAction, + getProvidersListAction, +]; + +// Initial banner +console.log("\n┌════════════════════════════════════════┐"); +console.log("│ AKASH NETWORK PLUGIN │"); +console.log("├────────────────────────────────────────┤"); +console.log("│ Initializing Akash Network Plugin... │"); +console.log("│ Version: 0.1.0 │"); +console.log("└════════════════════════════════════════┘"); + +// Format action registration message +const formatActionInfo = (action: any) => { + const name = action.name.padEnd(25); + const similes = (action.similes?.join(", ") || "none").padEnd(60); + const hasHandler = action.handler ? "✓" : "✗"; + const hasValidator = action.validate ? "✓" : "✗"; + const hasExamples = action.examples?.length > 0 ? "✓" : "✗"; + + return `│ ${name} │ ${hasHandler} │ ${hasValidator} │ ${hasExamples} │ ${similes} │`; +}; + +// Log registered actions +console.log("\n┌───────────────────────────┬───┬───┬───┬───────────────────────────────────────────────────────────┐"); +console.log("│ Action │ H │ V │ E │ Similes │"); +console.log("├───────────────────────────┼───┼───┼───┼────────────────────────────────────────────────────────────┤"); +actions.forEach(action => { + console.log(formatActionInfo(action)); +}); +console.log("└───────────────────────────┴───┴───┴───┴──────────────────────────────────────────────────────────┘"); + +// Plugin status +console.log("\n┌─────────────────────────────────────┐"); +console.log("│ Plugin Status │"); +console.log("├─────────────────────────────────────┤"); +console.log(`│ Name : akash │`); +console.log(`│ Actions : ${actions.length.toString().padEnd(24)} │`); +console.log(`│ Status : Loaded & Ready │`); +console.log("└─────────────────────────────────────┘\n"); + +export const akashPlugin: Plugin = { + name: "akash", + description: "Akash Network Plugin for deploying and managing cloud compute", + actions: actions, + evaluators: [] +}; + +export default akashPlugin; \ No newline at end of file diff --git a/packages/plugin-akash/src/providers/wallet.ts b/packages/plugin-akash/src/providers/wallet.ts new file mode 100644 index 0000000000..397c37ba5a --- /dev/null +++ b/packages/plugin-akash/src/providers/wallet.ts @@ -0,0 +1,108 @@ +import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing"; +import { SigningStargateClient } from "@cosmjs/stargate"; +import { elizaLogger, IAgentRuntime, Memory } from "@elizaos/core"; +// import { IAgentRuntime, Memory } from "@elizaos/core/src/types"; +import { validateAkashConfig } from "../environment"; +import { getAkashTypeRegistry } from "@akashnetwork/akashjs/build/stargate"; +import { + AkashProvider, + AkashWalletState, + AkashError, + AKASH_ERROR_CODES, +} from "../types"; + +// Use a proper UUID for the wallet room +const WALLET_ROOM_ID = "00000000-0000-0000-0000-000000000001"; + +export const walletProvider: AkashProvider = { + type: "AKASH_WALLET", + version: "1.0.0", + name: "wallet", + description: "Akash wallet provider", + + initialize: async (runtime: IAgentRuntime): Promise => { + elizaLogger.info("Initializing Akash wallet provider"); + try { + const mnemonic = runtime.getSetting("AKASH_MNEMONIC"); + if (!mnemonic) { + throw new Error("AKASH_MNEMONIC not found in environment variables"); + } + + const config = await validateAkashConfig(runtime); + + // Create wallet from mnemonic + const wallet = await DirectSecp256k1HdWallet.fromMnemonic(config.AKASH_MNEMONIC, { + prefix: "akash", + }); + + // Get the wallet address + const [account] = await wallet.getAccounts(); + const address = account.address; + + // Create signing client with registry + const client = await SigningStargateClient.connectWithSigner( + config.RPC_ENDPOINT, + wallet, + { registry: getAkashTypeRegistry() as any } + ); + + // Store wallet info in memory manager + const state: AkashWalletState = { + wallet, + client, + address, + }; + + // Create memory object + const memory: Memory = { + id: WALLET_ROOM_ID, + userId: runtime.agentId, + agentId: runtime.agentId, + roomId: WALLET_ROOM_ID, + content: { + type: "wallet_state", + text: `Akash wallet initialized with address: ${address}`, + data: state, + }, + createdAt: Date.now(), + }; + + await runtime.messageManager.createMemory(memory); + + elizaLogger.info("Akash wallet provider initialized successfully", { + address, + }); + } catch (error) { + elizaLogger.error("Failed to initialize Akash wallet provider", { + error: error instanceof Error ? error.message : String(error) + }); + throw error; + } + }, + + get: async (runtime: IAgentRuntime, _message?: Memory): Promise => { + const memories = await runtime.messageManager.getMemories({ + roomId: WALLET_ROOM_ID, + count: 1, + }); + + const state = memories[0]?.content?.data; + if (!state) { + throw new AkashError( + "Akash wallet not initialized", + AKASH_ERROR_CODES.WALLET_NOT_INITIALIZED + ); + } + return state as AkashWalletState; + }, + + validate: async (_runtime: IAgentRuntime, _message?: Memory): Promise => { + return true; + }, + + process: async (_runtime: IAgentRuntime, _message?: Memory): Promise => { + // No processing needed for wallet provider + } +}; + +export default walletProvider; diff --git a/packages/plugin-akash/src/runtime_inspect.ts b/packages/plugin-akash/src/runtime_inspect.ts new file mode 100644 index 0000000000..25b5aee39f --- /dev/null +++ b/packages/plugin-akash/src/runtime_inspect.ts @@ -0,0 +1,90 @@ +import { elizaLogger } from "@elizaos/core"; +import type { IAgentRuntime, Plugin, Action } from "@elizaos/core"; + +/** + * Utility to inspect runtime plugin loading + */ +export function inspectRuntime(runtime: IAgentRuntime) { + elizaLogger.info("=== Runtime Plugin Inspection ==="); + + // Check if runtime has plugins array + const hasPlugins = !!(runtime as any).plugins; + elizaLogger.info("Runtime plugins status:", { + hasPluginsArray: hasPlugins, + pluginCount: hasPlugins ? (runtime as any).plugins.length : 0 + }); + + // If plugins exist, check for our plugin + if (hasPlugins) { + const plugins = (runtime as any).plugins as Plugin[]; + const akashPlugin = plugins.find(p => p.name === "akash"); + + elizaLogger.info("Akash plugin status:", { + isLoaded: !!akashPlugin, + pluginDetails: akashPlugin ? { + name: akashPlugin.name, + actionCount: akashPlugin.actions?.length || 0, + actions: akashPlugin.actions?.map(a => a.name) || [] + } : null + }); + } + + // Check registered actions + const hasActions = !!(runtime as any).actions; + if (hasActions) { + const actions = (runtime as any).actions as Action[]; + const akashActions = actions.filter((action: Action) => + action.name === "CREATE_DEPLOYMENT" || + (action.similes || []).includes("CREATE_DEPLOYMENT") + ); + + elizaLogger.info("Akash actions status:", { + totalActions: actions.length, + akashActionsCount: akashActions.length, + akashActions: akashActions.map((action: Action) => ({ + name: action.name, + similes: action.similes + })) + }); + } +} + +/** + * Helper to check if a plugin is properly loaded + */ +export function isPluginLoaded(runtime: IAgentRuntime, pluginName: string): boolean { + // Check plugins array + const plugins = (runtime as any).plugins as Plugin[]; + if (!plugins) { + elizaLogger.warn(`No plugins array found in runtime`); + return false; + } + + // Look for our plugin + const plugin = plugins.find(p => p.name === pluginName); + if (!plugin) { + elizaLogger.warn(`Plugin ${pluginName} not found in runtime plugins`); + return false; + } + + // Check if actions are registered + const actions = (runtime as any).actions as Action[]; + if (!actions || !actions.length) { + elizaLogger.warn(`No actions found in runtime`); + return false; + } + + // Check if plugin's actions are registered + const pluginActions = plugin.actions || []; + const registeredActions = pluginActions.every(pluginAction => + actions.some((action: Action) => action.name === pluginAction.name) + ); + + if (!registeredActions) { + elizaLogger.warn(`Not all ${pluginName} actions are registered in runtime`); + return false; + } + + elizaLogger.info(`Plugin ${pluginName} is properly loaded and registered`); + return true; +} \ No newline at end of file diff --git a/packages/plugin-akash/src/sdl/example.sdl.yml b/packages/plugin-akash/src/sdl/example.sdl.yml new file mode 100644 index 0000000000..6e6ac83688 --- /dev/null +++ b/packages/plugin-akash/src/sdl/example.sdl.yml @@ -0,0 +1,33 @@ +--- +version: "2.0" +services: + web: + image: baktun/hello-akash-world:1.0.0 + expose: + - port: 3000 + as: 80 + to: + - global: true +profiles: + compute: + web: + resources: + cpu: + units: 0.5 + memory: + size: 512Mi + storage: + size: 512Mi + placement: + dcloud: + pricing: + web: + denom: uakt + amount: 20000 + + +deployment: + web: + dcloud: + profile: web + count: 1 diff --git a/packages/plugin-akash/src/types.ts b/packages/plugin-akash/src/types.ts new file mode 100644 index 0000000000..b784290b49 --- /dev/null +++ b/packages/plugin-akash/src/types.ts @@ -0,0 +1,167 @@ +import { DirectSecp256k1HdWallet} from "@cosmjs/proto-signing"; +import { SigningStargateClient } from "@cosmjs/stargate"; +// import { Provider } from "@elizaos/core"; +import { IAgentRuntime, Memory } from "@elizaos/core"; +import { SDL } from "@akashnetwork/akashjs/build/sdl"; +import { MsgCreateDeployment } from "@akashnetwork/akash-api/akash/deployment/v1beta3"; +import { MsgCreateLease} from "@akashnetwork/akash-api/akash/market/v1beta4"; + +// Core wallet state type +export interface AkashWalletState { + wallet: DirectSecp256k1HdWallet; + client: SigningStargateClient; + address: string; + certificate?: { + cert: string; + privateKey: string; + publicKey: string; + }; +} + +// Provider type extending core Provider +export interface AkashProvider { + type: string; + version: string; + name: string; + description: string; + initialize: (runtime: IAgentRuntime) => Promise; + get: (runtime: IAgentRuntime, message?: Memory) => Promise; + validate: (runtime: IAgentRuntime, message?: Memory) => Promise; + process: (runtime: IAgentRuntime, message?: Memory) => Promise; +} + +// Registry type for Akash +export type AkashRegistryTypes = [string, any][]; + +// Deployment related types +export interface AkashDeploymentId { + owner: string; + dseq: string; +} + +export interface AkashDeployment { + id: AkashDeploymentId; + sdl: SDL; + deposit: string; + msg?: MsgCreateDeployment; +} + +// Lease related types +export interface AkashLeaseId { + owner: string; + dseq: string; + provider: string; + gseq: number; + oseq: number; +} + +export interface AkashLease { + id: AkashLeaseId; + state?: string; + manifestData?: any; + msg?: MsgCreateLease; +} + +// Provider types +export interface AkashProviderInfo { + owner: string; + hostUri: string; + attributes: Array<{ + key: string; + value: string; + }>; +} + +// Bid types +export interface AkashBidId { + owner: string; + dseq: string; + gseq: number; + oseq: number; + provider: string; +} + +export interface AkashBid { + id: AkashBidId; + state: string; + price: { + denom: string; + amount: string; + }; +} + +// Error handling types +export enum AKASH_ERROR_CODES { + WALLET_NOT_INITIALIZED = "WALLET_NOT_INITIALIZED", + INVALID_MNEMONIC = "INVALID_MNEMONIC", + INVALID_ADDRESS = "INVALID_ADDRESS", + INSUFFICIENT_FUNDS = "INSUFFICIENT_FUNDS", + DEPLOYMENT_FAILED = "DEPLOYMENT_FAILED", + LEASE_FAILED = "LEASE_FAILED", + PROVIDER_NOT_FOUND = "PROVIDER_NOT_FOUND", + NETWORK_ERROR = "NETWORK_ERROR", + CERTIFICATE_ERROR = "CERTIFICATE_ERROR", + MANIFEST_ERROR = "MANIFEST_ERROR", + BID_ERROR = "BID_ERROR", + MANIFEST_FAILED = "MANIFEST_FAILED", + PROVIDER_ERROR = "PROVIDER_ERROR" +} + +export class AkashError extends Error { + constructor( + message: string, + public code: AKASH_ERROR_CODES, + public originalError?: Error + ) { + super(message); + this.name = "AkashError"; + } +} + +// Provider configuration +export interface AkashConfig { + AKASH_MNEMONIC: string; + RPC_ENDPOINT: string; + CHAIN_ID?: string; + GAS_PRICE?: string; + GAS_ADJUSTMENT?: number; + CERTIFICATE_PATH?: string; +} + +// Message types +export interface AkashMessage { + type: string; + value: any; +} + +// Response types +export interface AkashTxResponse { + code: number; + height: number; + txhash: string; + rawLog: string; + data?: string; + gasUsed: number; + gasWanted: number; +} + +// Provider state types +export interface AkashProviderState { + isInitialized: boolean; + lastSync: number; + balance?: string; + address?: string; + certificate?: { + cert: string; + privateKey: string; + publicKey: string; + }; +} + +// Memory room constants +export const AKASH_MEMORY_ROOMS = { + WALLET: "00000000-0000-0000-0000-000000000001", + DEPLOYMENT: "00000000-0000-0000-0000-000000000002", + LEASE: "00000000-0000-0000-0000-000000000003", + CERTIFICATE: "00000000-0000-0000-0000-000000000004" +} as const; diff --git a/packages/plugin-akash/src/utils/paths.ts b/packages/plugin-akash/src/utils/paths.ts new file mode 100644 index 0000000000..c74151b2f7 --- /dev/null +++ b/packages/plugin-akash/src/utils/paths.ts @@ -0,0 +1,133 @@ +import * as path from 'path'; +import { fileURLToPath } from 'url'; +import { elizaLogger } from "@elizaos/core"; +import { existsSync } from 'fs'; +import { getConfig } from '../environment'; + +export const getPluginRoot = (importMetaUrl: string) => { + // elizaLogger.info("=== Starting Plugin Root Resolution ===", { + // importMetaUrl, + // isFileProtocol: importMetaUrl.startsWith('file://'), + // urlSegments: importMetaUrl.split('/') + // }); + + const currentFileUrl = importMetaUrl; + const currentFilePath = fileURLToPath(currentFileUrl); + const currentDir = path.dirname(currentFilePath); + + // Find plugin-akash directory by walking up until we find it + let dir = currentDir; + while (dir && path.basename(dir) !== 'plugin-akash' && dir !== '/') { + dir = path.dirname(dir); + } + + if (!dir || dir === '/') { + elizaLogger.error("Could not find plugin-akash directory", { + currentFilePath, + currentDir, + searchPath: dir + }); + throw new Error("Could not find plugin-akash directory"); + } + + // elizaLogger.info("Plugin Root Path Details", { + // currentFilePath, + // currentDir, + // pluginRoot: dir, + // exists: existsSync(dir), + // parentDir: path.dirname(dir), + // parentExists: existsSync(path.dirname(dir)), + // parentContents: existsSync(path.dirname(dir)) ? fs.readdirSync(path.dirname(dir)) : [] + // }); + + return dir; +}; + +export const getSrcPath = (importMetaUrl: string) => { + // elizaLogger.info("=== Resolving Src Path ==="); + const pluginRoot = getPluginRoot(importMetaUrl); + const srcPath = path.join(pluginRoot, 'src'); + + // elizaLogger.info("Src Path Details", { + // pluginRoot, + // srcPath, + // exists: existsSync(srcPath), + // contents: existsSync(srcPath) ? fs.readdirSync(srcPath) : [], + // absolutePath: path.resolve(srcPath), + // relativeToCwd: path.relative(process.cwd(), srcPath) + // }); + + return srcPath; +}; + +export const getCertificatePath = (importMetaUrl: string) => { + const srcPath = getSrcPath(importMetaUrl); + const certPath = path.join(srcPath, '.certificates', 'cert.json'); + + // elizaLogger.debug("Certificate Path Resolution", { + // srcPath, + // certPath, + // exists: existsSync(certPath) + // }); + + return certPath; +}; + +export const getDefaultSDLPath = (importMetaUrl: string) => { + // elizaLogger.info("=== Resolving SDL Path ==="); + const pluginRoot = getPluginRoot(importMetaUrl); + const srcPath = getSrcPath(importMetaUrl); + const config = getConfig(process.env.AKASH_ENV); + const sdlFileName = config.AKASH_SDL; + const sdlPath = path.join(srcPath, 'sdl', sdlFileName); + // const sdlDir = path.dirname(sdlPath); + + // Only log if file doesn't exist as a warning + if (!existsSync(sdlPath)) { + // elizaLogger.warn("SDL file not found at expected path", { + // sdlPath, + // exists: false + // }); + } + + // Try to find SDL file in nearby directories + const searchPaths = [ + sdlPath, + path.join(srcPath, sdlFileName), + path.join(pluginRoot, sdlFileName), + path.join(pluginRoot, 'sdl', sdlFileName), + path.join(pluginRoot, 'src', 'sdl', sdlFileName) + ]; + + // Only log if we find the file + for (const searchPath of searchPaths) { + if (existsSync(searchPath)) { + // elizaLogger.info("Found SDL file at", { path: searchPath }); + return searchPath; + } + } + + return sdlPath; +}; + +// Helper function to ensure a path includes plugin-akash +export const ensurePluginPath = (filePath: string, importMetaUrl: string) => { + if (!filePath.includes('plugin-akash')) { + const srcPath = getSrcPath(importMetaUrl); + return path.join(srcPath, path.basename(filePath)); + } + return filePath; +}; + +export function getDeploymentsPath(importMetaUrl: string): string { + const srcPath = getSrcPath(importMetaUrl); + const deploymentsPath = path.join(srcPath, 'deployments'); + + // elizaLogger.debug("Deployments Path Resolution", { + // srcPath, + // deploymentsPath, + // exists: existsSync(deploymentsPath) + // }); + + return deploymentsPath; +} \ No newline at end of file diff --git a/packages/plugin-akash/tsconfig.json b/packages/plugin-akash/tsconfig.json new file mode 100644 index 0000000000..e535bee0d7 --- /dev/null +++ b/packages/plugin-akash/tsconfig.json @@ -0,0 +1,39 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "module": "ESNext", + "target": "ESNext", + "lib": [ + "ESNext", + "DOM" + ], + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "emitDeclarationOnly": true, + "isolatedModules": true, + "esModuleInterop": true, + "skipLibCheck": true, + "strict": true, + "declaration": true, + "sourceMap": true, + "types": [ + "vitest/globals", + "node", + "jest" + ], + "baseUrl": ".", + "preserveSymlinks": true + }, + "include": [ + "src/**/*", + "test/actions/getDeploymentApi.test.ts" + ], + "exclude": [ + "node_modules", + "dist", + "test", + "../../packages/core/**/*" + ] +} \ No newline at end of file diff --git a/packages/plugin-akash/tsup.config.ts b/packages/plugin-akash/tsup.config.ts new file mode 100644 index 0000000000..a2b714de91 --- /dev/null +++ b/packages/plugin-akash/tsup.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["esm"], + dts: true, + splitting: false, + sourcemap: true, + clean: true, +}); diff --git a/packages/plugin-akash/vitest.config.ts b/packages/plugin-akash/vitest.config.ts new file mode 100644 index 0000000000..2b76c16878 --- /dev/null +++ b/packages/plugin-akash/vitest.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from 'vitest/config'; +import path from 'path'; + +export default defineConfig({ + test: { + globals: true, + environment: 'node', + include: ['test/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'], + exclude: ['node_modules', 'dist', '.idea', '.git', '.cache'], + root: '.', + reporters: ['verbose'], + coverage: { + reporter: ['text', 'json', 'html'], + exclude: [ + 'node_modules/', + 'test/fixtures/', + 'test/setup/' + ] + }, + setupFiles: ['./test/setup/vitest.setup.ts'] + }, + resolve: { + alias: { + '@': path.resolve(__dirname, './src') + } + } +}); \ No newline at end of file diff --git a/packages/plugin-anyone/src/actions/startAnyone.ts b/packages/plugin-anyone/src/actions/startAnyone.ts index 9edc260ae7..855837c4f8 100644 --- a/packages/plugin-anyone/src/actions/startAnyone.ts +++ b/packages/plugin-anyone/src/actions/startAnyone.ts @@ -24,7 +24,8 @@ export const startAnyone: Action = { _callback: HandlerCallback ): Promise => { await AnyoneClientService.initialize(); - const anon = AnyoneClientService.getInstance(); + //lint says unused + //const anon = AnyoneClientService.getInstance(); const proxyService = AnyoneProxyService.getInstance(); await proxyService.initialize(); diff --git a/packages/plugin-asterai/.npmignore b/packages/plugin-asterai/.npmignore new file mode 100644 index 0000000000..0468b4b364 --- /dev/null +++ b/packages/plugin-asterai/.npmignore @@ -0,0 +1,6 @@ +* + +!dist/** +!package.json +!readme.md +!tsup.config.ts diff --git a/packages/plugin-asterai/README.md b/packages/plugin-asterai/README.md new file mode 100644 index 0000000000..c84bf32f3a --- /dev/null +++ b/packages/plugin-asterai/README.md @@ -0,0 +1,80 @@ +# @elizaos/plugin-asterai + +A plugin for interacting with [asterai](https://asterai.io) plugins and agents. + +## Description + +This plugin provides functionality to allow Eliza agents to interact with +asterai plugins and agents. + +This will expand your Eliza character's utility by giving it access to all +the functionality of asterai's ecosystem of marketplace and private plugins +and agents. + +## Installation + +```bash +pnpm install @elizaos/plugin-asterai +``` + +## Configuration + +The plugin requires the following environment variables to be set: + +```typescript +ASTERAI_AGENT_ID= +ASTERAI_PUBLIC_QUERY_KEY= +``` + +## Usage + +### Basic Integration + +```typescript +import { asteraiPlugin } from '@elizaos/plugin-asterai'; +``` + +### Example Usage + +The plugin supports natural language for interacting with the asterai agent +through your Eliza character. + +For example, if your asterai agent can fetch weather data: + +```typescript +"Hey Eliza, how's the weather in LA?" +``` + +Eliza will then query the asterai agent to fetch the information. + +## Development Guide + +### Setting Up Development Environment + +1. Clone the repository +2. Install dependencies: + +```bash +pnpm install +``` + +3. Build the plugin: + +```bash +pnpm run build +``` + +4. Run tests: + +```bash +pnpm run test +``` + +## Contributing + +Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information. + +## License + +This plugin is part of the Eliza project. See the main project repository for license information. + diff --git a/packages/plugin-asterai/eslint.config.mjs b/packages/plugin-asterai/eslint.config.mjs new file mode 100644 index 0000000000..92fe5bbebe --- /dev/null +++ b/packages/plugin-asterai/eslint.config.mjs @@ -0,0 +1,3 @@ +import eslintGlobalConfig from "../../eslint.config.mjs"; + +export default [...eslintGlobalConfig]; diff --git a/packages/plugin-asterai/package.json b/packages/plugin-asterai/package.json new file mode 100644 index 0000000000..b7b02acb85 --- /dev/null +++ b/packages/plugin-asterai/package.json @@ -0,0 +1,46 @@ +{ + "name": "@elizaos/plugin-asterai", + "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": { + "@asterai/client": "0.1.6", + "@elizaos/core": "workspace:*", + "bignumber.js": "9.1.2", + "bs58": "6.0.0", + "elliptic": "6.6.1", + "node-cache": "5.1.2", + "sha3": "2.1.4", + "uuid": "11.0.3", + "zod": "3.23.8" + }, + "devDependencies": { + "@types/elliptic": "6.4.18", + "@types/uuid": "10.0.0", + "tsup": "8.3.5" + }, + "scripts": { + "lines": "find . \\( -name '*.cdc' -o -name '*.ts' \\) -not -path '*/node_modules/*' -not -path '*/tests/*' -not -path '*/deps/*' -not -path '*/dist/*' -not -path '*/imports*' | xargs wc -l", + "build": "tsup --format esm --dts", + "dev": "tsup --format esm --dts --watch", + "lint": "eslint --fix --cache ." + }, + "peerDependencies": { + "whatwg-url": "7.1.0" + } +} diff --git a/packages/plugin-asterai/src/actions/query.ts b/packages/plugin-asterai/src/actions/query.ts new file mode 100644 index 0000000000..c59fbbe632 --- /dev/null +++ b/packages/plugin-asterai/src/actions/query.ts @@ -0,0 +1,72 @@ +import { + elizaLogger, + type Action, + type ActionExample, + type HandlerCallback, + type IAgentRuntime, + type Memory, + type State, +} from "@elizaos/core"; +import { validateAsteraiConfig } from "../environment"; +import {getInitAsteraiClient} from "../index.ts"; + +export const queryAction = { + name: "QUERY_ASTERAI_AGENT", + similes: [ + "MESSAGE_ASTERAI_AGENT", + "TALK_TO_ASTERAI_AGENT", + "SEND_MESSAGE_TO_ASTERAI_AGENT", + "COMMUNICATE_WITH_ASTERAI_AGENT", + ], + description: + "Call this action to send a message to the asterai agent which " + + "has access to external plugins and functionality to answer " + + "the user you are assisting, to help perform a workflow task, etc.", + validate: async (runtime: IAgentRuntime, _message: Memory) => { + const config = await validateAsteraiConfig(runtime); + getInitAsteraiClient( + config.ASTERAI_AGENT_ID, + config.ASTERAI_PUBLIC_QUERY_KEY + ); + return true; + }, + handler: async ( + runtime: IAgentRuntime, + message: Memory, + _state: State, + _options: { [key: string]: unknown }, + callback?: HandlerCallback + ): Promise => { + const config = await validateAsteraiConfig(runtime); + const asteraiClient = getInitAsteraiClient( + config.ASTERAI_AGENT_ID, + config.ASTERAI_PUBLIC_QUERY_KEY + ); + elizaLogger.debug("called QUERY_ASTERAI_AGENT action with message:", message.content); + const response = await asteraiClient.query({ + query: message.content.text + }); + const textResponse = await response.text(); + callback({ + text: textResponse + }); + return true; + }, + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "How's the weather in LA?", + }, + }, + { + user: "{{user2}}", + content: { + text: "Let me check that for you, just a moment.", + action: "QUERY_ASTERAI_AGENT", + }, + }, + ], + ] as ActionExample[][], +} as Action; diff --git a/packages/plugin-asterai/src/environment.ts b/packages/plugin-asterai/src/environment.ts new file mode 100644 index 0000000000..a15c6f919b --- /dev/null +++ b/packages/plugin-asterai/src/environment.ts @@ -0,0 +1,39 @@ +import { IAgentRuntime } from "@elizaos/core"; +import { z } from "zod"; + +const envSchema = z.object({ + ASTERAI_AGENT_ID: z + .string() + .min(1, "ASTERAI_AGENT_ID is required"), + ASTERAI_PUBLIC_QUERY_KEY: z + .string() + .min(1, "ASTERAI_PUBLIC_QUERY_KEY is required"), +}); + +export type AsteraiConfig = z.infer; + +export async function validateAsteraiConfig( + runtime: IAgentRuntime +): Promise { + try { + const config = { + ASTERAI_AGENT_ID: + runtime.getSetting("ASTERAI_AGENT_ID") || + process.env.ASTERAI_AGENT_ID, + ASTERAI_PUBLIC_QUERY_KEY: + runtime.getSetting("ASTERAI_PUBLIC_QUERY_KEY") || process.env.ASTERAI_PUBLIC_QUERY_KEY, + }; + + return envSchema.parse(config); + } catch (error) { + if (error instanceof z.ZodError) { + const errorMessages = error.errors + .map((err) => `${err.path.join(".")}: ${err.message}`) + .join("\n"); + throw new Error( + `Asterai plugin configuration validation failed:\n${errorMessages}` + ); + } + throw error; + } +} diff --git a/packages/plugin-asterai/src/index.ts b/packages/plugin-asterai/src/index.ts new file mode 100644 index 0000000000..7f77f154b2 --- /dev/null +++ b/packages/plugin-asterai/src/index.ts @@ -0,0 +1,33 @@ +import {asteraiProvider} from "./providers/asterai.provider.ts"; +import type { Plugin } from "@elizaos/core"; +import { queryAction } from "./actions/query"; +import { AsteraiClient } from "@asterai/client"; + +export * from "./environment"; +export * from "./providers/asterai.provider"; + +let asteraiClient: AsteraiClient | null = null; + +export const getInitAsteraiClient = ( + agentId: string, + publicQueryKey: string +): AsteraiClient => { + if (!asteraiClient) { + asteraiClient = new AsteraiClient({ + appId: agentId, + queryKey: publicQueryKey, + }) + } + return asteraiClient; +}; + +export const asteraiPlugin: Plugin = { + name: "asterai", + description: "asterai Plugin for Eliza", + providers: [asteraiProvider], + actions: [queryAction], + evaluators: [], + services: [], +}; + +export default asteraiPlugin; diff --git a/packages/plugin-asterai/src/providers/asterai.provider.ts b/packages/plugin-asterai/src/providers/asterai.provider.ts new file mode 100644 index 0000000000..f8bfc0084a --- /dev/null +++ b/packages/plugin-asterai/src/providers/asterai.provider.ts @@ -0,0 +1,63 @@ +import { + elizaLogger, + IAgentRuntime, + Memory, + Provider, + State, UUID, +} from "@elizaos/core"; +import {validateAsteraiConfig} from "../environment.ts"; +import {getInitAsteraiClient} from "../index.ts"; + +const asteraiProvider: Provider = { + get: async ( + runtime: IAgentRuntime, + message: Memory, + _state?: State + ): Promise => { + const hasConfiguredEnv = + !!runtime.getSetting("ASTERAI_AGENT_ID") && + !!runtime.getSetting("ASTERAI_PUBLIC_QUERY_KEY"); + if (!hasConfiguredEnv) { + elizaLogger.error( + "ASTERAI_AGENT_ID or ASTERAI_PUBLIC_QUERY_KEY " + + "not configured, skipping provider" + ); + return null; + } + const config = await validateAsteraiConfig(runtime); + const asteraiClient = getInitAsteraiClient( + config.ASTERAI_AGENT_ID, + config.ASTERAI_PUBLIC_QUERY_KEY + ); + if (!asteraiClient) { + elizaLogger.error("asteraiClient is not initialised"); + return null; + } + const agentId = runtime.getSetting("ASTERAI_AGENT_ID") as UUID; + let agentSummaryMemory = await runtime.knowledgeManager.getMemoryById(agentId); + if (!agentSummaryMemory) { + // Fetch & set summary memory. + const summary = await asteraiClient.fetchSummary(); + elizaLogger.debug("asterai agent summary fetched:", summary); + await runtime.knowledgeManager.createMemory({ + id: agentId, + userId: message.userId, + agentId: message.agentId, + roomId: message.roomId, + createdAt: Date.now(), + content: { + text: summary + } + }); + agentSummaryMemory = await runtime.knowledgeManager.getMemoryById(agentId); + } + if (!agentSummaryMemory) { + elizaLogger.error("failed to initialise agent's summary memory"); + return null; + } + return agentSummaryMemory.content.text; + }, +}; + +// Module exports +export { asteraiProvider }; diff --git a/packages/plugin-asterai/tsconfig.json b/packages/plugin-asterai/tsconfig.json new file mode 100644 index 0000000000..73993deaaf --- /dev/null +++ b/packages/plugin-asterai/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../core/tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": [ + "src/**/*.ts" + ] +} \ No newline at end of file diff --git a/packages/plugin-asterai/tsup.config.ts b/packages/plugin-asterai/tsup.config.ts new file mode 100644 index 0000000000..7f072ccb78 --- /dev/null +++ b/packages/plugin-asterai/tsup.config.ts @@ -0,0 +1,35 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + loader: { + ".cdc": "text", + }, + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + "safe-buffer", + "base-x", + "bs58", + "borsh", + "stream", + "buffer", + "querystring", + "amqplib", + // Add other modules you want to externalize + "@onflow/fcl", + "@onflow/types", + "sha3", + "elliptic", + ], +}); diff --git a/packages/plugin-autonome/package.json b/packages/plugin-autonome/package.json index 918a0ae6cf..61a552149b 100644 --- a/packages/plugin-autonome/package.json +++ b/packages/plugin-autonome/package.json @@ -1,6 +1,6 @@ { "name": "@elizaos/plugin-autonome", - "version": "0.1.7-alpha.1", + "version": "0.1.7", "main": "dist/index.js", "type": "module", "types": "dist/index.d.ts", diff --git a/packages/plugin-autonome/src/actions/launchAgent.ts b/packages/plugin-autonome/src/actions/launchAgent.ts index 0ae0111e80..f53eaddc5f 100644 --- a/packages/plugin-autonome/src/actions/launchAgent.ts +++ b/packages/plugin-autonome/src/actions/launchAgent.ts @@ -42,7 +42,7 @@ Given the recent messages, extract the following information about the requested export default { name: "LAUNCH_AGENT", similes: ["CREATE_AGENT", "DEPLOY_AGENT", "DEPLOY_ELIZA", "DEPLOY_BOT"], - validate: async (runtime: IAgentRuntime, message: Memory) => { + validate: async (_runtime: IAgentRuntime, _message: Memory) => { return true; }, description: "Launch an Eliza agent", @@ -95,6 +95,7 @@ export default { creationMethod: 2, envList: {}, templateId: "Eliza", + }; const sendPostRequest = async () => { try { @@ -169,4 +170,5 @@ export default { }, ], ] as ActionExample[][], -} as Action; +} satisfies Action; + diff --git a/packages/plugin-autonome/tsup.config.ts b/packages/plugin-autonome/tsup.config.ts index dd25475bb6..a47c9eb64b 100644 --- a/packages/plugin-autonome/tsup.config.ts +++ b/packages/plugin-autonome/tsup.config.ts @@ -15,15 +15,5 @@ export default defineConfig({ "https", "http", "agentkeepalive", - "safe-buffer", - "base-x", - "bs58", - "borsh", - "@solana/buffer-layout", - "stream", - "buffer", - "querystring", - "amqplib", - // Add other modules you want to externalize ], }); diff --git a/packages/plugin-avail/src/actions/submitData.ts b/packages/plugin-avail/src/actions/submitData.ts index 978ae5a3dc..e90622105a 100644 --- a/packages/plugin-avail/src/actions/submitData.ts +++ b/packages/plugin-avail/src/actions/submitData.ts @@ -9,16 +9,13 @@ import { type Action, elizaLogger, composeContext, - generateObject, generateObjectDeprecated, } from "@elizaos/core"; import { validateAvailConfig } from "../environment"; import { - getDecimals, + //getDecimals, initialize, - formatNumberToBalance, getKeyringFromSeed, - isValidAddress, } from "avail-js-sdk"; import { ISubmittableResult } from "@polkadot/types/types/extrinsic"; import { H256 } from "@polkadot/types/interfaces/runtime"; @@ -67,7 +64,7 @@ export default { "SUBMIT_DATA_ON_AVAIL_NETWORK", "SUBMIT_DATA_TO_AVAIL_NETWORK", ], - validate: async (runtime: IAgentRuntime, message: Memory) => { + validate: async (runtime: IAgentRuntime, _message: Memory) => { await validateAvailConfig(runtime); return true; }, @@ -116,14 +113,14 @@ export default { if (content.data != null) { try { const SEED = runtime.getSetting("AVAIL_SEED")!; - const ACCOUNT = runtime.getSetting("AVAIL_ADDRESS")!; + //const ACCOUNT = runtime.getSetting("AVAIL_ADDRESS")!; const ENDPOINT = runtime.getSetting("AVAIL_RPC_URL"); const APP_ID = runtime.getSetting("AVAIL_APP_ID"); const api = await initialize(ENDPOINT); const keyring = getKeyringFromSeed(SEED); const options = { app_id: APP_ID, nonce: -1 }; - const decimals = getDecimals(api); + //const decimals = getDecimals(api); const data = content.data; const submitDataInfo = await api.tx.dataAvailability diff --git a/packages/plugin-avail/src/actions/transfer.ts b/packages/plugin-avail/src/actions/transfer.ts index df3b04cbe8..8745048a96 100644 --- a/packages/plugin-avail/src/actions/transfer.ts +++ b/packages/plugin-avail/src/actions/transfer.ts @@ -9,7 +9,6 @@ import { type Action, elizaLogger, composeContext, - generateObject, generateObjectDeprecated, } from "@elizaos/core"; import { validateAvailConfig } from "../environment"; @@ -77,7 +76,7 @@ export default { "SEND_AVAIL_TOKEN_ON_AVAIL_DA", "PAY_ON_AVAIL", ], - validate: async (runtime: IAgentRuntime, message: Memory) => { + validate: async (runtime: IAgentRuntime, _message: Memory) => { await validateAvailConfig(runtime); return true; }, @@ -128,7 +127,7 @@ export default { if (content.amount != null && content.recipient != null) { try { const SEED = runtime.getSetting("AVAIL_SEED")!; - const PUBLIC_KEY = runtime.getSetting("AVAIL_ADDRESS")!; + //const PUBLIC_KEY = runtime.getSetting("AVAIL_ADDRESS")!; const ENDPOINT = runtime.getSetting("AVAIL_RPC_URL"); const api = await initialize(ENDPOINT); diff --git a/packages/plugin-coinbase/src/plugins/commerce.ts b/packages/plugin-coinbase/src/plugins/commerce.ts index 7dacdc0fcb..ca249b53d6 100644 --- a/packages/plugin-coinbase/src/plugins/commerce.ts +++ b/packages/plugin-coinbase/src/plugins/commerce.ts @@ -82,7 +82,7 @@ export async function getAllCharges(apiKey: string) { // Function to fetch details of a specific charge export async function getChargeDetails(apiKey: string, chargeId: string) { elizaLogger.debug("Starting getChargeDetails function"); - const getUrl = `${url}${chargeId}`; + const getUrl = `${url}/${chargeId}`; try { const response = await fetch(getUrl, { @@ -204,8 +204,8 @@ export const createCoinbaseChargeAction: Action = { text: `Charge created successfully: ${chargeResponse.hosted_url}`, attachments: [ { - id: crypto.randomUUID(), - url: chargeResponse.id, + id: chargeResponse.id, + url: chargeResponse.hosted_url, title: "Coinbase Commerce Charge", description: `Charge ID: ${chargeResponse.id}`, text: `Pay here: ${chargeResponse.hosted_url}`, @@ -351,6 +351,7 @@ export const getAllChargesAction: Action = { callback( { text: `Successfully fetched all charges. Total charges: ${charges.length}`, + attachments: charges, }, [] ); @@ -439,17 +440,20 @@ export const getChargeDetailsAction: Action = { elizaLogger.info("Fetched charge details:", chargeDetails); + const chargeData = chargeDetails.data; + callback( { text: `Successfully fetched charge details for ID: ${charge.id}`, attachments: [ { - id: crypto.randomUUID(), - url: chargeDetails.hosted_url, + id: chargeData.id, + url: chargeData.hosted_url, title: `Charge Details for ${charge.id}`, - description: `Details: ${JSON.stringify(chargeDetails, null, 2)}`, source: "coinbase", - text: "", + description: JSON.stringify(chargeDetails, null, 2), + text: `Pay here: ${chargeData.hosted_url}`, + contentType: "application/json", }, ], }, diff --git a/packages/plugin-cosmos/src/shared/helpers/cosmos-assets.ts b/packages/plugin-cosmos/src/shared/helpers/cosmos-assets.ts index 44321c8895..ae92d2cb24 100644 --- a/packages/plugin-cosmos/src/shared/helpers/cosmos-assets.ts +++ b/packages/plugin-cosmos/src/shared/helpers/cosmos-assets.ts @@ -3,12 +3,25 @@ import type { AssetList } from "@chain-registry/types"; export const getAvailableAssets = ( assets: AssetList[], customAssets: AssetList[] -) => [ - ...assets?.filter( - (asset) => - !(customAssets ?? []) - ?.map((customAsset) => customAsset.chain_name) - ?.includes(asset.chain_name) - ), - ...(customAssets ?? []), -]; +) => { + const result: AssetList[] = []; + const safeAssets = assets || []; + const safeCustomAssets = customAssets || []; + + // Get custom asset chain names for faster lookup + const customChainNames = new Set( + safeCustomAssets.map(asset => asset.chain_name) + ); + + // Add non-duplicate assets + for (const asset of safeAssets) { + if (!customChainNames.has(asset.chain_name)) { + result.push(asset); + } + } + + // Add all custom assets + result.push(...safeCustomAssets); + + return result; +} \ No newline at end of file diff --git a/packages/plugin-depin/src/actions/sentientai.ts b/packages/plugin-depin/src/actions/sentientai.ts index aee97b0fce..68f2440e0c 100644 --- a/packages/plugin-depin/src/actions/sentientai.ts +++ b/packages/plugin-depin/src/actions/sentientai.ts @@ -61,7 +61,7 @@ export const sentientAI: Action = { }, ], ], - validate: async (runtime: IAgentRuntime, message: Memory) => { + validate: async (_runtime: IAgentRuntime, _message: Memory) => { // no extra validation needed return true; }, diff --git a/packages/plugin-goplus/src/lib/GoPlusManage.ts b/packages/plugin-goplus/src/lib/GoPlusManage.ts index 1406e167ff..c1342f5416 100644 --- a/packages/plugin-goplus/src/lib/GoPlusManage.ts +++ b/packages/plugin-goplus/src/lib/GoPlusManage.ts @@ -13,9 +13,9 @@ export const GoPlusType = { ACCOUNT_ERC1155_SECURITY_CHECK: "ACCOUNT_ERC1155_SECURITY_CHECK", SIGNATURE_SECURITY_CHECK: "SIGNATURE_SECURITY_CHECK", URL_SECURITY_CHECK: "URL_SECURITY_CHECK", -} +} as const; -export type GoPlusType = (typeof GoPlusType)[keyof typeof GoPlusType] +export type GoPlusTypeType = (typeof GoPlusTypeEnum)[keyof typeof GoPlusType]; export type GoPlusParamType = { "type": GoPlusType, @@ -127,4 +127,4 @@ export class GoPlusManage { data2 } } -} \ No newline at end of file +} diff --git a/packages/plugin-hyperliquid/.npmignore b/packages/plugin-hyperliquid/.npmignore new file mode 100644 index 0000000000..078562ecea --- /dev/null +++ b/packages/plugin-hyperliquid/.npmignore @@ -0,0 +1,6 @@ +* + +!dist/** +!package.json +!readme.md +!tsup.config.ts \ No newline at end of file diff --git a/packages/plugin-hyperliquid/README.md b/packages/plugin-hyperliquid/README.md new file mode 100644 index 0000000000..a671c61b0e --- /dev/null +++ b/packages/plugin-hyperliquid/README.md @@ -0,0 +1,111 @@ +# Hyperliquid Plugin for Eliza + +This plugin enables interaction with the Hyperliquid DEX through Eliza, providing spot trading capabilities. + +## Features + +- 💱 Spot Trading + - Market orders (immediate execution) + - Limit orders (price-specific) + - Smart price validation to prevent mistakes +- 📊 Price Checking + - Real-time price information + - 24h price change + - Volume statistics +- 🔄 Order Management + - Cancel all open orders + - Clear feedback on execution + +## Installation + +Add the plugin to your Eliza configuration: + +```json +{ + "plugins": ["@elizaos/plugin-hyperliquid"] +} +``` + +## Configuration + +Set the following environment variables: + +```env +HYPERLIQUID_PRIVATE_KEY=your_private_key # Required for trading and cancelling orders +HYPERLIQUID_TESTNET=true_or_false # Optional, defaults to false +``` + +## Available Actions + +### 1. SPOT_TRADE + +Place spot market or limit orders. + +Examples: + +``` +# Market Orders +"buy 1 PIP" -> Buys 1 PIP at market price +"sell 2 HYPE" -> Sells 2 HYPE at market price +"market buy 1 ETH" -> Buys 1 ETH at market price + +# Limit Orders +"buy 1 PIP at 20 USDC" -> Places buy order for 1 PIP at 20 USDC +"sell 0.5 HYPE at 21 USDC" -> Places sell order for 0.5 HYPE at 21 USDC +``` + +### 2. PRICE_CHECK + +Get current price information for any token. + +Examples: + +``` +"What's the price of PIP?" +"Check HYPE price" +"Get ETH price" +``` + +Returns: Current price, 24h change, and volume. + +### 3. CANCEL_ORDERS + +Cancel all your open orders. + +Examples: + +``` +"Cancel all orders" +"Cancel my orders" +``` + +## Price Validation + +The plugin includes smart price validation to prevent mistakes: + +- Market Orders: Validates price is within ±50% of market price +- Limit Orders: + - Buy orders must be below market price + - Sell orders must be above market price + - Warns if price is very different from market (±80%) + +## Error Handling + +The plugin provides clear error messages for common issues: + +- Invalid token symbols +- Price validation failures +- Network connection issues +- Order execution failures + +## Security Notes + +- Store your private key securely using environment variables +- Test with small amounts first +- Use testnet for initial testing +- Monitor your orders regularly +- Double-check prices before confirming trades + +## License + +MIT diff --git a/packages/plugin-hyperliquid/eslint.config.mjs b/packages/plugin-hyperliquid/eslint.config.mjs new file mode 100644 index 0000000000..92fe5bbebe --- /dev/null +++ b/packages/plugin-hyperliquid/eslint.config.mjs @@ -0,0 +1,3 @@ +import eslintGlobalConfig from "../../eslint.config.mjs"; + +export default [...eslintGlobalConfig]; diff --git a/packages/plugin-hyperliquid/package.json b/packages/plugin-hyperliquid/package.json new file mode 100644 index 0000000000..14754a20f5 --- /dev/null +++ b/packages/plugin-hyperliquid/package.json @@ -0,0 +1,21 @@ +{ + "name": "@elizaos/plugin-hyperliquid", + "version": "0.1.7", + "main": "dist/index.js", + "type": "module", + "types": "dist/index.d.ts", + "dependencies": { + "@elizaos/core": "workspace:*", + "hyperliquid": "^1.5.6", + "zod": "^3.23.8" + }, + "devDependencies": { + "@types/node": "^20.0.0", + "tsup": "8.3.5" + }, + "scripts": { + "build": "tsup --format esm --dts", + "dev": "tsup --format esm --dts --watch", + "lint": "eslint --fix --cache ." + } +} diff --git a/packages/plugin-hyperliquid/src/actions/cancelOrders.ts b/packages/plugin-hyperliquid/src/actions/cancelOrders.ts new file mode 100644 index 0000000000..7c315ce536 --- /dev/null +++ b/packages/plugin-hyperliquid/src/actions/cancelOrders.ts @@ -0,0 +1,88 @@ +import { + Action, + ActionExample, + IAgentRuntime, + Memory, + State, + HandlerCallback, + elizaLogger, +} from "@elizaos/core"; +import { Hyperliquid } from "hyperliquid"; + +export const cancelOrders: Action = { + name: "CANCEL_ORDERS", + similes: ["CANCEL_ALL_ORDERS", "CANCEL", "CANCEL_ALL"], + description: "Cancel all open orders on Hyperliquid", + validate: async (runtime: IAgentRuntime) => { + return !!runtime.getSetting("HYPERLIQUID_PRIVATE_KEY"); + }, + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + options: Record, + callback?: HandlerCallback + ) => { + try { + // Initialize SDK + const sdk = new Hyperliquid({ + privateKey: runtime.getSetting("HYPERLIQUID_PRIVATE_KEY"), + testnet: runtime.getSetting("HYPERLIQUID_TESTNET") === "true", + enableWs: false, + }); + await sdk.connect(); + + elizaLogger.info("Cancelling all open orders..."); + const result = await sdk.custom.cancelAllOrders(); + elizaLogger.info("Cancel result:", result); + + if (callback) { + const cancelledCount = + result?.response?.data?.statuses?.length || 0; + callback({ + text: + cancelledCount > 0 + ? `Successfully cancelled ${cancelledCount} open order${cancelledCount > 1 ? "s" : ""}` + : "No open orders to cancel", + content: result, + }); + } + + return true; + } catch (error) { + elizaLogger.error("Error cancelling orders:", error); + if (callback) { + callback({ + text: `Error cancelling orders: ${error.message}`, + content: { error: error.message }, + }); + } + return false; + } + }, + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Cancel all my orders", + }, + }, + { + user: "{{agent}}", + content: { + text: "I'll cancel all your open orders.", + action: "CANCEL_ORDERS", + }, + }, + { + user: "{{agent}}", + content: { + text: "Successfully cancelled 2 open orders", + }, + }, + ], + ] as ActionExample[][], +}; + +export default cancelOrders; diff --git a/packages/plugin-hyperliquid/src/actions/priceCheck.ts b/packages/plugin-hyperliquid/src/actions/priceCheck.ts new file mode 100644 index 0000000000..8a7b6469a7 --- /dev/null +++ b/packages/plugin-hyperliquid/src/actions/priceCheck.ts @@ -0,0 +1,148 @@ +import { + Action, + ActionExample, + IAgentRuntime, + Memory, + State, + HandlerCallback, + composeContext, + elizaLogger, + generateObjectDeprecated, + ModelClass, +} from "@elizaos/core"; +import { Hyperliquid } from "hyperliquid"; +import { HyperliquidError } from "../types.js"; +import { priceCheckTemplate } from "../templates.js"; + +export const priceCheck: Action = { + name: "PRICE_CHECK", + similes: ["CHECK_PRICE", "GET_PRICE", "PRICE", "CURRENT_PRICE"], + description: "Get current price for a token on Hyperliquid", + validate: async () => true, // Public endpoint + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + options: Record, + callback?: HandlerCallback + ) => { + try { + // Initialize or update state + state = !state + ? await runtime.composeState(message) + : await runtime.updateRecentMessageState(state); + + const context = composeContext({ + state, + template: priceCheckTemplate, + }); + + const content = await generateObjectDeprecated({ + runtime, + context, + modelClass: ModelClass.SMALL, + }); + + if (!content?.symbol) { + throw new HyperliquidError( + "Could not determine which token price to check" + ); + } + + elizaLogger.info("Checking price for token:", content.symbol); + + // Initialize SDK + const sdk = new Hyperliquid({ + enableWs: false, + }); + await sdk.connect(); + + // Get market data + const [meta, assetCtxs] = + await sdk.info.spot.getSpotMetaAndAssetCtxs(); + + // Find token and market + const tokenIndex = meta.tokens.findIndex( + (token) => + token.name.toUpperCase() === content.symbol.toUpperCase() + ); + if (tokenIndex === -1) { + throw new HyperliquidError( + `Could not find token ${content.symbol}` + ); + } + + const marketIndex = assetCtxs.findIndex( + (ctx) => ctx.coin === `${content.symbol}-SPOT` + ); + if (marketIndex === -1) { + throw new HyperliquidError( + `Could not find market for ${content.symbol}` + ); + } + + const marketCtx = assetCtxs[marketIndex]; + if (!marketCtx || !marketCtx.midPx) { + throw new HyperliquidError( + `Could not get market price for ${content.symbol}` + ); + } + + const price = Number(marketCtx.midPx); + const dayChange = ( + ((price - Number(marketCtx.prevDayPx)) / + Number(marketCtx.prevDayPx)) * + 100 + ).toFixed(2); + const volume = Number(marketCtx.dayNtlVlm).toFixed(2); + + if (callback) { + callback({ + text: `${content.symbol} price: ${price.toFixed(2)} USDC (24h change: ${dayChange}%, volume: ${volume} USDC)`, + content: { + symbol: content.symbol, + price: price, + dayChange: dayChange, + volume: volume, + }, + }); + } + + return true; + } catch (error) { + elizaLogger.error("Error checking price:", error); + if (callback) { + callback({ + text: `Error checking price: ${error.message}`, + content: { error: error.message }, + }); + } + return false; + } + }, + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "What's the current price of PIP?", + }, + }, + { + user: "{{agent}}", + content: { + text: "I'll check the current PIP price for you.", + action: "PRICE_CHECK", + }, + }, + { + user: "{{agent}}", + content: { + text: "PIP price: 19.73 USDC (24h change: -1.82%, volume: 1053445.75 USDC)", + }, + }, + ], + ] as ActionExample[][], +}; + +export default priceCheck; diff --git a/packages/plugin-hyperliquid/src/actions/spotTrade.ts b/packages/plugin-hyperliquid/src/actions/spotTrade.ts new file mode 100644 index 0000000000..cdc3e3e100 --- /dev/null +++ b/packages/plugin-hyperliquid/src/actions/spotTrade.ts @@ -0,0 +1,263 @@ +import { + Action, + ActionExample, + IAgentRuntime, + Memory, + State, + HandlerCallback, + composeContext, + elizaLogger, + generateObjectDeprecated, + ModelClass, +} from "@elizaos/core"; +import { Hyperliquid } from "hyperliquid"; +import { + SpotOrderSchema, + HyperliquidError, + PRICE_VALIDATION, +} from "../types.js"; +import { spotTradeTemplate } from "../templates.js"; + +export const spotTrade: Action = { + name: "SPOT_TRADE", + similes: ["SPOT_ORDER", "SPOT_BUY", "SPOT_SELL"], + description: "Place a spot trade order on Hyperliquid", + validate: async (runtime: IAgentRuntime) => { + return !!runtime.getSetting("HYPERLIQUID_PRIVATE_KEY"); + }, + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + options: Record, + callback?: HandlerCallback + ) => { + try { + // Initialize or update state + state = !state + ? await runtime.composeState(message) + : await runtime.updateRecentMessageState(state); + + const context = composeContext({ + state, + template: spotTradeTemplate, + }); + + const content = await generateObjectDeprecated({ + runtime, + context, + modelClass: ModelClass.SMALL, + }); + + if (!content) { + throw new HyperliquidError( + "Could not parse trading parameters from conversation" + ); + } + + elizaLogger.info( + "Raw content from LLM:", + JSON.stringify(content, null, 2) + ); + + // Validate order parameters + const validatedOrder = SpotOrderSchema.parse(content); + elizaLogger.info("Validated order:", validatedOrder); + + // Initialize SDK + const sdk = new Hyperliquid({ + privateKey: runtime.getSetting("HYPERLIQUID_PRIVATE_KEY"), + testnet: runtime.getSetting("HYPERLIQUID_TESTNET") === "true", + enableWs: false, + }); + await sdk.connect(); + + // Get market data + const [meta, assetCtxs] = + await sdk.info.spot.getSpotMetaAndAssetCtxs(); + + // Find token and market + const tokenIndex = meta.tokens.findIndex( + (token) => + token.name.toUpperCase() === + validatedOrder.coin.toUpperCase() + ); + if (tokenIndex === -1) { + throw new HyperliquidError( + `Could not find token ${validatedOrder.coin}` + ); + } + const tokenInfo = meta.tokens[tokenIndex]; + elizaLogger.info("Found token:", tokenInfo.name); + + const marketIndex = assetCtxs.findIndex( + (ctx) => ctx.coin === `${validatedOrder.coin}-SPOT` + ); + if (marketIndex === -1) { + throw new HyperliquidError( + `Could not find market for ${validatedOrder.coin}` + ); + } + const marketCtx = assetCtxs[marketIndex]; + if (!marketCtx || !marketCtx.midPx) { + throw new HyperliquidError( + `Could not get market price for ${validatedOrder.coin}` + ); + } + + // Calculate prices + const midPrice = Number(marketCtx.midPx); + const isMarketOrder = !validatedOrder.limit_px; + let finalPrice: number; + + if (isMarketOrder) { + // For market orders, use current price with slippage + const slippage = PRICE_VALIDATION.SLIPPAGE; + finalPrice = validatedOrder.is_buy + ? midPrice * (1 + slippage) + : midPrice * (1 - slippage); + + // Validate market order price + if ( + finalPrice < + midPrice * PRICE_VALIDATION.MARKET_ORDER.MIN_RATIO || + finalPrice > + midPrice * PRICE_VALIDATION.MARKET_ORDER.MAX_RATIO + ) { + throw new HyperliquidError( + `Market order price (${finalPrice.toFixed(2)} USDC) is too far from market price (${midPrice.toFixed(2)} USDC). This might be due to low liquidity.` + ); + } + } else { + // For limit orders + finalPrice = validatedOrder.limit_px; + + // Validate limit order price is optimal + if (validatedOrder.is_buy && finalPrice > midPrice) { + throw new HyperliquidError( + `Cannot place buy limit order at ${finalPrice.toFixed(2)} USDC because it's above market price (${midPrice.toFixed(2)} USDC). To execute immediately, use a market order. For a limit order, set a price below ${midPrice.toFixed(2)} USDC.` + ); + } else if (!validatedOrder.is_buy && finalPrice < midPrice) { + throw new HyperliquidError( + `Cannot place sell limit order at ${finalPrice.toFixed(2)} USDC because it's below market price (${midPrice.toFixed(2)} USDC). To execute immediately, use a market order. For a limit order, set a price above ${midPrice.toFixed(2)} USDC.` + ); + } + + // Log warning if price is very different from market + if ( + finalPrice < + midPrice * + PRICE_VALIDATION.LIMIT_ORDER.WARNING_MIN_RATIO || + finalPrice > + midPrice * + PRICE_VALIDATION.LIMIT_ORDER.WARNING_MAX_RATIO + ) { + elizaLogger.warn( + `Limit price (${finalPrice.toFixed(2)} USDC) is very different from market price (${midPrice.toFixed(2)} USDC). Make sure this is intentional.`, + { + finalPrice, + midPrice, + ratio: finalPrice / midPrice, + } + ); + } + } + + // Prepare and place order + const rounded_px = Number(finalPrice.toFixed(tokenInfo.szDecimals)); + const orderRequest = { + coin: `${validatedOrder.coin}-SPOT`, + asset: 10000 + marketIndex, + is_buy: validatedOrder.is_buy, + sz: validatedOrder.sz, + limit_px: rounded_px, + reduce_only: false, + order_type: isMarketOrder + ? { market: {} } + : { limit: { tif: "Gtc" as const } }, + }; + + elizaLogger.info("Placing order:", orderRequest); + const result = await sdk.exchange.placeOrder(orderRequest); + + // Check if order was rejected + if ( + result.status === "ok" && + result.response?.type === "order" && + result.response.data?.statuses?.[0]?.error + ) { + throw new HyperliquidError( + result.response.data.statuses[0].error + ); + } + + // Send success callback + if (callback) { + const action = validatedOrder.is_buy ? "buy" : "sell"; + const executionPrice = + result.response?.data?.statuses?.[0]?.px || rounded_px; + callback({ + text: `Successfully placed ${isMarketOrder ? "a market" : "a limit"} order to ${action} ${validatedOrder.sz} ${validatedOrder.coin} at ${executionPrice}`, + content: result, + }); + } + + return true; + } catch (error) { + elizaLogger.error("Error placing spot order:", error); + if (callback) { + callback({ + text: `Error placing spot order: ${error.message}`, + content: { error: error.message }, + }); + } + return false; + } + }, + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Buy 0.1 HYPE at 20 USDC", + }, + }, + { + user: "{{agent}}", + content: { + text: "I'll place a spot buy order for 0.1 HYPE at 20 USDC.", + action: "SPOT_TRADE", + }, + }, + { + user: "{{agent}}", + content: { + text: "Successfully placed a limit order to buy 0.1 HYPE at 20 USDC", + }, + }, + ], + [ + { + user: "{{user1}}", + content: { + text: "Sell 2 HYPE at 21 USDC", + }, + }, + { + user: "{{agent}}", + content: { + text: "I'll place a spot sell order for 2 HYPE at 21 USDC.", + action: "SPOT_TRADE", + }, + }, + { + user: "{{agent}}", + content: { + text: "Successfully placed a limit order to sell 2 HYPE at 21 USDC", + }, + }, + ], + ] as ActionExample[][], +}; + +export default spotTrade; diff --git a/packages/plugin-hyperliquid/src/index.ts b/packages/plugin-hyperliquid/src/index.ts new file mode 100644 index 0000000000..a5e282f539 --- /dev/null +++ b/packages/plugin-hyperliquid/src/index.ts @@ -0,0 +1,16 @@ +import { Plugin } from "@elizaos/core"; +import { spotTrade } from "./actions/spotTrade"; +import { priceCheck } from "./actions/priceCheck"; +import { cancelOrders } from "./actions/cancelOrders"; + +export const hyperliquidPlugin: Plugin = { + name: "hyperliquid", + description: "Hyperliquid plugin", + actions: [spotTrade, priceCheck, cancelOrders], + providers: [], + evaluators: [], + services: [], + clients: [], +}; + +export default hyperliquidPlugin; diff --git a/packages/plugin-hyperliquid/src/templates.ts b/packages/plugin-hyperliquid/src/templates.ts new file mode 100644 index 0000000000..6ff8026537 --- /dev/null +++ b/packages/plugin-hyperliquid/src/templates.ts @@ -0,0 +1,57 @@ +export const spotTradeTemplate = `Look at your LAST RESPONSE in the conversation where you confirmed a trade request. +Based on ONLY that last message, extract the trading details: + +For Hyperliquid spot trading: +- Market orders (executes immediately at best available price): + "buy 1 HYPE" -> { "coin": "HYPE", "is_buy": true, "sz": 1 } + "sell 2 HYPE" -> { "coin": "HYPE", "is_buy": false, "sz": 2 } + "market buy 1 HYPE" -> { "coin": "HYPE", "is_buy": true, "sz": 1 } + "market sell 2 HYPE" -> { "coin": "HYPE", "is_buy": false, "sz": 2 } + +- Limit orders (waits for specified price): + "buy 1 HYPE at 20 USDC" -> { "coin": "HYPE", "is_buy": true, "sz": 1, "limit_px": 20 } + "sell 0.5 HYPE at 21 USDC" -> { "coin": "HYPE", "is_buy": false, "sz": 0.5, "limit_px": 21 } + "limit buy 1 HYPE at 20 USDC" -> { "coin": "HYPE", "is_buy": true, "sz": 1, "limit_px": 20 } + "limit sell 0.5 HYPE at 21 USDC" -> { "coin": "HYPE", "is_buy": false, "sz": 0.5, "limit_px": 21 } + +\`\`\`json +{ + "coin": "", + "is_buy": "", + "sz": "", + "limit_px": "" +} +\`\`\` + +Note: +- Just use the coin symbol (HYPE, ETH, etc.) +- sz is the size/quantity to trade (exactly as specified in the message) +- limit_px is optional: + - If specified (with "at X USDC"), order will be placed at that exact price + - If not specified, order will be placed at current market price +- Words like "market" or "limit" at the start are optional but help clarify intent + +Recent conversation: +{{recentMessages}}`; + +export const priceCheckTemplate = `Look at your LAST RESPONSE in the conversation where you confirmed which token price to check. +Based on ONLY that last message, extract the token symbol. + +For example: +- "I'll check PIP price for you" -> { "symbol": "PIP" } +- "Let me check the price of HYPE" -> { "symbol": "HYPE" } +- "I'll get the current ETH price" -> { "symbol": "ETH" } + +\`\`\`json +{ + "symbol": "" +} +\`\`\` + +Note: +- Just return the token symbol (PIP, HYPE, ETH, etc.) +- Remove any suffixes like "-SPOT" or "USDC" +- If multiple tokens are mentioned, use the last one + +Recent conversation: +{{recentMessages}}`; diff --git a/packages/plugin-hyperliquid/src/types.ts b/packages/plugin-hyperliquid/src/types.ts new file mode 100644 index 0000000000..d2cece49f3 --- /dev/null +++ b/packages/plugin-hyperliquid/src/types.ts @@ -0,0 +1,78 @@ +import { z } from "zod"; + +// Base configuration types +export interface HyperliquidConfig { + privateKey: string; + testnet?: boolean; + walletAddress?: string; +} + +// Enhanced schemas with better validation +export const SpotOrderSchema = z.object({ + coin: z.string().min(1), + is_buy: z.boolean(), + sz: z.number().positive(), + limit_px: z.number().positive().nullable(), + reduce_only: z.boolean().default(false), + order_type: z + .object({ + limit: z.object({ + tif: z.enum(["Ioc", "Gtc"]), + }), + }) + .default({ limit: { tif: "Gtc" } }), +}); + +// Inferred types from schemas +export type SpotOrder = z.infer; + +// Response types +export interface OrderResponse { + coin: string; + orderId: string; + status: "open" | "filled" | "cancelled" | "rejected"; + size: number; + price: number; + is_buy: boolean; +} + +// Error handling types +export class HyperliquidError extends Error { + constructor( + message: string, + public code?: number, + public details?: unknown + ) { + super(message); + this.name = "HyperliquidError"; + } +} + +// Constants +export const ORDER_STATUS = { + OPEN: "open", + FILLED: "filled", + CANCELLED: "cancelled", + REJECTED: "rejected", +} as const; + +export const PRICE_VALIDATION = { + MARKET_ORDER: { + MIN_RATIO: 0.5, // -50% from mid price + MAX_RATIO: 1.5, // +50% from mid price + }, + LIMIT_ORDER: { + WARNING_MIN_RATIO: 0.2, // -80% from mid price + WARNING_MAX_RATIO: 5, // +500% from mid price + }, + SLIPPAGE: 0.01, // 1% slippage for market orders +} as const; + +export type OrderStatus = keyof typeof ORDER_STATUS; + +// Balance types +export interface BalanceResponse { + coin: string; + free: number; + locked: number; +} diff --git a/packages/plugin-hyperliquid/tsconfig.json b/packages/plugin-hyperliquid/tsconfig.json new file mode 100644 index 0000000000..33e9858f48 --- /dev/null +++ b/packages/plugin-hyperliquid/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../core/tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src", + "declaration": true + }, + "include": [ + "src" + ] +} \ No newline at end of file diff --git a/packages/plugin-hyperliquid/tsup.config.ts b/packages/plugin-hyperliquid/tsup.config.ts new file mode 100644 index 0000000000..1a96f24afa --- /dev/null +++ b/packages/plugin-hyperliquid/tsup.config.ts @@ -0,0 +1,21 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + "safe-buffer", + // Add other modules you want to externalize + ], +}); diff --git a/packages/plugin-irys/src/services/irysService.ts b/packages/plugin-irys/src/services/irysService.ts index e97bae6ee8..24f4038e0a 100644 --- a/packages/plugin-irys/src/services/irysService.ts +++ b/packages/plugin-irys/src/services/irysService.ts @@ -116,9 +116,9 @@ export class IrysService extends Service implements IIrysService { } private async orchestrateRequest(requestMessage: string, tags: GraphQLTag[], timestamp: IrysTimestamp = null): Promise { - let serviceCategory = tags.find((tag) => tag.name == "Service-Category")?.values; - let protocol = tags.find((tag) => tag.name == "Protocol")?.values; - let minimumProviders = Number(tags.find((tag) => tag.name == "Minimum-Providers")?.values); + const serviceCategory = tags.find((tag) => tag.name == "Service-Category")?.values; + const protocol = tags.find((tag) => tag.name == "Protocol")?.values; + const minimumProviders = Number(tags.find((tag) => tag.name == "Minimum-Providers")?.values); /* Further implementation of the orchestrator { name: "Validation-Threshold", values: validationThreshold }, @@ -158,7 +158,7 @@ export class IrysService extends Service implements IIrysService { return { success: false, data: null, error: "Error in the orchestrator" }; } } - let responseTags: GraphQLTag[] = [ + const responseTags: GraphQLTag[] = [ { name: "Message-Type", values: [IrysMessageType.REQUEST_RESPONSE] }, { name: "Service-Category", values: [serviceCategory] }, { name: "Protocol", values: [protocol] }, @@ -319,7 +319,7 @@ export class IrysService extends Service implements IIrysService { const responseText = await fetchDataFromTransactionIdResponse.data.text(); try { data = JSON.parse(responseText); - } catch (error) { + } catch { data = responseText; } return { diff --git a/packages/plugin-lensNetwork/README.md b/packages/plugin-lensNetwork/README.md new file mode 100644 index 0000000000..3bf8e2e48e --- /dev/null +++ b/packages/plugin-lensNetwork/README.md @@ -0,0 +1,99 @@ +# @elizaos/plugin-abstract + +A plugin for interacting with the Abstract blockchain network within the ElizaOS ecosystem. + +## Description +The Abstract plugin enables seamless token transfers on the Abstract testnet. It provides functionality to transfer both native ETH and ERC20 tokens using secure wallet operations. + +## Installation + +```bash +pnpm install @elizaos/plugin-lensNetwork +``` + +## Configuration + +The plugin requires the following environment variables to be set: +```typescript +LENS_ADDRESS= +LENS_PRIVATE_KEY= +``` + +## Usage + +### Basic Integration + +```typescript +import { lensPlugin } from '@elizaos/plugin-lensNetwork'; +``` + +### Transfer Examples + +```typescript +// The plugin responds to natural language commands like: + +"Send 1 Grass to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62" + +``` + +## API Reference + +### Actions + +#### SEND_TOKEN + +Transfers tokens from the agent's wallet to another address. + +**Aliases:** +- TRANSFER_TOKEN_ON_LENS +- TRANSFER_TOKENS_ON_LENS +- SEND_TOKENS_ON_LENS +- SEND_ETH_ON_LENS +- PAY_ON_LENS +- MOVE_TOKENS_ON_LENS +- MOVE_ETH_ON_LENS + +## Common Issues & Troubleshooting + +1. **Transaction Failures** + - Verify wallet has sufficient balance + - Check recipient address format + - Ensure private key is correctly set + - Verify network connectivity + +2. **Configuration Issues** + - Verify all required environment variables are set + - Ensure private key format is correct + - Check wallet address format + +## Security Best Practices + +1. **Private Key Management** + - Store private key securely using environment variables + - Never commit private keys to version control + - Use separate wallets for development and production + - Monitor wallet activity regularly + +## Development Guide + +### Setting Up Development Environment + +1. Clone the repository +2. Install dependencies: + +```bash +pnpm install +``` + +3. Build the plugin: + +```bash +pnpm run build +``` + +4. Run the plugin: + +```bash +pnpm run dev +``` + diff --git a/packages/plugin-lensNetwork/package.json b/packages/plugin-lensNetwork/package.json new file mode 100644 index 0000000000..d3388c872e --- /dev/null +++ b/packages/plugin-lensNetwork/package.json @@ -0,0 +1,37 @@ +{ + "name": "@elizaos/plugin-lensNetwork", + "version": "0.1.7", + "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:*", + "tsup": "^8.3.5", + "web3": "^4.15.0", + "@lens-network/sdk": "^0.0.0-canary-20241203140504", + + "dotenv": "^16.0.3", + "ethers": "^6.0.0", + "zksync-ethers": "^6.0.0" + }, + "scripts": { + "build": "tsup --format esm --dts" + }, + "peerDependencies": { + "whatwg-url": "7.1.0" + } +} diff --git a/packages/plugin-lensNetwork/src/actions/transfer.ts b/packages/plugin-lensNetwork/src/actions/transfer.ts new file mode 100644 index 0000000000..84bb54309c --- /dev/null +++ b/packages/plugin-lensNetwork/src/actions/transfer.ts @@ -0,0 +1,292 @@ +import { + ActionExample, + Content, + HandlerCallback, + IAgentRuntime, + Memory, + ModelClass, + State, + type Action, + elizaLogger, + composeContext, + generateObject, +} from "@elizaos/core"; +import { validateLensConfig } from "../environment"; +import { getDefaultProvider, Network, Wallet } from "@lens-network/sdk/ethers"; +import { ethers, formatEther } from "ethers"; + +import { + Address, + createWalletClient, + erc20Abi, + http, + parseEther, + isAddress, +} from "viem"; + +import { z } from "zod"; + +const TransferSchema = z.object({ + tokenAddress: z.string(), + recipient: z.string(), + amount: z.string(), +}); + +export interface TransferContent extends Content { + tokenAddress: string; + recipient: string; + amount: string | number; +} + +export function isTransferContent( + content: TransferContent +): content is TransferContent { + // Validate types + const validTypes = + + typeof content.recipient === "string" && + (typeof content.amount === "string" || + typeof content.amount === "number"); + if (!validTypes) { + return false; + } + + // Validate addresses + const validAddresses = + + content.recipient.startsWith("0x") && + content.recipient.length === 42; + + return validAddresses; +} + +const transferTemplate = `Respond with a JSON markdown block containing only the extracted values. Use null for any values that cannot be determined. + +Here are several frequently used addresses. Use these for the corresponding tokens: +- ETH/eth: 0x000000000000000000000000000000000000800A + + +Example response: +\`\`\`json +{ + + "recipient": "0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62", + "amount": "1000" +} +\`\`\` + +{{recentMessages}} + +Given the recent messages, extract the following information about the requested token transfer: +- Token contract address +- Recipient wallet address +- Amount to transfer + +Respond with a JSON markdown block containing only the extracted values.`; + +const ETH_ADDRESS = "0x000000000000000000000000000000000000800A"; + +export async function setupProviders() { + // Initialize providers for both L2 (Lens) and L1 (Ethereum) + const lensProvider = getDefaultProvider(Network.Testnet); + const ethProvider = ethers.getDefaultProvider("sepolia"); + + return { lensProvider, ethProvider }; +} + +export async function setupWallet( + lensProvider: any, + ethProvider: any, + key: any +) { + // Create wallet instance with both L2 and L1 providers + const wallet = new Wallet(key, lensProvider, ethProvider); + + return wallet; +} + +export async function transferTokens( + wallet: any, + recipientAddress: string, + amount: string +) { + try { + // Validate recipient address + if (!isAddress(recipientAddress)) { + throw new Error("Invalid recipient address"); + } + + // Create transaction object + const tx = { + to: recipientAddress, + value: parseEther(amount), + }; + + // Send transaction + console.log( + `Initiating transfer of ${amount} tokens to ${recipientAddress}...` + ); + const transaction = await wallet.sendTransaction(tx); + + // Wait for transaction confirmation + console.log(`Transaction hash: ${transaction.hash}`); + const receipt = await transaction.wait(); + + console.log("Transfer completed successfully!"); + console.log("Transaction receipt:", receipt); + + return transaction.hash; + } catch (error) { + console.error("Error transferring tokens:", error); + throw error; + } +} + +export default { + name: "SEND_TOKEN", + similes: [ + "TRANSFER_TOKEN_ON_LENS", + "TRANSFER_TOKENS_ON_LENS", + "SEND_TOKENS_ON_LENS", + "SEND_GRASS_ON_LENS", + "PAY_ON_LENS", + "MOVE_TOKENS_ON_LENS", + "MOVE_GRASS_ON_LENS", + ], + validate: async (runtime: IAgentRuntime, message: Memory) => { + await validateLensConfig(runtime); + return true; + }, + description: "Transfer tokens from the agent's wallet to another address", + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + _options: { [key: string]: unknown }, + callback?: HandlerCallback + ): Promise => { + elizaLogger.log("Starting LENS SEND_TOKEN handler..."); + + // Initialize or update state + if (!state) { + state = (await runtime.composeState(message)) as State; + } else { + state = await runtime.updateRecentMessageState(state); + } + + // Compose transfer context + const transferContext = composeContext({ + state, + template: transferTemplate, + }); + + // Generate transfer content + const content = ( + await generateObject({ + runtime, + context: transferContext, + modelClass: ModelClass.SMALL, + schema: TransferSchema, + }) + ).object as unknown as TransferContent; + + // Validate transfer content + if (!isTransferContent(content)) { + console.error("Invalid content for TRANSFER_TOKEN action."); + if (callback) { + callback({ + text: "Unable to process transfer request. Invalid content provided.", + content: { error: "Invalid transfer content" }, + }); + } + return false; + } + + try { + const PRIVATE_KEY = runtime.getSetting("LENS_PRIVATE_KEY")!; + const { lensProvider, ethProvider } = await setupProviders(); + const wallet = await setupWallet( + lensProvider, + ethProvider, + PRIVATE_KEY + ); + const amount = content.amount.toString(); + + let hash; + + hash = await transferTokens( + wallet, + content.recipient as Address, + amount + ); + + elizaLogger.success( + "Transfer completed successfully! Transaction hash: " + hash + ); + if (callback) { + callback({ + text: + "Transfer completed successfully! Transaction hash: " + + hash, + content: {}, + }); + } + + return true; + } catch (error) { + elizaLogger.error("Error during token transfer:", error); + if (callback) { + callback({ + text: `Error transferring tokens: ${error.message}`, + content: { error: error.message }, + }); + } + return false; + } + }, + + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Send 1 Grass to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62", + }, + }, + { + user: "{{agent}}", + content: { + text: "Sure, I'll send 1 Grass to that address now.", + action: "SEND_TOKEN", + }, + }, + { + user: "{{agent}}", + content: { + text: "Successfully sent 1 Grass to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62\nTransaction: 0x4fed598033f0added272c3ddefd4d83a521634a738474400b27378db462a76ec", + }, + }, + ], + [ + { + user: "{{user1}}", + content: { + text: "Please send 0.1 GRASS to 0xbD8679cf79137042214fA4239b02F4022208EE82", + }, + }, + { + user: "{{agent}}", + content: { + text: "Of course. Sending 0.1 Grass to that address now.", + action: "SEND_TOKEN", + }, + }, + { + user: "{{agent}}", + content: { + text: "Successfully sent 0.1 Grass to 0xbD8679cf79137042214fA4239b02F4022208EE82\nTransaction: 0x0b9f23e69ea91ba98926744472717960cc7018d35bc3165bdba6ae41670da0f0", + }, + }, + ], + ] as ActionExample[][], +} as Action; diff --git a/packages/plugin-lensNetwork/src/environment.ts b/packages/plugin-lensNetwork/src/environment.ts new file mode 100644 index 0000000000..823fb3b892 --- /dev/null +++ b/packages/plugin-lensNetwork/src/environment.ts @@ -0,0 +1,32 @@ +import { IAgentRuntime } from "@elizaos/core"; +import { z } from "zod"; + +export const lensEnvSchema = z.object({ + LENS_ADDRESS: z.string().min(1, "LENS address is required"), + LENS_PRIVATE_KEY: z.string().min(1, "LENS private key is required"), +}); + +export type LensConfig = z.infer; + +export async function validateLensConfig( + runtime: IAgentRuntime +): Promise { + try { + const config = { + LENS_ADDRESS: runtime.getSetting("LENS_ADDRESS"), + LENS_PRIVATE_KEY: runtime.getSetting("LENS_PRIVATE_KEY"), + }; + + return lensEnvSchema.parse(config); + } catch (error) { + if (error instanceof z.ZodError) { + const errorMessages = error.errors + .map((err) => `${err.path.join(".")}: ${err.message}`) + .join("\n"); + throw new Error( + `Lens configuration validation failed:\n${errorMessages}` + ); + } + throw error; + } +} diff --git a/packages/plugin-lensNetwork/src/index.ts b/packages/plugin-lensNetwork/src/index.ts new file mode 100644 index 0000000000..953b1ddaf8 --- /dev/null +++ b/packages/plugin-lensNetwork/src/index.ts @@ -0,0 +1,13 @@ +import { Plugin } from "@elizaos/core"; + +import transfer from "./actions/transfer.ts"; + +export const lensPlugin: Plugin = { + name: "Lens", + description: "Lens Plugin for Eliza", + actions: [transfer], + evaluators: [], + providers: [], +}; + +export default lensPlugin; diff --git a/packages/plugin-lensNetwork/tsconfig.json b/packages/plugin-lensNetwork/tsconfig.json new file mode 100644 index 0000000000..73993deaaf --- /dev/null +++ b/packages/plugin-lensNetwork/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../core/tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": [ + "src/**/*.ts" + ] +} \ No newline at end of file diff --git a/packages/plugin-lensNetwork/tsup.config.ts b/packages/plugin-lensNetwork/tsup.config.ts new file mode 100644 index 0000000000..e42bf4efea --- /dev/null +++ b/packages/plugin-lensNetwork/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + // Add other modules you want to externalize + ], +}); diff --git a/packages/plugin-letzai/src/index.ts b/packages/plugin-letzai/src/index.ts index e240a32217..5bb4dd0db2 100644 --- a/packages/plugin-letzai/src/index.ts +++ b/packages/plugin-letzai/src/index.ts @@ -1,4 +1,4 @@ -import { elizaLogger, generateText, HandlerCallback, IAgentRuntime, ModelClass, Plugin, State } from "@elizaos/core"; +import { elizaLogger, HandlerCallback, IAgentRuntime, Plugin, State } from "@elizaos/core"; import { Memory } from "@elizaos/core"; diff --git a/packages/plugin-massa/.npmignore b/packages/plugin-massa/.npmignore new file mode 100644 index 0000000000..078562ecea --- /dev/null +++ b/packages/plugin-massa/.npmignore @@ -0,0 +1,6 @@ +* + +!dist/** +!package.json +!readme.md +!tsup.config.ts \ No newline at end of file diff --git a/packages/plugin-massa/eslint.config.mjs b/packages/plugin-massa/eslint.config.mjs new file mode 100644 index 0000000000..92fe5bbebe --- /dev/null +++ b/packages/plugin-massa/eslint.config.mjs @@ -0,0 +1,3 @@ +import eslintGlobalConfig from "../../eslint.config.mjs"; + +export default [...eslintGlobalConfig]; diff --git a/packages/plugin-massa/package.json b/packages/plugin-massa/package.json new file mode 100644 index 0000000000..456b935f5d --- /dev/null +++ b/packages/plugin-massa/package.json @@ -0,0 +1,19 @@ +{ + "name": "@elizaos/plugin-massa", + "version": "0.0.1-alpha.1", + "main": "dist/index.js", + "type": "module", + "types": "dist/index.d.ts", + "dependencies": { + "@elizaos/core": "workspace:*", + "@massalabs/massa-web3": "^5.0.1-dev", + "tsup": "8.3.5" + }, + "scripts": { + "build": "tsup --format esm --dts", + "lint": "eslint . --fix" + }, + "peerDependencies": { + "whatwg-url": "7.1.0" + } +} diff --git a/packages/plugin-massa/readme.md b/packages/plugin-massa/readme.md new file mode 100644 index 0000000000..05bb5d0f16 --- /dev/null +++ b/packages/plugin-massa/readme.md @@ -0,0 +1,16 @@ +# Massa Plugin + +## Overview + +This plugin aims to be the basis of all interactions with the Massa ecosystem. + +## Adding a new action + +Reuse providers and utilities from the existing actions where possible. Add more utilities if you think they will be useful for other actions. + +1. Add the action to the `actions` directory. Try to follow the naming convention of the other actions. +2. Export the action in the `index.ts` file. + + +## MASSA documentation +[https://docs.massa.net/](https://docs.massa.net/) \ No newline at end of file diff --git a/packages/plugin-massa/src/actions/transfer.ts b/packages/plugin-massa/src/actions/transfer.ts new file mode 100644 index 0000000000..7bcfaf26e7 --- /dev/null +++ b/packages/plugin-massa/src/actions/transfer.ts @@ -0,0 +1,285 @@ +// It should transfer tokens from the agent's wallet to the recipient. + +import { + type Action, + ActionExample, + composeContext, + Content, + elizaLogger, + generateObjectDeprecated, + HandlerCallback, + IAgentRuntime, + Memory, + ModelClass, + State, +} from "@elizaos/core"; +import { validateConfig } from "../enviroment"; +import { getMnsTarget } from "../utils/mns"; +import { + Web3Provider, + Account, + Address, + MRC20, + MAINNET_TOKENS, + parseUnits, + CHAIN_ID, + BUILDNET_TOKENS, +} from "@massalabs/massa-web3"; +import { validateAddress } from "../utils/address"; + +export interface TransferContent extends Content { + tokenAddress: string; + recipient: string; + amount: string; +} + +export function isTransferContent(content: any): content is TransferContent { + elizaLogger.log("Starting SEND_TOKEN content", content); + + // Validate types + const validTypes = + typeof content.tokenAddress === "string" && + typeof content.recipient === "string" && + (typeof content.amount === "string" || + typeof content.amount === "number"); + + if (!validTypes) { + return false; + } + + const tokenAddr = validateAddress(content.tokenAddress); + if (!tokenAddr || tokenAddr.isEOA) { + return false; + } + + const recipient: string = content.recipient; + // Additional checks based on whether recipient or mns is defined + if (recipient && !recipient.endsWith(".massa")) { + Address.fromString(content.recipient); + } + + return true; +} + +const transferTemplate = ( + tokens: Record +) => `Respond with a JSON markdown block containing only the extracted values. Use null for any values that cannot be determined. + +Smart contrat addresses are prefixed with "AS" and EOA addresses used for recipient are prefixed with "AU". + +These are known token addresses, if you get asked about them, use these: +${Object.entries(tokens) + .map(([name, address]) => `- ${name}: ${address}`) + .join("\n")} + +If a EOA recipient address is provided, use it as is. If a .massa name is provided, use it as recipient. + +Example response: +\`\`\`json +{ + "tokenAddress": "AS12LpYyAjYRJfYhyu7fkrS224gMdvFHVEeVWoeHZzMdhis7UZ3Eb", + "recipient": "mymassaname.massa", + "amount": "0.001" +} +\`\`\` + +{{recentMessages}} + +Given the recent messages, extract the following information about the requested token transfer: +- Amount in string format +- Token contract address +- Recipient wallet address or .massa name + +If one of the values cannot be determined, ask user for missing information. + + +Respond with a JSON markdown block containing only the extracted values.`; + +export default { + name: "SEND_TOKEN", + similes: [ + "TRANSFER_TOKEN_ON_MASSA", + "TRANSFER_TOKENS_ON_MASSA", + "SEND_TOKENS_ON_MASSA", + "SEND_ETH_ON_MASSA", + "PAY_ON_MASSA", + ], + validate: async (runtime: IAgentRuntime, _message: Memory) => { + await validateConfig(runtime); + return true; + }, + description: + "MUST use this action if the user requests send a token or transfer a token, the request might be varied, but it will always be a token transfer.", + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + _options: { [key: string]: unknown }, + callback?: HandlerCallback + ): Promise => { + elizaLogger.log("Starting SEND_TOKEN handler..."); + + // Initialize or update state + if (!state) { + state = (await runtime.composeState(message)) as State; + } else { + state = await runtime.updateRecentMessageState(state); + } + + const secretKey = runtime.getSetting("MASSA_PRIVATE_KEY"); + if (!secretKey) { + throw new Error("MASSA wallet credentials not configured"); + } + const account = await Account.fromPrivateKey(secretKey); + + const rpc = runtime.getSetting("MASSA_RPC_URL"); + if (!rpc) { + throw new Error("MASSA_RPC_URL not configured"); + } + const provider = Web3Provider.fromRPCUrl(rpc, account); + + const { chainId } = await provider.networkInfos(); + // Compose transfer context + const transferContext = composeContext({ + state, + template: transferTemplate( + chainId === CHAIN_ID.Mainnet ? MAINNET_TOKENS : BUILDNET_TOKENS + ), + }); + + // Generate transfer content + const content = await generateObjectDeprecated({ + runtime, + context: transferContext, + modelClass: ModelClass.MEDIUM, + }); + + elizaLogger.debug("Transfer content:", content); + + // Validate transfer content + const isValid = isTransferContent(content); + + if (!isValid) { + elizaLogger.error("Invalid content for TRANSFER_TOKEN action."); + if (callback) { + callback({ + text: "Not enough information to transfer tokens. Please respond with token address, recipient address or massa name, and amount.", + content: { error: "Invalid transfer content" }, + }); + } + return false; + } + + let recipientAddress = content.recipient; + // Validate recipient address + if (content.recipient.endsWith(".massa")) { + try { + recipientAddress = await getMnsTarget(provider, content.recipient.substring(0, content.recipient.length - ".massa".length)); + Address.fromString(recipientAddress); + } catch (error: any) { + elizaLogger.error( + "Error resolving MNS target:", + error?.message + ); + if (callback) { + callback({ + text: `Error resolving MNS target: ${error?.message}`, + content: { error: error }, + }); + } + return false; + } + } + + try { + const mrc20Token = new MRC20(provider, content.tokenAddress); + const decimals = await mrc20Token.decimals(); + const amount = parseUnits(content.amount, decimals); + const operation = await mrc20Token.transfer( + recipientAddress, + amount + ); + + elizaLogger.success( + "Transferring", + amount, + "of", + content.tokenAddress, + "to", + recipientAddress + ); + + await operation.waitSpeculativeExecution(); + + elizaLogger.success( + "Transfer completed successfully! Operation id: " + operation.id + ); + if (callback) { + callback({ + text: `Successfully transferred ${content.amount} tokens to ${content.recipient}\n OperationId: ${operation.id}`, + content: { + success: true, + operationId: operation.id, + amount: content.amount, + token: content.tokenAddress, + recipient: content.recipient, + }, + }); + } + + return true; + } catch (error: any) { + elizaLogger.error("Error during token transfer:", error?.message); + if (callback) { + callback({ + text: `Error transferring tokens: ${error?.message}`, + content: { error: error }, + }); + } + return false; + } + }, + + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Send 10 WMAS to AU1bfnCAQAhPT2gAcJkL31fCWJixFFtH7RjRHZsvaThVoeNUckep", + }, + }, + { + user: "{{agent}}", + content: { + text: "I'll transfer 10 WMAS to that address right away. Let me process that for you.", + }, + }, + { + user: "{{agent}}", + content: { + text: "Successfully sent 10 WMAS tokens to AU1bfnCAQAhPT2gAcJkL31fCWJixFFtH7RjRHZsvaThVoeNUckep\n Operation id: O12fZa1oNL18s3ZV2PCXVYUmQz2cQrNqKfFaRsyJNFsAcGYxEAKD", + }, + }, + ], + [ + { + user: "{{user1}}", + content: { + text: "Send 10 DAI to domain.massa", + }, + }, + { + user: "{{agent}}", + content: { + text: "I'll transfer 10 DAI to domain.massa right away. Let me process that for you.", + }, + }, + { + user: "{{agent}}", + content: { + text: "Successfully sent 10 DAI tokens to AU1bfnCAQAhPT2gAcJkL31fCWJixFFtH7RjRHZsvaThVoeNUckep\n Operation id: O12fZa1oNL18s3ZV2PCXVYUmQz2cQrNqKfFaRsyJNFsAcGYxEAKD", + }, + }, + ], + ] as ActionExample[][], +} as Action; diff --git a/packages/plugin-massa/src/enviroment.ts b/packages/plugin-massa/src/enviroment.ts new file mode 100644 index 0000000000..0947d55f29 --- /dev/null +++ b/packages/plugin-massa/src/enviroment.ts @@ -0,0 +1,38 @@ +import type { IAgentRuntime } from "@elizaos/core"; +import { PublicApiUrl } from "@massalabs/massa-web3"; +import { z } from "zod"; + +export const massaEnvSchema = z.object({ + MASSA_PRIVATE_KEY: z.string().min(1, "Massa private key is required"), + MASSA_RPC_URL: z.string().min(1, "Massa RPC URL is required"), +}); + +export type MassaConfig = z.infer; + +export async function validateConfig( + runtime: IAgentRuntime +): Promise { + try { + const config = { + MASSA_PRIVATE_KEY: + runtime.getSetting("MASSA_PRIVATE_KEY") || + process.env.MASSA_PRIVATE_KEY, + MASSA_RPC_URL: + runtime.getSetting("MASSA_RPC_URL") || + process.env.MASSA_RPC_URL || + PublicApiUrl.Mainnet, + }; + + return massaEnvSchema.parse(config); + } catch (error) { + if (error instanceof z.ZodError) { + const errorMessages = error.errors + .map((err) => `${err.path.join(".")}: ${err.message}`) + .join("\n"); + throw new Error( + `Massa configuration validation failed:\n${errorMessages}` + ); + } + throw error; + } +} diff --git a/packages/plugin-massa/src/index.ts b/packages/plugin-massa/src/index.ts new file mode 100644 index 0000000000..a8dbf11372 --- /dev/null +++ b/packages/plugin-massa/src/index.ts @@ -0,0 +1,12 @@ +import type { Plugin } from "@elizaos/core"; +import transfer from "./actions/transfer"; + +export const massaPlugin: Plugin = { + name: "massa", + description: "Massa Plugin for Eliza", + actions: [transfer], + evaluators: [], + providers: [], +}; + +export default massaPlugin; diff --git a/packages/plugin-massa/src/utils/address.ts b/packages/plugin-massa/src/utils/address.ts new file mode 100644 index 0000000000..20001a3052 --- /dev/null +++ b/packages/plugin-massa/src/utils/address.ts @@ -0,0 +1,9 @@ +import { Address } from "@massalabs/massa-web3"; + +export const validateAddress = (address: string): Address | undefined => { + try { + return Address.fromString(address); + } catch (_e) { + return undefined; + } +}; diff --git a/packages/plugin-massa/src/utils/index.ts b/packages/plugin-massa/src/utils/index.ts new file mode 100644 index 0000000000..981a5fcba8 --- /dev/null +++ b/packages/plugin-massa/src/utils/index.ts @@ -0,0 +1 @@ +export * from "./mns"; diff --git a/packages/plugin-massa/src/utils/mns.ts b/packages/plugin-massa/src/utils/mns.ts new file mode 100644 index 0000000000..bfabe015bf --- /dev/null +++ b/packages/plugin-massa/src/utils/mns.ts @@ -0,0 +1,15 @@ +import { CHAIN_ID, MNS, MNS_CONTRACTS, Provider } from "@massalabs/massa-web3"; + +export const getMnsTarget = async ( + provider: Provider, + name: string +): Promise => { + const { chainId } = await provider.networkInfos(); + const mnsContract = new MNS( + provider, + chainId === CHAIN_ID.Mainnet + ? MNS_CONTRACTS.mainnet + : MNS_CONTRACTS.buildnet + ); + return mnsContract.resolve(name); +}; diff --git a/packages/plugin-massa/tsconfig.json b/packages/plugin-massa/tsconfig.json new file mode 100644 index 0000000000..47216b2148 --- /dev/null +++ b/packages/plugin-massa/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "node", + "outDir": "dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "typeRoots": ["./node_modules/@types", "./src/types"], + "declaration": true + }, + "include": ["src"] +} diff --git a/packages/plugin-massa/tsup.config.ts b/packages/plugin-massa/tsup.config.ts new file mode 100644 index 0000000000..56cb67c2b8 --- /dev/null +++ b/packages/plugin-massa/tsup.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["esm", "cjs"], + dts: true, + splitting: false, + sourcemap: true, + clean: true, + shims: true, + treeshake: true, +}); diff --git a/packages/plugin-movement/src/tests/transfer.test.ts b/packages/plugin-movement/src/tests/transfer.test.ts index e98689a002..0704d231c4 100644 --- a/packages/plugin-movement/src/tests/transfer.test.ts +++ b/packages/plugin-movement/src/tests/transfer.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach, vi } from "vitest"; +import { describe, it, expect } from "vitest"; import transferAction from "../actions/transfer"; describe("Movement Transfer Action", () => { diff --git a/packages/plugin-nft-generation/src/utils/deployEVMContract.ts b/packages/plugin-nft-generation/src/utils/deployEVMContract.ts index 9413d8663d..99f2d61873 100644 --- a/packages/plugin-nft-generation/src/utils/deployEVMContract.ts +++ b/packages/plugin-nft-generation/src/utils/deployEVMContract.ts @@ -1,8 +1,5 @@ import { encodeAbiParameters } from "viem"; -import { fileURLToPath } from "url"; import { compileWithImports } from "./generateERC721ContractCode.ts"; -import path from "path"; -import fs from "fs"; import CustomERC721 from "../contract/CustomERC721.sol" // 动态生成 ERC-721 合约代码 diff --git a/packages/plugin-primus/.npmignore b/packages/plugin-primus/.npmignore new file mode 100644 index 0000000000..0468b4b364 --- /dev/null +++ b/packages/plugin-primus/.npmignore @@ -0,0 +1,6 @@ +* + +!dist/** +!package.json +!readme.md +!tsup.config.ts diff --git a/packages/plugin-primus/README.md b/packages/plugin-primus/README.md new file mode 100644 index 0000000000..fa570a11ee --- /dev/null +++ b/packages/plugin-primus/README.md @@ -0,0 +1,208 @@ +# @elizaos/plugin-primus + +A plugin to fully verify agent activities, including LLM access, actions, and interactions with external providers, +powered by Primus' zkTLS protocol. + +## Overview + +In the Eliza framework, an agent consists of three key components: a brain (accessing an LLM), actions (the tasks the +agent performs), and perception (gathering external information from providers). To fully verify agent activities, it's +essential to ensure that the agent's thoughts, actions, and external information requests are all verifiable. This +plugin enables full verification of these activities. + +The current plugin includes: + +- Verification of inference from OpenAI's LLM. +- An example for verifying actions, such as posting a tweet (this can be extended to any other actions). +- An example to verify that the Bitcoin price is accurately fetched from Binance (this can be extended to any other data + providers). + +## Usage +### LLM inference verification (PrimusAdapter) +`PrimusAdapter` implements `IVerifiableInferenceAdapter` and can be used as follows. +```typescript +import {PrimusAdapter} from "@elizaos/plugin-primus"; +import {VerifiableInferenceOptions} from '@elizaos/core'; + +// Initialize primus adapter +const primusAdatper = new PrimusAdapter({ + appId: process.env.PRIMUS_APP_ID, + appSecret: process.env.PRIMUS_APP_SECRET, + // Choose MPC-TLS or Proxy-TLS + attMode: "proxytls", + modelProvider: character.modelProvider, + token, +}); + +interface PrimusOptions { + appId: string; + appSecret: string; + attMode: string; + modelProvider?: ModelProviderName; + token?: string; +} + +// The options for generating an attestation +const options: VerifiableInferenceOptions = { + // Optional: Override the default endpoint + endpoint: "https://api.openapi.com/chat/completions", + // Optional: Add custom headers + headers: { + "Content-Type": "application/json", + "Authorization": "bearer Token", + }, + // Optional: Provider-specific options + providerOptions: { + temperature: 0.7, + }, +}; + +// Generate an attestation for a network request. +const result = await primusAdapter.generateText(context, "gpt-4o", options); +// Verify the validity of the attestation. +const isValid = await primusAdapter.verifyProof(result.proof); +``` + +The core functions in `PrimusAdatper` are the following, which are also used in Actions and Providers. +```typescript +// Generate a zkTLS proof. +generateProof = async ( + // The target endpoint of the network request. + endpoint: string, + // The HTTP method of the request, such as 'GET', 'POST', etc. + method: string, + // A record containing the headers of the request. + headers: Record, + // The body of the request. It should be a string. + body: string, + //A [JSONPath](https://datatracker.ietf.org/doc/rfc9535/) expression to locate the specific field in the response you want to attest. + responseParsePath: string +): Promise + +// Verify the proof. +verifyProof = async (attestation: any): Promise + +``` + +### Verify the interaction with Providers + +Here’s an example showcasing how to verify the validity of the BTC price retrieved from Binance. Developers can easily customize this process for other providers. + +```typescript +const tokenPriceProvider: Provider = { + get: async (runtime: IAgentRuntime, message: Memory, _state?: State) => { + // Set the URL + const url = "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT"; + const method = 'GET'; + const headers = { + 'Accept ': '*/*', + }; + // Generate the proof + const attestation = await generateProof(url, method, headers, "", "$.price"); + // Verify the proof. + const valid = await verifyProof(attestation); + if (!valid) { + throw new Error("Invalid price attestation"); + } + ...... + }, +}; +``` + +### Verify the Actions +Below is an example showcasing how to post price information from the [tokenPriceProvider](./src/providers/tokenPriceProvider.ts) to Twitter. Developers can easily adapt this process for other providers. + +Note that you need to configure the `.env` file correctly to post tweets. +```typescript +export const postTweetAction: Action = { + description: "Post a tweet on Twitter and be verified by Primus", + examples: [], + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State + ): Promise => { + const contentYouWantToPost = await tokenPriceProvider.get(runtime, message, state); + const endpoint = 'https://twitter.com/i/api/graphql/a1p9RWpkYKBjWv_I3WzS-A/CreateTweet'; + const method = 'POST'; + const attestation = await generateProof(endpoint,method,headers,bodyStr,"$.data.create_tweet.tweet_results.result.rest_id"); + elizaLogger.info( + "Tweet posting proof generated successfully:", + attestation + ); + const verifyResult = verifyProof(attestation); + if (!verifyResult) { + throw new Error( + "Attestation verify failed, data from source is illegality" + ); + } + + }, + name: "POST_TWEET", + similes: [], + validate: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State + ) => { + const hasCredentials = + !!process.env.TWITTER_USERNAME && !!process.env.TWITTER_PASSWORD; + elizaLogger.log(`Has credentials: ${hasCredentials}`); + + return hasCredentials; + }, +}; +``` + +## Installation + +```bash +pnpm add @elizaos/plugin-primus +``` + +## Configuration + +Add the following environment variables to your .env file: + +``` +PRIMUS_APP_ID=your_app_id +PRIMUS_APP_SECRET=your_app_secret +VERIFIABLE_INFERENCE_ENABLED=true +VERIFIABLE_INFERENCE_PROVIDER=primus +``` + +***How to get PRIMUS_APP_ID and PRIMUS_APP_SECRET*** + +1. Visit the [Primus Developer Hub](https://dev.primuslabs.xyz/). +2. Create a new project +3. Save your 'Application ID(PRIMUS_APP_ID)' and 'Secret Key(PRIMUS_APP_SECRET)' + +To use the plugin, add `@elizaos/plugin-primus` to the plugins field in your character file. Here's an example of how your character file might look after the update: + +```json +{ + "name": "trump", + "modelProvider": "openai", + // just support openai now + "plugins": [ + "@elizaos/plugin-primus" + ], + // other fields + ..... +} +``` + +## Run + +```bash +# Start the server +pnpm start --characters="characters/xxx.character.json" +``` + +```bash +# Start the client +pnpm start:client +``` + +You can ask the agent: "Get the BTC price and tweet." + diff --git a/packages/plugin-primus/package.json b/packages/plugin-primus/package.json new file mode 100644 index 0000000000..edc570c11e --- /dev/null +++ b/packages/plugin-primus/package.json @@ -0,0 +1,32 @@ +{ + "name": "@elizaos/plugin-primus", + "version": "0.1.7", + "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:*", + "agent-twitter-client": "0.0.18", + "@primuslabs/zktls-core-sdk": "^0.1.0", + "tsup": "8.3.5" + }, + "scripts": { + "build": "tsup --format esm --dts", + "dev": "tsup --format esm --dts --watch", + "test": "vitest run" + } +} diff --git a/packages/plugin-primus/src/actions/postTweetAction.ts b/packages/plugin-primus/src/actions/postTweetAction.ts new file mode 100644 index 0000000000..a186eda4c6 --- /dev/null +++ b/packages/plugin-primus/src/actions/postTweetAction.ts @@ -0,0 +1,127 @@ +import { + Action, + elizaLogger, + IAgentRuntime, + Memory, + State, +} from "@elizaos/core"; +import { TwitterScraper } from "../util/twitterScraper.ts"; +import {tokenPriceProvider} from "../providers/tokenPriceProvider.ts"; + +export const postTweetAction: Action = { + description: "Post a tweet on Twitter and be verified by Primus", + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Get the latest BTC price and post it on my twitter.", + }, + }, + { + user: "{{agentName}}", + content: { + text: "The latest tweet has posted.", + action: "POST_TWEET", + }, + }, + ], + [ + { + user: "{{user1}}", + content: { + text: "Help post a tweet which content is BTC price.", + }, + }, + { + user: "{{agentName}}", + content: { + text: "Completed!", + action: "POST_TWEET", + }, + }, + ], + [ + { + user: "{{user1}}", + content: { + text: "Post a tweet on twitter for me.", + }, + }, + { + user: "{{agentName}}", + content: { + text: "I'll post the latest tweet to your Twitter account now!", + action: "POST_TWEET", + }, + }, + ], + ], + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State + ): Promise => { + const contentYouWantToPost = await tokenPriceProvider.get(runtime, message, state); + //check VERIFIABLE_INFERENCE_ENABLED + if ( + !( + process.env.VERIFIABLE_INFERENCE_ENABLED === "true" && + process.env.PRIMUS_APP_ID && + process.env.PRIMUS_APP_SECRET + ) + ) { + elizaLogger.error( + `Parameter 'VERIFIABLE_INFERENCE_ENABLED' not set, Eliza will run this action!` + ); + return false; + } + + try { + if ( + process.env.TWITTER_DRY_RUN && + process.env.TWITTER_DRY_RUN.toLowerCase() === "true" + ) { + elizaLogger.info( + `Dry run: would have posted tweet: ${contentYouWantToPost}` + ); + return true; + } + + const scraperWithPrimus = new TwitterScraper(); + await scraperWithPrimus.login(); + if (!(await scraperWithPrimus.getScraper().isLoggedIn())) { + elizaLogger.error("Failed to login to Twitter"); + return false; + } + // post the tweet + elizaLogger.log("Attempting to send tweet:", contentYouWantToPost); + const result = await scraperWithPrimus.sendTweet(contentYouWantToPost); + + elizaLogger.log("Tweet response:", result); + + // Check for Twitter API errors + if (!result) { + elizaLogger.error(`Twitter API error ${result}`); + return false; + } + return true; + } catch (error) { + elizaLogger.error("Error in post action:", error); + return false; + } + }, + name: "POST_TWEET", + similes: ["TWEET", "POST", "SEND_TWEET"], + validate: async ( + runtime: IAgentRuntime, + message: Memory, + state?: State + ) => { + const hasCredentials = + !!process.env.TWITTER_USERNAME && !!process.env.TWITTER_PASSWORD; + elizaLogger.log(`Has credentials: ${hasCredentials}`); + + return hasCredentials; + }, +}; diff --git a/packages/plugin-primus/src/adapter/primusAdapter.ts b/packages/plugin-primus/src/adapter/primusAdapter.ts new file mode 100644 index 0000000000..6c54ffbc2d --- /dev/null +++ b/packages/plugin-primus/src/adapter/primusAdapter.ts @@ -0,0 +1,97 @@ +import { PrimusCoreTLS } from "@primuslabs/zktls-core-sdk"; +import { + IVerifiableInferenceAdapter, + VerifiableInferenceOptions, + VerifiableInferenceResult, + VerifiableInferenceProvider, + ModelProviderName, + models, + elizaLogger, +} from "@elizaos/core"; +import {generateProof, verifyProof} from "../util/primusUtil.ts"; + +interface PrimusOptions { + appId: string; + appSecret: string; + attMode: string; + modelProvider?: ModelProviderName; + token?: string; +} + +export class PrimusAdapter implements IVerifiableInferenceAdapter { + public options: PrimusOptions; + + constructor(options: PrimusOptions) { + this.options = options; + } + + async generateText( + context: string, + modelClass: string, + options?: VerifiableInferenceOptions + ): Promise { + const provider = this.options.modelProvider || ModelProviderName.OPENAI; + const baseEndpoint = options?.endpoint || models[provider].endpoint; + const model = models[provider].model[modelClass]; + const apiKey = this.options.token; + + if (!apiKey) { + throw new Error( + `API key (token) is required for provider: ${provider}` + ); + } + + // Get provider-specific endpoint, auth header and response json path + let endpoint; + let authHeader; + let responseParsePath; + + switch (provider) { + case ModelProviderName.OPENAI: + endpoint = `${baseEndpoint}/chat/completions`; + authHeader = `Bearer ${apiKey}`; + responseParsePath = "$.choices[0].message.content"; + break; + default: + throw new Error(`Unsupported model provider: ${provider}`); + } + + + const headers = { + "Content-Type": "application/json", + "Authorization": authHeader, + }; + + try { + let body = { + model: model.name, + messages: [{ role: "user", content: context }], + temperature: + options?.providerOptions?.temperature || + models[provider].model[modelClass].temperature, + }; + const attestation = await generateProof(endpoint,"POST",headers,JSON.stringify(body),responseParsePath); + elizaLogger.log(`model attestation:`, attestation); + + const responseData = JSON.parse(attestation.data); + let text = JSON.parse(responseData.content); + return { + text, + proof: attestation, + provider: VerifiableInferenceProvider.PRIMUS, + timestamp: Date.now(), + }; + } catch (error) { + console.error("Error in Primus generateText:", error); + throw error; + } + } + + async verifyProof(result: VerifiableInferenceResult): Promise { + const isValid = verifyProof(result.proof) + elizaLogger.log("Proof is valid:", isValid); + return isValid; + } +} + +export default PrimusAdapter; diff --git a/packages/plugin-primus/src/index.ts b/packages/plugin-primus/src/index.ts new file mode 100644 index 0000000000..8b9d13b1c0 --- /dev/null +++ b/packages/plugin-primus/src/index.ts @@ -0,0 +1,14 @@ +import { Plugin } from "@elizaos/core"; +import { postTweetAction } from "./actions/postTweetAction.ts"; +import {PrimusAdapter} from "./adapter/primusAdapter.ts"; + +export const twitterPlugin: Plugin = { + name: "twitter", + description: "Twitter integration plugin for posting tweets with proof generated by primus", + actions: [postTweetAction], + evaluators: [], + providers: [], +}; + +export default twitterPlugin; +export {PrimusAdapter}; diff --git a/packages/plugin-primus/src/providers/tokenPriceProvider.ts b/packages/plugin-primus/src/providers/tokenPriceProvider.ts new file mode 100644 index 0000000000..0dedddbc47 --- /dev/null +++ b/packages/plugin-primus/src/providers/tokenPriceProvider.ts @@ -0,0 +1,35 @@ +import {elizaLogger, IAgentRuntime, Memory, Provider, State} from "@elizaos/core"; +import {generateProof, verifyProof} from "../util/primusUtil.ts"; + +const tokenPriceProvider: Provider = { + get: async (runtime: IAgentRuntime, message: Memory, _state?: State) => { + //get btc price + const url = `${process.env.BINANCE_API_URL||'https://api.binance.com'}/api/v3/ticker/price?symbol=${process.env.BINANCE_SYMBOL || 'BTCUSDT'}`; + const method = 'GET'; + const headers = { + 'Accept ': '*/*', + }; + const attestation = await generateProof(url, method, headers, "", "$.price"); + const valid = await verifyProof(attestation); + if(!valid){ + throw new Error("Invalid price attestation"); + } + elizaLogger.info('price attestation:',attestation); + try{ + const responseData = JSON.parse((attestation as any).data); + const price = responseData.content; + return ` + Get BTC price from Binance: + BTC: ${price} USDT + Time: ${new Date().toUTCString()} + POST by eliza #eliza + Attested by Primus #primus #zktls + ` + }catch (error){ + elizaLogger.error('Failed to parse price data:', error); + throw new Error('Failed to parse price data'); + } + }, +}; + +export { tokenPriceProvider }; diff --git a/packages/plugin-primus/src/providers/tweetProvider.ts b/packages/plugin-primus/src/providers/tweetProvider.ts new file mode 100644 index 0000000000..299ac89be5 --- /dev/null +++ b/packages/plugin-primus/src/providers/tweetProvider.ts @@ -0,0 +1,39 @@ +import {elizaLogger, IAgentRuntime, Memory, Provider, State} from "@elizaos/core"; +import {TwitterScraper} from "../util/twitterScraper.ts"; + +const tweetProvider: Provider = { + get: async (runtime: IAgentRuntime, message: Memory, _state?: State) => { + const scraperWithPrimus = new TwitterScraper(); + try { + elizaLogger.info("Attempting Twitter login"); + await scraperWithPrimus.login(); + elizaLogger.info("Twitter login successful"); + }catch (error){ + elizaLogger.error("Twitter login failed:", error); + return false; + } + + if (!(await scraperWithPrimus.getScraper().isLoggedIn())) { + elizaLogger.error("Failed to login to Twitter"); + return false; + } + const userName = process.env.TWITTER_USERNAME_WANT_TO_GET_TWEET; + if(!userName){ + elizaLogger.error("TWITTER_USERNAME_WANT_TO_GET_TWEET is not set"); + return false; + } + elizaLogger.debug(`Fetching tweets for user: ${userName}`); + const userId = await scraperWithPrimus.getUserIdByScreenName(userName); + elizaLogger.debug(`Fetching tweets for user: ${userName}`); + try { + const result = await scraperWithPrimus.getUserLatestTweet(userId); + elizaLogger.debug("Tweet retrieved successfully"); + return result; + } catch (error) { + elizaLogger.error("Failed to fetch tweet:", error); + return false; + } + }, +}; + +export { tweetProvider }; diff --git a/packages/plugin-primus/src/templates.ts b/packages/plugin-primus/src/templates.ts new file mode 100644 index 0000000000..5746acaeb2 --- /dev/null +++ b/packages/plugin-primus/src/templates.ts @@ -0,0 +1,21 @@ +export const summarizeTweetTemplate = (twitterContent:string) => { + if (!twitterContent?.trim()) { + throw new Error('Twitter content cannot be empty'); + } + return ` + # Context + ${twitterContent} + + # Task + Generate a tweet that: + 1. Summarize the input + 2. The content does not contain emoji + 3. Must be less than 280 characters (Twitter's limit) + 4. The key information should be retained + 5. Is concise and engaging + + Generate only the tweet text, no other commentary. + Response format should be formatted in a JSON block like this: + {"text": "string", "characterCount": number} + `; +}; diff --git a/packages/plugin-primus/src/util/primusUtil.ts b/packages/plugin-primus/src/util/primusUtil.ts new file mode 100644 index 0000000000..30ccfce7a2 --- /dev/null +++ b/packages/plugin-primus/src/util/primusUtil.ts @@ -0,0 +1,42 @@ +import { PrimusCoreTLS,Attestation } from "@primuslabs/zktls-core-sdk"; + +export const generateProof = async ( + endpoint: string, + method: string, + headers: Record, + body: string, + responseParsePath: string +): Promise => { + const zkTLS = new PrimusCoreTLS(); + await zkTLS.init(process.env.PRIMUS_APP_ID, process.env.PRIMUS_APP_SECRET); + const requestParam = body + ? { + url: endpoint, + method: method, + header: headers, + body: body, + } + : { + url: endpoint, + method: method, + header: headers, + }; + // console.log('requestParam:',requestParam) + const attestationParams = zkTLS.generateRequestParams(requestParam, [ + { + keyName: "content", + parsePath: responseParsePath, + parseType: "string", + }, + ]); + attestationParams.setAttMode({ + algorithmType: "proxytls", + }); + return await zkTLS.startAttestation(attestationParams); +}; + +export const verifyProof = async (attestation: Attestation): Promise => { + const zkTLS = new PrimusCoreTLS(); + await zkTLS.init(process.env.PRIMUS_APP_ID, process.env.PRIMUS_APP_SECRET); + return zkTLS.verifyAttestation(attestation); +}; diff --git a/packages/plugin-primus/src/util/twitterScraper.ts b/packages/plugin-primus/src/util/twitterScraper.ts new file mode 100644 index 0000000000..81b488d2c1 --- /dev/null +++ b/packages/plugin-primus/src/util/twitterScraper.ts @@ -0,0 +1,260 @@ +import { Scraper } from "agent-twitter-client"; +import { elizaLogger } from "@elizaos/core"; +import { verifyProof, generateProof } from "./primusUtil.ts"; + +export class TwitterScraper { + private scraper: Scraper; + + constructor() {} + + public getScraper(): Scraper { + return this.scraper; + } + + public async getUserIdByScreenName(screenName: string) { + return await this.scraper.getUserIdByScreenName(screenName); + } + + public async login() { + this.scraper = new Scraper(); + const username = process.env.TWITTER_USERNAME; + const password = process.env.TWITTER_PASSWORD; + const email = process.env.TWITTER_EMAIL; + const twitter2faSecret = process.env.TWITTER_2FA_SECRET; + if (!username || !password) { + elizaLogger.error( + "Twitter credentials not configured in environment" + ); + return; + } + + // Login with credentials + await this.scraper.login(username, password, email, twitter2faSecret); + if (!(await this.scraper.isLoggedIn())) { + elizaLogger.error("Failed to login to Twitter"); + return false; + } + } + + public async getUserLatestTweet(userId: string) { + const onboardingTaskUrl = + "https://api.twitter.com/1.1/onboarding/task.json"; + const cookies = await (this.scraper as any).auth + .cookieJar() + .getCookies(onboardingTaskUrl); + const xCsrfToken = cookies.find((cookie) => cookie.key === "ct0"); + + //@ ts-expect-error - This is a private API. + const headers = { + authorization: `Bearer ${(this.scraper as any).auth.bearerToken}`, + cookie: await (this.scraper as any).auth + .cookieJar() + .getCookieString(onboardingTaskUrl), + "content-type": "application/json", + "User-Agent": + "Mozilla/5.0 (Linux; Android 11; Nokia G20) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.88 Mobile Safari/537.36", + "x-guest-token": (this.scraper as any).guestToken, + "x-twitter-auth-type": "OAuth2Client", + "x-twitter-active-user": "yes", + "x-twitter-client-language": "en", + "x-csrf-token": xCsrfToken?.value, + }; + + const variables = { + userId: userId, + count: 1, + includePromotedContent: true, + withQuickPromoteEligibilityTweetFields: true, + withVoice: true, + withV2Timeline: true, + }; + const features = { + profile_label_improvements_pcf_label_in_post_enabled: false, + rweb_tipjar_consumption_enabled: true, + tweetypie_unmention_optimization_enabled: false, + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: + false, + premium_content_api_read_enabled: false, + communities_web_enable_tweet_community_results_fetch: true, + c9s_tweet_anatomy_moderator_badge_enabled: true, + responsive_web_grok_analyze_button_fetch_trends_enabled: false, + responsive_web_grok_analyze_post_followups_enabled: true, + responsive_web_grok_share_attachment_enabled: true, + articles_preview_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + responsive_web_twitter_article_tweet_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + creator_subscriptions_quote_tweet_preview_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: + true, + rweb_video_timestamps_enabled: true, + longform_notetweets_rich_text_read_enabled: true, + longform_notetweets_inline_media_enabled: true, + responsive_web_enhance_cards_enabled: false, + }; + const fieldToggles = { + withArticlePlainText: false, + }; + const variablesUrlEncoded = encodeURIComponent( + JSON.stringify(variables) + ); + const featureUrlEncoded = encodeURIComponent(JSON.stringify(features)); + const fieldTogglesUrlEncoded = encodeURIComponent( + JSON.stringify(fieldToggles) + ); + const endpoint = `https://twitter.com/i/api/graphql/V7H0Ap3_Hh2FyS75OCDO3Q/UserTweets?variables=${variablesUrlEncoded}&features=${featureUrlEncoded}&fieldToggles=${fieldTogglesUrlEncoded}`; + const responseParsePath = + "$.data.user.result.timeline_v2.timeline.instructions[1].entry.content.itemContent.tweet_results.result.legacy.full_text"; + const attestation = await generateProof( + endpoint, + "GET", + headers, + undefined, + responseParsePath + ); + //log attestation + elizaLogger.info( + "Tweet getting proof generated successfully:", + attestation + ); + const verifyResult = verifyProof(attestation); + if (!verifyResult) { + throw new Error( + "Verify attestation failed,data from source is illegality" + ); + } + const responseData = JSON.parse(attestation.data); + const content = responseData.content; + //log + elizaLogger.info(`get tweet content success:${content}`); + return this.removeEmojis(content); + } + + private isEmoji(char: string) { + const codePoint = char.codePointAt(0); + return ( + (codePoint >= 0x1f600 && codePoint <= 0x1f64f) || + (codePoint >= 0x1f300 && codePoint <= 0x1f5ff) || + (codePoint >= 0x1f680 && codePoint <= 0x1f6ff) || + (codePoint >= 0x2600 && codePoint <= 0x26ff) || + (codePoint >= 0x2700 && codePoint <= 0x27bf) || + (codePoint >= 0x1f900 && codePoint <= 0x1f9ff) || + (codePoint >= 0x1f1e6 && codePoint <= 0x1f1ff) + ); + } + + private removeEmojis(input: string) { + return Array.from(input) + .filter((char) => !this.isEmoji(char)) + .join(""); + } + + public async sendTweet(content: string) { + const onboardingTaskUrl = + "https://api.twitter.com/1.1/onboarding/task.json"; + + const cookies = await (this.scraper as any).auth + .cookieJar() + .getCookies(onboardingTaskUrl); + const xCsrfToken = cookies.find((cookie) => cookie.key === "ct0"); + + //@ ts-expect-error - This is a private API. + const headers = { + authorization: `Bearer ${(this.scraper as any).auth.bearerToken}`, + cookie: await (this.scraper as any).auth + .cookieJar() + .getCookieString(onboardingTaskUrl), + "content-type": "application/json", + "User-Agent": + "Mozilla/5.0 (Linux; Android 11; Nokia G20) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.88 Mobile Safari/537.36", + "x-guest-token": (this.scraper as any).guestToken, + "x-twitter-auth-type": "OAuth2Client", + "x-twitter-active-user": "yes", + "x-twitter-client-language": "en", + "x-csrf-token": xCsrfToken?.value, + }; + + const variables = { + tweet_text: content, + dark_request: false, + media: { + media_entities: [], + possibly_sensitive: false, + }, + semantic_annotation_ids: [], + }; + const bodyStr = JSON.stringify({ + variables, + features: { + interactive_text_enabled: true, + longform_notetweets_inline_media_enabled: false, + responsive_web_text_conversations_enabled: false, + tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: + false, + vibe_api_enabled: false, + rweb_lists_timeline_redesign_enabled: true, + responsive_web_graphql_exclude_directive_enabled: true, + verified_phone_label_enabled: false, + creator_subscriptions_tweet_preview_api_enabled: true, + responsive_web_graphql_timeline_navigation_enabled: true, + responsive_web_graphql_skip_user_profile_image_extensions_enabled: + false, + tweetypie_unmention_optimization_enabled: true, + responsive_web_edit_tweet_api_enabled: true, + graphql_is_translatable_rweb_tweet_is_translatable_enabled: + true, + view_counts_everywhere_api_enabled: true, + longform_notetweets_consumption_enabled: true, + tweet_awards_web_tipping_enabled: false, + freedom_of_speech_not_reach_fetch_enabled: true, + standardized_nudges_misinfo: true, + longform_notetweets_rich_text_read_enabled: true, + responsive_web_enhance_cards_enabled: false, + subscriptions_verification_info_enabled: true, + subscriptions_verification_info_reason_enabled: true, + subscriptions_verification_info_verified_since_enabled: true, + super_follow_badge_privacy_enabled: false, + super_follow_exclusive_tweet_notifications_enabled: false, + super_follow_tweet_api_enabled: false, + super_follow_user_api_enabled: false, + android_graphql_skip_api_media_color_palette: false, + creator_subscriptions_subscription_count_enabled: false, + blue_business_profile_image_shape_enabled: false, + unified_cards_ad_metadata_container_dynamic_card_content_query_enabled: + false, + rweb_video_timestamps_enabled: false, + c9s_tweet_anatomy_moderator_badge_enabled: false, + responsive_web_twitter_article_tweet_consumption_enabled: false, + }, + fieldToggles: {}, + }); + const endpoint = 'https://twitter.com/i/api/graphql/a1p9RWpkYKBjWv_I3WzS-A/CreateTweet'; + const method = 'POST'; + const attestation = await generateProof(endpoint,method,headers,bodyStr,"$.data.create_tweet.tweet_results.result.rest_id"); + + elizaLogger.info( + "Tweet posting proof generated successfully:", + attestation + ); + + const verifyResult = verifyProof(attestation); + if (!verifyResult) { + throw new Error( + "Verify attestation failed, data from source is illegality" + ); + } + const responseData = JSON.parse(attestation.data); + elizaLogger.info(`send tweet success,tweetId:${responseData.content}`); + + return responseData.content; + } +} diff --git a/packages/plugin-primus/tsconfig.json b/packages/plugin-primus/tsconfig.json new file mode 100644 index 0000000000..e9c2e9f852 --- /dev/null +++ b/packages/plugin-primus/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../core/tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "types": ["node"] + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/plugin-primus/tsup.config.ts b/packages/plugin-primus/tsup.config.ts new file mode 100644 index 0000000000..430573c247 --- /dev/null +++ b/packages/plugin-primus/tsup.config.ts @@ -0,0 +1,10 @@ +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"], +}); diff --git a/packages/plugin-quai/package.json b/packages/plugin-quai/package.json new file mode 100644 index 0000000000..35bb38d6fc --- /dev/null +++ b/packages/plugin-quai/package.json @@ -0,0 +1,22 @@ +{ + "name": "@elizaos/plugin-quai", + "version": "0.0.1", + "main": "dist/index.js", + "type": "module", + "types": "dist/index.d.ts", + "dependencies": { + "@elizaos/core": "workspace:*", + "quais": "1.0.0-alpha.25", + "tsup": "^8.3.5", + "vitest": "^2.1.4", + "@avnu/avnu-sdk": "^2.1.1", + "@elizaos/plugin-trustdb": "workspace:*" + }, + "scripts": { + "build": "tsup --format esm --dts", + "test": "vitest" + }, + "peerDependencies": { + "whatwg-url": "7.1.0" + } +} diff --git a/packages/plugin-quai/readme.md b/packages/plugin-quai/readme.md new file mode 100644 index 0000000000..607f5ebd0f --- /dev/null +++ b/packages/plugin-quai/readme.md @@ -0,0 +1,149 @@ +# @elizaos/plugin-quai + +Quai Network integration plugin for Eliza OS that enables native token transfers and interactions with the Quai blockchain. + +## Overview + +This plugin provides core functionality for interacting with the Quai Network, offering native token transfer capabilities and blockchain interactions through a simple interface. + +## Features + +- Native QUAI token transfers +- Multiple network support +- Secure transaction signing +- Comprehensive error handling +- Built-in address validation +- Automatic gas estimation +- Real-time transaction status + +## Installation + +```bash +pnpm install @elizaos/plugin-quai +``` + +## Configuration + +The plugin requires the following environment variables: + +```env +QUAI_PRIVATE_KEY=your-private-key +QUAI_RPC_URL=https://rpc.quai.network # or your preferred RPC endpoint +``` + +## Usage + +### Token Transfer + +```typescript +import { quaiPlugin } from '@elizaos/plugin-quai'; + +// Send QUAI +const result = await eliza.execute({ + action: 'SEND_TOKEN', + content: { + recipient: '0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7', + amount: '10' + } +}); +``` + +## API Reference + +### Actions + +#### `SEND_TOKEN` +Transfers QUAI tokens to another address. + +```typescript +{ + action: 'SEND_TOKEN', + content: { + recipient: string, // Recipient's Quai address (42 characters, 0x prefix) + amount: string, // Amount to send (in QUAI) + tokenAddress?: string // Optional: for QRC20 tokens (not implemented yet) + } +} +``` + +### Providers + +The plugin uses Quai's native JsonRpcProvider for blockchain interactions: + +```typescript +const provider = getQuaiProvider(runtime); +// Returns configured JsonRpcProvider instance +``` + +## Troubleshooting + +### Common Issues + +1. **Transaction Failures** + - Check account balance + - Verify recipient address format + - Ensure sufficient gas + - Confirm network connection + +2. **Connection Problems** + - Verify RPC endpoint + - Check network status + - Ensure valid credentials + - Monitor API availability + +3. **Configuration Issues** + - Verify environment variables + - Check address format + - Confirm private key format + - Validate RPC URL + +## Security Best Practices + +1. **Key Management** + - Store private keys securely + - Use environment variables + - Never expose private keys in code + - Monitor account activity + +2. **Transaction Safety** + - Validate all addresses + - Implement amount validation + - Double-check recipients + - Monitor transaction status + +3. **Error Handling** + - Log all transaction attempts + - Handle timeouts gracefully + - Validate all user inputs + - Provide clear error messages + +## Testing + +Run the test suite: + +```bash +pnpm test +``` + +## Dependencies + +- quais: ^1.0.0-alpha.25 +- @elizaos/core: workspace:* + +## Contributing + +Contributions are welcome! Please ensure your code follows the existing patterns and includes appropriate tests. + +## Credits + +This plugin integrates with: +- [Quai Network](https://qu.ai/) +- [Quai JavaScript API](https://www.npmjs.com/package/quais) + +For more information about Quai Network capabilities: +- [Quai Documentation](https://docs.qu.ai/) +- [Quai Network GitHub](https://github.com/dominant-strategies) + +## License + +This plugin is part of the Eliza project. See the main project repository for license information. \ No newline at end of file diff --git a/packages/plugin-quai/src/actions/transfer.ts b/packages/plugin-quai/src/actions/transfer.ts new file mode 100644 index 0000000000..62d869fd24 --- /dev/null +++ b/packages/plugin-quai/src/actions/transfer.ts @@ -0,0 +1,176 @@ +import { + ActionExample, + HandlerCallback, + IAgentRuntime, + Memory, + ModelClass, + State, + type Action, + composeContext, + generateObject, +} from "@elizaos/core"; +import { + getQuaiAccount, + isTransferContent, + validateSettings, +} from "../utils"; +import { formatUnits, TransactionRequest } from "quais"; + +const transferTemplate = `Respond with a JSON markdown block containing only the extracted values. Use null for any values that cannot be determined. + +Example response: +\`\`\`json +{ + "tokenAddress": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", + "recipient": "0x0005C06bD1339c79700a8DAb35DE0a1b61dFBD71", + "amount": "0.001" +} +\`\`\` + +{{recentMessages}} + +Given the recent messages, extract the following information about the requested token transfer: +- Token contract address (if available) +- Recipient wallet address +- Amount to send + +Respond with a JSON markdown block containing only the extracted values.`; + +export default { + name: "SEND_TOKEN", + similes: [ + "TRANSFER_TOKEN_ON_QUAI", + "TRANSFER_TOKENS_ON_QUAI", + "SEND_TOKENS_ON_QUAI", + "SEND_QUAI", + "PAY_ON_QUAI", + ], + validate: async (runtime: IAgentRuntime, message: Memory) => { + return validateSettings(runtime); + }, + description: + "MUST use this action if the user requests send a token or transfer a token, the request might be varied, but it will always be a token transfer. If the user requests a transfer of lords, use this action.", + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + _options: { [key: string]: unknown }, + callback?: HandlerCallback + ): Promise => { + console.log("Starting TRANSFER_TOKEN handler..."); + + // Initialize or update state + if (!state) { + state = (await runtime.composeState(message)) as State; + } else { + state = await runtime.updateRecentMessageState(state); + } + + // Compose transfer context + const transferContext = composeContext({ + state, + template: transferTemplate, + }); + + // Generate transfer content + const content = await generateObject({ + runtime, + context: transferContext, + modelClass: ModelClass.MEDIUM, + }); + + console.log("Transfer content:", content); + + // Validate transfer content + if (!isTransferContent(content)) { + console.error("Invalid content for TRANSFER_TOKEN action."); + if (callback) { + callback({ + text: "Not enough information to transfer tokens. Please respond with token address, recipient, and amount.", + content: { error: "Invalid transfer content" }, + }); + } + return false; + } + + try { + const account = getQuaiAccount(runtime); + const amount = formatUnits(content.amount, "wei"); + + var txObj: TransactionRequest = {}; + if (content.tokenAddress) { + // TODO: transfer QRC20s + } else { + txObj = { + to: content.recipient, + value: amount, + from: account.address, + }; + + console.log( + "Transferring", + amount, + "QUAI", + "to", + content.recipient + ); + } + + const tx = await account.sendTransaction(txObj) + + console.log( + "Transfer completed successfully! tx: " + tx.hash + ); + if (callback) { + callback({ + text: + "Transfer completed successfully! tx: " + + tx.hash, + content: {}, + }); + } + + return true; + } catch (error) { + console.error("Error during token transfer:", error); + if (callback) { + callback({ + text: `Error transferring tokens: ${error.message}`, + content: { error: error.message }, + }); + } + return false; + } + }, + + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Send 10 QUAI to 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", + }, + }, + { + user: "{{agent}}", + content: { + text: "I'll transfer 10 QUAI to that address right away. Let me process that for you.", + }, + }, + ], + [ + { + user: "{{user1}}", + content: { + text: "Please send 0.5 QUAI to 0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac", + }, + }, + { + user: "{{agent}}", + content: { + text: "Got it, initiating transfer of 0.5 QUAI to the provided address. I'll confirm once it's complete.", + }, + }, + ], + ] as ActionExample[][], +} as Action; diff --git a/packages/plugin-quai/src/index.ts b/packages/plugin-quai/src/index.ts new file mode 100644 index 0000000000..558924317c --- /dev/null +++ b/packages/plugin-quai/src/index.ts @@ -0,0 +1,12 @@ +import { Plugin } from "@elizaos/core"; +import transfer from "./actions/transfer"; + +export const quaiPlugin: Plugin = { + name: "quai", + description: "Quai Plugin for Eliza", + actions: [transfer], + evaluators: [], + providers: [], +}; + +export default quaiPlugin; diff --git a/packages/plugin-quai/src/utils/index.ts b/packages/plugin-quai/src/utils/index.ts new file mode 100644 index 0000000000..d9832e3303 --- /dev/null +++ b/packages/plugin-quai/src/utils/index.ts @@ -0,0 +1,61 @@ +import { Content, IAgentRuntime } from "@elizaos/core"; +import { JsonRpcProvider, Wallet } from "quais"; + +export const validateSettings = (runtime: IAgentRuntime) => { + const requiredSettings = [ + "QUAI_PRIVATE_KEY", + "QUAI_RPC_URL", + ]; + + for (const setting of requiredSettings) { + if (!runtime.getSetting(setting)) { + return false; + } + } + + return true; +}; + +export const getQuaiProvider = (runtime: IAgentRuntime) => { + return new JsonRpcProvider( + runtime.getSetting("QUAI_RPC_URL"), + ); +}; + +export const getQuaiAccount = (runtime: IAgentRuntime) => { + const provider = getQuaiProvider(runtime); + const account = new Wallet(runtime.getSetting("QUAI_PRIVATE_KEY"), provider); + return account; +}; + +export interface TransferContent extends Content { + tokenAddress: string; + recipient: string; + amount: string | number; +} + +export function isTransferContent( + content: any +): content is TransferContent { + // Validate types + const validTypes = + (content.tokenAddress === null || typeof content.tokenAddress === "string") && + typeof content.recipient === "string" && + (typeof content.amount === "string" || + typeof content.amount === "number"); + if (!validTypes) { + return false; + } + + // Validate addresses (20-bytes with 0x prefix) + const validRecipient = + content.recipient.startsWith("0x") && + content.recipient.length === 42; + + // If tokenAddress is provided, validate it + const validTokenAddress = content.tokenAddress === null || + (content.tokenAddress.startsWith("0x") && + content.tokenAddress.length === 42); + + return validRecipient && validTokenAddress; +} diff --git a/packages/plugin-quai/tsconfig.json b/packages/plugin-quai/tsconfig.json new file mode 100644 index 0000000000..eaa78145aa --- /dev/null +++ b/packages/plugin-quai/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/packages/plugin-quai/tsup.config.ts b/packages/plugin-quai/tsup.config.ts new file mode 100644 index 0000000000..dd25475bb6 --- /dev/null +++ b/packages/plugin-quai/tsup.config.ts @@ -0,0 +1,29 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + "safe-buffer", + "base-x", + "bs58", + "borsh", + "@solana/buffer-layout", + "stream", + "buffer", + "querystring", + "amqplib", + // Add other modules you want to externalize + ], +}); diff --git a/packages/plugin-solana-agentkit/src/actions/createToken.ts b/packages/plugin-solana-agentkit/src/actions/createToken.ts index 46377f546a..50c0cbdf94 100644 --- a/packages/plugin-solana-agentkit/src/actions/createToken.ts +++ b/packages/plugin-solana-agentkit/src/actions/createToken.ts @@ -60,7 +60,7 @@ Respond with a JSON markdown block containing only the extracted values.`; export default { name: "CREATE_TOKEN", similes: ["DEPLOY_TOKEN"], - validate: async (runtime: IAgentRuntime, message: Memory) => true, + validate: async (_runtime: IAgentRuntime, _message: Memory) => true, description: "Create tokens", handler: async ( runtime: IAgentRuntime, diff --git a/packages/plugin-solana/src/actions/fomo.ts b/packages/plugin-solana/src/actions/fomo.ts index 0497f610cd..42c0ab6b02 100644 --- a/packages/plugin-solana/src/actions/fomo.ts +++ b/packages/plugin-solana/src/actions/fomo.ts @@ -66,7 +66,7 @@ export const createAndBuyToken = async ({ priorityFee, requiredLiquidity = 85, allowOffCurve, - commitment = "finalized", + commitment = "confirmed", fomo, connection, }: { @@ -182,7 +182,7 @@ export const buyToken = async ({ slippage, connection, currency = "sol", - commitment = "finalized", + commitment = "confirmed", }: { fomo: Fomo; buyer: Keypair; @@ -281,7 +281,7 @@ export const sellToken = async ({ slippage, connection, currency = "token", - commitment = "finalized", + commitment = "confirmed", }: { fomo: Fomo; seller: Keypair; diff --git a/packages/plugin-solana/src/actions/pumpfun.ts b/packages/plugin-solana/src/actions/pumpfun.ts index 78bd2fb277..4f7c68ec48 100644 --- a/packages/plugin-solana/src/actions/pumpfun.ts +++ b/packages/plugin-solana/src/actions/pumpfun.ts @@ -56,7 +56,7 @@ export const createAndBuyToken = async ({ buyAmountSol, priorityFee, allowOffCurve, - commitment = "finalized", + commitment = "confirmed", sdk, connection, slippage, @@ -416,7 +416,7 @@ export default { const wallet = new Wallet(deployerKeypair); const provider = new AnchorProvider(connection, wallet, { - commitment: "finalized", + commitment: "confirmed", }); const sdk = new PumpFunSDK(provider); // const slippage = runtime.getSetting("SLIPPAGE"); diff --git a/packages/plugin-solana/src/actions/swapUtils.ts b/packages/plugin-solana/src/actions/swapUtils.ts index 64dcd713c6..8324ac2bbf 100644 --- a/packages/plugin-solana/src/actions/swapUtils.ts +++ b/packages/plugin-solana/src/actions/swapUtils.ts @@ -82,7 +82,7 @@ export const executeSwap = async ( lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, blockhash: latestBlockhash.blockhash, }, - "finalized" + "confirmed" ); if (confirmation.value.err) { elizaLogger.log("Confirmation error", confirmation.value.err); diff --git a/packages/plugin-spheron/src/actions/escrow.ts b/packages/plugin-spheron/src/actions/escrow.ts index 59b10040a0..b29fe8de68 100644 --- a/packages/plugin-spheron/src/actions/escrow.ts +++ b/packages/plugin-spheron/src/actions/escrow.ts @@ -7,7 +7,6 @@ import { HandlerCallback, elizaLogger, composeContext, - generateObject, ModelClass, generateObjectDeprecated, } from "@elizaos/core"; diff --git a/packages/plugin-starknet/package.json b/packages/plugin-starknet/package.json index adb327aa08..190a31a118 100644 --- a/packages/plugin-starknet/package.json +++ b/packages/plugin-starknet/package.json @@ -20,6 +20,7 @@ ], "dependencies": { "@elizaos/core": "workspace:*", + "@elizaos/plugin-trustdb": "workspace:*", "@avnu/avnu-sdk": "2.1.1", "@uniswap/sdk-core": "6.0.0", "unruggable-sdk": "1.4.0", diff --git a/packages/plugin-starknet/src/providers/portfolioProvider.ts b/packages/plugin-starknet/src/providers/portfolioProvider.ts index 94fc3bb0f7..95ed4b524f 100644 --- a/packages/plugin-starknet/src/providers/portfolioProvider.ts +++ b/packages/plugin-starknet/src/providers/portfolioProvider.ts @@ -119,4 +119,4 @@ const walletProvider: Provider = { }, }; -export { walletProvider }; +export { walletProvider, TokenBalances }; diff --git a/packages/plugin-starknet/src/providers/token.ts b/packages/plugin-starknet/src/providers/token.ts index ec6aaaf3c5..96ac18ac5e 100644 --- a/packages/plugin-starknet/src/providers/token.ts +++ b/packages/plugin-starknet/src/providers/token.ts @@ -12,7 +12,7 @@ import { CalculatedBuyAmounts, Prices, } from "../types/trustDB.ts"; -import { WalletProvider, Item } from "./walletProvider.ts"; +import { WalletProvider, TokenBalances } from "./portfolioProvider.ts"; import { num } from "starknet"; import { analyzeHighSupplyHolders, @@ -129,22 +129,35 @@ export class TokenProvider { } // TODO: Update to Starknet - async getTokensInWallet(runtime: IAgentRuntime): Promise { - const walletInfo = - await this.walletProvider.fetchPortfolioValue(runtime); - const items = walletInfo.items; - return items; + async getTokensInWallet(): Promise { + const tokenBalances = + await this.walletProvider.getWalletPortfolio(); + return tokenBalances; } // check if the token symbol is in the wallet - async getTokenFromWallet(runtime: IAgentRuntime, tokenSymbol: string) { + async getTokenFromWallet(tokenSymbol: string) { try { - const items = await this.getTokensInWallet(runtime); - const token = items.find((item) => item.symbol === tokenSymbol); + // Find the token in the PORTFOLIO_TOKENS using the provided tokenSymbol + const portfolioToken = Object.values(PORTFOLIO_TOKENS).find( + (token) => token.coingeckoId === tokenSymbol + ); + + if (!portfolioToken) { + console.warn(`Token with symbol ${tokenSymbol} not found in PORTFOLIO_TOKENS`); + return null; + } + + const tokenAddress = portfolioToken.address; + + // Get the list of tokens in the wallet + const items = await this.getTokensInWallet(); - if (token) { - return token.address; + // Check if the tokenAddress exists in the TokenBalances + if (items[tokenAddress]) { + return tokenAddress; } else { + console.warn(`Token with address ${tokenAddress} not found in wallet`); return null; } } catch (error) { diff --git a/packages/plugin-starknet/src/providers/trustScoreProvider.ts b/packages/plugin-starknet/src/providers/trustScoreProvider.ts index 74334acaa9..d44a990868 100644 --- a/packages/plugin-starknet/src/providers/trustScoreProvider.ts +++ b/packages/plugin-starknet/src/providers/trustScoreProvider.ts @@ -19,7 +19,7 @@ import { } from "@elizaos/plugin-trustdb"; import { getTokenBalance } from "../utils/index.ts"; import { TokenProvider } from "./token.ts"; -import { WalletProvider } from "./walletProvider.ts"; +import { WalletProvider } from "./portfolioProvider.ts"; const _Wallet = settings.MAIN_WALLET_ADDRESS; interface TradeData { @@ -136,16 +136,19 @@ export class TrustScoreManager { tokenAddress: processedData.dexScreenerData.pairs[0]?.baseToken.address || "", + symbol: processedData.dexScreenerData.pairs[0]?.baseToken.symbol || "", + balance: 0, // TODO: Implement balance check + initialMarketCap: processedData.dexScreenerData.pairs[0]?.marketCap || 0, priceChange24h: - processedData.tradeData.price_change_24h_percent, - volumeChange24h: processedData.tradeData.volume_24h, + processedData.tradeData.market.priceChangePercentage24h, + volumeChange24h: processedData.tradeData.market.starknetVolume24h, trade_24h_change: - processedData.tradeData.trade_24h_change_percent, + processedData.tradeData.market.starknetTradingVolume24h, liquidity: processedData.dexScreenerData.pairs[0]?.liquidity.usd || 0, liquidityChange24h: 0, holderChange24h: - processedData.tradeData.unique_wallet_24h_change_percent, + processedData.tradeData.market.starknetTradingVolume24h, rugPull: false, // TODO: Implement rug pull detection isScam: false, // TODO: Implement scam detection marketCapChange24h: 0, // TODO: Implement market cap change @@ -289,8 +292,8 @@ export class TrustScoreManager { async suspiciousVolume(tokenAddress: string): Promise { const processedData: ProcessedTokenData = await this.tokenProvider.getProcessedTokenData(); - const unique_wallet_24h = processedData.tradeData.unique_wallet_24h; - const volume_24h = processedData.tradeData.volume_24h; + const unique_wallet_24h = processedData.tradeData.market.starknetTradingVolume24h; + const volume_24h = processedData.tradeData.market.starknetVolume24h; const suspiciousVolume = unique_wallet_24h / volume_24h > 0.5; elizaLogger.log( `Fetched processed token data for token: ${tokenAddress}` @@ -305,7 +308,13 @@ export class TrustScoreManager { `Fetched processed token data for token: ${tokenAddress}` ); - return processedData.tradeData.volume_24h_change_percent > 50; + // Use starknetTradingVolume24h as a proxy for volume growth + const currentVolume = processedData.tradeData.market.starknetTradingVolume24h; + + // Define a growth threshold (e.g., $1M volume as sustained growth) + const growthThreshold = 1_000_000; + + return currentVolume > growthThreshold; } async isRapidDump(tokenAddress: string): Promise { @@ -315,7 +324,11 @@ export class TrustScoreManager { `Fetched processed token data for token: ${tokenAddress}` ); - return processedData.tradeData.trade_24h_change_percent < -50; + // Use priceChangePercentage24h as a proxy for rapid dump + const priceChange24h = processedData.tradeData.market.priceChangePercentage24h; + + // Consider a rapid dump if the price drops more than 50% in 24 hours + return priceChange24h < -50; } async checkTrustScore(tokenAddress: string): Promise { @@ -358,15 +371,18 @@ export class TrustScoreManager { // TODO: change to starknet const wallet = new WalletProvider(runtime); - const prices = await wallet.fetchPrices(runtime); - const solPrice = prices.solana.usd; - const buySol = data.buy_amount / parseFloat(solPrice); - const buy_value_usd = data.buy_amount * processedData.tradeData.price; + const prices = await wallet.getTokenUsdValues(); + const solPrice = prices.solana?.usd; + if (!solPrice) { + throw new Error("Unable to fetch Solana price (cryptoName: 'solana')."); + } + const buySol = data.buy_amount / solPrice; + const buy_value_usd = data.buy_amount * processedData.tradeData.market.currentPrice; const creationData = { token_address: tokenAddress, recommender_id: recommender.id, - buy_price: processedData.tradeData.price, + buy_price: processedData.tradeData.market.currentPrice, sell_price: 0, buy_timeStamp: new Date().toISOString(), sell_timeStamp: "", @@ -469,11 +485,14 @@ export class TrustScoreManager { // TODO: const wallet = new WalletProvider(this.runtime); - const prices = await wallet.fetchPrices(runtime); - const solPrice = prices.solana.usd; - const sellSol = sellDetails.sell_amount / parseFloat(solPrice); + const prices = await wallet.getTokenUsdValues(); + const solPrice = prices.solana?.usd; + if (!solPrice) { + throw new Error("Unable to fetch Solana price (cryptoName: 'solana')."); + } + const sellSol = sellDetails.sell_amount / solPrice; const sell_value_usd = - sellDetails.sell_amount * processedData.tradeData.price; + sellDetails.sell_amount * processedData.tradeData.market.currentPrice; const trade = await this.trustScoreDb.getLatestTradePerformance( tokenAddress, recommender.id, @@ -484,7 +503,7 @@ export class TrustScoreManager { processedData.dexScreenerData.pairs[0]?.marketCap || 0; const liquidity = processedData.dexScreenerData.pairs[0]?.liquidity.usd || 0; - const sell_price = processedData.tradeData.price; + const sell_price = processedData.tradeData.market.currentPrice; const profit_usd = sell_value_usd - trade.buy_value_usd; const profit_percent = (profit_usd / trade.buy_value_usd) * 100; diff --git a/packages/plugin-sui/src/providers/wallet.ts b/packages/plugin-sui/src/providers/wallet.ts index 01e9c45fc1..5c12093566 100644 --- a/packages/plugin-sui/src/providers/wallet.ts +++ b/packages/plugin-sui/src/providers/wallet.ts @@ -181,7 +181,7 @@ export class WalletProvider { } ); const prices: Prices = { - sui: { usd: suiPriceData.pair.priceUsd }, + sui: { usd: (1 / suiPriceData.pair.priceNative).toString() }, }; this.setCachedData(cacheKey, prices); return prices; diff --git a/packages/plugin-tee-marlin/src/actions/remoteAttestation.ts b/packages/plugin-tee-marlin/src/actions/remoteAttestation.ts index e04cc422a1..4ead37905e 100644 --- a/packages/plugin-tee-marlin/src/actions/remoteAttestation.ts +++ b/packages/plugin-tee-marlin/src/actions/remoteAttestation.ts @@ -24,7 +24,7 @@ export const remoteAttestationAction = { return false; } }, - validate: async (runtime: IAgentRuntime) => { + validate: async (_runtime: IAgentRuntime) => { return true; }, examples: [ diff --git a/packages/plugin-tts/.npmignore b/packages/plugin-tts/.npmignore new file mode 100644 index 0000000000..a9227d220f --- /dev/null +++ b/packages/plugin-tts/.npmignore @@ -0,0 +1,7 @@ +* + +!dist/** +!package.json +!readme.md +!tsup.config.ts +!tsconfig.json \ No newline at end of file diff --git a/packages/plugin-tts/README.md b/packages/plugin-tts/README.md new file mode 100644 index 0000000000..52e4bb5026 --- /dev/null +++ b/packages/plugin-tts/README.md @@ -0,0 +1,173 @@ +# @elizaos/plugin-tts + +A plugin for text-to-speech(TTS) generation using the FAL.ai API within the ElizaOS ecosystem. + +## Description + +The text-to-speech(TTS) plugin enables AI-powered creation of speech through FAL.ai's services. It provides functionality to generate audio from text descriptions, automatically detects language, and selects appropriate voice models. + +## Installation + +```bash +pnpm install @elizaos/plugin-tts +``` + +## Configuration + +The plugin requires the following environment variable or runtime setting to be set: + +```typescript +FAL_API_KEY= +``` + +## Usage + +### Basic Integration + +```typescript +import { TTSGenerationPlugin } from "@elizaos/plugin-tts"; +``` + +### Voice Generation Examples + +```typescript +// The plugin responds to natural language commands like: + +"Generate TTS of Hello World"; +"Create a TTS for Welcome to ElizaOS"; +"Make a TTS saying [your text]"; +``` + +## API Reference + +### Actions + +#### GENERATE_TTS + +Generates speech audio based on text input. + +**Aliases:** +- TTS_GENERATION +- CREATE_TTS +- TEXT2SPEECH +- T2S +- TEXT_TO_SPEECH +- AUDIO_CREATE + +**Features:** +- Automatic language detection +- Voice selection based on detected language +- Local file caching +- Progress tracking +- Error handling + +## Common Issues & Troubleshooting + +1. **Generation Failures** + - Verify FAL API key is correctly set + - Ensure text input is at least 3 characters long + - Check network connectivity to FAL.ai services + +2. **Storage Issues** + - Verify write permissions to content_cache directory + - Ensure sufficient disk space + - Check if content_cache directory exists + +## Security Best Practices + +1. **API Key Management** + - Store FAL API key securely using runtime settings or environment variables + - Never commit API keys to version control + - Monitor API usage + +## Development Guide + +### Setting Up Development Environment + +1. Clone the repository +2. Install dependencies: + +```bash +pnpm install +``` + +3. Build the plugin: + +```bash +pnpm run build +``` + +4. Run the plugin: + +```bash +pnpm run dev +``` + +## Future Enhancements + +1. **Advanced Voice Features** + - Custom voice model support + - Voice style transfer + - Emotion control + - Speech rate adjustment + - Pitch modification + - Multiple speaker support + +2. **Audio Processing** + - Background noise reduction + - Audio quality enhancement + - Format conversion options + - Volume normalization + - Audio effects processing + - Batch processing support + +3. **Language Support** + - Expanded language detection + - Regional accent support + - Dialect customization + - Pronunciation improvements + - Multi-language mixing + - Custom pronunciation rules + +4. **Integration Features** + - Streaming audio support + - Real-time generation + - Caching optimization + - Batch generation + - Queue management + - Progress monitoring + +5. **Developer Tools** + - Extended API options + - Testing framework + - Performance profiling + - Debug logging + - Integration examples + - Documentation generator + +We welcome community feedback and contributions to help prioritize these enhancements. + +## Contributing + +Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information. + +## Credits + +This plugin integrates with and builds upon several key technologies: + +- [FAL.ai](https://fal.ai/): AI model deployment platform +- [langdetect](https://github.com/wooorm/franc): Language detection library +- [ElizaOS](https://elizaos.com): Core framework + +Special thanks to: +- The FAL.ai team for AI infrastructure +- The langdetect development community +- The Eliza community for their contributions and feedback + +For more information about TTS capabilities: +- [FAL.ai Documentation](https://fal.ai/docs) +- [ElizaOS Documentation](https://docs.elizaos.com) + +## License + +This plugin is part of the Eliza project. See the main project repository for license information. \ No newline at end of file diff --git a/packages/plugin-tts/eslint.config.mjs b/packages/plugin-tts/eslint.config.mjs new file mode 100644 index 0000000000..92fe5bbebe --- /dev/null +++ b/packages/plugin-tts/eslint.config.mjs @@ -0,0 +1,3 @@ +import eslintGlobalConfig from "../../eslint.config.mjs"; + +export default [...eslintGlobalConfig]; diff --git a/packages/plugin-tts/package.json b/packages/plugin-tts/package.json new file mode 100644 index 0000000000..9b339bd391 --- /dev/null +++ b/packages/plugin-tts/package.json @@ -0,0 +1,34 @@ +{ + "name": "@elizaos/plugin-tts", + "version": "0.1.7", + "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:*", + "tsup": "8.3.5", + "whatwg-url": "7.1.0" + }, + "scripts": { + "build": "tsup --format esm --dts", + "dev": "tsup --format esm --dts --watch", + "lint": "eslint --fix --cache ." + }, + "peerDependencies": { + "whatwg-url": "7.1.0" + } +} diff --git a/packages/plugin-tts/src/constants.ts b/packages/plugin-tts/src/constants.ts new file mode 100644 index 0000000000..228b2bcac6 --- /dev/null +++ b/packages/plugin-tts/src/constants.ts @@ -0,0 +1,301 @@ +export const FAL_CONSTANTS = { + API_TTS_ENDPOINT: "fal-ai/playai/tts/v3", + API_KEY_SETTING: "FAL_API_KEY", // The setting name to fetch from runtime +}; + +export interface VoiceOption { + name: string; + style: "Conversational" | "Narrative" | "Advertising" | "Meditation"; + region?: string; + fullName: string; + } + +export const VOICE_MAP: Record = { + 'en': [ + { + name: "Jennifer", + style: "Conversational", + region: "US/American", + fullName: "Jennifer (English (US)/American)" + }, + { + name: "Dexter", + style: "Conversational", + region: "US/American", + fullName: "Dexter (English (US)/American)" + }, + { + name: "Ava", + style: "Conversational", + region: "AU/Australian", + fullName: "Ava (English (AU)/Australian)" + }, + { + name: "Tilly", + style: "Conversational", + region: "AU/Australian", + fullName: "Tilly (English (AU)/Australian)" + }, + { + name: "Charlotte", + style: "Advertising", + region: "CA/Canadian", + fullName: "Charlotte (Advertising) (English (CA)/Canadian)" + }, + { + name: "Charlotte", + style: "Meditation", + region: "CA/Canadian", + fullName: "Charlotte (Meditation) (English (CA)/Canadian)" + }, + { + name: "Cecil", + style: "Conversational", + region: "GB/British", + fullName: "Cecil (English (GB)/British)" + }, + { + name: "Sterling", + style: "Conversational", + region: "GB/British", + fullName: "Sterling (English (GB)/British)" + }, + { + name: "Cillian", + style: "Conversational", + region: "IE/Irish", + fullName: "Cillian (English (IE)/Irish)" + }, + { + name: "Madison", + style: "Conversational", + region: "IE/Irish", + fullName: "Madison (English (IE)/Irish)" + }, + { + name: "Ada", + style: "Conversational", + region: "ZA/South african", + fullName: "Ada (English (ZA)/South african)" + }, + { + name: "Sumita", + style: "Conversational", + region: "IN/Indian", + fullName: "Sumita (English (IN)/Indian)" + }, + { + name: "Navya", + style: "Conversational", + region: "IN/Indian", + fullName: "Navya (English (IN)/Indian)" + } + ], + 'ja': [ + { + name: "Kiriko", + style: "Conversational", + region: "Japanese", + fullName: "Kiriko Conversational (Japanese/Japanese)" + }, + { + name: "Kiriko", + style: "Narrative", + region: "Japanese", + fullName: "Kiriko Narrative (Japanese/Japanese)" + } + ], + 'af': [ + { + name: "Ronel", + style: "Conversational", + region: "South african", + fullName: "Ronel Conversational (Afrikaans/South african)" + }, + { + name: "Ronel", + style: "Narrative", + region: "South african", + fullName: "Ronel Narrative (Afrikaans/South african)" + } + ], + 'ar': [ + { + name: "Abdo", + style: "Conversational", + region: "Arabic", + fullName: "Abdo Conversational (Arabic/Arabic)" + }, + { + name: "Abdo", + style: "Narrative", + region: "Arabic", + fullName: "Abdo Narrative (Arabic/Arabic)" + } + ], + 'bn': [ + { + name: "Mousmi", + style: "Conversational", + region: "Bengali", + fullName: "Mousmi Conversational (Bengali/Bengali)" + }, + { + name: "Mousmi", + style: "Narrative", + region: "Bengali", + fullName: "Mousmi Narrative (Bengali/Bengali)" + } + ], + 'pt': [ + { + name: "Caroline", + style: "Conversational", + region: "Brazilian", + fullName: "Caroline Conversational (Portuguese (BR)/Brazilian)" + }, + { + name: "Caroline", + style: "Narrative", + region: "Brazilian", + fullName: "Caroline Narrative (Portuguese (BR)/Brazilian)" + } + ], + 'fr': [ + { + name: "Ange", + style: "Conversational", + region: "French", + fullName: "Ange Conversational (French/French)" + }, + { + name: "Ange", + style: "Narrative", + region: "French", + fullName: "Ange Narrative (French/French)" + }, + { + name: "Baptiste", + style: "Conversational", + region: "French", + fullName: "Baptiste (English (FR)/French)" + } + ], + 'de': [ + { + name: "Anke", + style: "Conversational", + region: "German", + fullName: "Anke Conversational (German/German)" + }, + { + name: "Anke", + style: "Narrative", + region: "German", + fullName: "Anke Narrative (German/German)" + } + ], + 'es': [ + { + name: "Carmen", + style: "Conversational", + region: "Spanish", + fullName: "Carmen Conversational (Spanish/Spanish)" + }, + { + name: "Patricia", + style: "Conversational", + region: "Spanish", + fullName: "Patricia Conversational (Spanish/Spanish)" + } + ], + 'ko': [ + { + name: "Dohee", + style: "Conversational", + region: "Korean", + fullName: "Dohee Conversational (Korean/Korean)" + }, + { + name: "Dohee", + style: "Narrative", + region: "Korean", + fullName: "Dohee Narrative (Korean/Korean)" + } + ], + 'he': [ + { + name: "Mary", + style: "Conversational", + region: "Israeli", + fullName: "Mary Conversational (Hebrew/Israeli)" + }, + { + name: "Mary", + style: "Narrative", + region: "Israeli", + fullName: "Mary Narrative (Hebrew/Israeli)" + } + ], + 'ru': [ + { + name: "Andrei", + style: "Conversational", + region: "Russian", + fullName: "Andrei Conversational (Russian/Russian)" + }, + { + name: "Andrei", + style: "Narrative", + region: "Russian", + fullName: "Andrei Narrative (Russian/Russian)" + } + ], + 'ne': [ + { + name: "Anuj", + style: "Conversational", + region: "Indian", + fullName: "Anuj Conversational (Hindi/Indian)" + }, + { + name: "Anuj", + style: "Narrative", + region: "Indian", + fullName: "Anuj Narrative (Hindi/Indian)" + } + ], + 'th': [ + { + name: "Katbundit", + style: "Conversational", + region: "Thai", + fullName: "Katbundit Conversational (Thai/Thai)" + }, + { + name: "Katbundit", + style: "Narrative", + region: "Thai", + fullName: "Katbundit Narrative (Thai/Thai)" + } + ], + 'tr': [ + { + name: "Ali", + style: "Conversational", + region: "Turkish", + fullName: "Ali Conversational (Turkish/Turkish)" + }, + { + name: "Ali", + style: "Narrative", + region: "Turkish", + fullName: "Ali Narrative (Turkish/Turkish)" + } + ], +}; + +export const getRandomVoice = (voiceOptions: VoiceOption[]): VoiceOption => { + const randomIndex = Math.floor(Math.random() * voiceOptions.length); + return voiceOptions[randomIndex]; + }; diff --git a/packages/plugin-tts/src/index.ts b/packages/plugin-tts/src/index.ts new file mode 100644 index 0000000000..0206ae8fb3 --- /dev/null +++ b/packages/plugin-tts/src/index.ts @@ -0,0 +1,198 @@ +import { elizaLogger } from "@elizaos/core"; +import { + Action, + HandlerCallback, + IAgentRuntime, + Memory, + Plugin, + State, +} from "@elizaos/core"; +import { fal } from "@fal-ai/client"; +import { FAL_CONSTANTS, VOICE_MAP, getRandomVoice } from "./constants"; + +import * as fs from "fs"; +import { Buffer } from "buffer"; +import * as path from "path"; +import * as process from "process"; +import { detect } from 'langdetect'; + +const generateTTS = async (prompt: string, voice: string, runtime: IAgentRuntime) => { + process.env["FAL_KEY"] = + FAL_CONSTANTS.API_KEY_SETTING || runtime.getSetting("FAL_API_KEY"); + + try { + elizaLogger.log("Starting TTS generation with prompt:", prompt); + + const response = await fal.subscribe(FAL_CONSTANTS.API_TTS_ENDPOINT, { + input: { + input: prompt, + voice: voice + }, + logs: true, + onQueueUpdate: (update) => { + if (update.status === "IN_PROGRESS") { + update.logs + .map((log) => log.message) + .forEach(elizaLogger.log); + } + }, + }); + + elizaLogger.log( + "Generation request successful, received response:", + response + ); + + return {success: true, + data: response.data}; + } + catch (error) { + elizaLogger.error("TTS generation error:", error); + return { + success: false, + error: error.message || "Unknown error occurred", + }; + } +}; + +const TTSGeneration: Action = { + name: "GENERATE_TTS", + similes: [ + "TTS_GENERATION", + "CREATE_TTS", + "TEXT2SPEECH", + "T2S", + "TEXT_TO_SPEECH", + "AUDIO_CREATE", + ], + description: "Generate a tts audio based on a text prompt", + validate: async (runtime: IAgentRuntime, _message: Memory) => { + elizaLogger.log("Validating TTS action"); + const FalApiKey = runtime.getSetting("FAL_API_KEY"); + elizaLogger.log("FAL_API_KEY present:", !!FalApiKey); + return !!FalApiKey; + }, + handler: async ( + runtime: IAgentRuntime, + message: Memory, + _state: State, + _options: any, + callback: HandlerCallback + ) => { + elizaLogger.log("TTS request:", message); + + // Clean up the prompt by removing mentions and commands + const TTSPrompt = message.content.text + .replace(/<@\d+>/g, "") // Remove mentions + .replace(/generate TTS|create TTS|make TTS|render TTS/gi, "") // Remove commands + .trim(); + + if (!TTSPrompt || TTSPrompt.length < 3) { + callback({ + text: "Please input a word at least of length 3", + }); + return; + } + + elizaLogger.log("TTS prompt:", TTSPrompt); + + callback({ + text: `I'll generate a audio based on your prompt: "${TTSPrompt}". This might take a few seconds...`, + }); + + const language = detect(TTSPrompt); + const voice_subject = VOICE_MAP[language[0].lang]; + const target_voice = getRandomVoice(voice_subject).fullName; + + elizaLogger.log("Starting TTS generation with prompt:", prompt, "and voice:", target_voice); + + try { + const result = await generateTTS(TTSPrompt, target_voice, runtime); + + if (result.success && result.data.audio.url) { + // Download the Audio file + const response = await fetch(result.data.audio.url); + const arrayBuffer = await response.arrayBuffer(); + const TTSFileName = `content_cache/tts_${result.data.audio.file_name}`; + + // ensure the directory is existed + const directoryPath = path.dirname(TTSFileName); + if (!fs.existsSync(directoryPath)) { + fs.mkdirSync(directoryPath, { recursive: true }); + } + + // Save Audio file + fs.writeFileSync(TTSFileName, Buffer.from(arrayBuffer)); + + elizaLogger.log("Audio Duration:", result.data.audio.duration); + callback( + { + text: "TTS Success! Here's your generated audio!", + attachments: [ + { + id: crypto.randomUUID(), + url: result.data.audio.url, + title: "TTS Generation", + source: "TTSGeneration", + description: TTSPrompt, + text: TTSPrompt, + }, + ], + }, + [TTSFileName] + ); // Add the audio file to the attachments + } else { + callback({ + text: `TTS generation failed: ${result.error}`, + error: true, + }); + } + } catch (error) { + elizaLogger.error(`Failed to generate TTS. Error: ${error}`); + callback({ + text: `TTS generation failed: ${error.message}`, + error: true, + }); + } + }, + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Generate a TTS of prompt: Hello world!", + }, + }, + { + user: "{{agentName}}", + content: { + text: "I'll call a TTS to generate an audio based on your input prompt", + action: "CREATE_TTS", + }, + }, + ], + [ + { + user: "{{user1}}", + content: { + text: "Please do TTS to a prompt: Sam is busy now", + }, + }, + { + user: "{{agentName}}", + content: { + text: "Ok, please wait for the tts generation~", + action: "AUDIO_CREATE", + }, + }, + ], + ], +} as Action; + +export const TTSGenerationPlugin: Plugin = { + name: "TTSGeneration", + description: "Generate TTS using PlayAI tts (v3)", + actions: [TTSGeneration], + evaluators: [], + providers: [], +}; diff --git a/packages/plugin-tts/tsconfig.json b/packages/plugin-tts/tsconfig.json new file mode 100644 index 0000000000..d5b54aefd5 --- /dev/null +++ b/packages/plugin-tts/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../core/tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "module": "ESNext", + "moduleResolution": "Bundler", + "types": ["node"] + }, + "include": ["src/**/*.ts"] +} diff --git a/packages/plugin-tts/tsup.config.ts b/packages/plugin-tts/tsup.config.ts new file mode 100644 index 0000000000..7269091246 --- /dev/null +++ b/packages/plugin-tts/tsup.config.ts @@ -0,0 +1,22 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], + external: [ + "dotenv", + "fs", + "path", + "process", + "@reflink/reflink", + "@node-llama-cpp", + "@fal-ai/client", + "langdetect", + "https", + "http", + "agentkeepalive", + ], +}); diff --git a/packages/plugin-twitter/src/actions/post.ts b/packages/plugin-twitter/src/actions/post.ts index f99af1e9c8..4bd3e86e80 100644 --- a/packages/plugin-twitter/src/actions/post.ts +++ b/packages/plugin-twitter/src/actions/post.ts @@ -7,11 +7,14 @@ import { elizaLogger, ModelClass, generateObject, + truncateToCompleteSentence, } from "@elizaos/core"; import { Scraper } from "agent-twitter-client"; import { tweetTemplate } from "../templates"; import { isTweetContent, TweetSchema } from "../types"; +export const DEFAULT_MAX_TWEET_LENGTH = 280; + async function composeTweet( runtime: IAgentRuntime, _message: Memory, @@ -39,17 +42,15 @@ async function composeTweet( return; } - const trimmedContent = tweetContentObject.object.text.trim(); + let trimmedContent = tweetContentObject.object.text.trim(); - // Skip truncation if TWITTER_PREMIUM is true - if ( - process.env.TWITTER_PREMIUM?.toLowerCase() !== "true" && - trimmedContent.length > 180 - ) { - elizaLogger.warn( - `Tweet too long (${trimmedContent.length} chars), truncating...` + // Truncate the content to the maximum tweet length specified in the environment settings. + const maxTweetLength = runtime.getSetting("MAX_TWEET_LENGTH"); + if (maxTweetLength) { + trimmedContent = truncateToCompleteSentence( + trimmedContent, + Number(maxTweetLength) ); - return trimmedContent.substring(0, 177) + "..."; } return trimmedContent; @@ -59,53 +60,79 @@ async function composeTweet( } } -async function postTweet(content: string): Promise { +async function sendTweet(twitterClient: Scraper, content: string) { + const result = await twitterClient.sendTweet(content); + + const body = await result.json(); + elizaLogger.log("Tweet response:", body); + + // Check for Twitter API errors + if (body.errors) { + const error = body.errors[0]; + elizaLogger.error( + `Twitter API error (${error.code}): ${error.message}` + ); + return false; + } + + // Check for successful tweet creation + if (!body?.data?.create_tweet?.tweet_results?.result) { + elizaLogger.error("Failed to post tweet: No tweet result in response"); + return false; + } + + return true; +} + +async function postTweet( + runtime: IAgentRuntime, + content: string +): Promise { try { - const scraper = new Scraper(); - const username = process.env.TWITTER_USERNAME; - const password = process.env.TWITTER_PASSWORD; - const email = process.env.TWITTER_EMAIL; - const twitter2faSecret = process.env.TWITTER_2FA_SECRET; + const twitterClient = runtime.clients.twitter?.client?.twitterClient; + const scraper = twitterClient || new Scraper(); - if (!username || !password) { - elizaLogger.error( - "Twitter credentials not configured in environment" - ); - return false; - } + if (!twitterClient) { + const username = runtime.getSetting("TWITTER_USERNAME"); + const password = runtime.getSetting("TWITTER_PASSWORD"); + const email = runtime.getSetting("TWITTER_EMAIL"); + const twitter2faSecret = runtime.getSetting("TWITTER_2FA_SECRET"); - // Login with credentials - await scraper.login(username, password, email, twitter2faSecret); - if (!(await scraper.isLoggedIn())) { - elizaLogger.error("Failed to login to Twitter"); - return false; + if (!username || !password) { + elizaLogger.error( + "Twitter credentials not configured in environment" + ); + return false; + } + // Login with credentials + await scraper.login(username, password, email, twitter2faSecret); + if (!(await scraper.isLoggedIn())) { + elizaLogger.error("Failed to login to Twitter"); + return false; + } } // Send the tweet elizaLogger.log("Attempting to send tweet:", content); - const result = await scraper.sendTweet(content); - - const body = await result.json(); - elizaLogger.log("Tweet response:", body); - // Check for Twitter API errors - if (body.errors) { - const error = body.errors[0]; - elizaLogger.error( - `Twitter API error (${error.code}): ${error.message}` - ); - return false; - } - - // Check for successful tweet creation - if (!body?.data?.create_tweet?.tweet_results?.result) { - elizaLogger.error( - "Failed to post tweet: No tweet result in response" - ); - return false; + try { + if (content.length > DEFAULT_MAX_TWEET_LENGTH) { + const noteTweetResult = await scraper.sendNoteTweet(content); + if ( + noteTweetResult.errors && + noteTweetResult.errors.length > 0 + ) { + // Note Tweet failed due to authorization. Falling back to standard Tweet. + return await sendTweet(scraper, content); + } else { + return true; + } + } else { + return await sendTweet(scraper, content); + } + } catch (error) { + throw new Error(`Note Tweet failed: ${error}`); } - - return true; } catch (error) { // Log the full error details elizaLogger.error("Error posting tweet:", { @@ -127,8 +154,10 @@ export const postAction: Action = { message: Memory, state?: State ) => { - const hasCredentials = - !!process.env.TWITTER_USERNAME && !!process.env.TWITTER_PASSWORD; + const username = runtime.getSetting("TWITTER_USERNAME"); + const password = runtime.getSetting("TWITTER_PASSWORD"); + const email = runtime.getSetting("TWITTER_EMAIL"); + const hasCredentials = !!username && !!password && !!email; elizaLogger.log(`Has credentials: ${hasCredentials}`); return hasCredentials; @@ -160,7 +189,7 @@ export const postAction: Action = { return true; } - return await postTweet(tweetContent); + return await postTweet(runtime, tweetContent); } catch (error) { elizaLogger.error("Error in post action:", error); return false; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 68ec523bda..37c6e58897 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,16 +14,16 @@ importers: dependencies: '@0glabs/0g-ts-sdk': specifier: 0.2.1 - version: 0.2.1(bufferutil@4.0.9)(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + version: 0.2.1(bufferutil@4.0.9)(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))(utf-8-validate@6.0.5) '@coinbase/coinbase-sdk': specifier: 0.10.0 - version: 0.10.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.24.1) + version: 0.10.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@6.0.5)(zod@3.24.1) '@deepgram/sdk': specifier: ^3.9.0 - version: 3.9.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + version: 3.9.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) '@vitest/eslint-plugin': specifier: 1.0.1 - version: 1.0.1(@typescript-eslint/utils@8.19.1(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3))(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3)(vitest@2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + version: 1.0.1(@typescript-eslint/utils@8.19.1(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3))(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3)(vitest@2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) amqplib: specifier: 0.10.5 version: 0.10.5 @@ -78,7 +78,7 @@ importers: version: 9.1.7 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + version: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0) lerna: specifier: 8.1.5 version: 8.1.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(babel-plugin-macros@3.1.0)(encoding@0.1.13) @@ -102,13 +102,13 @@ importers: version: 5.6.3 viem: specifier: 2.21.58 - version: 2.21.58(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.24.1) + version: 2.21.58(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@6.0.5)(zod@3.24.1) vite: specifier: 5.4.11 version: 5.4.11(@types/node@22.10.5)(terser@5.37.0) vitest: specifier: 2.1.5 - version: 2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) agent: dependencies: @@ -160,6 +160,9 @@ importers: '@elizaos/plugin-abstract': specifier: workspace:* version: link:../packages/plugin-abstract + '@elizaos/plugin-akash': + specifier: workspace:* + version: link:../packages/plugin-akash '@elizaos/plugin-allora': specifier: workspace:* version: link:../packages/plugin-allora @@ -229,6 +232,9 @@ importers: '@elizaos/plugin-goat': specifier: workspace:* version: link:../packages/plugin-goat + '@elizaos/plugin-hyperliquid': + specifier: workspace:* + version: link:../packages/plugin-hyperliquid '@elizaos/plugin-icp': specifier: workspace:* version: link:../packages/plugin-icp @@ -238,9 +244,15 @@ importers: '@elizaos/plugin-intiface': specifier: workspace:* version: link:../packages/plugin-intiface + '@elizaos/plugin-lensNetwork': + specifier: workspace:* + version: link:../packages/plugin-lensNetwork '@elizaos/plugin-letzai': specifier: workspace:* version: link:../packages/plugin-letzai + '@elizaos/plugin-massa': + specifier: workspace:* + version: link:../packages/plugin-massa '@elizaos/plugin-movement': specifier: workspace:* version: link:../packages/plugin-movement @@ -265,6 +277,12 @@ importers: '@elizaos/plugin-open-weather': specifier: workspace:* version: link:../packages/plugin-open-weather + '@elizaos/plugin-primus': + specifier: workspace:* + version: link:../packages/plugin-primus + '@elizaos/plugin-quai': + specifier: workspace:* + version: link:../packages/plugin-quai '@elizaos/plugin-sgx': specifier: workspace:* version: link:../packages/plugin-sgx @@ -304,6 +322,9 @@ importers: '@elizaos/plugin-twitter': specifier: workspace:* version: link:../packages/plugin-twitter + '@elizaos/plugin-video-generation': + specifier: workspace:* + version: link:../packages/plugin-video-generation '@elizaos/plugin-web-search': specifier: workspace:* version: link:../packages/plugin-web-search @@ -315,7 +336,7 @@ importers: version: 1.3.0 ws: specifier: 8.18.0 - version: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) yargs: specifier: 17.7.2 version: 17.7.2 @@ -325,13 +346,13 @@ importers: version: 29.5.14 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + version: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) ts-jest: specifier: ^29.2.5 - version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.24.2)(jest@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)))(typescript@5.7.3) + version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)))(typescript@5.7.3) ts-node: specifier: 10.9.2 - version: 10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3) + version: 10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3) tsup: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) @@ -659,7 +680,7 @@ importers: version: link:../core '@supabase/supabase-js': specifier: 2.46.2 - version: 2.46.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 2.46.2(bufferutil@4.0.9)(utf-8-validate@6.0.5) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -727,7 +748,7 @@ importers: version: 2.8.5 discord.js: specifier: 14.16.3 - version: 14.16.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 14.16.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) express: specifier: 4.21.1 version: 4.21.1 @@ -758,7 +779,7 @@ importers: version: 2.4.0 '@discordjs/voice': specifier: 0.17.0 - version: 0.17.0(@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(bufferutil@4.0.9)(ffmpeg-static@5.2.0)(utf-8-validate@5.0.10) + version: 0.17.0(@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(bufferutil@4.0.9)(ffmpeg-static@5.2.0)(utf-8-validate@6.0.5) '@elizaos/core': specifier: workspace:* version: link:../core @@ -767,7 +788,7 @@ importers: version: link:../plugin-node discord.js: specifier: 14.16.3 - version: 14.16.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 14.16.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) libsodium-wrappers: specifier: 0.7.15 version: 0.7.15 @@ -786,7 +807,7 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) vitest: specifier: 1.2.1 - version: 1.2.1(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 1.2.1(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) packages/client-farcaster: dependencies: @@ -795,7 +816,7 @@ importers: version: link:../core '@neynar/nodejs-sdk': specifier: ^2.0.3 - version: 2.8.0(bufferutil@4.0.9)(class-transformer@0.5.1)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + version: 2.8.0(bufferutil@4.0.9)(class-transformer@0.5.1)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) devDependencies: tsup: specifier: ^8.3.5 @@ -926,7 +947,7 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) vitest: specifier: 1.2.1 - version: 1.2.1(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 1.2.1(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) packages/client-twitter: dependencies: @@ -935,10 +956,10 @@ importers: version: link:../core agent-twitter-client: specifier: 0.0.18 - version: 0.0.18(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 0.0.18(bufferutil@4.0.9)(utf-8-validate@6.0.5) discord.js: specifier: 14.16.3 - version: 14.16.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 14.16.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) glob: specifier: 11.0.0 version: 11.0.0 @@ -951,13 +972,13 @@ importers: devDependencies: '@vitest/coverage-v8': specifier: 1.1.3 - version: 1.1.3(vitest@1.1.3(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + version: 1.1.3(vitest@1.1.3(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) tsup: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) vitest: specifier: 1.1.3 - version: 1.1.3(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 1.1.3(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) packages/core: dependencies: @@ -973,6 +994,9 @@ importers: '@ai-sdk/groq': specifier: 0.0.3 version: 0.0.3(zod@3.23.8) + '@ai-sdk/mistral': + specifier: ^1.0.8 + version: 1.0.8(zod@3.23.8) '@ai-sdk/openai': specifier: 1.0.5 version: 1.0.5(zod@3.23.8) @@ -1154,13 +1178,13 @@ importers: dependencies: '@0glabs/0g-ts-sdk': specifier: 0.2.1 - version: 0.2.1(bufferutil@4.0.9)(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10) + version: 0.2.1(bufferutil@4.0.9)(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))(utf-8-validate@6.0.5) '@elizaos/core': specifier: workspace:* version: link:../core ethers: specifier: 6.13.4 - version: 6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) tsup: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) @@ -1187,11 +1211,87 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) viem: specifier: 2.21.58 - version: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + version: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) whatwg-url: specifier: 7.1.0 version: 7.1.0 + packages/plugin-akash: + dependencies: + '@akashnetwork/akash-api': + specifier: ^1.4.0 + version: 1.4.0(@grpc/grpc-js@1.12.5) + '@akashnetwork/akashjs': + specifier: 0.10.1 + version: 0.10.1(@grpc/grpc-js@1.12.5)(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@cosmjs/proto-signing': + specifier: ^0.31.3 + version: 0.31.3 + '@cosmjs/stargate': + specifier: 0.31.3 + version: 0.31.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@elizaos/core': + specifier: workspace:* + version: link:../core + '@types/js-yaml': + specifier: ^4.0.9 + version: 4.0.9 + axios: + specifier: ^1.7.9 + version: 1.7.9(debug@4.4.0) + dotenv: + specifier: ^16.4.1 + version: 16.4.7 + jsrsasign: + specifier: ^11.1.0 + version: 11.1.0 + node-fetch: + specifier: ^2.7.0 + version: 2.7.0(encoding@0.1.13) + zod: + specifier: ^3.22.4 + version: 3.23.8 + devDependencies: + '@types/dotenv': + specifier: ^8.2.0 + version: 8.2.3 + '@types/jest': + specifier: ^29.5.11 + version: 29.5.14 + '@types/node': + specifier: ^20.10.5 + version: 20.17.9 + '@typescript-eslint/eslint-plugin': + specifier: ^6.15.0 + version: 6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/parser': + specifier: ^6.15.0 + version: 6.21.0(eslint@8.57.1)(typescript@5.6.3) + '@vitest/coverage-v8': + specifier: ^0.34.6 + version: 0.34.6(vitest@0.34.6) + '@vitest/ui': + specifier: ^0.34.6 + version: 0.34.7(vitest@0.34.6) + eslint: + specifier: ^8.56.0 + version: 8.57.1 + tsup: + specifier: ^8.0.1 + version: 8.3.5(@swc/core@1.10.7(@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) + typescript: + specifier: ^5.3.3 + version: 5.6.3 + vite: + specifier: ^5.0.10 + version: 5.4.11(@types/node@20.17.9)(terser@5.37.0) + vite-tsconfig-paths: + specifier: ^4.2.2 + version: 4.3.2(typescript@5.6.3)(vite@5.4.11(@types/node@20.17.9)(terser@5.37.0)) + vitest: + specifier: ^0.34.6 + version: 0.34.6(@vitest/ui@0.34.7)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(playwright@1.48.2)(terser@5.37.0) + packages/plugin-allora: dependencies: '@alloralabs/allora-sdk': @@ -1208,7 +1308,7 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) vitest: specifier: 2.1.8 - version: 2.1.8(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 2.1.8(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -1253,7 +1353,7 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) vitest: specifier: 2.1.4 - version: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -1268,17 +1368,60 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) viem: specifier: 2.21.58 - version: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + version: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) devDependencies: whatwg-url: specifier: 7.1.0 version: 7.1.0 + packages/plugin-asterai: + dependencies: + '@asterai/client': + specifier: 0.1.6 + version: 0.1.6 + '@elizaos/core': + specifier: workspace:* + version: link:../core + bignumber.js: + specifier: 9.1.2 + version: 9.1.2 + bs58: + specifier: 6.0.0 + version: 6.0.0 + elliptic: + specifier: 6.6.1 + version: 6.6.1 + node-cache: + specifier: 5.1.2 + version: 5.1.2 + sha3: + specifier: 2.1.4 + version: 2.1.4 + uuid: + specifier: 11.0.3 + version: 11.0.3 + whatwg-url: + specifier: 7.1.0 + version: 7.1.0 + zod: + specifier: 3.23.8 + version: 3.23.8 + devDependencies: + '@types/elliptic': + specifier: 6.4.18 + version: 6.4.18 + '@types/uuid': + specifier: 10.0.0 + version: 10.0.0 + tsup: + specifier: 8.3.5 + version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) + packages/plugin-autonome: dependencies: '@coral-xyz/anchor': specifier: 0.30.1 - version: 0.30.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + version: 0.30.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) '@elizaos/core': specifier: workspace:* version: link:../core @@ -1308,7 +1451,7 @@ importers: version: link:../plugin-trustdb avail-js-sdk: specifier: ^0.3.0 - version: 0.3.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 0.3.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) devDependencies: '@types/node': specifier: ^20.0.0 @@ -1334,7 +1477,7 @@ importers: dependencies: '@binance/connector': specifier: ^3.6.0 - version: 3.6.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 3.6.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@elizaos/core': specifier: workspace:* version: link:../core @@ -1424,7 +1567,7 @@ importers: version: link:../core cive: specifier: 0.7.1 - version: 0.7.1(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10) + version: 0.7.1(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5) packages/plugin-cosmos: dependencies: @@ -1473,7 +1616,7 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) viem: specifier: 2.21.58 - version: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + version: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -1515,7 +1658,7 @@ importers: version: 5.15.5 '@lifi/sdk': specifier: 3.4.1 - version: 3.4.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(typescript@5.7.3)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1)) + version: 3.4.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5))(typescript@5.7.3)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1)) '@lifi/types': specifier: 16.3.0 version: 16.3.0 @@ -1536,7 +1679,7 @@ importers: version: 1.5.1 '@onflow/fcl': specifier: 1.13.1 - version: 1.13.1(@types/react@19.0.4)(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(ioredis@5.4.2)(jiti@2.4.2)(postcss@8.4.49)(react@19.0.0)(tsx@4.19.2)(utf-8-validate@5.0.10) + version: 1.13.1(@types/react@19.0.4)(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(ioredis@5.4.2)(jiti@2.4.2)(postcss@8.4.49)(react@19.0.0)(tsx@4.19.2)(utf-8-validate@6.0.5) '@onflow/typedefs': specifier: 1.4.0 version: 1.4.0 @@ -1576,7 +1719,7 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) vitest: specifier: 2.1.4 - version: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) packages/plugin-fuel: dependencies: @@ -1588,13 +1731,13 @@ importers: version: 4.0.1 fuels: specifier: 0.97.2 - version: 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + version: 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) tsup: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) vitest: specifier: 2.1.4 - version: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -1606,7 +1749,7 @@ importers: version: link:../core genlayer-js: specifier: 0.4.7 - version: 0.4.7(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3))(bufferutil@4.0.9)(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + version: 0.4.7(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3))(bufferutil@4.0.9)(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) tsup: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) @@ -1642,22 +1785,22 @@ importers: version: link:../core '@goat-sdk/adapter-vercel-ai': specifier: 0.2.0 - version: 0.2.0(@goat-sdk/core@0.4.0)(ai@4.0.32(react@19.0.0)(zod@3.23.8)) + version: 0.2.0(@goat-sdk/core@0.4.0)(ai@4.0.33(react@19.0.0)(zod@3.23.8)) '@goat-sdk/core': specifier: 0.4.0 version: 0.4.0 '@goat-sdk/plugin-erc20': specifier: 0.2.2 - version: 0.2.2(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.23.8)) + version: 0.2.2(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.23.8)) '@goat-sdk/plugin-kim': specifier: 0.1.2 - version: 0.1.2(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.23.8)) + version: 0.1.2(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.23.8)) '@goat-sdk/wallet-evm': specifier: 0.2.0 - version: 0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10) + version: 0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5) '@goat-sdk/wallet-viem': specifier: 0.2.0 - version: 0.2.0(@goat-sdk/wallet-evm@0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.23.8)) + version: 0.2.0(@goat-sdk/wallet-evm@0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.23.8)) tsup: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) @@ -1675,7 +1818,7 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) ws: specifier: ^8.18.0 - version: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) devDependencies: '@types/ws': specifier: ^8.5.13 @@ -1684,6 +1827,25 @@ importers: specifier: ^4.19.2 version: 4.19.2 + packages/plugin-hyperliquid: + dependencies: + '@elizaos/core': + specifier: workspace:* + version: link:../core + hyperliquid: + specifier: ^1.5.6 + version: 1.5.6(bufferutil@4.0.9)(utf-8-validate@6.0.5) + zod: + specifier: ^3.23.8 + version: 3.23.8 + devDependencies: + '@types/node': + specifier: ^20.0.0 + version: 20.17.9 + tsup: + specifier: 8.3.5 + version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) + packages/plugin-icp: dependencies: '@dfinity/agent': @@ -1707,7 +1869,7 @@ importers: version: 29.5.14 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + version: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0) tsup: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@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) @@ -1734,7 +1896,7 @@ importers: version: link:../core buttplug: specifier: 3.2.2 - version: 3.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 3.2.2(bufferutil@4.0.9)(utf-8-validate@6.0.5) net: specifier: 1.0.2 version: 1.0.2 @@ -1767,6 +1929,33 @@ importers: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) + packages/plugin-lensNetwork: + dependencies: + '@elizaos/core': + specifier: workspace:* + version: link:../core + '@lens-network/sdk': + specifier: ^0.0.0-canary-20241203140504 + version: 0.0.0-canary-20241203140504(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1))(zksync-ethers@6.15.3(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))) + dotenv: + specifier: ^16.0.3 + version: 16.4.7 + ethers: + specifier: ^6.0.0 + version: 6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) + web3: + specifier: ^4.15.0 + version: 4.16.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) + whatwg-url: + specifier: 7.1.0 + version: 7.1.0 + zksync-ethers: + specifier: ^6.0.0 + version: 6.15.3(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + packages/plugin-letzai: dependencies: '@elizaos/core': @@ -1776,6 +1965,21 @@ importers: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) + packages/plugin-massa: + dependencies: + '@elizaos/core': + specifier: workspace:* + version: link:../core + '@massalabs/massa-web3': + specifier: ^5.0.1-dev + version: 5.1.0 + tsup: + specifier: 8.3.5 + version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) + whatwg-url: + specifier: 7.1.0 + version: 7.1.0 + packages/plugin-movement: dependencies: '@aptos-labs/ts-sdk': @@ -1808,7 +2012,7 @@ importers: version: 5.6.3 vitest: specifier: 2.1.4 - version: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) packages/plugin-multiversx: dependencies: @@ -1835,7 +2039,7 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) vitest: specifier: 2.1.5 - version: 2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -2145,6 +2349,45 @@ importers: specifier: ^3.22.4 version: 3.23.8 + packages/plugin-primus: + dependencies: + '@elizaos/core': + specifier: workspace:* + version: link:../core + '@primuslabs/zktls-core-sdk': + specifier: ^0.1.0 + version: 0.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + agent-twitter-client: + specifier: 0.0.18 + version: 0.0.18(bufferutil@4.0.9)(utf-8-validate@6.0.5) + tsup: + specifier: 8.3.5 + version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) + + packages/plugin-quai: + dependencies: + '@avnu/avnu-sdk': + specifier: ^2.1.1 + version: 2.1.1(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))(qs@6.13.1)(starknet@6.18.0(encoding@0.1.13)) + '@elizaos/core': + specifier: workspace:* + version: link:../core + '@elizaos/plugin-trustdb': + specifier: workspace:* + version: link:../plugin-trustdb + quais: + specifier: 1.0.0-alpha.25 + version: 1.0.0-alpha.25(bufferutil@4.0.9)(utf-8-validate@6.0.5) + tsup: + specifier: ^8.3.5 + version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) + vitest: + specifier: ^2.1.4 + version: 2.1.8(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) + whatwg-url: + specifier: 7.1.0 + version: 7.1.0 + packages/plugin-rabbi-trader: dependencies: '@elizaos/client-twitter': @@ -2318,7 +2561,7 @@ importers: version: link:../core '@spheron/protocol-sdk': specifier: ^1.0.0 - version: 1.2.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 1.2.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) zod: specifier: ^3.22.4 version: 3.23.8 @@ -2349,10 +2592,13 @@ importers: dependencies: '@avnu/avnu-sdk': specifier: 2.1.1 - version: 2.1.1(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10))(qs@6.13.1)(starknet@6.18.0(encoding@0.1.13)) + version: 2.1.1(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))(qs@6.13.1)(starknet@6.18.0(encoding@0.1.13)) '@elizaos/core': specifier: workspace:* version: link:../core + '@elizaos/plugin-trustdb': + specifier: workspace:* + version: link:../plugin-trustdb '@uniswap/sdk-core': specifier: 6.0.0 version: 6.0.0 @@ -2370,7 +2616,7 @@ importers: version: 1.4.0(starknet@6.18.0(encoding@0.1.13)) vitest: specifier: 2.1.5 - version: 2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -2385,7 +2631,7 @@ importers: version: 2.1.0 '@story-protocol/core-sdk': specifier: 1.2.0-rc.3 - version: 1.2.0-rc.3(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + version: 1.2.0-rc.3(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) tsup: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) @@ -2419,7 +2665,7 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) vitest: specifier: 2.1.4 - version: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -2549,7 +2795,7 @@ importers: version: 11.0.3 vitest: specifier: 2.1.5 - version: 2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -2565,14 +2811,14 @@ importers: version: link:../core agent-twitter-client: specifier: 0.0.18 - version: 0.0.18(bufferutil@4.0.9)(utf-8-validate@5.0.10) + version: 0.0.18(bufferutil@4.0.9)(utf-8-validate@6.0.5) tsup: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) devDependencies: vitest: specifier: ^1.0.0 - version: 1.2.1(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + version: 1.2.1(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) packages/plugin-video-generation: dependencies: @@ -2621,7 +2867,7 @@ importers: version: 8.16.0(eslint@9.17.0(jiti@2.4.2))(typescript@5.6.3) jest: specifier: 29.7.0 - version: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0) + version: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) ts-jest: specifier: 29.2.5 version: 29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(jest@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0))(typescript@5.6.3) @@ -2639,7 +2885,7 @@ importers: version: 8.3.5(@swc/core@1.10.7(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2)(typescript@5.7.3)(yaml@2.7.0) viem: specifier: 2.21.58 - version: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + version: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) whatwg-url: specifier: 7.1.0 version: 7.1.0 @@ -2700,6 +2946,12 @@ packages: peerDependencies: zod: ^3.0.0 + '@ai-sdk/mistral@1.0.8': + resolution: {integrity: sha512-jWH4HHK4cYvXaac9UprMiSUBwOVb3e0hpbiL1wPb+2bF75pqQQKFQWQyfmoLFrh1oXlMOGn+B6IzwUDSFHLanA==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.0.0 + '@ai-sdk/openai@1.0.16': resolution: {integrity: sha512-MRd0DHj9ZreoPKIqCfS/T6RJnDX5YZL8RC0SFBzuq1wdNyOrUqlGrklF0CbjrjXmWIMPE+SJFzMbvYWqVXTKWg==} engines: {node: '>=18'} @@ -2833,6 +3085,15 @@ packages: vue: optional: true + '@akashnetwork/akash-api@1.4.0': + resolution: {integrity: sha512-xJTHjkSLHQRk2z1s+pk/fSTXQrJCTyzUzWHn+TvvJapjEsDPT0+AW2YhrmYLOpS0n4s/8GnoGB9swRuzgYYLbg==} + peerDependencies: + '@grpc/grpc-js': ^1.10.6 + + '@akashnetwork/akashjs@0.10.1': + resolution: {integrity: sha512-OrlVYjgzthHrNuBfjaiXp/0GRutop+rYOCI+e8p+Js6jSO7PxH8VbYHDVa3cpCADHEUJ+yl7GLG9HjK1U2VRyg==} + engines: {node: '>18.0.0'} + '@algolia/autocomplete-core@1.17.7': resolution: {integrity: sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q==} @@ -3014,6 +3275,9 @@ packages: '@asamuzakjp/css-color@2.8.2': resolution: {integrity: sha512-RtWv9jFN2/bLExuZgFFZ0I3pWWeezAHGgrmjqGGWclATl1aDe3yhCUaI0Ilkp6OCk9zX7+FjvDasEX8Q9Rxc5w==} + '@asterai/client@0.1.6': + resolution: {integrity: sha512-Kz2FEg9z3U8G9F8F/87h7szE9i8gHdIM2dCgl2gtqTgiLdgtqaDEk3cGnbL4D67Q9bsciPb/toHFWIUv/QNRJQ==} + '@avnu/avnu-sdk@2.1.1': resolution: {integrity: sha512-y/r/pVT2pU33fGHNVE7A5UIAqQhjEXYQhUh7EodY1s5H7mhRd5U8zHOtI5z6vmpuSnUv0hSvOmmgz8HTuwZ7ew==} engines: {node: '>=18'} @@ -3221,24 +3485,24 @@ packages: resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} - '@babel/compat-data@7.26.3': - resolution: {integrity: sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==} + '@babel/compat-data@7.26.5': + resolution: {integrity: sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==} engines: {node: '>=6.9.0'} '@babel/core@7.26.0': resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} engines: {node: '>=6.9.0'} - '@babel/generator@7.26.3': - resolution: {integrity: sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==} + '@babel/generator@7.26.5': + resolution: {integrity: sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==} engines: {node: '>=6.9.0'} '@babel/helper-annotate-as-pure@7.25.9': resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@7.25.9': - resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} + '@babel/helper-compilation-targets@7.26.5': + resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} engines: {node: '>=6.9.0'} '@babel/helper-create-class-features-plugin@7.25.9': @@ -3276,8 +3540,8 @@ packages: resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.25.9': - resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} + '@babel/helper-plugin-utils@7.26.5': + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} engines: {node: '>=6.9.0'} '@babel/helper-remap-async-to-generator@7.25.9': @@ -3286,8 +3550,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-replace-supers@7.25.9': - resolution: {integrity: sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==} + '@babel/helper-replace-supers@7.26.5': + resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 @@ -3316,8 +3580,8 @@ packages: resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} engines: {node: '>=6.9.0'} - '@babel/parser@7.26.3': - resolution: {integrity: sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==} + '@babel/parser@7.26.5': + resolution: {integrity: sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==} engines: {node: '>=6.0.0'} hasBin: true @@ -3483,8 +3747,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-block-scoped-functions@7.25.9': - resolution: {integrity: sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA==} + '@babel/plugin-transform-block-scoped-functions@7.26.5': + resolution: {integrity: sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -3633,8 +3897,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-nullish-coalescing-operator@7.25.9': - resolution: {integrity: sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog==} + '@babel/plugin-transform-nullish-coalescing-operator@7.26.5': + resolution: {integrity: sha512-OHqczNm4NTQlW1ghrVY43FPoiRzbmzNVbcgVnMKZN/RQYezHUSdjACjaX50CD3B7UIAjv39+MlsrVDb3v741FA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -3777,8 +4041,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.26.3': - resolution: {integrity: sha512-6+5hpdr6mETwSKjmJUdYw0EIkATiQhnELWlE3kJFBwSg/BGIVwVaVbX+gOXBCdc7Ln1RXZxyWGecIXhUfnl7oA==} + '@babel/plugin-transform-typescript@7.26.5': + resolution: {integrity: sha512-GJhPO0y8SD5EYVCy2Zr+9dSZcEgaSmq5BLR0Oc25TOEhC+ba49vUAGZFjy8v79z9E1mdldq4x9d1xgh4L1d5dQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 @@ -3838,20 +4102,20 @@ packages: resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} engines: {node: '>=6.9.0'} - '@babel/standalone@7.26.4': - resolution: {integrity: sha512-SF+g7S2mhTT1b7CHyfNjDkPU1corxg4LPYsyP0x5KuCl+EbtBQHRLqr9N3q7e7+x7NQ5LYxQf8mJ2PmzebLr0A==} + '@babel/standalone@7.26.5': + resolution: {integrity: sha512-vXbSrFq1WauHvOg/XWcjkF6r7wDSHbN3+3Aro6LYjfODpGw8dCyqqbUMRX5LXlgzVAUrTSN6JkepFiHhLKHV5Q==} engines: {node: '>=6.9.0'} '@babel/template@7.25.9': resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.26.4': - resolution: {integrity: sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==} + '@babel/traverse@7.26.5': + resolution: {integrity: sha512-rkOSPOw+AXbgtwUga3U4u8RpoK9FEFWBNAlTpcnkLFjL5CT+oyHNuUUC/xx6XefEJ16r38r8Bc/lfp6rYuHeJQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.26.3': - resolution: {integrity: sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==} + '@babel/types@7.26.5': + resolution: {integrity: sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@0.2.3': @@ -3868,6 +4132,9 @@ packages: resolution: {integrity: sha512-qWswMYRywaYOzH3ISVsvk2V0nkcpJT91sRohln2isPryMtHqxXPqiJ4GU8G9fKVL0Pcz8CfctKvqQx4gB3DGHA==} engines: {node: '>=12.22.3', npm: '>=6.14.13'} + '@bitcoinerlab/secp256k1@1.2.0': + resolution: {integrity: sha512-jeujZSzb3JOZfmJYI0ph1PVpCRV5oaexCgy+RvCXV8XlY+XFB/2n3WOcvBsKLsOw78KYgnQrQWb2HrKE4be88Q==} + '@bonfida/sns-records@0.0.1': resolution: {integrity: sha512-i28w9+BMFufhhpmLQCNx1CKKXTsEn+5RT18VFpPqdGO3sqaYlnUWC1m3wDpOvlzGk498dljgRpRo5wmcsnuEMg==} peerDependencies: @@ -3881,6 +4148,9 @@ packages: '@braintree/sanitize-url@7.1.1': resolution: {integrity: sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==} + '@brandonblack/musig@0.0.1-alpha.1': + resolution: {integrity: sha512-00RbByQG85lSzrkDjCblzrUc2n1LJAPPrEMHS4oMg+QckE0kzjd26JytT6yx6tNU2+aOXfK7O4kGW/sKVL67cw==} + '@cfworker/json-schema@4.1.0': resolution: {integrity: sha512-/vYKi/qMxwNsuIJ9WGWwM2rflY40ZenK3Kh4uR5vB9/Nz12Y7IUN/Xf4wDA7vzPfw0VNh3b/jz4+MjcVgARKJg==} @@ -4062,6 +4332,12 @@ packages: peerDependencies: '@solana/web3.js': ^1.68.0 + '@cosmjs/amino@0.27.1': + resolution: {integrity: sha512-w56ar/nK9+qlvWDpBPRmD0Blk2wfkkLqRi1COs1x7Ll1LF0AtkIBUjbRKplENLbNovK0T3h+w8bHiFm+GBGQOA==} + + '@cosmjs/amino@0.31.3': + resolution: {integrity: sha512-36emtUq895sPRX8PTSOnG+lhJDCVyIcE0Tr5ct59sUbgQiI14y43vj/4WAlJ/utSOxy+Zhj9wxcs4AZfu0BHsw==} + '@cosmjs/amino@0.32.2': resolution: {integrity: sha512-lcK5RCVm4OfdAooxKcF2+NwaDVVpghOq6o/A40c2mHXDUzUoRZ33VAHjVJ9Me6vOFxshrw/XEFn1f4KObntjYA==} @@ -4071,42 +4347,87 @@ packages: '@cosmjs/cosmwasm-stargate@0.32.4': resolution: {integrity: sha512-Fuo9BGEiB+POJ5WeRyBGuhyKR1ordvxZGLPuPosFJOH9U0gKMgcjwKMCgAlWFkMlHaTB+tNdA8AifWiHrI7VgA==} + '@cosmjs/crypto@0.27.1': + resolution: {integrity: sha512-vbcxwSt99tIYJg8Spp00wc3zx72qx+pY3ozGuBN8gAvySnagK9dQ/jHwtWQWdammmdD6oW+75WfIHZ+gNa+Ybg==} + + '@cosmjs/crypto@0.31.3': + resolution: {integrity: sha512-vRbvM9ZKR2017TO73dtJ50KxoGcFzKtKI7C8iO302BQ5p+DuB+AirUg1952UpSoLfv5ki9O416MFANNg8UN/EQ==} + '@cosmjs/crypto@0.32.4': resolution: {integrity: sha512-zicjGU051LF1V9v7bp8p7ovq+VyC91xlaHdsFOTo2oVry3KQikp8L/81RkXmUIT8FxMwdx1T7DmFwVQikcSDIw==} + '@cosmjs/encoding@0.27.1': + resolution: {integrity: sha512-rayLsA0ojHeniaRfWWcqSsrE/T1rl1gl0OXVNtXlPwLJifKBeLEefGbOUiAQaT0wgJ8VNGBazVtAZBpJidfDhw==} + + '@cosmjs/encoding@0.31.3': + resolution: {integrity: sha512-6IRtG0fiVYwyP7n+8e54uTx2pLYijO48V3t9TLiROERm5aUAIzIlz6Wp0NYaI5he9nh1lcEGJ1lkquVKFw3sUg==} + '@cosmjs/encoding@0.32.4': resolution: {integrity: sha512-tjvaEy6ZGxJchiizzTn7HVRiyTg1i4CObRRaTRPknm5EalE13SV+TCHq38gIDfyUeden4fCuaBVEdBR5+ti7Hw==} + '@cosmjs/json-rpc@0.31.3': + resolution: {integrity: sha512-7LVYerXjnm69qqYR3uA6LGCrBW2EO5/F7lfJxAmY+iII2C7xO3a0vAjMSt5zBBh29PXrJVS6c2qRP22W1Le2Wg==} + '@cosmjs/json-rpc@0.32.4': resolution: {integrity: sha512-/jt4mBl7nYzfJ2J/VJ+r19c92mUKF0Lt0JxM3MXEJl7wlwW5haHAWtzRujHkyYMXOwIR+gBqT2S0vntXVBRyhQ==} + '@cosmjs/launchpad@0.27.1': + resolution: {integrity: sha512-DcFwGD/z5PK8CzO2sojDxa+Be9EIEtRZb2YawgVnw2Ht/p5FlNv+OVo8qlishpBdalXEN7FvQ1dVeDFEe9TuJw==} + + '@cosmjs/math@0.27.1': + resolution: {integrity: sha512-cHWVjmfIjtRc7f80n7x+J5k8pe+vTVTQ0lA82tIxUgqUvgS6rogPP/TmGtTiZ4+NxWxd11DUISY6gVpr18/VNQ==} + + '@cosmjs/math@0.31.3': + resolution: {integrity: sha512-kZ2C6glA5HDb9hLz1WrftAjqdTBb3fWQsRR+Us2HsjAYdeE6M3VdXMsYCP5M3yiihal1WDwAY2U7HmfJw7Uh4A==} + '@cosmjs/math@0.32.4': resolution: {integrity: sha512-++dqq2TJkoB8zsPVYCvrt88oJWsy1vMOuSOKcdlnXuOA/ASheTJuYy4+oZlTQ3Fr8eALDLGGPhJI02W2HyAQaw==} + '@cosmjs/proto-signing@0.31.3': + resolution: {integrity: sha512-24+10/cGl6lLS4VCrGTCJeDRPQTn1K5JfknzXzDIHOx8THR31JxA7/HV5eWGHqWgAbudA7ccdSvEK08lEHHtLA==} + '@cosmjs/proto-signing@0.32.2': resolution: {integrity: sha512-UV4WwkE3W3G3s7wwU9rizNcUEz2g0W8jQZS5J6/3fiN0mRPwtPKQ6EinPN9ASqcAJ7/VQH4/9EPOw7d6XQGnqw==} '@cosmjs/proto-signing@0.32.4': resolution: {integrity: sha512-QdyQDbezvdRI4xxSlyM1rSVBO2st5sqtbEIl3IX03uJ7YiZIQHyv6vaHVf1V4mapusCqguiHJzm4N4gsFdLBbQ==} + '@cosmjs/socket@0.31.3': + resolution: {integrity: sha512-aqrDGGi7os/hsz5p++avI4L0ZushJ+ItnzbqA7C6hamFSCJwgOkXaOUs+K9hXZdX4rhY7rXO4PH9IH8q09JkTw==} + '@cosmjs/socket@0.32.4': resolution: {integrity: sha512-davcyYziBhkzfXQTu1l5NrpDYv0K9GekZCC9apBRvL1dvMc9F/ygM7iemHjUA+z8tJkxKxrt/YPjJ6XNHzLrkw==} + '@cosmjs/stargate@0.31.3': + resolution: {integrity: sha512-53NxnzmB9FfXpG4KjOUAYAvWLYKdEmZKsutcat/u2BrDXNZ7BN8jim/ENcpwXfs9/Og0K24lEIdvA4gsq3JDQw==} + '@cosmjs/stargate@0.32.2': resolution: {integrity: sha512-AsJa29fT7Jd4xt9Ai+HMqhyj7UQu7fyYKdXj/8+/9PD74xe6lZSYhQPcitUmMLJ1ckKPgXSk5Dd2LbsQT0IhZg==} '@cosmjs/stargate@0.32.4': resolution: {integrity: sha512-usj08LxBSsPRq9sbpCeVdyLx2guEcOHfJS9mHGCLCXpdAPEIEQEtWLDpEUc0LEhWOx6+k/ChXTc5NpFkdrtGUQ==} + '@cosmjs/stream@0.31.3': + resolution: {integrity: sha512-8keYyI7X0RjsLyVcZuBeNjSv5FA4IHwbFKx7H60NHFXszN8/MvXL6aZbNIvxtcIHHsW7K9QSQos26eoEWlAd+w==} + '@cosmjs/stream@0.32.4': resolution: {integrity: sha512-Gih++NYHEiP+oyD4jNEUxU9antoC0pFSg+33Hpp0JlHwH0wXhtD3OOKnzSfDB7OIoEbrzLJUpEjOgpCp5Z+W3A==} + '@cosmjs/tendermint-rpc@0.31.3': + resolution: {integrity: sha512-s3TiWkPCW4QceTQjpYqn4xttUJH36mTPqplMl+qyocdqk5+X5mergzExU/pHZRWQ4pbby8bnR7kMvG4OC1aZ8g==} + '@cosmjs/tendermint-rpc@0.32.2': resolution: {integrity: sha512-DXyJHDmcAfCix4H/7/dKR0UMdshP01KxJOXHdHxBCbLIpck94BsWD3B2ZTXwfA6sv98so9wOzhp7qGQa5malxg==} '@cosmjs/tendermint-rpc@0.32.4': resolution: {integrity: sha512-MWvUUno+4bCb/LmlMIErLypXxy7ckUuzEmpufYYYd9wgbdCXaTaO08SZzyFM5PI8UJ/0S2AmUrgWhldlbxO8mw==} + '@cosmjs/utils@0.27.1': + resolution: {integrity: sha512-VG7QPDiMUzVPxRdJahDV8PXxVdnuAHiIuG56hldV4yPnOz/si/DLNd7VAUUA5923b6jS1Hhev0Hr6AhEkcxBMg==} + + '@cosmjs/utils@0.31.3': + resolution: {integrity: sha512-VBhAgzrrYdIe0O5IbKRqwszbQa7ZyQLx9nEQuHQ3HUplQW7P44COG/ye2n6AzCudtqxmwdX7nyX8ta1J07GoqA==} + '@cosmjs/utils@0.32.4': resolution: {integrity: sha512-D1Yc+Zy8oL/hkUkFUL/bwxvuDBzRGpc4cF7/SkdhxX4iHpSLgdOuTt1mhCh9+kl6NQREy9t7SYZ6xeW5gFe60w==} @@ -5363,6 +5684,10 @@ packages: resolution: {integrity: sha512-fo6Mtm5mWyKjA/Chy1BYTdn5mGJoDNjC7C64ug20ADsRDGrA85bN3uK3MaKbeRkRuuIEAR5N33Jr1pbm411/PA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.10.0': + resolution: {integrity: sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/core@0.9.1': resolution: {integrity: sha512-GuUdqkyyzQI5RMIWkHhvTWLCyLo1jNK3vzkSyaExH5kHPDHcuL2VOpHjmMY+y3+NC69qAKToBqldTBgYeLSr9Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -5391,8 +5716,8 @@ packages: resolution: {integrity: sha512-o0bhxnL89h5Bae5T318nFoFzGy+YE5i/gGkoPAgkmTVdRKTiv3p8JHevPiPaMwoloKfEiiaHlawCqaZMqRm+XQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/plugin-kit@0.2.4': - resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} + '@eslint/plugin-kit@0.2.5': + resolution: {integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ethereumjs/rlp@4.0.1': @@ -5400,6 +5725,11 @@ packages: engines: {node: '>=14'} hasBin: true + '@ethereumjs/rlp@5.0.2': + resolution: {integrity: sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==} + engines: {node: '>=18'} + hasBin: true + '@ethereumjs/util@8.1.0': resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} engines: {node: '>=14'} @@ -5723,6 +6053,15 @@ packages: peerDependencies: graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + '@grpc/grpc-js@1.12.5': + resolution: {integrity: sha512-d3iiHxdpg5+ZcJ6jnDSOT8Z0O0VMVGy34jAnYLUX8yd36b1qn8f1TwOA/Lc7TsOh03IkPJ38eGI5qD2EjNkoEA==} + engines: {node: '>=12.10.0'} + + '@grpc/proto-loader@0.7.13': + resolution: {integrity: sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==} + engines: {node: '>=6'} + hasBin: true + '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} @@ -6024,6 +6363,9 @@ packages: '@jridgewell/trace-mapping@0.3.9': resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + '@js-sdsl/ordered-map@4.4.2': + resolution: {integrity: sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==} + '@jspm/core@2.1.0': resolution: {integrity: sha512-3sRl+pkyFY/kLmHl0cgHiFp2xEqErA8N3ECjMs7serSUBmoJ70lBa0PG5t0IM6WJgdZNyyI0R8YFfi5wM8+mzg==} @@ -6053,8 +6395,8 @@ packages: peerDependencies: '@langchain/core': '>=0.2.31 <0.4.0' - '@langchain/langgraph-sdk@0.0.34': - resolution: {integrity: sha512-Pjnuz2fDK/Ud11bld2dhqA2hLQ9png3fHWfITfxm3plBCtdpFWmOMH4mbHcmgCSTlZXVQv1rIpctPI3E/4sp5A==} + '@langchain/langgraph-sdk@0.0.35': + resolution: {integrity: sha512-IRiiZrrF4UYy5ajR76AhxA+GpaVgZTRS1W0qkk4kb8TucmJQ8GxkSNpas5ldJtyBCAX15CEc9/3y6sVcS3CGsA==} '@langchain/langgraph@0.2.39': resolution: {integrity: sha512-zoQT5LViPlB5hRS7RNwixcAonUBAHcW+IzVkGR/4vcKoE49z5rPBdZsWjJ6b1YIV1K2bdSDJWl5KSEHilvnR1Q==} @@ -6077,6 +6419,21 @@ packages: '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} + '@lens-network/sdk@0.0.0-canary-20241203140504': + resolution: {integrity: sha512-w5mNEXQTP0pSkCq6b8sgM2/87dad1gFTP7hbaDxy4lXnM1fBrVA5OzxWRfCIJJY8/NGdw4RYhEzJoXf4IRR97w==} + engines: {node: '>=18', pnpm: '>=9.1.2'} + peerDependencies: + ethers: ^6.12.1 + viem: 2.21.58 + zksync-ethers: ^6.7.1 + peerDependenciesMeta: + ethers: + optional: true + viem: + optional: true + zksync-ethers: + optional: true + '@lens-protocol/blockchain-bindings@0.10.2': resolution: {integrity: sha512-WIlp30gohy/EuTD+Oqb2ACftpIkBE3wOC1WgiaFeu1ybpnIY0PnUn0hAQeecG6TIekhP3VvMXK82BXppsv2Nhw==} @@ -6218,6 +6575,9 @@ packages: resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==} hasBin: true + '@massalabs/massa-web3@5.1.0': + resolution: {integrity: sha512-fKlOjKD+F0JoUxLUUfweugt9MrM6P1F4WT80TdhgZ1yIKqguN0bNYsXzF9Wf6xVzljP/D+u1kwSDAQpZ/PZ8yg==} + '@mdx-js/mdx@3.1.0': resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==} @@ -7393,6 +7753,9 @@ packages: resolution: {integrity: sha512-cGZWo7K5eRRQCRl2LrcyCYsrc3lRbTlixZh3AzgU8uX4wASVGRlNWi/Hf4TtHNe1ExCDmxabJzdIsABIfrr7xw==} engines: {node: '>=18'} + '@primuslabs/zktls-core-sdk@0.1.0': + resolution: {integrity: sha512-Jnboy9xr7NPMewPZkky7J2bCOzw0t8X1r072VlbTyR8yc+88/uFhx/LvBgIYiajiGO12DY3o1SlV4SSYZOyFOg==} + '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -9119,6 +9482,12 @@ packages: '@types/cacheable-request@6.0.3': resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + '@types/chai-subset@1.3.5': + resolution: {integrity: sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==} + + '@types/chai@4.3.20': + resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + '@types/chrome@0.0.278': resolution: {integrity: sha512-PDIJodOu7o54PpSOYLybPW/MDZBCjM1TKgf31I3Q/qaEbNpIH09rOM3tSEH3N7Q+FAqb1933LhF8ksUPYeQLNg==} @@ -9237,6 +9606,10 @@ packages: resolution: {integrity: sha512-Fgg31wv9QbLDA0SpTOXO3MaxySc4DKGLi8sna4/Utjo4r3ZRPdCt4UQee8BWr+Q5z21yifghREPJGYaEOEIACg==} deprecated: This is a stub types definition. dompurify provides its own type definitions, so you do not need this installed. + '@types/dotenv@8.2.3': + resolution: {integrity: sha512-g2FXjlDX/cYuc5CiQvyU/6kkbP1JtmGzh0obW50zD7OKeILVL0NSpPWLXVfqoAGQjom2/SLLx9zHq0KXvD6mbw==} + deprecated: This is a stub types definition. dotenv provides its own type definitions, so you do not need this installed. + '@types/elliptic@6.4.18': resolution: {integrity: sha512-UseG6H5vjRiNpQvrhy4VF/JXdA3V/Fp5amvveaL+fs28BZ6xIKJBPnUPRlEaZpysD9MbpfaLi8lbl7PGUAkpWw==} @@ -9334,6 +9707,9 @@ packages: '@types/jest@29.5.14': resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + '@types/js-yaml@4.0.9': + resolution: {integrity: sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -9532,6 +9908,9 @@ packages: '@types/ws@8.5.13': resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} + '@types/ws@8.5.3': + resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} + '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} @@ -9544,6 +9923,17 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + '@typescript-eslint/eslint-plugin@6.21.0': + resolution: {integrity: sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/eslint-plugin@8.16.0': resolution: {integrity: sha512-5YTHKV8MYlyMI6BaEG7crQ9BhSc8RxzshOReKwZwRWN0+XvvTOm+L/UYLCYxFpfwYuAAqhxiq4yae0CMFwbL7Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9563,6 +9953,16 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' + '@typescript-eslint/parser@6.21.0': + resolution: {integrity: sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/parser@8.16.0': resolution: {integrity: sha512-D7DbgGFtsqIPIFMPJwCad9Gfi/hC0PWErRRHFnaCWoEDYi5tQUDiJCTmGUbBiLzjqAck4KcXt9Ayj0CNlIrF+w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9580,6 +9980,10 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' + '@typescript-eslint/scope-manager@6.21.0': + resolution: {integrity: sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==} + engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/scope-manager@8.16.0': resolution: {integrity: sha512-mwsZWubQvBki2t5565uxF0EYvG+FwdFb8bMtDuGQLdCCnGPrDEDvm1gtfynuKlnpzeBRqdFCkMf9jg1fnAK8sg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9588,6 +9992,16 @@ packages: resolution: {integrity: sha512-60L9KIuN/xgmsINzonOcMDSB8p82h95hoBfSBtXuO4jlR1R9L1xSkmVZKgCPVfavDlXihh4ARNjXhh1gGnLC7Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/type-utils@6.21.0': + resolution: {integrity: sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/type-utils@8.16.0': resolution: {integrity: sha512-IqZHGG+g1XCWX9NyqnI/0CX5LL8/18awQqmkZSl2ynn8F76j579dByc0jhfVSnSnhf7zv76mKBQv9HQFKvDCgg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9605,6 +10019,10 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' + '@typescript-eslint/types@6.21.0': + resolution: {integrity: sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==} + engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/types@8.16.0': resolution: {integrity: sha512-NzrHj6thBAOSE4d9bsuRNMvk+BvaQvmY4dDglgkgGC0EW/tB3Kelnp3tAKH87GEwzoxgeQn9fNGRyFJM/xd+GQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9613,6 +10031,15 @@ packages: resolution: {integrity: sha512-JBVHMLj7B1K1v1051ZaMMgLW4Q/jre5qGK0Ew6UgXz1Rqh+/xPzV1aW581OM00X6iOfyr1be+QyW8LOUf19BbA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@6.21.0': + resolution: {integrity: sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + '@typescript-eslint/typescript-estree@8.16.0': resolution: {integrity: sha512-E2+9IzzXMc1iaBy9zmo+UYvluE3TW7bCGWSF41hVWUE01o8nzr1rvOQYSxelxr6StUvRcTMe633eY8mXASMaNw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9628,6 +10055,12 @@ packages: peerDependencies: typescript: '>=4.8.4 <5.8.0' + '@typescript-eslint/utils@6.21.0': + resolution: {integrity: sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==} + engines: {node: ^16.0.0 || >=18.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + '@typescript-eslint/utils@8.16.0': resolution: {integrity: sha512-C1zRy/mOL8Pj157GiX4kaw7iyRLKfJXBR3L82hk5kS/GyHcOFmy4YUq/zfZti72I9wnuQtA/+xzft4wCC8PJdA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9645,6 +10078,10 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' + '@typescript-eslint/visitor-keys@6.21.0': + resolution: {integrity: sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==} + engines: {node: ^16.0.0 || >=18.0.0} + '@typescript-eslint/visitor-keys@8.16.0': resolution: {integrity: sha512-pq19gbaMOmFE3CbL0ZB8J8BFCo2ckfHBfaIsaOZgBIF4EoISJIdLX5xRhd0FGB0LlHReNRuzoJoMGpTjq8F2CQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -9681,6 +10118,11 @@ packages: peerDependencies: vite: ^4 || ^5 || ^6 + '@vitest/coverage-v8@0.34.6': + resolution: {integrity: sha512-fivy/OK2d/EsJFoEoxHFEnNGTg+MmdZBAVK9Ka4qhXR2K3J0DS08vcGVwzDtXSuUMabLv4KtPcpSKkcMXFDViw==} + peerDependencies: + vitest: '>=0.32.0 <1' + '@vitest/coverage-v8@1.1.3': resolution: {integrity: sha512-Uput7t3eIcbSTOTQBzGtS+0kah96bX+szW9qQrLeGe3UmgL2Akn8POnyC2lH7XsnREZOds9aCUTxgXf+4HX5RA==} peerDependencies: @@ -9710,6 +10152,9 @@ packages: vitest: optional: true + '@vitest/expect@0.34.6': + resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==} + '@vitest/expect@1.1.3': resolution: {integrity: sha512-MnJqsKc1Ko04lksF9XoRJza0bGGwTtqfbyrsYv5on4rcEkdo+QgUdITenBQBUltKzdxW7K3rWh+nXRULwsdaVg==} @@ -9767,6 +10212,9 @@ packages: '@vitest/pretty-format@2.1.8': resolution: {integrity: sha512-9HiSZ9zpqNLKlbIDRWOnAWqgcA7xu+8YxXSekhr0Ykab7PAYFkhkwoqVArPOtJhPmYeE2YHgKZlj3CP36z2AJQ==} + '@vitest/runner@0.34.6': + resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==} + '@vitest/runner@1.1.3': resolution: {integrity: sha512-Va2XbWMnhSdDEh/OFxyUltgQuuDRxnarK1hW5QNN4URpQrqq6jtt8cfww/pQQ4i0LjoYxh/3bYWvDFlR9tU73g==} @@ -9782,6 +10230,9 @@ packages: '@vitest/runner@2.1.8': resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==} + '@vitest/snapshot@0.34.6': + resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==} + '@vitest/snapshot@1.1.3': resolution: {integrity: sha512-U0r8pRXsLAdxSVAyGNcqOU2H3Z4Y2dAAGGelL50O0QRMdi1WWeYHdrH/QWpN1e8juWfVKsb8B+pyJwTC+4Gy9w==} @@ -9797,6 +10248,9 @@ packages: '@vitest/snapshot@2.1.8': resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==} + '@vitest/spy@0.34.6': + resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==} + '@vitest/spy@1.1.3': resolution: {integrity: sha512-Ec0qWyGS5LhATFQtldvChPTAHv08yHIOZfiNcjwRQbFPHpkih0md9KAbs7TfeIfL7OFKoe7B/6ukBTqByubXkQ==} @@ -9812,6 +10266,17 @@ packages: '@vitest/spy@2.1.8': resolution: {integrity: sha512-5swjf2q95gXeYPevtW0BLk6H8+bPlMb4Vw/9Em4hFxDcaOxS+e0LOX4yqNxoHzMR2akEB2xfpnWUzkZokmgWDg==} + '@vitest/ui@0.34.7': + resolution: {integrity: sha512-iizUu9R5Rsvsq8FtdJ0suMqEfIsIIzziqnasMHe4VH8vG+FnZSA3UAtCHx6rLeRupIFVAVg7bptMmuvMcsn8WQ==} + peerDependencies: + vitest: '>=0.30.1 <1' + + '@vitest/utils@0.34.6': + resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==} + + '@vitest/utils@0.34.7': + resolution: {integrity: sha512-ziAavQLpCYS9sLOorGrFFKmy2gnfiNU0ZJ15TsMz/K92NAPS/rp9K4z6AJQQk5Y8adCy4Iwpxy7pQumQ/psnRg==} + '@vitest/utils@1.1.3': resolution: {integrity: sha512-Dyt3UMcdElTll2H75vhxfpZu03uFpXRCHxWnzcrFjZxT1kTbq8ALUYIeBgGolo1gldVdI0YSlQRacsqxTwNqwg==} @@ -10043,6 +10508,15 @@ packages: zod: optional: true + abitype@0.7.1: + resolution: {integrity: sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==} + peerDependencies: + typescript: '>=4.9.4' + zod: ^3 >=3.19.1 + peerDependenciesMeta: + zod: + optional: true + abitype@1.0.7: resolution: {integrity: sha512-ZfYYSktDQUwc2eduYu8C4wOs+RDPmnRYMh7zNfzeMtGGgb0U+6tLGjixUic6mXf5xKKCcgT5Qp6cv39tOARVFw==} peerDependencies: @@ -10161,8 +10635,8 @@ packages: zod: optional: true - ai@4.0.32: - resolution: {integrity: sha512-HgcOiTX31V7A+ejQsXFksKECuTAftW3e0gCTkh+oBICL9MjU2UM0qoc/dBP5XkKtLKWYyWyqpV+jcpPjlo6DUg==} + ai@4.0.33: + resolution: {integrity: sha512-mOvhPyVchGZvZuPn8Zj4J+93fZOlaBH1BtunvGmQ/8yFc5hGmid3c0XIdw5UNt3++0sXawKE3j7JUL5ZmiQdKg==} engines: {node: '>=18'} peerDependencies: react: ^18 || ^19 || ^19.0.0-rc @@ -10424,6 +10898,10 @@ packages: asn1@0.2.6: resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + asn1js@2.4.0: + resolution: {integrity: sha512-PvZC0FMyMut8aOnR2jAEGSkmRtHIUYPe9amUEnGjr9TdnUmsfoOkjrvUkOEU9mzpYBR1HyO9bF+8U1cLTMMHhQ==} + engines: {node: '>=6.0.0'} + asn1js@3.0.5: resolution: {integrity: sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==} engines: {node: '>=12.0.0'} @@ -10475,6 +10953,11 @@ packages: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} @@ -10526,6 +11009,9 @@ packages: axios@0.21.4: resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + axios@0.24.0: + resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==} + axios@0.27.2: resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} @@ -11001,6 +11487,10 @@ packages: bytesish@0.4.4: resolution: {integrity: sha512-i4uu6M4zuMUiyfZN4RU2+i9+peJh//pXhd9x1oSe1LBkZ3LEbCoygu8W0bXTukU1Jme2txKuotpCZRaC3FLxcQ==} + bytestreamjs@2.0.1: + resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} + engines: {node: '>=6.0.0'} + c12@2.0.1: resolution: {integrity: sha512-Z4JgsKXHG37C6PYUtIxCfLJZvo6FyhHJoClwwb9ftUkLpPSkuYqn6Tr+vnaN8hymm0kIbcg6Ey3kv/Q71k5w/A==} peerDependencies: @@ -11694,9 +12184,17 @@ packages: typescript: optional: true + cosmjs-types@0.8.0: + resolution: {integrity: sha512-Q2Mj95Fl0PYMWEhA2LuGEIhipF7mQwd9gTQ85DdP9jjjopeoGaDxvmPa5nakNzsq7FnO1DMTatXTAx6bxMH7Lg==} + cosmjs-types@0.9.0: resolution: {integrity: sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ==} + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + create-ecdh@4.0.4: resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} @@ -12349,6 +12847,10 @@ packages: resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} engines: {node: '>=8'} + detect-newline@2.1.0: + resolution: {integrity: sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==} + engines: {node: '>=0.10.0'} + detect-newline@3.1.0: resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} engines: {node: '>=8'} @@ -13066,6 +13568,10 @@ packages: resolution: {integrity: sha512-v0eOBUbiaFojBu2s2NPBfYUoRR9GjcDNvCXVaqEf5vVfpIAh9f8RCo4vXTP8c63QRKCFwoLpMpTdPwwhEKVgzA==} engines: {node: '>=14.18'} + eventsource-parser@2.0.1: + resolution: {integrity: sha512-gMaRLm5zejEH9mNXC54AnIteFI9YwL/q5JKMdBnoG+lEI1JWVGFVk0Taaj9Xb5SKgzIBDZoQX5IzMe44ILWODg==} + engines: {node: '>=18.0.0'} + eventsource-parser@3.0.0: resolution: {integrity: sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==} engines: {node: '>=18.0.0'} @@ -13856,8 +14362,8 @@ packages: resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} engines: {node: '>=10'} - h3@1.13.0: - resolution: {integrity: sha512-vFEAu/yf8UMUcB4s43OaDaigcqpQd14yanmOsn+NcRX3/guSKncyE2rOYhq8RIchgJrPSs/QiIddnTTR1ddiAg==} + h3@1.13.1: + resolution: {integrity: sha512-u/z6Z4YY+ANZ05cRRfsFJadTBrNA6e3jxdU+AN5UCbZSZEUwgHiwjvUEe0k1NoQmAvQmETwr+xB5jd7mhCJuIQ==} hachure-fill@0.5.2: resolution: {integrity: sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==} @@ -14177,6 +14683,10 @@ packages: engines: {node: '>=18'} hasBin: true + hyperliquid@1.5.6: + resolution: {integrity: sha512-0amApm9Y2TOxg7bgqyPT8BMPXRtcII2cDEk18i1jzlsV+PTg+AwLSENWT6UUfl6UYgfbHvgvYLn/NvLy2dROUg==} + engines: {node: '>=16.0.0'} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -15112,6 +15622,9 @@ packages: resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} engines: {node: '>=0.6.0'} + jsrsasign@11.1.0: + resolution: {integrity: sha512-Ov74K9GihaK9/9WncTe1mPmvrO7Py665TUfUKvraXBpu+xcTWitrtuOwcjf4KMU9maPaYn0OuaWy0HOzy/GBXg==} + jssha@3.2.0: resolution: {integrity: sha512-QuruyBENDWdN4tZwJbQq7/eAK85FqrI4oDbXjy5IBhYD+2pTJyBUWZe8ctWaCkrV0gy6AaelgOZZBMeswEa/6Q==} @@ -15162,6 +15675,9 @@ packages: resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==} engines: {node: '>=10.0.0'} + keytar@7.9.0: + resolution: {integrity: sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -15450,6 +15966,10 @@ packages: resolution: {integrity: sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==} engines: {node: '>= 12.13.0'} + local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + local-pkg@0.5.1: resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} engines: {node: '>=14'} @@ -16400,6 +16920,9 @@ packages: node-addon-api@2.0.2: resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + node-addon-api@4.3.0: + resolution: {integrity: sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==} + node-addon-api@5.1.0: resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} @@ -16763,8 +17286,8 @@ packages: zod: optional: true - openai@4.78.0: - resolution: {integrity: sha512-4rRsKkx++5m1zayxkryVH+K/z91cv1sRbaNJAhSQjZiSCQOR7eaM8KpfIssXrS9Hlpta7+VcuO/fi57pW8xGjA==} + openai@4.78.1: + resolution: {integrity: sha512-drt0lHZBd2lMyORckOXFPQTmnGLWSLt8VK0W9BhOKWpMFBEoHMoz5gxMPmVq5icp+sOrsbMnsmZTVHUlKvD1Ow==} hasBin: true peerDependencies: zod: ^3.23.8 @@ -17259,6 +17782,10 @@ packages: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} + pkijs@3.2.4: + resolution: {integrity: sha512-Et9V5QpvBilPFgagJcaKBqXjKrrgF5JL2mSDELk1vvbOTt4fuBhSSsGn9Tcz0TQTfS5GCpXQ31Whrpqeqp0VRg==} + engines: {node: '>=12.0.0'} + platform@1.3.6: resolution: {integrity: sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==} @@ -18282,6 +18809,10 @@ packages: resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} engines: {node: '>=0.6'} + quais@1.0.0-alpha.25: + resolution: {integrity: sha512-dohlLbU55+7VYwmP2dENQ9ptPBBY+Rw6glRfgdMv5ClimQGfxF3DQHWe1G+qwWdyM9avkdoyBwBkw9BHwph/vA==} + engines: {node: '>=17.0.0'} + query-string@7.1.3: resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} engines: {node: '>=6'} @@ -19012,6 +19543,9 @@ packages: secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + secure-random@1.1.2: + resolution: {integrity: sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ==} + seedrandom@3.0.5: resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==} @@ -19209,6 +19743,9 @@ packages: simple-git@3.27.0: resolution: {integrity: sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==} + simple-jsonrpc-js@1.2.0: + resolution: {integrity: sha512-owkAmh7fjSYBUZVestTPCZMKYQvNiDejqZ/iGfVaKs1nrC1ZBDA3qGraf94+JNFJmu536Tb8oPe8PSPuq7GO6Q==} + simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} @@ -19305,6 +19842,10 @@ packages: resolution: {integrity: sha512-0xtkGhWCC9MGt/EzgnvbbbKhqWjl1+/rncmhTh5qCpbYguXh6S/qwePfv/JQ8jePXXmqingylxoC49pCkSPIbA==} engines: {node: '>= 6.3.0'} + sort-json@2.0.1: + resolution: {integrity: sha512-s8cs2bcsQCzo/P2T/uoU6Js4dS/jnX8+4xunziNoq9qmSpZNCrRIAIvp4avsz0ST18HycV4z/7myJ7jsHWB2XQ==} + hasBin: true + sort-keys@2.0.0: resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} engines: {node: '>=4'} @@ -19971,6 +20512,10 @@ packages: engines: {node: '>= 12.10.0', npm: '>= 6.12.0', yarn: '>= 1.20.0'} hasBin: true + tinypool@0.7.0: + resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + engines: {node: '>=14.0.0'} + tinypool@0.8.4: resolution: {integrity: sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==} engines: {node: '>=14.0.0'} @@ -20788,6 +21333,10 @@ packages: resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} engines: {node: '>=6.14.2'} + utf-8-validate@6.0.5: + resolution: {integrity: sha512-EYZR+OpIXp9Y1eG1iueg8KRsY8TuT8VNgnanZ0uA3STqhHQTLwbl+WX76/9X5OY12yQubymBpaBSmMPkSTQcKA==} + engines: {node: '>=6.14.2'} + utf8@3.0.0: resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} @@ -20822,6 +21371,10 @@ packages: resolution: {integrity: sha512-d0z310fCWv5dJwnX1Y/MncBAqGMKEzlBb1AOf7z9K8ALnd0utBX/msg/fA0+sbyN1ihbMsLhrBlnl1ak7Wa0rg==} hasBin: true + uuid@11.0.5: + resolution: {integrity: sha512-508e6IcKLrhxKdBbcA2b4KQZlLVp2+J5UwQ6F7Drckkc5N9ZJwFa4TgWtsww9UG8fGHbm6gbV19TdM5pQ4GaIA==} + hasBin: true + uuid@3.4.0: resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. @@ -20881,6 +21434,9 @@ packages: varint@5.0.2: resolution: {integrity: sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==} + varint@6.0.0: + resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} + varuint-bitcoin@2.0.0: resolution: {integrity: sha512-6QZbU/rHO2ZQYpWFDALCDSRsXbAs1VOEmXAxtbtjLtKuMJ/FQ8YbhfxlaiKv5nklci0M6lZtlZyxo9Q+qNnyog==} @@ -20918,6 +21474,11 @@ packages: typescript: optional: true + vite-node@0.34.6: + resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} + engines: {node: '>=v14.18.0'} + hasBin: true + vite-node@1.1.3: resolution: {integrity: sha512-BLSO72YAkIUuNrOx+8uznYICJfTEbvBAmWClY3hpath5+h1mbPS5OMn42lrTxXuyCazVyZoDkSRnju78GiVCqA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -20948,6 +21509,14 @@ packages: peerDependencies: vite: '>=2.0.0' + vite-tsconfig-paths@4.3.2: + resolution: {integrity: sha512-0Vd/a6po6Q+86rPlntHye7F31zA2URZMbH8M3saAZ/xR9QoGN/L21bxEGfXdWmFdNkqPpRdxFT7nmNe12e9/uA==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + vite-tsconfig-paths@5.1.4: resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} peerDependencies: @@ -21027,6 +21596,37 @@ packages: yaml: optional: true + vitest@0.34.6: + resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + vitest@1.1.3: resolution: {integrity: sha512-2l8om1NOkiA90/Y207PsEvJLYygddsOyr81wLQ20Ra8IlLKbyQncWsGZjnbkyG2KwwuTXLQjEPOJuxGMG8qJBQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -21241,10 +21841,86 @@ packages: web-vitals@3.5.2: resolution: {integrity: sha512-c0rhqNcHXRkY/ogGDJQxZ9Im9D19hDihbzSQJrsioex+KnFgmMzBiy57Z1EjkhX/+OjyBpclDCzz2ITtjokFmg==} + web3-core@4.7.1: + resolution: {integrity: sha512-9KSeASCb/y6BG7rwhgtYC4CvYY66JfkmGNEYb7q1xgjt9BWfkf09MJPaRyoyT5trdOxYDHkT9tDlypvQWaU8UQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-errors@1.3.1: + resolution: {integrity: sha512-w3NMJujH+ZSW4ltIZZKtdbkbyQEvBzyp3JRn59Ckli0Nz4VMsVq8aF1bLWM7A2kuQ+yVEm3ySeNU+7mSRwx7RQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-abi@4.4.1: + resolution: {integrity: sha512-60ecEkF6kQ9zAfbTY04Nc9q4eEYM0++BySpGi8wZ2PD1tw/c0SDvsKhV6IKURxLJhsDlb08dATc3iD6IbtWJmg==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-accounts@4.3.1: + resolution: {integrity: sha512-rTXf+H9OKze6lxi7WMMOF1/2cZvJb2AOnbNQxPhBDssKOllAMzLhg1FbZ4Mf3lWecWfN6luWgRhaeSqO1l+IBQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-contract@4.7.2: + resolution: {integrity: sha512-3ETqs2pMNPEAc7BVY/C3voOhTUeJdkf2aM3X1v+edbngJLHAxbvxKpOqrcO0cjXzC4uc2Q8Zpf8n8zT5r0eLnA==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-ens@4.4.0: + resolution: {integrity: sha512-DeyVIS060hNV9g8dnTx92syqvgbvPricE3MerCxe/DquNZT3tD8aVgFfq65GATtpCgDDJffO2bVeHp3XBemnSQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-iban@4.0.7: + resolution: {integrity: sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-personal@4.1.0: + resolution: {integrity: sha512-RFN83uMuvA5cu1zIwwJh9A/bAj0OBxmGN3tgx19OD/9ygeUZbifOL06jgFzN0t+1ekHqm3DXYQM8UfHpXi7yDQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth@4.11.1: + resolution: {integrity: sha512-q9zOkzHnbLv44mwgLjLXuyqszHuUgZWsQayD2i/rus2uk0G7hMn11bE2Q3hOVnJS4ws4VCtUznlMxwKQ+38V2w==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-net@4.1.0: + resolution: {integrity: sha512-WWmfvHVIXWEoBDWdgKNYKN8rAy6SgluZ0abyRyXOL3ESr7ym7pKWbfP4fjApIHlYTh8tNqkrdPfM4Dyi6CA0SA==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-providers-http@4.2.0: + resolution: {integrity: sha512-IPMnDtHB7dVwaB7/mMxAZzyq7d5ezfO1+Vw0bNfAeIi7gaDlJiggp85SdyAfOgov8AMUA/dyiY72kQ0KmjXKvQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-providers-ipc@4.0.7: + resolution: {integrity: sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-providers-ws@4.0.8: + resolution: {integrity: sha512-goJdgata7v4pyzHRsg9fSegUG4gVnHZSHODhNnn6J93ykHkBI1nz4fjlGpcQLUMi4jAMz6SHl9Ibzs2jj9xqPw==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-rpc-methods@1.3.0: + resolution: {integrity: sha512-/CHmzGN+IYgdBOme7PdqzF+FNeMleefzqs0LVOduncSaqsppeOEoskLXb2anSpzmQAP3xZJPaTrkQPWSJMORig==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-rpc-providers@1.0.0-rc.4: + resolution: {integrity: sha512-PXosCqHW0EADrYzgmueNHP3Y5jcSmSwH+Dkqvn7EYD0T2jcsdDAIHqk6szBiwIdhumM7gv9Raprsu/s/f7h1fw==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-types@1.10.0: + resolution: {integrity: sha512-0IXoaAFtFc8Yin7cCdQfB9ZmjafrbP6BO0f0KT/khMhXKUpoJ6yShrVhiNpyRBo8QQjuOagsWzwSK2H49I7sbw==} + engines: {node: '>=14', npm: '>=6.12.0'} + web3-utils@1.10.4: resolution: {integrity: sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==} engines: {node: '>=8.0.0'} + web3-utils@4.3.3: + resolution: {integrity: sha512-kZUeCwaQm+RNc2Bf1V3BYbF29lQQKz28L0y+FA4G0lS8IxtJVGi5SeDTUkpwqqkdHHC7JcapPDnyyzJ1lfWlOw==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-validator@2.0.6: + resolution: {integrity: sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3@4.16.0: + resolution: {integrity: sha512-SgoMSBo6EsJ5GFCGar2E/pR2lcR/xmUSuQ61iK6yDqzxmm42aPPxSqZfJz2z/UCR6pk03u77pU8TGV6lgMDdIQ==} + engines: {node: '>=14.0.0', npm: '>=6.12.0'} + webauthn-p256@0.0.10: resolution: {integrity: sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA==} @@ -21631,6 +22307,12 @@ packages: zimmerframe@1.1.2: resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==} + zksync-ethers@6.15.3: + resolution: {integrity: sha512-AAFf5HKlkGpLRSE1CB8gBIlswbnWBPHD2ex4bcFG8GJFr1iQuq+LbMrisDm17jNR4Msi1WkNgIartS7nXcOrTg==} + engines: {node: '>=18.9.0'} + peerDependencies: + ethers: ^6.7.1 + zlibjs@0.3.1: resolution: {integrity: sha512-+J9RrgTKOmlxFSDHo0pI1xM6BLVUv+o0ZT9ANtCxGkjIVCCUdx9alUF8Gm+dGLKbkkkidWIHFDZHDMpfITt4+w==} @@ -21656,12 +22338,12 @@ packages: snapshots: - '@0glabs/0g-ts-sdk@0.2.1(bufferutil@4.0.9)(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10))(utf-8-validate@5.0.10)': + '@0glabs/0g-ts-sdk@0.2.1(bufferutil@4.0.9)(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))(utf-8-validate@6.0.5)': dependencies: '@ethersproject/bytes': 5.7.0 '@ethersproject/keccak256': 5.7.0 - ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) - open-jsonrpc-provider: 0.2.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) + open-jsonrpc-provider: 0.2.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - debug @@ -21715,6 +22397,12 @@ snapshots: '@ai-sdk/provider-utils': 1.0.22(zod@3.23.8) zod: 3.23.8 + '@ai-sdk/mistral@1.0.8(zod@3.23.8)': + dependencies: + '@ai-sdk/provider': 1.0.4 + '@ai-sdk/provider-utils': 2.0.7(zod@3.23.8) + zod: 3.23.8 + '@ai-sdk/openai@1.0.16(zod@3.24.1)': dependencies: '@ai-sdk/provider': 1.0.4 @@ -21880,6 +22568,40 @@ snapshots: transitivePeerDependencies: - zod + '@akashnetwork/akash-api@1.4.0(@grpc/grpc-js@1.12.5)': + dependencies: + '@grpc/grpc-js': 1.12.5 + rxjs: 7.8.1 + + '@akashnetwork/akashjs@0.10.1(@grpc/grpc-js@1.12.5)(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@akashnetwork/akash-api': 1.4.0(@grpc/grpc-js@1.12.5) + '@cosmjs/amino': 0.32.4 + '@cosmjs/launchpad': 0.27.1 + '@cosmjs/proto-signing': 0.32.4 + '@cosmjs/stargate': 0.32.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@cosmjs/tendermint-rpc': 0.32.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) + asn1js: 2.4.0 + atob: 2.1.2 + axios: 0.24.0 + console-browserify: 1.2.0 + js-yaml: 4.1.0 + json-stable-stringify: 1.2.1 + jsrsasign: 11.1.0 + keytar: 7.9.0 + node-fetch: 2.7.0(encoding@0.1.13) + pkijs: 3.2.4 + process: 0.11.10 + pvutils: 1.1.3 + simple-jsonrpc-js: 1.2.0 + sort-json: 2.0.1 + transitivePeerDependencies: + - '@grpc/grpc-js' + - bufferutil + - debug + - encoding + - utf-8-validate + '@algolia/autocomplete-core@1.17.7(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)(search-insights@2.17.3)': dependencies: '@algolia/autocomplete-plugin-algolia-insights': 1.17.7(@algolia/client-search@5.19.0)(algoliasearch@5.19.0)(search-insights@2.17.3) @@ -22158,9 +22880,16 @@ snapshots: '@csstools/css-tokenizer': 3.0.3 lru-cache: 11.0.2 - '@avnu/avnu-sdk@2.1.1(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10))(qs@6.13.1)(starknet@6.18.0(encoding@0.1.13))': + '@asterai/client@0.1.6': dependencies: - ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) + buffer: 6.0.3 + eventsource-parser: 2.0.1 + protobufjs: 7.4.0 + typescript: 5.6.3 + + '@avnu/avnu-sdk@2.1.1(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))(qs@6.13.1)(starknet@6.18.0(encoding@0.1.13))': + dependencies: + ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) qs: 6.13.1 starknet: 6.18.0(encoding@0.1.13) @@ -22833,20 +23562,20 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.26.3': {} + '@babel/compat-data@7.26.5': {} '@babel/core@7.26.0': dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.3 - '@babel/helper-compilation-targets': 7.25.9 + '@babel/generator': 7.26.5 + '@babel/helper-compilation-targets': 7.26.5 '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) '@babel/helpers': 7.26.0 - '@babel/parser': 7.26.3 + '@babel/parser': 7.26.5 '@babel/template': 7.25.9 - '@babel/traverse': 7.26.4 - '@babel/types': 7.26.3 + '@babel/traverse': 7.26.5 + '@babel/types': 7.26.5 convert-source-map: 2.0.0 debug: 4.4.0(supports-color@5.5.0) gensync: 1.0.0-beta.2 @@ -22855,21 +23584,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/generator@7.26.3': + '@babel/generator@7.26.5': dependencies: - '@babel/parser': 7.26.3 - '@babel/types': 7.26.3 + '@babel/parser': 7.26.5 + '@babel/types': 7.26.5 '@jridgewell/gen-mapping': 0.3.8 '@jridgewell/trace-mapping': 0.3.25 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.25.9': dependencies: - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 - '@babel/helper-compilation-targets@7.25.9': + '@babel/helper-compilation-targets@7.26.5': dependencies: - '@babel/compat-data': 7.26.3 + '@babel/compat-data': 7.26.5 '@babel/helper-validator-option': 7.25.9 browserslist: 4.24.4 lru-cache: 5.1.1 @@ -22881,9 +23610,9 @@ snapshots: '@babel/helper-annotate-as-pure': 7.25.9 '@babel/helper-member-expression-to-functions': 7.25.9 '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.0) '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 - '@babel/traverse': 7.26.4 + '@babel/traverse': 7.26.5 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -22898,8 +23627,8 @@ snapshots: '@babel/helper-define-polyfill-provider@0.6.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.26.5 debug: 4.4.0(supports-color@5.5.0) lodash.debounce: 4.0.8 resolve: 1.22.10 @@ -22908,15 +23637,15 @@ snapshots: '@babel/helper-member-expression-to-functions@7.25.9': dependencies: - '@babel/traverse': 7.26.4 - '@babel/types': 7.26.3 + '@babel/traverse': 7.26.5 + '@babel/types': 7.26.5 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.25.9': dependencies: - '@babel/traverse': 7.26.4 - '@babel/types': 7.26.3 + '@babel/traverse': 7.26.5 + '@babel/types': 7.26.5 transitivePeerDependencies: - supports-color @@ -22925,38 +23654,38 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.26.4 + '@babel/traverse': 7.26.5 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.25.9': dependencies: - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 - '@babel/helper-plugin-utils@7.25.9': {} + '@babel/helper-plugin-utils@7.26.5': {} '@babel/helper-remap-async-to-generator@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 '@babel/helper-wrap-function': 7.25.9 - '@babel/traverse': 7.26.4 + '@babel/traverse': 7.26.5 transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.25.9(@babel/core@7.26.0)': + '@babel/helper-replace-supers@7.26.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-member-expression-to-functions': 7.25.9 '@babel/helper-optimise-call-expression': 7.25.9 - '@babel/traverse': 7.26.4 + '@babel/traverse': 7.26.5 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.25.9': dependencies: - '@babel/traverse': 7.26.4 - '@babel/types': 7.26.3 + '@babel/traverse': 7.26.5 + '@babel/types': 7.26.5 transitivePeerDependencies: - supports-color @@ -22969,42 +23698,42 @@ snapshots: '@babel/helper-wrap-function@7.25.9': dependencies: '@babel/template': 7.25.9 - '@babel/traverse': 7.26.4 - '@babel/types': 7.26.3 + '@babel/traverse': 7.26.5 + '@babel/types': 7.26.5 transitivePeerDependencies: - supports-color '@babel/helpers@7.26.0': dependencies: '@babel/template': 7.25.9 - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 - '@babel/parser@7.26.3': + '@babel/parser@7.26.5': dependencies: - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.26.4 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/traverse': 7.26.5 transitivePeerDependencies: - supports-color '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: @@ -23013,8 +23742,8 @@ snapshots: '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.26.4 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/traverse': 7.26.5 transitivePeerDependencies: - supports-color @@ -23025,115 +23754,115 @@ snapshots: '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-async-generator-functions@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) - '@babel/traverse': 7.26.4 + '@babel/traverse': 7.26.5 transitivePeerDependencies: - supports-color @@ -23141,26 +23870,26 @@ snapshots: dependencies: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.25.9(@babel/core@7.26.0)': + '@babel/plugin-transform-block-scoped-functions@7.26.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-block-scoping@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-class-properties@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 transitivePeerDependencies: - supports-color @@ -23168,7 +23897,7 @@ snapshots: dependencies: '@babel/core': 7.26.0 '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 transitivePeerDependencies: - supports-color @@ -23176,10 +23905,10 @@ snapshots: dependencies: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) - '@babel/traverse': 7.26.4 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.0) + '@babel/traverse': 7.26.5 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -23187,50 +23916,50 @@ snapshots: '@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/template': 7.25.9 '@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-dotall-regex@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-duplicate-keys@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-dynamic-import@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-exponentiation-operator@7.26.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-export-namespace-from@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-for-of@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 transitivePeerDependencies: - supports-color @@ -23238,37 +23967,37 @@ snapshots: '@babel/plugin-transform-function-name@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/traverse': 7.26.4 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/traverse': 7.26.5 transitivePeerDependencies: - supports-color '@babel/plugin-transform-json-strings@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-literals@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-logical-assignment-operators@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-member-expression-literals@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-modules-amd@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 transitivePeerDependencies: - supports-color @@ -23276,7 +24005,7 @@ snapshots: dependencies: '@babel/core': 7.26.0 '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 transitivePeerDependencies: - supports-color @@ -23284,9 +24013,9 @@ snapshots: dependencies: '@babel/core': 7.26.0 '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-validator-identifier': 7.25.9 - '@babel/traverse': 7.26.4 + '@babel/traverse': 7.26.5 transitivePeerDependencies: - supports-color @@ -23294,7 +24023,7 @@ snapshots: dependencies: '@babel/core': 7.26.0 '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 transitivePeerDependencies: - supports-color @@ -23302,47 +24031,47 @@ snapshots: dependencies: '@babel/core': 7.26.0 '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-new-target@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-transform-nullish-coalescing-operator@7.25.9(@babel/core@7.26.0)': + '@babel/plugin-transform-nullish-coalescing-operator@7.26.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-numeric-separator@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-object-rest-spread@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-object-super@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-replace-supers': 7.25.9(@babel/core@7.26.0) + '@babel/helper-plugin-utils': 7.26.5 + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.26.0) transitivePeerDependencies: - supports-color '@babel/plugin-transform-optional-catch-binding@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-optional-chaining@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 transitivePeerDependencies: - supports-color @@ -23350,13 +24079,13 @@ snapshots: '@babel/plugin-transform-parameters@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-private-methods@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 transitivePeerDependencies: - supports-color @@ -23365,24 +24094,24 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 transitivePeerDependencies: - supports-color '@babel/plugin-transform-property-literals@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-react-constant-elements@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-react-display-name@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-react-jsx-development@7.25.9(@babel/core@7.26.0)': dependencies: @@ -23396,9 +24125,9 @@ snapshots: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 transitivePeerDependencies: - supports-color @@ -23406,30 +24135,30 @@ snapshots: dependencies: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-regenerator@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 regenerator-transform: 0.15.2 '@babel/plugin-transform-regexp-modifiers@7.26.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-reserved-words@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-runtime@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-module-imports': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 babel-plugin-polyfill-corejs2: 0.4.12(@babel/core@7.26.0) babel-plugin-polyfill-corejs3: 0.10.6(@babel/core@7.26.0) babel-plugin-polyfill-regenerator: 0.6.3(@babel/core@7.26.0) @@ -23440,12 +24169,12 @@ snapshots: '@babel/plugin-transform-shorthand-properties@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-spread@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 transitivePeerDependencies: - supports-color @@ -23453,24 +24182,24 @@ snapshots: '@babel/plugin-transform-sticky-regex@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-template-literals@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-typeof-symbol@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 - '@babel/plugin-transform-typescript@7.26.3(@babel/core@7.26.0)': + '@babel/plugin-transform-typescript@7.26.5(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-annotate-as-pure': 7.25.9 '@babel/helper-create-class-features-plugin': 7.25.9(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) transitivePeerDependencies: @@ -23479,32 +24208,32 @@ snapshots: '@babel/plugin-transform-unicode-escapes@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-unicode-property-regex@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-unicode-regex@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/plugin-transform-unicode-sets-regex@7.25.9(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.26.0) - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/preset-env@7.26.0(@babel/core@7.26.0)': dependencies: - '@babel/compat-data': 7.26.3 + '@babel/compat-data': 7.26.5 '@babel/core': 7.26.0 - '@babel/helper-compilation-targets': 7.25.9 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-validator-option': 7.25.9 '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.9(@babel/core@7.26.0) '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.9(@babel/core@7.26.0) @@ -23518,7 +24247,7 @@ snapshots: '@babel/plugin-transform-arrow-functions': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-async-generator-functions': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-async-to-generator': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-block-scoped-functions': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-block-scoped-functions': 7.26.5(@babel/core@7.26.0) '@babel/plugin-transform-block-scoping': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-class-properties': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-class-static-block': 7.26.0(@babel/core@7.26.0) @@ -23543,7 +24272,7 @@ snapshots: '@babel/plugin-transform-modules-umd': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-named-capturing-groups-regex': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-new-target': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-nullish-coalescing-operator': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.26.5(@babel/core@7.26.0) '@babel/plugin-transform-numeric-separator': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-object-rest-spread': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-object-super': 7.25.9(@babel/core@7.26.0) @@ -23577,14 +24306,14 @@ snapshots: '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/types': 7.26.3 + '@babel/helper-plugin-utils': 7.26.5 + '@babel/types': 7.26.5 esutils: 2.0.3 '@babel/preset-react@7.26.3(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-validator-option': 7.25.9 '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) @@ -23596,11 +24325,11 @@ snapshots: '@babel/preset-typescript@7.26.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@babel/helper-validator-option': 7.25.9 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-modules-commonjs': 7.26.3(@babel/core@7.26.0) - '@babel/plugin-transform-typescript': 7.26.3(@babel/core@7.26.0) + '@babel/plugin-transform-typescript': 7.26.5(@babel/core@7.26.0) transitivePeerDependencies: - supports-color @@ -23613,50 +24342,54 @@ snapshots: dependencies: regenerator-runtime: 0.14.1 - '@babel/standalone@7.26.4': {} + '@babel/standalone@7.26.5': {} '@babel/template@7.25.9': dependencies: '@babel/code-frame': 7.26.2 - '@babel/parser': 7.26.3 - '@babel/types': 7.26.3 + '@babel/parser': 7.26.5 + '@babel/types': 7.26.5 - '@babel/traverse@7.26.4': + '@babel/traverse@7.26.5': dependencies: '@babel/code-frame': 7.26.2 - '@babel/generator': 7.26.3 - '@babel/parser': 7.26.3 + '@babel/generator': 7.26.5 + '@babel/parser': 7.26.5 '@babel/template': 7.25.9 - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 debug: 4.4.0(supports-color@5.5.0) globals: 11.12.0 transitivePeerDependencies: - supports-color - '@babel/types@7.26.3': + '@babel/types@7.26.5': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 '@bcoe/v8-coverage@0.2.3': {} - '@bigmi/core@0.0.4(bitcoinjs-lib@7.0.0-rc.0(typescript@5.7.3))(bs58@6.0.0)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1))': + '@bigmi/core@0.0.4(bitcoinjs-lib@7.0.0-rc.0(typescript@5.7.3))(bs58@6.0.0)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1))': dependencies: '@noble/hashes': 1.7.0 bech32: 2.0.0 bitcoinjs-lib: 7.0.0-rc.0(typescript@5.7.3) bs58: 6.0.0 - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) - '@binance/connector@3.6.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@binance/connector@3.6.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: axios: 1.7.9(debug@4.4.0) - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - debug - utf-8-validate + '@bitcoinerlab/secp256k1@1.2.0': + dependencies: + '@noble/curves': 1.8.0 + '@bonfida/sns-records@0.0.1(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) @@ -23685,6 +24418,8 @@ snapshots: '@braintree/sanitize-url@7.1.1': {} + '@brandonblack/musig@0.0.1-alpha.1': {} + '@cfworker/json-schema@4.1.0': {} '@chain-registry/types@0.50.47': {} @@ -23771,7 +24506,7 @@ snapshots: transitivePeerDependencies: - encoding - '@coinbase/coinbase-sdk@0.10.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.24.1)': + '@coinbase/coinbase-sdk@0.10.0(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@6.0.5)(zod@3.24.1)': dependencies: '@scure/bip32': 1.6.1 abitype: 1.0.8(typescript@5.6.3)(zod@3.24.1) @@ -23782,10 +24517,10 @@ snapshots: bip39: 3.1.0 decimal.js: 10.4.3 dotenv: 16.4.7 - ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) node-jose: 2.2.0 secp256k1: 5.0.1 - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.24.1) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@6.0.5)(zod@3.24.1) transitivePeerDependencies: - bufferutil - debug @@ -23795,7 +24530,7 @@ snapshots: '@coinbase/wallet-sdk@4.2.4': dependencies: - '@noble/hashes': 1.6.1 + '@noble/hashes': 1.7.0 clsx: 1.2.1 eventemitter3: 5.0.1 preact: 10.25.4 @@ -24010,6 +24745,28 @@ snapshots: - encoding - utf-8-validate + '@coral-xyz/anchor@0.30.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5)': + dependencies: + '@coral-xyz/anchor-errors': 0.30.1 + '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.95.8(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5)) + '@noble/hashes': 1.7.0 + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + bn.js: 5.2.1 + bs58: 4.0.1 + buffer-layout: 1.2.2 + camelcase: 6.3.0 + cross-fetch: 3.2.0(encoding@0.1.13) + crypto-hash: 1.3.0 + eventemitter3: 4.0.7 + pako: 2.1.0 + snake-case: 3.0.4 + superstruct: 0.15.5 + toml: 3.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + '@coral-xyz/borsh@0.26.0(@solana/web3.js@1.95.8(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))': dependencies: '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) @@ -24040,6 +24797,26 @@ snapshots: bn.js: 5.2.1 buffer-layout: 1.2.2 + '@coral-xyz/borsh@0.30.1(@solana/web3.js@1.95.8(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5))': + dependencies: + '@solana/web3.js': 1.95.8(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + bn.js: 5.2.1 + buffer-layout: 1.2.2 + + '@cosmjs/amino@0.27.1': + dependencies: + '@cosmjs/crypto': 0.27.1 + '@cosmjs/encoding': 0.27.1 + '@cosmjs/math': 0.27.1 + '@cosmjs/utils': 0.27.1 + + '@cosmjs/amino@0.31.3': + dependencies: + '@cosmjs/crypto': 0.31.3 + '@cosmjs/encoding': 0.31.3 + '@cosmjs/math': 0.31.3 + '@cosmjs/utils': 0.31.3 + '@cosmjs/amino@0.32.2': dependencies: '@cosmjs/crypto': 0.32.4 @@ -24071,6 +24848,29 @@ snapshots: - debug - utf-8-validate + '@cosmjs/crypto@0.27.1': + dependencies: + '@cosmjs/encoding': 0.27.1 + '@cosmjs/math': 0.27.1 + '@cosmjs/utils': 0.27.1 + bip39: 3.1.0 + bn.js: 5.2.1 + elliptic: 6.6.1 + js-sha3: 0.8.0 + libsodium-wrappers: 0.7.15 + ripemd160: 2.0.2 + sha.js: 2.4.11 + + '@cosmjs/crypto@0.31.3': + dependencies: + '@cosmjs/encoding': 0.31.3 + '@cosmjs/math': 0.31.3 + '@cosmjs/utils': 0.31.3 + '@noble/hashes': 1.7.0 + bn.js: 5.2.1 + elliptic: 6.6.1 + libsodium-wrappers-sumo: 0.7.15 + '@cosmjs/crypto@0.32.4': dependencies: '@cosmjs/encoding': 0.32.4 @@ -24081,21 +24881,68 @@ snapshots: elliptic: 6.6.1 libsodium-wrappers-sumo: 0.7.15 + '@cosmjs/encoding@0.27.1': + dependencies: + base64-js: 1.5.1 + bech32: 1.1.4 + readonly-date: 1.0.0 + + '@cosmjs/encoding@0.31.3': + dependencies: + base64-js: 1.5.1 + bech32: 1.1.4 + readonly-date: 1.0.0 + '@cosmjs/encoding@0.32.4': dependencies: base64-js: 1.5.1 bech32: 1.1.4 readonly-date: 1.0.0 + '@cosmjs/json-rpc@0.31.3': + dependencies: + '@cosmjs/stream': 0.31.3 + xstream: 11.14.0 + '@cosmjs/json-rpc@0.32.4': dependencies: '@cosmjs/stream': 0.32.4 xstream: 11.14.0 + '@cosmjs/launchpad@0.27.1': + dependencies: + '@cosmjs/amino': 0.27.1 + '@cosmjs/crypto': 0.27.1 + '@cosmjs/encoding': 0.27.1 + '@cosmjs/math': 0.27.1 + '@cosmjs/utils': 0.27.1 + axios: 0.21.4 + fast-deep-equal: 3.1.3 + transitivePeerDependencies: + - debug + + '@cosmjs/math@0.27.1': + dependencies: + bn.js: 5.2.1 + + '@cosmjs/math@0.31.3': + dependencies: + bn.js: 5.2.1 + '@cosmjs/math@0.32.4': dependencies: bn.js: 5.2.1 + '@cosmjs/proto-signing@0.31.3': + dependencies: + '@cosmjs/amino': 0.31.3 + '@cosmjs/crypto': 0.31.3 + '@cosmjs/encoding': 0.31.3 + '@cosmjs/math': 0.31.3 + '@cosmjs/utils': 0.31.3 + cosmjs-types: 0.8.0 + long: 4.0.0 + '@cosmjs/proto-signing@0.32.2': dependencies: '@cosmjs/amino': 0.32.2 @@ -24114,6 +24961,16 @@ snapshots: '@cosmjs/utils': 0.32.4 cosmjs-types: 0.9.0 + '@cosmjs/socket@0.31.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/stream': 0.31.3 + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@cosmjs/socket@0.32.4(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@cosmjs/stream': 0.32.4 @@ -24124,6 +24981,25 @@ snapshots: - bufferutil - utf-8-validate + '@cosmjs/stargate@0.31.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@confio/ics23': 0.6.8 + '@cosmjs/amino': 0.31.3 + '@cosmjs/encoding': 0.31.3 + '@cosmjs/math': 0.31.3 + '@cosmjs/proto-signing': 0.31.3 + '@cosmjs/stream': 0.31.3 + '@cosmjs/tendermint-rpc': 0.31.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@cosmjs/utils': 0.31.3 + cosmjs-types: 0.8.0 + long: 4.0.0 + protobufjs: 6.11.4 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + '@cosmjs/stargate@0.32.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@confio/ics23': 0.6.8 @@ -24158,10 +25034,31 @@ snapshots: - debug - utf-8-validate + '@cosmjs/stream@0.31.3': + dependencies: + xstream: 11.14.0 + '@cosmjs/stream@0.32.4': dependencies: xstream: 11.14.0 + '@cosmjs/tendermint-rpc@0.31.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/crypto': 0.31.3 + '@cosmjs/encoding': 0.31.3 + '@cosmjs/json-rpc': 0.31.3 + '@cosmjs/math': 0.31.3 + '@cosmjs/socket': 0.31.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@cosmjs/stream': 0.31.3 + '@cosmjs/utils': 0.31.3 + axios: 0.21.4 + readonly-date: 1.0.0 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + '@cosmjs/tendermint-rpc@0.32.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@cosmjs/crypto': 0.32.4 @@ -24196,6 +25093,10 @@ snapshots: - debug - utf-8-validate + '@cosmjs/utils@0.27.1': {} + + '@cosmjs/utils@0.31.3': {} + '@cosmjs/utils@0.32.4': {} '@cosmology/lcd@0.13.5': @@ -24464,14 +25365,14 @@ snapshots: dependencies: dayjs: 1.11.13 - '@deepgram/sdk@3.9.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@deepgram/sdk@3.9.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5)': dependencies: '@deepgram/captions': 1.2.0 '@types/node': 18.19.70 cross-fetch: 3.2.0(encoding@0.1.13) deepmerge: 4.3.1 events: 3.3.0 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - encoding @@ -24571,13 +25472,13 @@ snapshots: '@discordjs/util@1.1.1': {} - '@discordjs/voice@0.17.0(@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(bufferutil@4.0.9)(ffmpeg-static@5.2.0)(utf-8-validate@5.0.10)': + '@discordjs/voice@0.17.0(@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(bufferutil@4.0.9)(ffmpeg-static@5.2.0)(utf-8-validate@6.0.5)': dependencies: '@types/ws': 8.5.13 discord-api-types: 0.37.83 prism-media: 1.3.5(@discordjs/opus@https://codeload.github.com/discordjs/opus/tar.gz/31da49d8d2cc6c5a2ab1bfd332033ff7d5f9fb02(encoding@0.1.13))(ffmpeg-static@5.2.0) tslib: 2.8.1 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - '@discordjs/opus' - bufferutil @@ -24586,7 +25487,7 @@ snapshots: - opusscript - utf-8-validate - '@discordjs/ws@1.1.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@discordjs/ws@1.1.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: '@discordjs/collection': 2.1.1 '@discordjs/rest': 2.4.0 @@ -24596,7 +25497,7 @@ snapshots: '@vladfrangu/async_event_emitter': 2.4.6 discord-api-types: 0.37.83 tslib: 2.8.1 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -24622,7 +25523,7 @@ snapshots: '@docusaurus/babel@3.6.3(@swc/core@1.10.7(@swc/helpers@0.5.15))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3)': dependencies: '@babel/core': 7.26.0 - '@babel/generator': 7.26.3 + '@babel/generator': 7.26.5 '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.26.0) '@babel/plugin-transform-runtime': 7.25.9(@babel/core@7.26.0) '@babel/preset-env': 7.26.0(@babel/core@7.26.0) @@ -24630,7 +25531,7 @@ snapshots: '@babel/preset-typescript': 7.26.0(@babel/core@7.26.0) '@babel/runtime': 7.26.0 '@babel/runtime-corejs3': 7.26.0 - '@babel/traverse': 7.26.4 + '@babel/traverse': 7.26.5 '@docusaurus/logger': 3.6.3 '@docusaurus/utils': 3.6.3(@swc/core@1.10.7(@swc/helpers@0.5.15))(acorn@8.14.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.7.3) babel-plugin-dynamic-import-node: 2.3.3 @@ -25893,6 +26794,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@eslint/core@0.10.0': + dependencies: + '@types/json-schema': 7.0.15 + '@eslint/core@0.9.1': dependencies: '@types/json-schema': 7.0.15 @@ -25933,12 +26838,15 @@ snapshots: '@eslint/object-schema@2.1.5': {} - '@eslint/plugin-kit@0.2.4': + '@eslint/plugin-kit@0.2.5': dependencies: + '@eslint/core': 0.10.0 levn: 0.4.1 '@ethereumjs/rlp@4.0.1': {} + '@ethereumjs/rlp@5.0.2': {} + '@ethereumjs/util@8.1.0': dependencies: '@ethereumjs/rlp': 4.0.1 @@ -26108,6 +27016,32 @@ snapshots: - bufferutil - utf-8-validate + '@ethersproject/providers@5.7.2(bufferutil@4.0.9)(utf-8-validate@6.0.5)': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + bech32: 1.1.4 + ws: 7.4.6(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@ethersproject/random@5.7.0': dependencies: '@ethersproject/bytes': 5.7.0 @@ -26258,23 +27192,23 @@ snapshots: '@floating-ui/utils@0.2.9': {} - '@fuel-ts/abi-coder@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/abi-coder@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: - '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/errors': 0.97.2 - '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/interfaces': 0.97.2 '@fuel-ts/math': 0.97.2 - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) type-fest: 4.32.0 transitivePeerDependencies: - vitest - '@fuel-ts/abi-typegen@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/abi-typegen@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: '@fuel-ts/errors': 0.97.2 '@fuel-ts/interfaces': 0.97.2 - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/versions': 0.97.2 commander: 12.1.0 glob: 10.4.5 @@ -26285,18 +27219,18 @@ snapshots: transitivePeerDependencies: - vitest - '@fuel-ts/account@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/account@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: - '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/address': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/address': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/errors': 0.97.2 - '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/interfaces': 0.97.2 '@fuel-ts/math': 0.97.2 - '@fuel-ts/merkle': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/merkle': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/versions': 0.97.2 '@fuels/vm-asm': 0.58.2 '@noble/curves': 1.8.0 @@ -26309,30 +27243,30 @@ snapshots: - encoding - vitest - '@fuel-ts/address@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/address@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: - '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/errors': 0.97.2 '@fuel-ts/interfaces': 0.97.2 - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@noble/hashes': 1.7.0 bech32: 2.0.0 transitivePeerDependencies: - vitest - '@fuel-ts/contract@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/contract@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: - '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/account': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/account': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/errors': 0.97.2 - '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/interfaces': 0.97.2 '@fuel-ts/math': 0.97.2 - '@fuel-ts/merkle': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/program': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/merkle': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/program': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/versions': 0.97.2 '@fuels/vm-asm': 0.58.2 ramda: 0.30.1 @@ -26340,12 +27274,12 @@ snapshots: - encoding - vitest - '@fuel-ts/crypto@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/crypto@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: '@fuel-ts/errors': 0.97.2 '@fuel-ts/interfaces': 0.97.2 '@fuel-ts/math': 0.97.2 - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@noble/hashes': 1.7.0 transitivePeerDependencies: - vitest @@ -26354,11 +27288,11 @@ snapshots: dependencies: '@fuel-ts/versions': 0.97.2 - '@fuel-ts/hasher@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/hasher@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: - '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/interfaces': 0.97.2 - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@noble/hashes': 1.7.0 transitivePeerDependencies: - vitest @@ -26371,78 +27305,78 @@ snapshots: '@types/bn.js': 5.1.6 bn.js: 5.2.1 - '@fuel-ts/merkle@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/merkle@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: - '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/math': 0.97.2 transitivePeerDependencies: - vitest - '@fuel-ts/program@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/program@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: - '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/account': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/address': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/account': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/address': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/errors': 0.97.2 '@fuel-ts/interfaces': 0.97.2 '@fuel-ts/math': 0.97.2 - '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuels/vm-asm': 0.58.2 ramda: 0.30.1 transitivePeerDependencies: - encoding - vitest - '@fuel-ts/recipes@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/recipes@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: - '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/abi-typegen': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/account': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/contract': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/abi-typegen': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/account': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/contract': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/interfaces': 0.97.2 - '@fuel-ts/program': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/program': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) transitivePeerDependencies: - encoding - vitest - '@fuel-ts/script@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/script@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: - '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/account': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/address': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/account': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/address': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/errors': 0.97.2 '@fuel-ts/interfaces': 0.97.2 '@fuel-ts/math': 0.97.2 - '@fuel-ts/program': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/program': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) transitivePeerDependencies: - encoding - vitest - '@fuel-ts/transactions@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/transactions@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: - '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/address': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/address': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/errors': 0.97.2 - '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/interfaces': 0.97.2 '@fuel-ts/math': 0.97.2 - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) transitivePeerDependencies: - vitest - '@fuel-ts/utils@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@fuel-ts/utils@0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: '@fuel-ts/errors': 0.97.2 '@fuel-ts/interfaces': 0.97.2 '@fuel-ts/math': 0.97.2 '@fuel-ts/versions': 0.97.2 fflate: 0.8.2 - vitest: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + vitest: 2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) '@fuel-ts/versions@0.97.2': dependencies: @@ -26457,10 +27391,10 @@ snapshots: '@shikijs/types': 1.26.1 '@shikijs/vscode-textmate': 10.0.1 - '@goat-sdk/adapter-vercel-ai@0.2.0(@goat-sdk/core@0.4.0)(ai@4.0.32(react@19.0.0)(zod@3.23.8))': + '@goat-sdk/adapter-vercel-ai@0.2.0(@goat-sdk/core@0.4.0)(ai@4.0.33(react@19.0.0)(zod@3.23.8))': dependencies: '@goat-sdk/core': 0.4.0 - ai: 4.0.32(react@19.0.0)(zod@3.23.8) + ai: 4.0.33(react@19.0.0)(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.3)(utf-8-validate@5.0.10)': @@ -26492,33 +27426,33 @@ snapshots: viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(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.3)(utf-8-validate@5.0.10)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.23.8))': + '@goat-sdk/plugin-erc20@0.2.2(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.23.8))': dependencies: '@goat-sdk/core': 0.4.0 - '@goat-sdk/wallet-evm': 0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10) - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.23.8) + '@goat-sdk/wallet-evm': 0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.23.8) zod: 3.23.8 transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - '@goat-sdk/plugin-kim@0.1.2(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.23.8))': + '@goat-sdk/plugin-kim@0.1.2(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.23.8))': dependencies: '@goat-sdk/core': 0.4.0 - '@goat-sdk/wallet-evm': 0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10) - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.23.8) + '@goat-sdk/wallet-evm': 0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.23.8) zod: 3.23.8 transitivePeerDependencies: - bufferutil - typescript - utf-8-validate - '@goat-sdk/wallet-evm@0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)': + '@goat-sdk/wallet-evm@0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)': dependencies: '@goat-sdk/core': 0.4.0 abitype: 1.0.8(typescript@5.7.3)(zod@3.23.8) - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.23.8) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.23.8) zod: 3.23.8 transitivePeerDependencies: - bufferutil @@ -26530,10 +27464,10 @@ snapshots: '@goat-sdk/core': 0.3.8(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@5.0.10) viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(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.3)(utf-8-validate@5.0.10))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(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.3)(utf-8-validate@6.0.5))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(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.3)(utf-8-validate@5.0.10) - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.23.8) + '@goat-sdk/wallet-evm': 0.2.0(@goat-sdk/core@0.4.0)(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.23.8) '@google-cloud/vertexai@1.9.2(encoding@0.1.13)': dependencies: @@ -26564,6 +27498,18 @@ snapshots: dependencies: graphql: 16.10.0 + '@grpc/grpc-js@1.12.5': + dependencies: + '@grpc/proto-loader': 0.7.13 + '@js-sdsl/ordered-map': 4.4.2 + + '@grpc/proto-loader@0.7.13': + dependencies: + lodash.camelcase: 4.3.0 + long: 5.2.4 + protobufjs: 7.4.0 + yargs: 17.7.2 + '@hapi/hoek@9.3.0': {} '@hapi/topo@5.1.0': @@ -26829,7 +27775,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -26842,14 +27788,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@18.19.70)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@18.19.70)(typescript@5.6.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -26870,21 +27816,21 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3))': + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + jest-config: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -26912,14 +27858,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3)) + jest-config: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -26944,7 +27890,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -26962,7 +27908,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.10.5 + '@types/node': 20.17.9 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -26984,7 +27930,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 22.10.5 + '@types/node': 20.17.9 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -27054,7 +28000,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -27085,6 +28031,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@js-sdsl/ordered-map@4.4.2': {} + '@jspm/core@2.1.0': {} '@kikobeats/time-span@1.0.5': {} @@ -27114,14 +28062,14 @@ snapshots: transitivePeerDependencies: - openai - '@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1))': + '@langchain/core@0.3.27(openai@4.78.1(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.15(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)) + langsmith: 0.2.15(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) mustache: 4.2.0 p-queue: 6.6.2 p-retry: 4.6.2 @@ -27142,33 +28090,33 @@ snapshots: - encoding optional: true - '@langchain/groq@0.1.3(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)': + '@langchain/groq@0.1.3(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)': dependencies: - '@langchain/core': 0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)) - '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13) + '@langchain/core': 0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) + '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.78.1(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.78.0(encoding@0.1.13)(zod@3.24.1)))': + '@langchain/langgraph-checkpoint@0.0.13(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))': dependencies: - '@langchain/core': 0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)) + '@langchain/core': 0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) uuid: 10.0.0 - '@langchain/langgraph-sdk@0.0.34': + '@langchain/langgraph-sdk@0.0.35': 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.78.0(encoding@0.1.13)(zod@3.24.1)))': + '@langchain/langgraph@0.2.39(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))': dependencies: - '@langchain/core': 0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)) - '@langchain/langgraph-checkpoint': 0.0.13(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1))) - '@langchain/langgraph-sdk': 0.0.34 + '@langchain/core': 0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) + '@langchain/langgraph-checkpoint': 0.0.13(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))) + '@langchain/langgraph-sdk': 0.0.35 uuid: 10.0.0 zod: 3.23.8 @@ -27176,17 +28124,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.78.0(encoding@0.1.13)(zod@3.23.8) + openai: 4.78.1(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.78.0(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)': + '@langchain/openai@0.3.16(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13)': dependencies: - '@langchain/core': 0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)) + '@langchain/core': 0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) js-tiktoken: 1.0.15 - openai: 4.78.0(encoding@0.1.13)(zod@3.23.8) + openai: 4.78.1(encoding@0.1.13)(zod@3.23.8) zod: 3.23.8 zod-to-json-schema: 3.24.1(zod@3.23.8) transitivePeerDependencies: @@ -27197,13 +28145,19 @@ 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.78.0(encoding@0.1.13)(zod@3.24.1)))': + '@langchain/textsplitters@0.1.0(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))': dependencies: - '@langchain/core': 0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)) + '@langchain/core': 0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) js-tiktoken: 1.0.15 '@leichtgewicht/ip-codec@2.0.5': {} + '@lens-network/sdk@0.0.0-canary-20241203140504(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5))(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1))(zksync-ethers@6.15.3(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)))': + optionalDependencies: + ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) + zksync-ethers: 6.15.3(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + '@lens-protocol/blockchain-bindings@0.10.2(@jest/globals@29.7.0)(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@ethersproject/abi': 5.7.0 @@ -27435,18 +28389,18 @@ snapshots: dependencies: '@lifi/types': 16.3.0 - '@lifi/sdk@3.4.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(typescript@5.7.3)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1))': + '@lifi/sdk@3.4.1(@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5))(typescript@5.7.3)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1))': dependencies: - '@bigmi/core': 0.0.4(bitcoinjs-lib@7.0.0-rc.0(typescript@5.7.3))(bs58@6.0.0)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1)) + '@bigmi/core': 0.0.4(bitcoinjs-lib@7.0.0-rc.0(typescript@5.7.3))(bs58@6.0.0)(viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1)) '@lifi/types': 16.3.0 '@noble/curves': 1.8.0 '@noble/hashes': 1.7.0 - '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/wallet-adapter-base': 0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5)) + '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) bech32: 2.0.0 bitcoinjs-lib: 7.0.0-rc.0(typescript@5.7.3) bs58: 6.0.0 - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) transitivePeerDependencies: - typescript @@ -27501,7 +28455,7 @@ snapshots: '@lit-protocol/misc-browser': 2.1.62(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@lit-protocol/types': 2.1.62 '@lit-protocol/uint8arrays': 2.1.62 - '@walletconnect/ethereum-provider': 2.17.3(@types/react@19.0.4)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.4.2)(react@19.0.0)(utf-8-validate@5.0.10) + '@walletconnect/ethereum-provider': 2.17.3(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) ethers: 5.7.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) lit-connect-modal: 0.1.11 lit-siwe: 1.1.8(@ethersproject/contracts@5.7.0)(@ethersproject/hash@5.7.0)(@ethersproject/providers@5.7.2(bufferutil@4.0.9)(utf-8-validate@5.0.10))(@ethersproject/wallet@5.7.0) @@ -27617,7 +28571,7 @@ snapshots: '@lit-protocol/nacl': 2.1.62 '@lit-protocol/types': 2.1.62 '@lit-protocol/uint8arrays': 2.1.62 - '@walletconnect/ethereum-provider': 2.17.3(@types/react@19.0.4)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.4.2)(react@19.0.0)(utf-8-validate@5.0.10) + '@walletconnect/ethereum-provider': 2.17.3(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) ethers: 5.7.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) jszip: 3.10.1 lit-connect-modal: 0.1.11 @@ -27681,6 +28635,22 @@ snapshots: - supports-color optional: true + '@massalabs/massa-web3@5.1.0': + dependencies: + '@noble/ed25519': 1.7.3 + '@noble/hashes': 1.7.0 + bs58check: 4.0.0 + decimal.js: 10.4.3 + dotenv: 16.4.7 + eventemitter3: 5.0.1 + lodash.isequal: 4.5.0 + secure-random: 1.1.2 + tslib: 2.8.1 + varint: 6.0.0 + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + '@mdx-js/mdx@3.1.0(acorn@8.14.0)': dependencies: '@types/estree': 1.0.6 @@ -28259,11 +29229,11 @@ snapshots: transitivePeerDependencies: - encoding - '@neynar/nodejs-sdk@2.8.0(bufferutil@4.0.9)(class-transformer@0.5.1)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1)': + '@neynar/nodejs-sdk@2.8.0(bufferutil@4.0.9)(class-transformer@0.5.1)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1)': dependencies: '@openapitools/openapi-generator-cli': 2.15.3(class-transformer@0.5.1)(encoding@0.1.13) semver: 7.6.3 - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) transitivePeerDependencies: - '@nestjs/microservices' - '@nestjs/platform-express' @@ -28864,15 +29834,15 @@ snapshots: - '@onflow/util-config' - supports-color - '@onflow/fcl-core@1.13.1(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(utf-8-validate@5.0.10)': + '@onflow/fcl-core@1.13.1(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(utf-8-validate@6.0.5)': dependencies: '@babel/runtime': 7.26.0 '@improbable-eng/grpc-web': 0.15.0(google-protobuf@3.21.4) '@onflow/config': 1.5.1 '@onflow/interaction': 0.0.11 '@onflow/rlp': 1.2.3 - '@onflow/sdk': 1.5.5(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@onflow/transport-http': 1.10.4(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@onflow/sdk': 1.5.5(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + '@onflow/transport-http': 1.10.4(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) '@onflow/types': 1.4.1 '@onflow/util-actor': 1.3.4 '@onflow/util-address': 1.2.3 @@ -28891,16 +29861,16 @@ snapshots: - supports-color - utf-8-validate - '@onflow/fcl-wc@5.5.1(@onflow/fcl-core@1.13.1(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(utf-8-validate@5.0.10))(@types/react@19.0.4)(bufferutil@4.0.9)(ioredis@5.4.2)(jiti@2.4.2)(postcss@8.4.49)(react@19.0.0)(tsx@4.19.2)(utf-8-validate@5.0.10)': + '@onflow/fcl-wc@5.5.1(@onflow/fcl-core@1.13.1(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(utf-8-validate@6.0.5))(@types/react@19.0.4)(bufferutil@4.0.9)(ioredis@5.4.2)(jiti@2.4.2)(postcss@8.4.49)(react@19.0.0)(tsx@4.19.2)(utf-8-validate@6.0.5)': dependencies: '@babel/runtime': 7.26.0 '@onflow/config': 1.5.1 - '@onflow/fcl-core': 1.13.1(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(utf-8-validate@5.0.10) + '@onflow/fcl-core': 1.13.1(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(utf-8-validate@6.0.5) '@onflow/util-invariant': 1.2.4 '@onflow/util-logger': 1.3.3 '@walletconnect/modal': 2.7.0(@types/react@19.0.4)(react@19.0.0) '@walletconnect/modal-core': 2.7.0(@types/react@19.0.4)(react@19.0.0) - '@walletconnect/sign-client': 2.17.3(bufferutil@4.0.9)(ioredis@5.4.2)(utf-8-validate@5.0.10) + '@walletconnect/sign-client': 2.17.3(bufferutil@4.0.9)(ioredis@5.4.2)(utf-8-validate@6.0.5) '@walletconnect/types': 2.17.3(ioredis@5.4.2) '@walletconnect/utils': 2.17.3(ioredis@5.4.2) postcss-cli: 11.0.0(jiti@2.4.2)(postcss@8.4.49)(tsx@4.19.2) @@ -28936,15 +29906,15 @@ snapshots: - uploadthing - utf-8-validate - '@onflow/fcl@1.13.1(@types/react@19.0.4)(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(ioredis@5.4.2)(jiti@2.4.2)(postcss@8.4.49)(react@19.0.0)(tsx@4.19.2)(utf-8-validate@5.0.10)': + '@onflow/fcl@1.13.1(@types/react@19.0.4)(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(ioredis@5.4.2)(jiti@2.4.2)(postcss@8.4.49)(react@19.0.0)(tsx@4.19.2)(utf-8-validate@6.0.5)': dependencies: '@babel/runtime': 7.26.0 '@onflow/config': 1.5.1 - '@onflow/fcl-core': 1.13.1(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(utf-8-validate@5.0.10) - '@onflow/fcl-wc': 5.5.1(@onflow/fcl-core@1.13.1(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(utf-8-validate@5.0.10))(@types/react@19.0.4)(bufferutil@4.0.9)(ioredis@5.4.2)(jiti@2.4.2)(postcss@8.4.49)(react@19.0.0)(tsx@4.19.2)(utf-8-validate@5.0.10) + '@onflow/fcl-core': 1.13.1(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(utf-8-validate@6.0.5) + '@onflow/fcl-wc': 5.5.1(@onflow/fcl-core@1.13.1(bufferutil@4.0.9)(encoding@0.1.13)(google-protobuf@3.21.4)(utf-8-validate@6.0.5))(@types/react@19.0.4)(bufferutil@4.0.9)(ioredis@5.4.2)(jiti@2.4.2)(postcss@8.4.49)(react@19.0.0)(tsx@4.19.2)(utf-8-validate@6.0.5) '@onflow/interaction': 0.0.11 '@onflow/rlp': 1.2.3 - '@onflow/sdk': 1.5.5(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@onflow/sdk': 1.5.5(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) '@onflow/types': 1.4.1 '@onflow/util-actor': 1.3.4 '@onflow/util-address': 1.2.3 @@ -28998,12 +29968,12 @@ snapshots: '@babel/runtime': 7.26.0 buffer: 6.0.3 - '@onflow/sdk@1.5.5(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@onflow/sdk@1.5.5(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5)': dependencies: '@babel/runtime': 7.26.0 '@onflow/config': 1.5.1 '@onflow/rlp': 1.2.3 - '@onflow/transport-http': 1.10.4(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@onflow/transport-http': 1.10.4(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) '@onflow/typedefs': 1.4.0 '@onflow/util-actor': 1.3.4 '@onflow/util-address': 1.2.3 @@ -29021,7 +29991,7 @@ snapshots: - supports-color - utf-8-validate - '@onflow/transport-http@1.10.4(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + '@onflow/transport-http@1.10.4(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5)': dependencies: '@babel/runtime': 7.26.0 '@onflow/util-address': 1.2.3 @@ -29031,8 +30001,8 @@ snapshots: abort-controller: 3.0.0 cross-fetch: 4.1.0(encoding@0.1.13) events: 3.3.0 - isomorphic-ws: 5.0.0(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + isomorphic-ws: 5.0.0(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - '@onflow/util-config' - bufferutil @@ -29360,10 +30330,10 @@ snapshots: '@polkadot-api/utils@0.0.1-492c132563ea6b40ae1fc5470dec4cd18768d182.1.0': optional: true - '@polkadot/api-augment@10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@polkadot/api-augment@10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: - '@polkadot/api-base': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@polkadot/rpc-augment': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/api-base': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@polkadot/rpc-augment': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@polkadot/types': 10.13.1 '@polkadot/types-augment': 10.13.1 '@polkadot/types-codec': 10.13.1 @@ -29374,9 +30344,9 @@ snapshots: - supports-color - utf-8-validate - '@polkadot/api-base@10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@polkadot/api-base@10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: - '@polkadot/rpc-core': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/rpc-core': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@polkadot/types': 10.13.1 '@polkadot/util': 12.6.2 rxjs: 7.8.1 @@ -29386,12 +30356,12 @@ snapshots: - supports-color - utf-8-validate - '@polkadot/api-derive@10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@polkadot/api-derive@10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: - '@polkadot/api': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@polkadot/api-augment': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@polkadot/api-base': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@polkadot/rpc-core': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/api': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@polkadot/api-augment': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@polkadot/api-base': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@polkadot/rpc-core': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@polkadot/types': 10.13.1 '@polkadot/types-codec': 10.13.1 '@polkadot/util': 12.6.2 @@ -29403,15 +30373,15 @@ snapshots: - supports-color - utf-8-validate - '@polkadot/api@10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@polkadot/api@10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: - '@polkadot/api-augment': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@polkadot/api-base': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@polkadot/api-derive': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/api-augment': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@polkadot/api-base': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@polkadot/api-derive': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@polkadot/keyring': 12.6.2(@polkadot/util-crypto@12.6.2(@polkadot/util@12.6.2))(@polkadot/util@12.6.2) - '@polkadot/rpc-augment': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@polkadot/rpc-core': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@polkadot/rpc-provider': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/rpc-augment': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@polkadot/rpc-core': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@polkadot/rpc-provider': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@polkadot/types': 10.13.1 '@polkadot/types-augment': 10.13.1 '@polkadot/types-codec': 10.13.1 @@ -29439,9 +30409,9 @@ snapshots: '@substrate/ss58-registry': 1.51.0 tslib: 2.8.1 - '@polkadot/rpc-augment@10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@polkadot/rpc-augment@10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: - '@polkadot/rpc-core': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/rpc-core': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@polkadot/types': 10.13.1 '@polkadot/types-codec': 10.13.1 '@polkadot/util': 12.6.2 @@ -29451,10 +30421,10 @@ snapshots: - supports-color - utf-8-validate - '@polkadot/rpc-core@10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@polkadot/rpc-core@10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: - '@polkadot/rpc-augment': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@polkadot/rpc-provider': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/rpc-augment': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@polkadot/rpc-provider': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@polkadot/types': 10.13.1 '@polkadot/util': 12.6.2 rxjs: 7.8.1 @@ -29464,7 +30434,7 @@ snapshots: - supports-color - utf-8-validate - '@polkadot/rpc-provider@10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@polkadot/rpc-provider@10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: '@polkadot/keyring': 12.6.2(@polkadot/util-crypto@12.6.2(@polkadot/util@12.6.2))(@polkadot/util@12.6.2) '@polkadot/types': 10.13.1 @@ -29473,13 +30443,13 @@ snapshots: '@polkadot/util-crypto': 12.6.2(@polkadot/util@12.6.2) '@polkadot/x-fetch': 12.6.2 '@polkadot/x-global': 12.6.2 - '@polkadot/x-ws': 12.6.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/x-ws': 12.6.2(bufferutil@4.0.9)(utf-8-validate@6.0.5) eventemitter3: 5.0.1 mock-socket: 9.3.1 nock: 13.5.6 tslib: 2.8.1 optionalDependencies: - '@substrate/connect': 0.8.8(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@substrate/connect': 0.8.8(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - supports-color @@ -29628,11 +30598,20 @@ snapshots: '@polkadot/x-global': 12.6.2 tslib: 2.8.1 - '@polkadot/x-ws@12.6.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@polkadot/x-ws@12.6.2(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: '@polkadot/x-global': 12.6.2 tslib: 2.8.1 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@primuslabs/zktls-core-sdk@0.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)': + dependencies: + ethers: 5.7.2(bufferutil@4.0.9)(utf-8-validate@6.0.5) + uuid: 11.0.5 + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -30621,7 +31600,7 @@ snapshots: '@slack/logger@3.0.0': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@slack/types@2.14.0': {} @@ -31425,10 +32404,10 @@ snapshots: dependencies: buffer: 6.0.3 - '@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))': + '@solana/wallet-adapter-base@0.9.23(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5))': dependencies: '@solana/wallet-standard-features': 1.2.0 - '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) '@wallet-standard/base': 1.1.0 '@wallet-standard/features': 1.1.0 eventemitter3: 4.0.7 @@ -31504,6 +32483,28 @@ snapshots: - encoding - utf-8-validate + '@solana/web3.js@1.95.8(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5)': + dependencies: + '@babel/runtime': 7.26.0 + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.6.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) + node-fetch: 2.7.0(encoding@0.1.13) + rpc-websockets: 9.0.4 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + '@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: '@babel/runtime': 7.26.0 @@ -31526,10 +32527,32 @@ snapshots: - encoding - utf-8-validate - '@spheron/protocol-sdk@1.2.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5)': + dependencies: + '@babel/runtime': 7.26.0 + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.6.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) + node-fetch: 2.7.0(encoding@0.1.13) + rpc-websockets: 9.0.4 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + '@spheron/protocol-sdk@1.2.3(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: base64-js: 1.5.1 - ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) js-yaml: 4.1.0 transitivePeerDependencies: - bufferutil @@ -31628,14 +32651,14 @@ snapshots: '@starknet-io/types-js@0.7.10': {} - '@story-protocol/core-sdk@1.2.0-rc.3(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1)': + '@story-protocol/core-sdk@1.2.0-rc.3(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1)': dependencies: abitype: 0.10.3(typescript@5.7.3)(zod@3.24.1) axios: 1.7.9(debug@4.4.0) bs58: 6.0.0 dotenv: 16.4.7 multiformats: 9.9.0 - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) transitivePeerDependencies: - bufferutil - debug @@ -31649,18 +32672,18 @@ snapshots: '@substrate/connect-known-chains@1.9.0': optional: true - '@substrate/connect@0.8.8(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@substrate/connect@0.8.8(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: '@substrate/connect-extension-protocol': 2.2.1 '@substrate/connect-known-chains': 1.9.0 - '@substrate/light-client-extension-helpers': 0.0.4(smoldot@2.0.22(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - smoldot: 2.0.22(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@substrate/light-client-extension-helpers': 0.0.4(smoldot@2.0.22(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + smoldot: 2.0.22(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - utf-8-validate optional: true - '@substrate/light-client-extension-helpers@0.0.4(smoldot@2.0.22(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@substrate/light-client-extension-helpers@0.0.4(smoldot@2.0.22(bufferutil@4.0.9)(utf-8-validate@6.0.5))': dependencies: '@polkadot-api/client': 0.0.1-492c132563ea6b40ae1fc5470dec4cd18768d182.1.0(rxjs@7.8.1) '@polkadot-api/json-rpc-provider': 0.0.1-492c132563ea6b40ae1fc5470dec4cd18768d182.1.0 @@ -31669,7 +32692,7 @@ snapshots: '@substrate/connect-extension-protocol': 2.2.1 '@substrate/connect-known-chains': 1.9.0 rxjs: 7.8.1 - smoldot: 2.0.22(bufferutil@4.0.9)(utf-8-validate@5.0.10) + smoldot: 2.0.22(bufferutil@4.0.9)(utf-8-validate@6.0.5) optional: true '@substrate/ss58-registry@1.51.0': {} @@ -31692,12 +32715,12 @@ snapshots: dependencies: '@supabase/node-fetch': 2.6.15 - '@supabase/realtime-js@2.10.9(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@supabase/realtime-js@2.10.9(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: '@supabase/node-fetch': 2.6.15 '@types/phoenix': 1.6.6 '@types/ws': 8.5.13 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -31706,13 +32729,13 @@ snapshots: dependencies: '@supabase/node-fetch': 2.6.15 - '@supabase/supabase-js@2.46.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + '@supabase/supabase-js@2.46.2(bufferutil@4.0.9)(utf-8-validate@6.0.5)': dependencies: '@supabase/auth-js': 2.65.1 '@supabase/functions-js': 2.4.3 '@supabase/node-fetch': 2.6.15 '@supabase/postgrest-js': 1.16.3 - '@supabase/realtime-js': 2.10.9(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@supabase/realtime-js': 2.10.9(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@supabase/storage-js': 2.7.1 transitivePeerDependencies: - bufferutil @@ -31777,7 +32800,7 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 entities: 4.5.0 '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.7.3))': @@ -32029,24 +33052,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.26.3 - '@babel/types': 7.26.3 + '@babel/parser': 7.26.5 + '@babel/types': 7.26.5 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.6 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.26.3 - '@babel/types': 7.26.3 + '@babel/parser': 7.26.5 + '@babel/types': 7.26.5 '@types/babel__traverse@7.20.6': dependencies: - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 '@types/better-sqlite3@7.6.12': dependencies: @@ -32056,7 +33079,7 @@ snapshots: '@types/bn.js@5.1.6': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/body-parser@1.19.5': dependencies: @@ -32065,15 +33088,21 @@ snapshots: '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/cacheable-request@6.0.3': dependencies: '@types/http-cache-semantics': 4.0.4 '@types/keyv': 3.1.4 - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/responselike': 1.0.3 + '@types/chai-subset@1.3.5': + dependencies: + '@types/chai': 4.3.20 + + '@types/chai@4.3.20': {} + '@types/chrome@0.0.278': dependencies: '@types/filesystem': 0.0.36 @@ -32082,11 +33111,11 @@ snapshots: '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.0.4 - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/connect@3.4.38': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/cookie@0.6.0': {} @@ -32221,6 +33250,10 @@ snapshots: dependencies: dompurify: 3.2.2 + '@types/dotenv@8.2.3': + dependencies: + dotenv: 16.4.7 + '@types/elliptic@6.4.18': dependencies: '@types/bn.js': 5.1.6 @@ -32245,14 +33278,14 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/qs': 6.9.17 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 '@types/express-serve-static-core@5.0.4': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/qs': 6.9.17 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -32292,7 +33325,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/gtag.js@0.0.12': {} @@ -32316,7 +33349,7 @@ snapshots: '@types/http-proxy@1.17.15': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/ioredis@5.0.0': dependencies: @@ -32326,7 +33359,7 @@ snapshots: '@types/is-stream@1.1.0': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/istanbul-lib-coverage@2.0.6': {} @@ -32343,17 +33376,19 @@ snapshots: expect: 29.7.0 pretty-format: 29.7.0 + '@types/js-yaml@4.0.9': {} + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} '@types/jsonwebtoken@9.0.7': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/keyv@3.1.4': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/lodash.isstring@4.0.9': dependencies: @@ -32387,12 +33422,12 @@ snapshots: '@types/node-fetch@2.6.12': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 form-data: 4.0.1 '@types/node-forge@1.3.11': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/node@10.17.60': {} @@ -32482,7 +33517,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/retry@0.12.0': {} @@ -32490,14 +33525,14 @@ snapshots: '@types/sax@1.2.7': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/semver@7.5.8': {} '@types/send@0.17.4': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/serve-index@1.9.4': dependencies: @@ -32506,12 +33541,12 @@ snapshots: '@types/serve-static@1.15.7': dependencies: '@types/http-errors': 2.0.4 - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/send': 0.17.4 '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/sql.js@1.4.9': dependencies: @@ -32533,7 +33568,7 @@ snapshots: '@types/unzipper@0.10.10': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/uuid@10.0.0': {} @@ -32545,11 +33580,15 @@ snapshots: '@types/ws@7.4.7': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 '@types/ws@8.5.13': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 + + '@types/ws@8.5.3': + dependencies: + '@types/node': 20.17.9 '@types/yargs-parser@21.0.3': {} @@ -32563,9 +33602,29 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 optional: true + '@typescript-eslint/eslint-plugin@6.21.0(@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 6.21.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/type-utils': 6.21.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.4.0(supports-color@5.5.0) + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + semver: 7.6.3 + ts-api-utils: 1.4.3(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/eslint-plugin@8.16.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3))(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3)': dependencies: '@eslint-community/regexpp': 4.12.1 @@ -32619,6 +33678,19 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/parser@6.21.0(eslint@8.57.1)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.4.0(supports-color@5.5.0) + eslint: 8.57.1 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3)': dependencies: '@typescript-eslint/scope-manager': 8.16.0 @@ -32657,6 +33729,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/scope-manager@6.21.0': + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + '@typescript-eslint/scope-manager@8.16.0': dependencies: '@typescript-eslint/types': 8.16.0 @@ -32667,6 +33744,18 @@ snapshots: '@typescript-eslint/types': 8.19.1 '@typescript-eslint/visitor-keys': 8.19.1 + '@typescript-eslint/type-utils@6.21.0(eslint@8.57.1)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.3) + '@typescript-eslint/utils': 6.21.0(eslint@8.57.1)(typescript@5.6.3) + debug: 4.4.0(supports-color@5.5.0) + eslint: 8.57.1 + ts-api-utils: 1.4.3(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/type-utils@8.16.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3)': dependencies: '@typescript-eslint/typescript-estree': 8.16.0(typescript@5.6.3) @@ -32702,10 +33791,27 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/types@6.21.0': {} + '@typescript-eslint/types@8.16.0': {} '@typescript-eslint/types@8.19.1': {} + '@typescript-eslint/typescript-estree@6.21.0(typescript@5.6.3)': + dependencies: + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/visitor-keys': 6.21.0 + debug: 4.4.0(supports-color@5.5.0) + globby: 11.1.0 + is-glob: 4.0.3 + minimatch: 9.0.3 + semver: 7.6.3 + ts-api-utils: 1.4.3(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/typescript-estree@8.16.0(typescript@5.6.3)': dependencies: '@typescript-eslint/types': 8.16.0 @@ -32735,6 +33841,20 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@6.21.0(eslint@8.57.1)(typescript@5.6.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@8.57.1) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 6.21.0 + '@typescript-eslint/types': 6.21.0 + '@typescript-eslint/typescript-estree': 6.21.0(typescript@5.6.3) + eslint: 8.57.1 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/utils@8.16.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.16.0(jiti@2.4.2)) @@ -32782,6 +33902,11 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/visitor-keys@6.21.0': + dependencies: + '@typescript-eslint/types': 6.21.0 + eslint-visitor-keys: 3.4.3 + '@typescript-eslint/visitor-keys@8.16.0': dependencies: '@typescript-eslint/types': 8.16.0 @@ -32833,7 +33958,24 @@ snapshots: transitivePeerDependencies: - '@swc/helpers' - '@vitest/coverage-v8@1.1.3(vitest@1.1.3(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@vitest/coverage-v8@0.34.6(vitest@0.34.6)': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 0.2.3 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 + picocolors: 1.1.1 + std-env: 3.8.0 + test-exclude: 6.0.0 + v8-to-istanbul: 9.3.0 + vitest: 0.34.6(@vitest/ui@0.34.7)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(playwright@1.48.2)(terser@5.37.0) + transitivePeerDependencies: + - supports-color + + '@vitest/coverage-v8@1.1.3(vitest@1.1.3(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 @@ -32848,7 +33990,7 @@ snapshots: std-env: 3.8.0 test-exclude: 6.0.0 v8-to-istanbul: 9.3.0 - vitest: 1.1.3(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + vitest: 1.1.3(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) transitivePeerDependencies: - supports-color @@ -32870,13 +34012,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitest/eslint-plugin@1.0.1(@typescript-eslint/utils@8.19.1(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3))(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3)(vitest@2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0))': + '@vitest/eslint-plugin@1.0.1(@typescript-eslint/utils@8.19.1(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3))(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3)(vitest@2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0))': dependencies: eslint: 9.16.0(jiti@2.4.2) optionalDependencies: '@typescript-eslint/utils': 8.19.1(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3) typescript: 5.6.3 - vitest: 2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0) + vitest: 2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0) + + '@vitest/expect@0.34.6': + dependencies: + '@vitest/spy': 0.34.6 + '@vitest/utils': 0.34.6 + chai: 4.5.0 '@vitest/expect@1.1.3': dependencies: @@ -32947,6 +34095,12 @@ snapshots: dependencies: tinyrainbow: 1.2.0 + '@vitest/runner@0.34.6': + dependencies: + '@vitest/utils': 0.34.6 + p-limit: 4.0.0 + pathe: 1.1.2 + '@vitest/runner@1.1.3': dependencies: '@vitest/utils': 1.1.3 @@ -32974,6 +34128,12 @@ snapshots: '@vitest/utils': 2.1.8 pathe: 1.1.2 + '@vitest/snapshot@0.34.6': + dependencies: + magic-string: 0.30.17 + pathe: 1.1.2 + pretty-format: 29.7.0 + '@vitest/snapshot@1.1.3': dependencies: magic-string: 0.30.17 @@ -33004,6 +34164,10 @@ snapshots: magic-string: 0.30.17 pathe: 1.1.2 + '@vitest/spy@0.34.6': + dependencies: + tinyspy: 2.2.1 + '@vitest/spy@1.1.3': dependencies: tinyspy: 2.2.1 @@ -33024,6 +34188,29 @@ snapshots: dependencies: tinyspy: 3.0.2 + '@vitest/ui@0.34.7(vitest@0.34.6)': + dependencies: + '@vitest/utils': 0.34.7 + fast-glob: 3.3.3 + fflate: 0.8.2 + flatted: 3.3.2 + pathe: 1.1.2 + picocolors: 1.1.1 + sirv: 2.0.4 + vitest: 0.34.6(@vitest/ui@0.34.7)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(playwright@1.48.2)(terser@5.37.0) + + '@vitest/utils@0.34.6': + dependencies: + diff-sequences: 29.6.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + + '@vitest/utils@0.34.7': + dependencies: + diff-sequences: 29.6.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + '@vitest/utils@1.1.3': dependencies: diff-sequences: 29.6.3 @@ -33060,7 +34247,7 @@ snapshots: '@vue/compiler-core@3.5.13': dependencies: - '@babel/parser': 7.26.3 + '@babel/parser': 7.26.5 '@vue/shared': 3.5.13 entities: 4.5.0 estree-walker: 2.0.2 @@ -33073,7 +34260,7 @@ snapshots: '@vue/compiler-sfc@3.5.13': dependencies: - '@babel/parser': 7.26.3 + '@babel/parser': 7.26.5 '@vue/compiler-core': 3.5.13 '@vue/compiler-dom': 3.5.13 '@vue/compiler-ssr': 3.5.13 @@ -33159,6 +34346,47 @@ snapshots: - uploadthing - utf-8-validate + '@walletconnect/core@2.17.3(bufferutil@4.0.9)(ioredis@5.4.2)(utf-8-validate@6.0.5)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.4.2) + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.0.4 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.17.3(ioredis@5.4.2) + '@walletconnect/utils': 2.17.3(ioredis@5.4.2) + '@walletconnect/window-getters': 1.0.1 + events: 3.3.0 + lodash.isequal: 4.5.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - uploadthing + - utf-8-validate + '@walletconnect/environment@1.0.1': dependencies: tslib: 1.14.1 @@ -33201,6 +34429,44 @@ snapshots: - uploadthing - utf-8-validate + '@walletconnect/ethereum-provider@2.17.3(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.4.2) + '@walletconnect/modal': 2.7.0(@types/react@19.0.4)(react@19.0.0) + '@walletconnect/sign-client': 2.17.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/types': 2.17.3(ioredis@5.4.2) + '@walletconnect/universal-provider': 2.17.3(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) + '@walletconnect/utils': 2.17.3(ioredis@5.4.2) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - uploadthing + - utf-8-validate + '@walletconnect/events@1.0.1': dependencies: keyvaluestorage-interface: 1.0.0 @@ -33248,6 +34514,16 @@ snapshots: - bufferutil - utf-8-validate + '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.0.9)(utf-8-validate@6.0.5)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@walletconnect/keyvaluestorage@1.1.1(ioredis@5.4.2)': dependencies: '@walletconnect/safe-json': 1.0.2 @@ -33352,6 +34628,72 @@ snapshots: - uploadthing - utf-8-validate + '@walletconnect/sign-client@2.17.3(bufferutil@4.0.9)(ioredis@5.4.2)(utf-8-validate@6.0.5)': + dependencies: + '@walletconnect/core': 2.17.3(bufferutil@4.0.9)(ioredis@5.4.2)(utf-8-validate@6.0.5) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.17.3(ioredis@5.4.2) + '@walletconnect/utils': 2.17.3(ioredis@5.4.2) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - uploadthing + - utf-8-validate + + '@walletconnect/sign-client@2.17.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@walletconnect/core': 2.17.3(bufferutil@4.0.9)(ioredis@5.4.2)(utf-8-validate@5.0.10) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.17.3(ioredis@5.4.2) + '@walletconnect/utils': 2.17.3(ioredis@5.4.2) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - uploadthing + - utf-8-validate + '@walletconnect/time@1.0.2': dependencies: tslib: 1.14.1 @@ -33421,6 +34763,43 @@ snapshots: - uploadthing - utf-8-validate + '@walletconnect/universal-provider@2.17.3(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(ioredis@5.4.2) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.17.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/types': 2.17.3(ioredis@5.4.2) + '@walletconnect/utils': 2.17.3(ioredis@5.4.2) + events: 3.3.0 + lodash: 4.17.21 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - uploadthing + - utf-8-validate + '@walletconnect/utils@2.17.3(ioredis@5.4.2)': dependencies: '@ethersproject/hash': 5.7.0 @@ -33589,6 +34968,12 @@ snapshots: typescript: 5.7.3 zod: 3.24.1 + abitype@0.7.1(typescript@5.7.3)(zod@3.24.1): + dependencies: + typescript: 5.7.3 + optionalDependencies: + zod: 3.24.1 + abitype@1.0.7(typescript@5.6.3)(zod@3.24.1): optionalDependencies: typescript: 5.6.3 @@ -33665,7 +35050,7 @@ snapshots: agent-base@7.1.3: {} - agent-twitter-client@0.0.18(bufferutil@4.0.9)(utf-8-validate@5.0.10): + agent-twitter-client@0.0.18(bufferutil@4.0.9)(utf-8-validate@6.0.5): dependencies: '@roamhq/wrtc': 0.8.0 '@sinclair/typebox': 0.32.35 @@ -33678,7 +35063,7 @@ snapshots: tslib: 2.8.1 twitter-api-v2: 1.19.0 undici: 7.2.1 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -33717,7 +35102,7 @@ snapshots: - solid-js - vue - ai@4.0.32(react@19.0.0)(zod@3.23.8): + ai@4.0.33(react@19.0.0)(zod@3.23.8): dependencies: '@ai-sdk/provider': 1.0.4 '@ai-sdk/provider-utils': 2.0.7(zod@3.23.8) @@ -33730,7 +35115,7 @@ snapshots: react: 19.0.0 zod: 3.23.8 - ai@4.0.32(react@19.0.0)(zod@3.24.1): + ai@4.0.33(react@19.0.0)(zod@3.24.1): dependencies: '@ai-sdk/provider': 1.0.4 '@ai-sdk/provider-utils': 2.0.7(zod@3.24.1) @@ -34047,6 +35432,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + asn1js@2.4.0: + dependencies: + pvutils: 1.1.3 + asn1js@3.0.5: dependencies: pvtsutils: 1.3.6 @@ -34096,6 +35485,8 @@ snapshots: at-least-node@1.0.0: {} + atob@2.1.2: {} + atomic-sleep@1.0.0: {} autocomplete.js@0.37.1: @@ -34135,9 +35526,9 @@ snapshots: postcss: 8.4.49 postcss-value-parser: 4.2.0 - avail-js-sdk@0.3.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + avail-js-sdk@0.3.0(bufferutil@4.0.9)(utf-8-validate@6.0.5): dependencies: - '@polkadot/api': 10.13.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/api': 10.13.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) neverthrow: 7.2.0 transitivePeerDependencies: - bufferutil @@ -34176,6 +35567,12 @@ snapshots: transitivePeerDependencies: - debug + axios@0.24.0: + dependencies: + follow-redirects: 1.15.9(debug@4.4.0) + transitivePeerDependencies: + - debug + axios@0.27.2: dependencies: follow-redirects: 1.15.9(debug@4.4.0) @@ -34269,7 +35666,7 @@ snapshots: babel-plugin-istanbul@6.1.1: dependencies: - '@babel/helper-plugin-utils': 7.25.9 + '@babel/helper-plugin-utils': 7.26.5 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -34280,7 +35677,7 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: '@babel/template': 7.25.9 - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.6 @@ -34292,7 +35689,7 @@ snapshots: babel-plugin-polyfill-corejs2@0.4.12(@babel/core@7.26.0): dependencies: - '@babel/compat-data': 7.26.3 + '@babel/compat-data': 7.26.5 '@babel/core': 7.26.0 '@babel/helper-define-polyfill-provider': 0.6.3(@babel/core@7.26.0) semver: 6.3.1 @@ -34856,12 +36253,12 @@ snapshots: dependencies: streamsearch: 1.1.0 - buttplug@3.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10): + buttplug@3.2.2(bufferutil@4.0.9)(utf-8-validate@6.0.5): dependencies: class-transformer: 0.5.1 eventemitter3: 5.0.1 reflect-metadata: 0.2.2 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -34874,6 +36271,8 @@ snapshots: bytesish@0.4.4: {} + bytestreamjs@2.0.1: {} + c12@2.0.1(magicast@0.3.5): dependencies: chokidar: 4.0.3 @@ -35178,13 +36577,13 @@ snapshots: dependencies: consola: 3.3.3 - cive@0.7.1(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10): + cive@0.7.1(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5): dependencies: '@noble/curves': 1.8.0 '@noble/hashes': 1.7.0 '@scure/bip32': 1.6.1 '@scure/bip39': 1.5.1 - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.23.8) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.23.8) zod: 3.23.8 transitivePeerDependencies: - bufferutil @@ -35681,8 +37080,15 @@ snapshots: optionalDependencies: typescript: 5.7.3 + cosmjs-types@0.8.0: + dependencies: + long: 4.0.0 + protobufjs: 6.11.4 + cosmjs-types@0.9.0: {} + crc-32@1.2.2: {} + create-ecdh@4.0.4: dependencies: bn.js: 4.12.1 @@ -35720,13 +37126,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0): + create-jest@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0) + jest-config: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -35735,13 +37141,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)): + create-jest@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0): dependencies: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + jest-config: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -36442,6 +37848,8 @@ snapshots: detect-libc@2.0.3: {} + detect-newline@2.1.0: {} + detect-newline@3.1.0: {} detect-node-es@1.1.0: {} @@ -36510,14 +37918,14 @@ snapshots: discord-api-types@0.37.97: {} - discord.js@14.16.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + discord.js@14.16.3(bufferutil@4.0.9)(utf-8-validate@6.0.5): dependencies: '@discordjs/builders': 1.10.0 '@discordjs/collection': 1.5.3 '@discordjs/formatters': 0.5.0 '@discordjs/rest': 2.4.0 '@discordjs/util': 1.1.1 - '@discordjs/ws': 1.1.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@discordjs/ws': 1.1.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) '@sapphire/snowflake': 3.5.3 discord-api-types: 0.37.100 fast-deep-equal: 3.1.3 @@ -37355,7 +38763,7 @@ snapshots: '@eslint/core': 0.9.1 '@eslint/eslintrc': 3.2.0 '@eslint/js': 9.16.0 - '@eslint/plugin-kit': 0.2.4 + '@eslint/plugin-kit': 0.2.5 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.1 @@ -37396,7 +38804,7 @@ snapshots: '@eslint/core': 0.9.1 '@eslint/eslintrc': 3.2.0 '@eslint/js': 9.17.0 - '@eslint/plugin-kit': 0.2.4 + '@eslint/plugin-kit': 0.2.5 '@humanfs/node': 0.16.6 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.1 @@ -37577,6 +38985,42 @@ snapshots: - bufferutil - utf-8-validate + ethers@5.7.2(bufferutil@4.0.9)(utf-8-validate@6.0.5): + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/contracts': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/json-wallets': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/providers': 5.7.2(bufferutil@4.0.9)(utf-8-validate@6.0.5) + '@ethersproject/random': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/solidity': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/units': 5.7.0 + '@ethersproject/wallet': 5.7.0 + '@ethersproject/web': 5.7.1 + '@ethersproject/wordlists': 5.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: '@adraffy/ens-normalize': 1.10.1 @@ -37590,6 +39034,19 @@ snapshots: - bufferutil - utf-8-validate + ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5): + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + ethjs-unit@0.1.6: dependencies: bn.js: 4.11.6 @@ -37597,7 +39054,7 @@ snapshots: eval@0.1.8: dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 require-like: 0.1.2 event-emitter@0.3.5: @@ -37625,6 +39082,8 @@ snapshots: eventsource-parser@1.1.2: {} + eventsource-parser@2.0.1: {} + eventsource-parser@3.0.0: {} eventsource@2.0.2: {} @@ -38163,24 +39622,24 @@ snapshots: fsevents@2.3.3: optional: true - fuels@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)): + fuels@0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)): dependencies: - '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/abi-typegen': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/account': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/address': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/contract': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/abi-coder': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/abi-typegen': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/account': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/address': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/contract': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/crypto': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/errors': 0.97.2 - '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/hasher': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/interfaces': 0.97.2 '@fuel-ts/math': 0.97.2 - '@fuel-ts/merkle': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/program': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/recipes': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/script': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) - '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0)) + '@fuel-ts/merkle': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/program': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/recipes': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/script': 0.97.2(encoding@0.1.13)(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/transactions': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) + '@fuel-ts/utils': 0.97.2(vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0)) '@fuel-ts/versions': 0.97.2 bundle-require: 5.1.0(esbuild@0.24.2) chalk: 4.1.2 @@ -38267,11 +39726,11 @@ snapshots: dependencies: is-property: 1.0.2 - genlayer-js@0.4.7(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3))(bufferutil@4.0.9)(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1): + genlayer-js@0.4.7(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3))(bufferutil@4.0.9)(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1): dependencies: eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.16.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.6.3))(eslint@9.17.0(jiti@2.4.2)) typescript-parsec: 0.3.4 - viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@5.0.10)(zod@3.24.1) + viem: 2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) transitivePeerDependencies: - '@typescript-eslint/parser' - bufferutil @@ -38684,7 +40143,7 @@ snapshots: dependencies: duplexer: 0.1.2 - h3@1.13.0: + h3@1.13.1: dependencies: cookie-es: 1.2.2 crossws: 0.3.1 @@ -39162,6 +40621,19 @@ snapshots: husky@9.1.7: {} + hyperliquid@1.5.6(bufferutil@4.0.9)(utf-8-validate@6.0.5): + dependencies: + '@msgpack/msgpack': 3.0.0-beta2 + '@types/ws': 8.5.13 + axios: 1.7.9(debug@4.4.0) + ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) + typescript: 5.6.3 + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -39692,18 +41164,26 @@ snapshots: dependencies: ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@6.0.5)): + dependencies: + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@6.0.5) + isomorphic-ws@4.0.1(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - isomorphic-ws@5.0.0(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + isomorphic-ws@5.0.0(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)): dependencies: - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)): + dependencies: + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + isstream@0.1.2: {} istanbul-lib-coverage@3.2.2: {} @@ -39711,7 +41191,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.26.0 - '@babel/parser': 7.26.3 + '@babel/parser': 7.26.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -39721,7 +41201,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 7.26.0 - '@babel/parser': 7.26.3 + '@babel/parser': 7.26.5 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.6.3 @@ -39803,6 +41283,24 @@ snapshots: - bufferutil - utf-8-validate + jayson@4.1.3(bufferutil@4.0.9)(utf-8-validate@6.0.5): + dependencies: + '@types/connect': 3.4.38 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + jest-changed-files@29.7.0: dependencies: execa: 5.1.1 @@ -39815,7 +41313,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3(babel-plugin-macros@3.1.0) @@ -39854,16 +41352,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0): + jest-cli@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0) + create-jest: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0) + jest-config: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -39873,16 +41371,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)): + jest-cli@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + create-jest: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + jest-config: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -39942,7 +41440,7 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0): + jest-config@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@18.19.70)(typescript@5.6.3)): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 @@ -39968,11 +41466,12 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.17.9 + ts-node: 10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@18.19.70)(typescript@5.6.3) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@18.19.70)(typescript@5.6.3)): + jest-config@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 @@ -39997,13 +41496,13 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 22.10.5 - ts-node: 10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@18.19.70)(typescript@5.6.3) + '@types/node': 20.17.9 + ts-node: 10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)): + jest-config@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3)): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 @@ -40028,13 +41527,13 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 22.10.5 - ts-node: 10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3) + '@types/node': 20.17.9 + ts-node: 10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3) transitivePeerDependencies: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3)): + jest-config@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 @@ -40060,7 +41559,6 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 22.10.5 - ts-node: 10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -40098,7 +41596,7 @@ snapshots: jest-diff@29.7.0: dependencies: - chalk: 4.1.0 + chalk: 4.1.2 diff-sequences: 29.6.3 jest-get-type: 29.6.3 pretty-format: 29.7.0 @@ -40120,7 +41618,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -40130,7 +41628,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 22.10.5 + '@types/node': 20.17.9 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -40169,7 +41667,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -40204,7 +41702,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -40232,7 +41730,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 chalk: 4.1.2 cjs-module-lexer: 1.4.1 collect-v8-coverage: 1.0.2 @@ -40253,10 +41751,10 @@ snapshots: jest-snapshot@29.7.0: dependencies: '@babel/core': 7.26.0 - '@babel/generator': 7.26.3 + '@babel/generator': 7.26.5 '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.0) - '@babel/types': 7.26.3 + '@babel/types': 7.26.5 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 @@ -40278,7 +41776,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -40297,7 +41795,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.10.5 + '@types/node': 20.17.9 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -40306,13 +41804,13 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 22.10.5 + '@types/node': 20.17.9 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -40329,24 +41827,24 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0): + jest@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0) + jest-cli: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros - supports-color - ts-node - jest@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)): + jest@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0): dependencies: - '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + jest-cli: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -40464,6 +41962,37 @@ snapshots: - supports-color - utf-8-validate + jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5): + dependencies: + cssstyle: 4.2.1 + data-urls: 5.0.0 + decimal.js: 10.4.3 + form-data: 4.0.1 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.16 + parse5: 7.2.1 + rrweb-cssom: 0.7.1 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.1.0 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.1.0 + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + xml-name-validator: 5.0.0 + optionalDependencies: + canvas: 2.11.2(encoding@0.1.13) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + optional: true + jsesc@3.0.2: {} jsesc@3.1.0: {} @@ -40550,6 +42079,8 @@ snapshots: json-schema: 0.4.0 verror: 1.10.0 + jsrsasign@11.1.0: {} + jssha@3.2.0: {} jsx-ast-utils@3.3.5: @@ -40618,6 +42149,11 @@ snapshots: node-gyp-build: 4.8.4 readable-stream: 3.6.2 + keytar@7.9.0: + dependencies: + node-addon-api: 4.3.0 + prebuild-install: 7.1.2 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 @@ -40653,15 +42189,15 @@ snapshots: inherits: 2.0.4 stream-splicer: 2.0.1 - langchain@0.3.10(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)))(@langchain/groq@0.1.3(@langchain/core@0.3.27(openai@4.78.0(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.78.0(encoding@0.1.13)(zod@3.24.1)): + langchain@0.3.10(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(@langchain/groq@0.1.3(@langchain/core@0.3.27(openai@4.78.1(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.78.1(encoding@0.1.13)(zod@3.24.1)): dependencies: - '@langchain/core': 0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)) - '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13) - '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1))) + '@langchain/core': 0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) + '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13) + '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.27(openai@4.78.1(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.15(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)) + langsmith: 0.2.15(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) openapi-types: 12.1.3 p-retry: 4.6.2 uuid: 10.0.0 @@ -40669,7 +42205,7 @@ snapshots: zod: 3.23.8 zod-to-json-schema: 3.24.1(zod@3.23.8) optionalDependencies: - '@langchain/groq': 0.1.3(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13) + '@langchain/groq': 0.1.3(@langchain/core@0.3.27(openai@4.78.1(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: @@ -40718,7 +42254,7 @@ snapshots: optionalDependencies: openai: 4.73.0(encoding@0.1.13)(zod@3.23.8) - langsmith@0.2.15(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)): + langsmith@0.2.15(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)): dependencies: '@types/uuid': 10.0.0 commander: 10.0.1 @@ -40727,7 +42263,7 @@ snapshots: semver: 7.6.3 uuid: 10.0.0 optionalDependencies: - openai: 4.78.0(encoding@0.1.13)(zod@3.24.1) + openai: 4.78.1(encoding@0.1.13)(zod@3.24.1) language-subtag-registry@0.3.23: {} @@ -40981,6 +42517,8 @@ snapshots: loader-utils@3.3.1: {} + local-pkg@0.4.3: {} + local-pkg@0.5.1: dependencies: mlly: 1.7.3 @@ -41159,8 +42697,8 @@ snapshots: magicast@0.3.5: dependencies: - '@babel/parser': 7.26.3 - '@babel/types': 7.26.3 + '@babel/parser': 7.26.5 + '@babel/types': 7.26.5 source-map-js: 1.2.1 make-dir@2.1.0: @@ -42161,7 +43699,7 @@ snapshots: array-differ: 3.0.0 array-union: 2.1.0 arrify: 2.0.1 - minimatch: 3.0.5 + minimatch: 3.1.2 multistream@4.1.0: dependencies: @@ -42295,6 +43833,8 @@ snapshots: node-addon-api@2.0.2: {} + node-addon-api@4.3.0: {} + node-addon-api@5.1.0: {} node-addon-api@6.1.0: {} @@ -42580,7 +44120,7 @@ snapshots: '@yarnpkg/parsers': 3.0.0-rc.46 '@zkochan/js-yaml': 0.0.7 axios: 1.7.9(debug@4.4.0) - chalk: 4.1.0 + chalk: 4.1.2 cli-cursor: 3.1.0 cli-spinners: 2.6.1 cliui: 8.0.1 @@ -42779,12 +44319,12 @@ snapshots: platform: 1.3.6 protobufjs: 7.4.0 - open-jsonrpc-provider@0.2.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + open-jsonrpc-provider@0.2.1(bufferutil@4.0.9)(utf-8-validate@6.0.5): dependencies: axios: 0.27.2 reconnecting-websocket: 4.4.0 websocket: 1.0.35 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - debug @@ -42825,7 +44365,7 @@ snapshots: transitivePeerDependencies: - encoding - openai@4.78.0(encoding@0.1.13)(zod@3.23.8): + openai@4.78.1(encoding@0.1.13)(zod@3.23.8): dependencies: '@types/node': 18.19.70 '@types/node-fetch': 2.6.12 @@ -42839,7 +44379,7 @@ snapshots: transitivePeerDependencies: - encoding - openai@4.78.0(encoding@0.1.13)(zod@3.24.1): + openai@4.78.1(encoding@0.1.13)(zod@3.24.1): dependencies: '@types/node': 18.19.70 '@types/node-fetch': 2.6.12 @@ -42871,7 +44411,7 @@ snapshots: ora@5.3.0: dependencies: bl: 4.1.0 - chalk: 4.1.0 + chalk: 4.1.2 cli-cursor: 3.1.0 cli-spinners: 2.6.1 is-interactive: 1.0.0 @@ -42921,7 +44461,7 @@ snapshots: dependencies: '@adraffy/ens-normalize': 1.11.0 '@noble/curves': 1.7.0 - '@noble/hashes': 1.6.1 + '@noble/hashes': 1.7.0 '@scure/bip32': 1.6.1 '@scure/bip39': 1.5.1 abitype: 1.0.7(typescript@5.7.3)(zod@3.24.1) @@ -43414,6 +44954,15 @@ snapshots: dependencies: find-up: 3.0.0 + pkijs@3.2.4: + dependencies: + '@noble/hashes': 1.7.0 + asn1js: 3.0.5 + bytestreamjs: 2.0.1 + pvtsutils: 1.3.6 + pvutils: 1.1.3 + tslib: 2.8.1 + platform@1.3.6: {} playwright-core@1.48.2: {} @@ -44343,7 +45892,7 @@ snapshots: '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 '@types/long': 4.0.2 - '@types/node': 22.10.5 + '@types/node': 20.17.9 long: 4.0.0 protobufjs@7.4.0: @@ -44358,7 +45907,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 22.10.5 + '@types/node': 20.17.9 long: 5.2.4 protocols@2.0.1: {} @@ -44542,6 +46091,22 @@ snapshots: qs@6.5.3: {} + quais@1.0.0-alpha.25(bufferutil@4.0.9)(utf-8-validate@6.0.5): + dependencies: + '@bitcoinerlab/secp256k1': 1.2.0 + '@brandonblack/musig': 0.0.1-alpha.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@scure/base': 1.2.1 + aes-js: 4.0.0-beta.5 + dotenv: 16.4.7 + google-protobuf: 3.21.4 + tslib: 2.8.1 + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + query-string@7.1.3: dependencies: decode-uri-component: 0.2.2 @@ -45452,6 +47017,8 @@ snapshots: secure-json-parse@2.7.0: {} + secure-random@1.1.2: {} + seedrandom@3.0.5: {} selderee@0.11.0: @@ -45738,6 +47305,8 @@ snapshots: transitivePeerDependencies: - supports-color + simple-jsonrpc-js@1.2.0: {} + simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 @@ -45793,9 +47362,9 @@ snapshots: smart-buffer@4.2.0: {} - smoldot@2.0.22(bufferutil@4.0.9)(utf-8-validate@5.0.10): + smoldot@2.0.22(bufferutil@4.0.9)(utf-8-validate@6.0.5): dependencies: - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -45844,10 +47413,10 @@ snapshots: '@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.3)(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)(typescript@5.7.3)(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.78.0(encoding@0.1.13)(zod@3.24.1)) - '@langchain/groq': 0.1.3(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13) - '@langchain/langgraph': 0.2.39(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1))) - '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13) + '@langchain/core': 0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)) + '@langchain/groq': 0.1.3(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(encoding@0.1.13) + '@langchain/langgraph': 0.2.39(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1))) + '@langchain/openai': 0.3.16(@langchain/core@0.3.27(openai@4.78.1(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.3)(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) @@ -45865,7 +47434,7 @@ snapshots: '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@tensor-oss/tensorswap-sdk': 4.5.0(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)(utf-8-validate@5.0.10) '@tiplink/api': 0.3.1(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(sodium-native@3.4.1)(utf-8-validate@5.0.10) - ai: 4.0.32(react@19.0.0)(zod@3.24.1) + ai: 4.0.33(react@19.0.0)(zod@3.24.1) bn.js: 5.2.1 bs58: 6.0.0 chai: 5.1.2 @@ -45873,8 +47442,8 @@ snapshots: dotenv: 16.4.7 flash-sdk: 2.25.3(@swc/core@1.10.7(@swc/helpers@0.5.15))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.3)(utf-8-validate@5.0.10) form-data: 4.0.1 - langchain: 0.3.10(@langchain/core@0.3.27(openai@4.78.0(encoding@0.1.13)(zod@3.24.1)))(@langchain/groq@0.1.3(@langchain/core@0.3.27(openai@4.78.0(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.78.0(encoding@0.1.13)(zod@3.24.1)) - openai: 4.78.0(encoding@0.1.13)(zod@3.24.1) + langchain: 0.3.10(@langchain/core@0.3.27(openai@4.78.1(encoding@0.1.13)(zod@3.24.1)))(@langchain/groq@0.1.3(@langchain/core@0.3.27(openai@4.78.1(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.78.1(encoding@0.1.13)(zod@3.24.1)) + openai: 4.78.1(encoding@0.1.13)(zod@3.24.1) typedoc: 0.27.6(typescript@5.7.3) zod: 3.24.1 transitivePeerDependencies: @@ -45925,6 +47494,12 @@ snapshots: sort-css-media-queries@2.2.0: {} + sort-json@2.0.1: + dependencies: + detect-indent: 5.0.0 + detect-newline: 2.1.0 + minimist: 1.2.8 + sort-keys@2.0.0: dependencies: is-plain-obj: 1.1.0 @@ -46683,6 +48258,8 @@ snapshots: tinyld@1.3.4: {} + tinypool@0.7.0: {} + tinypool@0.8.4: {} tinypool@1.0.2: {} @@ -46817,12 +48394,12 @@ snapshots: ts-interface-checker@0.1.13: {} - ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.24.2)(jest@29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)))(typescript@5.7.3): + ts-jest@29.2.5(@babel/core@7.26.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.26.0))(esbuild@0.24.2)(jest@29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)))(typescript@5.7.3): dependencies: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + jest: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -46861,7 +48438,7 @@ snapshots: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0) + jest: 29.7.0(@types/node@20.17.9)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@20.17.9)(typescript@5.7.3)) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -46880,7 +48457,7 @@ snapshots: bs-logger: 0.2.6 ejs: 3.1.10 fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3)) + jest: 29.7.0(@types/node@22.10.5)(babel-plugin-macros@3.1.0) jest-util: 29.7.0 json5: 2.2.3 lodash.memoize: 4.1.2 @@ -46978,26 +48555,6 @@ snapshots: '@swc/core': 1.10.7(@swc/helpers@0.5.15) optional: true - ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.10.5)(typescript@5.7.3): - dependencies: - '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 - '@tsconfig/node12': 1.0.11 - '@tsconfig/node14': 1.0.3 - '@tsconfig/node16': 1.0.4 - '@types/node': 22.10.5 - acorn: 8.14.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 5.7.3 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - optionalDependencies: - '@swc/core': 1.10.7(@swc/helpers@0.5.15) - ts-node@10.9.2(@swc/core@1.10.7(@swc/helpers@0.5.15))(@types/node@22.8.4)(typescript@5.6.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -47541,7 +49098,7 @@ snapshots: anymatch: 3.1.3 chokidar: 3.6.0 destr: 2.0.3 - h3: 1.13.0 + h3: 1.13.1 lru-cache: 10.4.3 node-fetch-native: 1.6.4 ofetch: 1.4.1 @@ -47553,8 +49110,8 @@ snapshots: untyped@1.5.2: dependencies: '@babel/core': 7.26.0 - '@babel/standalone': 7.26.4 - '@babel/types': 7.26.3 + '@babel/standalone': 7.26.5 + '@babel/types': 7.26.5 citty: 0.1.6 defu: 6.1.4 jiti: 2.4.2 @@ -47652,6 +49209,11 @@ snapshots: dependencies: node-gyp-build: 4.8.4 + utf-8-validate@6.0.5: + dependencies: + node-gyp-build: 4.8.4 + optional: true + utf8@3.0.0: {} utfstring@2.0.2: {} @@ -47680,6 +49242,8 @@ snapshots: uuid@11.0.3: {} + uuid@11.0.5: {} + uuid@3.4.0: {} uuid@8.3.2: {} @@ -47721,6 +49285,8 @@ snapshots: varint@5.0.2: {} + varint@6.0.0: {} + varuint-bitcoin@2.0.0: dependencies: uint8array-tools: 0.0.8 @@ -47762,17 +49328,17 @@ 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.24.1): + viem@2.21.58(bufferutil@4.0.9)(typescript@5.6.3)(utf-8-validate@6.0.5)(zod@3.24.1): 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.24.1) - isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) ox: 0.4.4(typescript@5.6.3)(zod@3.24.1) webauthn-p256: 0.0.10 - ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) optionalDependencies: typescript: 5.6.3 transitivePeerDependencies: @@ -47816,6 +49382,61 @@ snapshots: - utf-8-validate - zod + viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(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.7.3)(zod@3.23.8) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + ox: 0.4.4(typescript@5.7.3)(zod@3.23.8) + webauthn-p256: 0.0.10 + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + optionalDependencies: + typescript: 5.7.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.21.58(bufferutil@4.0.9)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1): + 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.7.3)(zod@3.24.1) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + ox: 0.4.4(typescript@5.7.3)(zod@3.24.1) + webauthn-p256: 0.0.10 + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + optionalDependencies: + typescript: 5.7.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vite-node@0.34.6(@types/node@20.17.9)(terser@5.37.0): + dependencies: + cac: 6.7.14 + debug: 4.4.0(supports-color@5.5.0) + mlly: 1.7.3 + pathe: 1.1.2 + picocolors: 1.1.1 + vite: 5.4.11(@types/node@20.17.9)(terser@5.37.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite-node@1.1.3(@types/node@22.10.5)(terser@5.37.0): dependencies: cac: 6.7.14 @@ -47949,6 +49570,17 @@ snapshots: transitivePeerDependencies: - supports-color + vite-tsconfig-paths@4.3.2(typescript@5.6.3)(vite@5.4.11(@types/node@20.17.9)(terser@5.37.0)): + dependencies: + debug: 4.4.0(supports-color@5.5.0) + globrex: 0.1.2 + tsconfck: 3.1.4(typescript@5.6.3) + optionalDependencies: + vite: 5.4.11(@types/node@20.17.9)(terser@5.37.0) + transitivePeerDependencies: + - supports-color + - typescript + vite-tsconfig-paths@5.1.4(typescript@5.6.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(terser@5.37.0)(tsx@4.19.2)(yaml@2.7.0)): dependencies: debug: 4.4.0(supports-color@5.5.0) @@ -48003,7 +49635,47 @@ snapshots: tsx: 4.19.2 yaml: 2.7.0 - vitest@1.1.3(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0): + vitest@0.34.6(@vitest/ui@0.34.7)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(playwright@1.48.2)(terser@5.37.0): + dependencies: + '@types/chai': 4.3.20 + '@types/chai-subset': 1.3.5 + '@types/node': 20.17.9 + '@vitest/expect': 0.34.6 + '@vitest/runner': 0.34.6 + '@vitest/snapshot': 0.34.6 + '@vitest/spy': 0.34.6 + '@vitest/utils': 0.34.6 + acorn: 8.14.0 + acorn-walk: 8.3.4 + cac: 6.7.14 + chai: 4.5.0 + debug: 4.4.0(supports-color@5.5.0) + local-pkg: 0.4.3 + magic-string: 0.30.17 + pathe: 1.1.2 + picocolors: 1.1.1 + std-env: 3.8.0 + strip-literal: 1.3.0 + tinybench: 2.9.0 + tinypool: 0.7.0 + vite: 5.4.11(@types/node@20.17.9)(terser@5.37.0) + vite-node: 0.34.6(@types/node@20.17.9)(terser@5.37.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@vitest/ui': 0.34.7(vitest@0.34.6) + jsdom: 25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10) + playwright: 1.48.2 + transitivePeerDependencies: + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vitest@1.1.3(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0): dependencies: '@vitest/expect': 1.1.3 '@vitest/runner': 1.1.3 @@ -48028,7 +49700,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.10.5 - jsdom: 25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10) + jsdom: 25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5) transitivePeerDependencies: - less - lightningcss @@ -48039,7 +49711,7 @@ snapshots: - supports-color - terser - vitest@1.2.1(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0): + vitest@1.2.1(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0): dependencies: '@vitest/expect': 1.2.1 '@vitest/runner': 1.2.1 @@ -48064,7 +49736,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.10.5 - jsdom: 25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10) + jsdom: 25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5) transitivePeerDependencies: - less - lightningcss @@ -48147,7 +49819,43 @@ snapshots: - supports-color - terser - vitest@2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0): + vitest@2.1.4(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0): + dependencies: + '@vitest/expect': 2.1.4 + '@vitest/mocker': 2.1.4(vite@5.4.11(@types/node@22.10.5)(terser@5.37.0)) + '@vitest/pretty-format': 2.1.8 + '@vitest/runner': 2.1.4 + '@vitest/snapshot': 2.1.4 + '@vitest/spy': 2.1.4 + '@vitest/utils': 2.1.4 + chai: 5.1.2 + debug: 4.4.0(supports-color@5.5.0) + expect-type: 1.1.0 + magic-string: 0.30.17 + pathe: 1.1.2 + std-env: 3.8.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 1.2.0 + vite: 5.4.11(@types/node@22.10.5)(terser@5.37.0) + vite-node: 2.1.4(@types/node@22.10.5)(terser@5.37.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.10.5 + jsdom: 25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5) + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vitest@2.1.5(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0): dependencies: '@vitest/expect': 2.1.5 '@vitest/mocker': 2.1.5(vite@5.4.11(@types/node@22.10.5)(terser@5.37.0)) @@ -48171,7 +49879,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.10.5 - jsdom: 25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10) + jsdom: 25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5) transitivePeerDependencies: - less - lightningcss @@ -48183,7 +49891,7 @@ snapshots: - supports-color - terser - vitest@2.1.8(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0): + vitest@2.1.8(@types/node@22.10.5)(jsdom@25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5))(terser@5.37.0): dependencies: '@vitest/expect': 2.1.8 '@vitest/mocker': 2.1.8(vite@5.4.11(@types/node@22.10.5)(terser@5.37.0)) @@ -48207,7 +49915,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.10.5 - jsdom: 25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10) + jsdom: 25.0.1(bufferutil@4.0.9)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@6.0.5) transitivePeerDependencies: - less - lightningcss @@ -48343,6 +50051,189 @@ snapshots: web-vitals@3.5.2: {} + web3-core@4.7.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5): + dependencies: + web3-errors: 1.3.1 + web3-eth-accounts: 4.3.1 + web3-eth-iban: 4.0.7 + web3-providers-http: 4.2.0(encoding@0.1.13) + web3-providers-ws: 4.0.8(bufferutil@4.0.9)(utf-8-validate@6.0.5) + web3-types: 1.10.0 + web3-utils: 4.3.3 + web3-validator: 2.0.6 + optionalDependencies: + web3-providers-ipc: 4.0.7 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-errors@1.3.1: + dependencies: + web3-types: 1.10.0 + + web3-eth-abi@4.4.1(typescript@5.7.3)(zod@3.24.1): + dependencies: + abitype: 0.7.1(typescript@5.7.3)(zod@3.24.1) + web3-errors: 1.3.1 + web3-types: 1.10.0 + web3-utils: 4.3.3 + web3-validator: 2.0.6 + transitivePeerDependencies: + - typescript + - zod + + web3-eth-accounts@4.3.1: + dependencies: + '@ethereumjs/rlp': 4.0.1 + crc-32: 1.2.2 + ethereum-cryptography: 2.2.1 + web3-errors: 1.3.1 + web3-types: 1.10.0 + web3-utils: 4.3.3 + web3-validator: 2.0.6 + + web3-eth-contract@4.7.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1): + dependencies: + '@ethereumjs/rlp': 5.0.2 + web3-core: 4.7.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-errors: 1.3.1 + web3-eth: 4.11.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) + web3-eth-abi: 4.4.1(typescript@5.7.3)(zod@3.24.1) + web3-types: 1.10.0 + web3-utils: 4.3.3 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-eth-ens@4.4.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + web3-core: 4.7.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-errors: 1.3.1 + web3-eth: 4.11.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) + web3-eth-contract: 4.7.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) + web3-net: 4.1.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-types: 1.10.0 + web3-utils: 4.3.3 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-eth-iban@4.0.7: + dependencies: + web3-errors: 1.3.1 + web3-types: 1.10.0 + web3-utils: 4.3.3 + web3-validator: 2.0.6 + + web3-eth-personal@4.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1): + dependencies: + web3-core: 4.7.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-eth: 4.11.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) + web3-rpc-methods: 1.3.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-types: 1.10.0 + web3-utils: 4.3.3 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-eth@4.11.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1): + dependencies: + setimmediate: 1.0.5 + web3-core: 4.7.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-errors: 1.3.1 + web3-eth-abi: 4.4.1(typescript@5.7.3)(zod@3.24.1) + web3-eth-accounts: 4.3.1 + web3-net: 4.1.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-providers-ws: 4.0.8(bufferutil@4.0.9)(utf-8-validate@6.0.5) + web3-rpc-methods: 1.3.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-types: 1.10.0 + web3-utils: 4.3.3 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-net@4.1.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5): + dependencies: + web3-core: 4.7.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-rpc-methods: 1.3.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-types: 1.10.0 + web3-utils: 4.3.3 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-providers-http@4.2.0(encoding@0.1.13): + dependencies: + cross-fetch: 4.1.0(encoding@0.1.13) + web3-errors: 1.3.1 + web3-types: 1.10.0 + web3-utils: 4.3.3 + transitivePeerDependencies: + - encoding + + web3-providers-ipc@4.0.7: + dependencies: + web3-errors: 1.3.1 + web3-types: 1.10.0 + web3-utils: 4.3.3 + optional: true + + web3-providers-ws@4.0.8(bufferutil@4.0.9)(utf-8-validate@6.0.5): + dependencies: + '@types/ws': 8.5.3 + isomorphic-ws: 5.0.0(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5)) + web3-errors: 1.3.1 + web3-types: 1.10.0 + web3-utils: 4.3.3 + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + web3-rpc-methods@1.3.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5): + dependencies: + web3-core: 4.7.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-types: 1.10.0 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-rpc-providers@1.0.0-rc.4(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5): + dependencies: + web3-errors: 1.3.1 + web3-providers-http: 4.2.0(encoding@0.1.13) + web3-providers-ws: 4.0.8(bufferutil@4.0.9)(utf-8-validate@6.0.5) + web3-types: 1.10.0 + web3-utils: 4.3.3 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-types@1.10.0: {} + web3-utils@1.10.4: dependencies: '@ethereumjs/util': 8.1.0 @@ -48354,6 +50245,48 @@ snapshots: randombytes: 2.1.0 utf8: 3.0.0 + web3-utils@4.3.3: + dependencies: + ethereum-cryptography: 2.2.1 + eventemitter3: 5.0.1 + web3-errors: 1.3.1 + web3-types: 1.10.0 + web3-validator: 2.0.6 + + web3-validator@2.0.6: + dependencies: + ethereum-cryptography: 2.2.1 + util: 0.12.5 + web3-errors: 1.3.1 + web3-types: 1.10.0 + zod: 3.23.8 + + web3@4.16.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1): + dependencies: + web3-core: 4.7.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-errors: 1.3.1 + web3-eth: 4.11.1(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) + web3-eth-abi: 4.4.1(typescript@5.7.3)(zod@3.24.1) + web3-eth-accounts: 4.3.1 + web3-eth-contract: 4.7.2(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) + web3-eth-ens: 4.4.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) + web3-eth-iban: 4.0.7 + web3-eth-personal: 4.1.0(bufferutil@4.0.9)(encoding@0.1.13)(typescript@5.7.3)(utf-8-validate@6.0.5)(zod@3.24.1) + web3-net: 4.1.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-providers-http: 4.2.0(encoding@0.1.13) + web3-providers-ws: 4.0.8(bufferutil@4.0.9)(utf-8-validate@6.0.5) + web3-rpc-methods: 1.3.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-rpc-providers: 1.0.0-rc.4(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@6.0.5) + web3-types: 1.10.0 + web3-utils: 4.3.3 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + webauthn-p256@0.0.10: dependencies: '@noble/curves': 1.7.0 @@ -48687,11 +50620,21 @@ snapshots: bufferutil: 4.0.9 utf-8-validate: 5.0.10 + ws@7.4.6(bufferutil@4.0.9)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): optionalDependencies: bufferutil: 4.0.9 utf-8-validate: 5.0.10 + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + ws@8.13.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): optionalDependencies: bufferutil: 4.0.9 @@ -48702,11 +50645,21 @@ snapshots: bufferutil: 4.0.9 utf-8-validate: 5.0.10 + ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): optionalDependencies: bufferutil: 4.0.9 utf-8-validate: 5.0.10 + ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@6.0.5): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 6.0.5 + wtf_wikipedia@10.3.2(encoding@0.1.13): dependencies: isomorphic-unfetch: 3.1.0(encoding@0.1.13) @@ -48836,6 +50789,10 @@ snapshots: zimmerframe@1.1.2: {} + zksync-ethers@6.15.3(ethers@6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5)): + dependencies: + ethers: 6.13.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) + zlibjs@0.3.1: {} zod-to-json-schema@3.24.1(zod@3.23.8): diff --git a/tests/test1.mjs b/tests/test1.mjs index 199ce48ec2..4b3c95017b 100644 --- a/tests/test1.mjs +++ b/tests/test1.mjs @@ -3,14 +3,155 @@ import { send, log, logError, runIntegrationTest } from "./testLibrary.mjs"; async function helloTrump() { const reply = await send("Hi"); - assert(reply.length > 10); + assert(reply.length > 0, "Response should not be empty"); + const response = reply[0]; + assert(response.text, "Response should have text property"); + assert( + response.text.length > 10, + `Response should be longer than 10 characters, is ${reply.length}` + ); } +helloTrump.description = "Hello Trump"; +helloTrump.skipIf = !process.env.OPENAI_API_KEY; -async function coinbaseTest() { - // TODO +async function coinbaseCommerceChargeTest() { + const chargeDescription = "Exclusive digital artwork collection"; + const chargeRequest = `Create a charge for $100 USD for Digital Art NFT with description '${chargeDescription}'`; + const response = await send(chargeRequest); + + // Verify response structure + assert(Array.isArray(response), "Response should be an array"); + assert(response.length === 2, "Response should contain two messages"); + + // Verify initial response + const initialResponse = response[0]; + assert.strictEqual(initialResponse.action, "CREATE_CHARGE"); + + // Verify charge creation response + const chargeResponse = response[1]; + assert( + chargeResponse.text.startsWith("Charge created successfully:"), + "Should indicate successful charge creation" + ); + assert( + chargeResponse.text.includes("https://commerce.coinbase.com/pay/"), + "Should contain valid Coinbase Commerce URL" + ); + + // Verify attachment structure + assert( + Array.isArray(chargeResponse.attachments), + "Should have attachments array" + ); + assert( + chargeResponse.attachments.length === 1, + "Should have one attachment" + ); + + const attachment = chargeResponse.attachments[0]; + assert.strictEqual(attachment.source, "coinbase"); + assert.strictEqual(attachment.title, "Coinbase Commerce Charge"); + assert(attachment.id, "Should have an ID"); + assert(attachment.url, "Should have a charge ID URL"); + assert( + attachment.description.startsWith("Charge ID:"), + "Should have charge ID description" + ); + assert(attachment.text.startsWith("Pay here:"), "Should have payment URL"); + assert( + attachment.text.includes("https://commerce.coinbase.com/pay/"), + "Should have valid Coinbase Commerce URL" + ); + + // Store the created charge ID for later comparison + const createdChargeId = attachment.id; + const createdChargeUrl = attachment.url; + + // Fetch and verify all charges + const chargesResponse = await send("Fetch all charges"); + + // Verify response structure + assert( + Array.isArray(chargesResponse), + "Charges response should be an array" + ); + assert( + chargesResponse.length === 2, + "Should have two messages (prompt and response)" + ); + + // Verify charges data + const charges = chargesResponse[1].attachments; + assert(Array.isArray(charges), "Charges should be an array"); + assert(charges.length > 0, "Should have at least one charge"); + + // Verify each charge has required properties + charges.forEach((charge) => { + assert(charge.id, "Each charge should have an id"); + assert(charge.hosted_url, "Each charge should have a hosted_url"); + assert( + charge.hosted_url.includes("commerce.coinbase.com/pay/"), + "hosted_url should be a valid Coinbase URL" + ); + assert(charge.web3_data, "Each charge should have web3_data object"); + }); + + // Verify the previously created charge exists in the list + const foundCharge = charges.find((charge) => charge.id === createdChargeId); + assert(foundCharge, "Previously created charge should exist in the list"); + assert.strictEqual( + foundCharge.hosted_url, + createdChargeUrl, + "Hosted URL should match" + ); + assert.strictEqual( + foundCharge.description, + chargeDescription, + "Description should match" + ); + + // Test GetChargeDetails action + const getDetailsResponse = await send( + `Get details for charge ID: ${createdChargeId}` + ); + + // Verify response structure for charge details + assert( + Array.isArray(getDetailsResponse), + "GetChargeDetails response should be an array" + ); + assert( + getDetailsResponse.length === 2, + "Should have two messages (prompt and response)" + ); + + // Verify charge details response + const detailsResponse = getDetailsResponse[1]; + assert( + Array.isArray(detailsResponse.attachments), + "Should have attachments array" + ); + + const detailsAttachment = detailsResponse.attachments[0]; + + const chargeData = JSON.parse(detailsAttachment.description); + + assert.equal( + chargeData.data.hosted_url, + createdChargeUrl, + "Hosted URLs should match" + ); + assert.equal( + chargeData.data.description, + chargeDescription, + "Charge description should match" + ); } +coinbaseCommerceChargeTest.description = "Coinbase Commerce Charge"; +coinbaseCommerceChargeTest.skipIf = + !process.env.OPENAI_API_KEY || !process.env.COINBASE_COMMERCE_KEY; -const testSuite = [helloTrump]; // Add tests here +const testSuite = [helloTrump, coinbaseCommerceChargeTest]; try { for (const test of testSuite) await runIntegrationTest(test); } catch (error) { diff --git a/tests/testLibrary.mjs b/tests/testLibrary.mjs index ad76251b38..1fffdf05d8 100644 --- a/tests/testLibrary.mjs +++ b/tests/testLibrary.mjs @@ -7,6 +7,7 @@ export const DEFAULT_AGENT_ID = stringToUuid(DEFAULT_CHARACTER ?? uuidv4()); function projectRoot() { return path.join(import.meta.dirname, ".."); + // return "/Users/piotr/Documents/GitHub/Sifchain/eliza" } function log(message) { @@ -109,7 +110,7 @@ async function sendPostRequest(url, method, payload) { if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`); const data = await response.json(); - return data[0].text; + return data; } catch (error) { throw new Error(`Failed to send message: ${error.message}`); } @@ -125,15 +126,38 @@ async function send(message) { } async function runIntegrationTest(fn) { - const proc = await startAgent(); - try { - await fn(); - log("✓ Test passed"); - } catch (error) { - log("✗ Test failed"); - logError(error); - } finally { - await stopAgent(proc); + log(fn); + const skip = fn.hasOwnProperty("skipIf") ? fn.skipIf : false; + if (skip) { + log( + fn.description + ? `Skipping test ${fn.description}...` + : "Skipping test..." + ); + } else { + log( + fn.description + ? `Running test ${fn.description}...` + : "Running test..." + ); + const proc = await startAgent(); + try { + await fn(); + log( + fn.description + ? `✓ Test ${fn.description} passed` + : "✓ Test passed" + ); + } catch (error) { + log( + fn.description + ? `✗ Test ${fn.description} failed` + : "✗ Test failed" + ); + logError(error); + } finally { + await stopAgent(proc); + } } } @@ -149,4 +173,5 @@ export { runIntegrationTest, log, logError, + sleep, };