diff --git a/.env.example b/.env.example index 414f963858..0a8bdcac23 100644 --- a/.env.example +++ b/.env.example @@ -340,3 +340,11 @@ STORY_PRIVATE_KEY= # Story private key STORY_API_BASE_URL= # Story API base URL STORY_API_KEY= # Story API key PINATA_JWT= # Pinata JWT for uploading files to IPFS + +# Cosmos based networks +COSMOS_MNEMONIC= # Mnemonic to generate cosmos accounts +COSMOS_CHAIN_NAME= # chainName matching with chain-registry entries here: https://github.com/cosmos/chain-registry +COSMOS_RPC_URL= # (optional) rpc url for the chain. ex: https://rpc.osmosis.zone:443 +COSMOS_CHAIN_DENOM= # (optional) the base token denom +COSMOS_CHAIN_DECIMALS=6 # (optional) the decimals for token actions. default is 6 +COSMOS_COINGECKO_ID=osmosis # the coingecko id of the token \ No newline at end of file diff --git a/packages/plugin-cosmos/.npmignore b/packages/plugin-cosmos/.npmignore new file mode 100644 index 0000000000..078562ecea --- /dev/null +++ b/packages/plugin-cosmos/.npmignore @@ -0,0 +1,6 @@ +* + +!dist/** +!package.json +!readme.md +!tsup.config.ts \ No newline at end of file diff --git a/packages/plugin-cosmos/eslint.config.mjs b/packages/plugin-cosmos/eslint.config.mjs new file mode 100644 index 0000000000..92fe5bbebe --- /dev/null +++ b/packages/plugin-cosmos/eslint.config.mjs @@ -0,0 +1,3 @@ +import eslintGlobalConfig from "../../eslint.config.mjs"; + +export default [...eslintGlobalConfig]; diff --git a/packages/plugin-cosmos/package.json b/packages/plugin-cosmos/package.json new file mode 100644 index 0000000000..cda377ab92 --- /dev/null +++ b/packages/plugin-cosmos/package.json @@ -0,0 +1,29 @@ +{ + "name": "@ai16z/plugin-cosmos", + "version": "0.1.0-alpha.1", + "main": "dist/index.js", + "type": "module", + "types": "dist/index.d.ts", + "dependencies": { + "@ai16z/eliza": "workspace:*", + "bignumber.js": "9.1.2", + "node-cache": "5.1.2", + "tsup": "8.3.5", + "@cosmjs/stargate": "^0.29.2", + "@cosmjs/amino": "^0.29.2", + "cosmjs-utils": "*", + "osmojs": "16.15.0", + "chain-registry": "*", + "vitest": "^0.34.1" + }, + "scripts": { + "build": "tsup --format esm,cjs --dts", + "test": "vitest run", + "test:watch": "vitest", + "lint": "eslint . --fix" + }, + "peerDependencies": { + "whatwg-url": "7.1.0", + "form-data": "4.0.1" + } + } diff --git a/packages/plugin-cosmos/src/actions/transfer.ts b/packages/plugin-cosmos/src/actions/transfer.ts new file mode 100644 index 0000000000..0eaa53ec3e --- /dev/null +++ b/packages/plugin-cosmos/src/actions/transfer.ts @@ -0,0 +1,290 @@ +import { + ActionExample, + Content, + HandlerCallback, + IAgentRuntime, + Memory, + ModelClass, + State, + type Action, + composeContext, + generateObject, + } from "@ai16z/eliza"; + import { chains } from "chain-registry"; + import { getOfflineSignerProto as getOfflineSigner } from "cosmjs-utils"; + import { SigningStargateClient } from "@cosmjs/stargate"; + import { coins, StdFee } from "@cosmjs/amino"; + + export interface TransferContent extends Content { + recipient: string; + amount: string | number; + tokenAddress?: string; // optional if we want to handle cw20 or other tokens + } + + function isTransferContent( + runtime: IAgentRuntime, + content: any + ): content is TransferContent { + return ( + typeof content.recipient === "string" && + (typeof content.amount === "string" || typeof content.amount === "number") + ); + } + + 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 + { + "recipient": "osmo1abcd1234...", + "amount": "1.5", + "tokenAddress": null + } + \`\`\` + + {{recentMessages}} + + Given the recent messages and wallet information below: + + {{walletInfo}} + + Extract the following information about the requested token transfer: + - Recipient address + - Amount to transfer + - Token contract address (null for native transfers) + + Respond with a JSON markdown block containing only the extracted values. + `; + + /** + * Quickly checks if an RPC endpoint is reachable by fetching /status. + * Return true if ok, false if not. + */ + async function canGetStatus(rpcUrl: string): Promise { + try { + const url = rpcUrl.endsWith("/") ? rpcUrl + "status" : `${rpcUrl}/status`; + const response = await fetch(url, { method: "GET" }); + if (!response.ok) { + throw new Error(`RPC /status responded with HTTP ${response.status}`); + } + return true; + } catch { + return false; + } + } + + async function getWorkingRpcUrl(rpcUrls: string[]): Promise { + for (const url of rpcUrls) { + if (await canGetStatus(url)) { + return url; + } + } + return null; + } + + /** + * Transfer tokens, preferring env-based RPC/DENOM/DECIMALS, else chain-registry. + */ + async function transferTokens( + runtime: IAgentRuntime, + recipient: string, + amount: string + ): Promise { + // 1) Identify chain + mnemonic + const chainName = runtime.getSetting("COSMOS_CHAIN_NAME") || "osmosis"; + const mnemonic = runtime.getSetting("COSMOS_MNEMONIC"); + if (!mnemonic) { + throw new Error("COSMOS_MNEMONIC not configured"); + } + + // 2) Lookup chain in registry + const chain = chains.find((c) => c.chain_name === chainName); + if (!chain) { + throw new Error(`Chain '${chainName}' not found in chain-registry`); + } + + // 3) Build a candidate RPC list + // First, check env-based RPC + const candidateRpcs: string[] = []; + const envRpc = runtime.getSetting("COSMOS_RPC_URL"); + if (envRpc) { + candidateRpcs.push(envRpc); + } + // Then add chain-registry RPC endpoints + const registryRpcs = chain.apis?.rpc?.map((r) => r.address) ?? []; + candidateRpcs.push(...registryRpcs); + + // 4) Find a working RPC by checking /status + const workingRpc = await getWorkingRpcUrl(candidateRpcs); + if (!workingRpc) { + throw new Error(`No working RPC endpoint found for '${chainName}'`); + } + + // 5) Determine denom & decimals + // - If env is set, prefer that + // - else fallback to chain.fees + const chainFees = chain.fees?.fee_tokens?.[0]; + const envDenom = runtime.getSetting("COSMOS_DENOM"); + const envDecimals = runtime.getSetting("COSMOS_DECIMALS"); + + const defaultDenom = chainFees?.denom || "uosmo"; + const denom = envDenom || defaultDenom; + const decimals = envDecimals ? Number(envDecimals) : 6; // or read from chain data + + // average gas price + const averageGasPrice = chainFees?.average_gas_price ?? 0.025; + + // 6) Create offline signer + const signer = await getOfflineSigner({ + mnemonic, + chain, + }); + + // 7) Connect Stargate client w/ signer + const stargateClient = await SigningStargateClient.connectWithSigner( + workingRpc, + signer + ); + + // 8) Build the transaction + const [fromAccount] = await signer.getAccounts(); + const fromAddress = fromAccount.address; + const shift = 10 ** decimals; + const sendAmount = String(Math.floor(Number(amount) * shift)); + + const msg = { + typeUrl: "/cosmos.bank.v1beta1.MsgSend", + value: { + fromAddress, + toAddress: recipient, + amount: coins(sendAmount, denom), + }, + }; + const messages = [msg]; + const memo = ""; + + // 9) Estimate gas usage + const gasEstimated = await stargateClient.simulate(fromAddress, messages, memo); + const feeAmount = Math.floor(gasEstimated * averageGasPrice).toString(); + + const fee: StdFee = { + amount: coins(feeAmount, denom), + gas: gasEstimated.toString(), + }; + + // 10) Sign & broadcast + const result = await stargateClient.signAndBroadcast( + fromAddress, + messages, + fee, + memo + ); + + return result.transactionHash; + } + + export const executeTransfer: Action = { + name: "SEND_COSMOS", + similes: ["TRANSFER_COSMOS", "SEND_TOKENS", "TRANSFER_TOKENS", "PAY_COSMOS"], + validate: async (_runtime: IAgentRuntime, _message: Memory) => { + // Add your validation logic if needed + return true; + }, + description: "Transfer native Cosmos tokens to another address", + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + _options: { [key: string]: unknown }, + callback?: HandlerCallback + ): Promise => { + // 1) Ensure up-to-date state + if (!state) { + state = (await runtime.composeState(message)) as State; + } else { + state = await runtime.updateRecentMessageState(state); + } + + // 2) Compose transfer context + const transferContext = composeContext({ + state, + template: transferTemplate, + }); + + // 3) Generate JSON from user conversation + const content = await generateObject({ + runtime, + context: transferContext, + modelClass: ModelClass.SMALL, + }); + + // 4) Validate + if (!isTransferContent(runtime, content)) { + console.error("Invalid content for SEND_COSMOS action."); + if (callback) { + callback({ + text: "Unable to process transfer request. Invalid content provided.", + content: { error: "Invalid transfer content" }, + }); + } + return false; + } + + try { + // 5) Transfer + const txHash = await transferTokens( + runtime, + content.recipient, + content.amount.toString() + ); + + // 6) If successful + if (callback) { + callback({ + text: `Successfully transferred ${content.amount} tokens to ${content.recipient}\nTransaction: ${txHash}`, + content: { + success: true, + signature: txHash, + amount: content.amount, + recipient: content.recipient, + }, + }); + } + return true; + } catch (error) { + console.error("Error during Cosmos transfer:", error); + if (callback) { + callback({ + text: `Error transferring tokens: ${error}`, + content: { error }, + }); + } + return false; + } + }, + + // 7) Example usage + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Send 1.5 tokens to osmo1abcd1234...", + }, + }, + { + user: "{{user2}}", + content: { + text: "I'll send 1.5 OSMO now...", + action: "SEND_COSMOS", + }, + }, + { + user: "{{user2}}", + content: { + text: "Successfully sent 1.5 OSMO to osmo1abcd1234...\nTransaction: ABC123XYZ", + }, + }, + ], + ] as ActionExample[][], + } as Action; diff --git a/packages/plugin-cosmos/src/environment.ts b/packages/plugin-cosmos/src/environment.ts new file mode 100644 index 0000000000..d2d90ea9e6 --- /dev/null +++ b/packages/plugin-cosmos/src/environment.ts @@ -0,0 +1,53 @@ +import { IAgentRuntime } from "@elizaos/core"; +import { z } from "zod"; + +/** + * Example environment variables for Cosmos + * that mimic the NEAR example structure + */ +export const cosmosEnvSchema = z.object({ + COSMOS_MNEMONIC: z.string().min(1, "Cosmos wallet mnemonic is required"), + COSMOS_CHAIN_NAME: z.string().default("osmosis"), + COSMOS_RPC_URL: z.string().default("https://rpc.osmosis.zone"), + COSMOS_DENOM: z.string().default("uosmo"), + COSMOS_DECIMALS: z.string().default("6"), +}); + +/** + * Type for the validated config + */ +export type CosmosConfig = z.infer; + +/** + * Simple config loader that merges runtime settings with environment variables + */ +export async function validateCosmosConfig( + runtime: IAgentRuntime +): Promise { + try { + const config = { + COSMOS_MNEMONIC: + runtime.getSetting("COSMOS_MNEMONIC") || process.env.COSMOS_MNEMONIC, + COSMOS_CHAIN_NAME: + runtime.getSetting("COSMOS_CHAIN_NAME") || process.env.COSMOS_CHAIN_NAME, + COSMOS_RPC_URL: + runtime.getSetting("COSMOS_RPC_URL") || process.env.COSMOS_RPC_URL, + COSMOS_DENOM: + runtime.getSetting("COSMOS_DENOM") || process.env.COSMOS_DENOM, + COSMOS_DECIMALS: + runtime.getSetting("COSMOS_DECIMALS") || process.env.COSMOS_DECIMALS, + }; + + return cosmosEnvSchema.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( + `Cosmos configuration validation failed:\n${errorMessages}` + ); + } + throw error; + } +} diff --git a/packages/plugin-cosmos/src/index.ts b/packages/plugin-cosmos/src/index.ts new file mode 100644 index 0000000000..2a6aea8fcb --- /dev/null +++ b/packages/plugin-cosmos/src/index.ts @@ -0,0 +1,14 @@ +import { Plugin } from "@ai16z/eliza/src/types"; +import { walletProvider } from "./providers/wallet"; +import { executeTransfer } from "./actions/transfer"; +// If you want to implement swap, custom tokens, etc., create the files similarly and import them. + +export const cosmosPlugin: Plugin = { + name: "COSMOS", + description: "Cosmos (e.g. Osmosis) Plugin for Eliza", + providers: [walletProvider], + actions: [executeTransfer], + evaluators: [], +}; + +export default cosmosPlugin; diff --git a/packages/plugin-cosmos/src/providers/wallet.ts b/packages/plugin-cosmos/src/providers/wallet.ts new file mode 100644 index 0000000000..e03184f3ab --- /dev/null +++ b/packages/plugin-cosmos/src/providers/wallet.ts @@ -0,0 +1,338 @@ +import { + IAgentRuntime, + Memory, + Provider, + State + } from "@ai16z/eliza"; + import { chains } from "chain-registry"; + import BigNumber from "bignumber.js"; + import NodeCache from "node-cache"; + import { getOfflineSignerProto as getOfflineSigner } from "cosmjs-utils"; + import { SigningStargateClient } from "@cosmjs/stargate"; + + /** + * Minimal CosmosChainInfo shape for demonstration. + * Extend as needed to match your usage. + */ + interface CosmosChainInfo { + chain_name: string; + denom?: string; + decimals?: number; + coingecko_id: string; + bech32_prefix: string; + apis?: { + rpc?: Array<{ address: string }>; + }; + fees?: { + fee_tokens?: Array<{ + denom: string; + average_gas_price?: number; + }>; + }; + } + + /** + * Basic token interface for the portfolio + */ + export interface CosmosToken { + name: string; + symbol: string; + decimals: number; + balance: string; + uiAmount: string; + priceUsd: string; + valueUsd: string; + } + + /** + * Portfolio interface showing total USD plus an array of tokens + */ + interface WalletPortfolio { + totalUsd: string; + tokens: Array; + } + + export class WalletProvider implements Provider { + private cache: NodeCache; + private stargateClient: SigningStargateClient | null = null; + private signerAddress: string | null = null; + + constructor( + private mnemonic: string, + private chainInfo: CosmosChainInfo + ) { + // console.log("WalletProvider instantiated with chainInfo:", chainInfo); + this.cache = new NodeCache({ stdTTL: 300 }); // 5-min TTL + } + + /** + * The Eliza framework calls this method to "get" data from the provider. + * Here we simply fetch the user's formatted portfolio. + */ + async get( + runtime: IAgentRuntime, + _message: Memory, + _state?: State + ): Promise { + try { + return await this.getFormattedPortfolio(runtime); + } catch (error) { + console.error("Error in wallet provider get:", error); + return null; + } + } + + /** + * Connect once, returning a SigningStargateClient + */ + public async connect(runtime: IAgentRuntime): Promise { + if (this.stargateClient) return this.stargateClient; + if (!this.mnemonic) { + throw new Error("Cosmos wallet mnemonic not provided"); + } + + // Grab the first RPC in chainInfo.apis + const rpcUrl = this.chainInfo.apis?.rpc?.[0]?.address; + if (!rpcUrl) { + throw new Error("No RPC endpoint specified in chainInfo"); + } + + const signer = await getOfflineSigner({ + mnemonic: this.mnemonic, + chain: this.chainInfo, + }); + + const stargateClient = await SigningStargateClient.connectWithSigner(rpcUrl, signer); + const [account] = await signer.getAccounts(); + this.signerAddress = account.address; + this.stargateClient = stargateClient; + + console.log("Agent init with signer address: ", this.signerAddress) + return stargateClient; + } + + /** + * Retrieves balance for a single token, fetches price, calculates portfolio + * with additional checks to handle NaN or invalid values. + */ + async fetchPortfolioValue(runtime: IAgentRuntime): Promise { + const cacheKey = `portfolio-${this.chainInfo.chain_name}`; + const cachedValue = this.cache.get(cacheKey); + if (cachedValue) { + console.log("Cache hit for fetchPortfolioValue"); + return cachedValue; + } + + // Connect if not already + const client = await this.connect(runtime); + if (!this.signerAddress) { + throw new Error("Signer address not available after connect"); + } + + // 1) Safely determine denom & decimals + const denom = this.chainInfo.denom || "uosmo"; + + // parse the decimals as an integer + let decimals = parseInt(String(this.chainInfo.decimals), 10); + if (isNaN(decimals) || decimals < 1) { + console.warn( + `Invalid or missing decimals (${this.chainInfo.decimals}), defaulting to 1` + ); + decimals = 1; + } + + // 2) Fetch all balances from the chain + const balances = await client.getAllBalances(this.signerAddress); + const baseTokenBalance = balances.find((b) => b.denom === denom); + let rawBalance = baseTokenBalance?.amount ?? "0"; + + // 3) Coingecko ID from chainInfo or fallback + const cgID = this.chainInfo.coingecko_id || "osmosis"; + + let tokenPriceUsd = await this.fetchTokenPrice(runtime, cgID); + + // 4) Ensure rawBalance is a valid number + let balanceBN = new BigNumber(rawBalance); + if (!balanceBN.isFinite()) { + console.warn(`Invalid raw balance value: ${rawBalance}, defaulting to 0.`); + balanceBN = new BigNumber(0); + } + + // Also ensure tokenPriceUsd is numeric + if (isNaN(tokenPriceUsd) || !tokenPriceUsd) { + console.warn(`Invalid token price: ${tokenPriceUsd}, defaulting to 0.`); + tokenPriceUsd = 0; + } + + // 5) Convert minimal denom -> "1" denom + const convertedBalance = balanceBN.shiftedBy(-decimals); + const valueUsd = convertedBalance.multipliedBy(tokenPriceUsd).toFixed(); + + // Construct a simple portfolio + const portfolio: WalletPortfolio = { + totalUsd: valueUsd, + tokens: [ + { + name: this.chainInfo.chain_name ?? "Cosmos Chain", + symbol: denom.toUpperCase(), + decimals, + balance: balanceBN.toFixed(), // store the validated balance + uiAmount: convertedBalance.toString(), + priceUsd: String(tokenPriceUsd), + valueUsd, + }, + ], + }; + + this.cache.set(cacheKey, portfolio); + return portfolio; + } + + /** + * Fetch price from Coingecko (or 0 if fails) + */ + private async fetchTokenPrice(runtime: IAgentRuntime, cgID: string): Promise { + const cacheKey = `price-${cgID}`; + const cachedPrice = this.cache.get(cacheKey); + if (cachedPrice !== undefined && cachedPrice) { + return cachedPrice; + } + + try { + // For example: fetch OSMO price if cgID = "osmosis" + const url = `https://api.coingecko.com/api/v3/simple/price?ids=${cgID}&vs_currencies=usd`; + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Error fetching price for ${cgID}. Status: ${response.status}`); + } + const data = await response.json(); + + const price = data[cgID]?.usd ?? 0; + this.cache.set(cacheKey, price); + return price; + } catch (error) { + console.error("Error fetching token price:", error); + return 0; + } + } + + /** + * Format the portfolio into a text string + */ + formatPortfolio(runtime: IAgentRuntime, portfolio: WalletPortfolio): string { + let output = ``; + output += `Chain: ${this.chainInfo.chain_name}\n`; + + if (this.signerAddress) { + output += `Account Address: ${this.signerAddress}\n\n`; + } + + const totalUsd = new BigNumber(portfolio.totalUsd).toFixed(2); + output += `Total Value: $${totalUsd}\n\nToken Balances:\n`; + + for (const token of portfolio.tokens) { + const valUsd = new BigNumber(token.valueUsd).toFixed(2); + output += `${token.name} (${token.symbol}): ${token.uiAmount} ($${valUsd})\n`; + } + + output += `\nMarket Prices:\n`; + for (const token of portfolio.tokens) { + const tokenPriceUsd = new BigNumber(token.priceUsd).toFixed(2); + output += `${token.symbol}: $${tokenPriceUsd}\n`; + } + + return output; + } + + /** + * Convenience method to fetch + format + */ + async getFormattedPortfolio(runtime: IAgentRuntime): Promise { + try { + const portfolio = await this.fetchPortfolioValue(runtime); + return this.formatPortfolio(runtime, portfolio); + } catch (error) { + console.error("Error generating portfolio report:", error); + return "Unable to fetch wallet information. Please try again later."; + } + } + } + + /** + * Single exported provider. + * If COSMOS_RPC_URL is set, we create a local chainInfo. + * Otherwise, we load chainInfo from chain-registry for chain_name. + */ + const walletProvider: Provider = { + get: async (runtime, message, state) => { + try { + // 1) Pull settings from environment or .env + const mnemonic = runtime.getSetting("COSMOS_MNEMONIC"); + if (!mnemonic) { + throw new Error("COSMOS_MNEMONIC not configured"); + } + const coingeckoID = runtime.getSetting("COSMOS_COINGECKO_ID") || "osmosis"; + const chainName = runtime.getSetting("COSMOS_CHAIN_NAME") || "osmosis"; + + // 2) Check if user provided a custom RPC via COSMOS_RPC_URL + const customRpc = runtime.getSetting("COSMOS_RPC_URL"); + if (customRpc) { + // Possibly read denom, decimals, and bech32_prefix from env or use defaults + const customDenom = runtime.getSetting("COSMOS_CHAIN_DENOM") || "uosmo"; + // We'll parse the env decimals as integer, min 1 is enforced inside fetchPortfolioValue + const customDecimals = Number(runtime.getSetting("COSMOS_CHAIN_DECIMALS") || 6); + const bech32Prefix = runtime.getSetting("COSMOS_BECH32_PREFIX") || "osmo"; + + // Example fallback average gas price + const averageGasPrice = 0.025; + + // 2A) Construct a minimal chainInfo object from environment + const localChainInfo: CosmosChainInfo = { + chain_name: chainName, + bech32_prefix: bech32Prefix, + coingecko_id: coingeckoID, + apis: { rpc: [{ address: customRpc }] }, + fees: { + fee_tokens: [ + { + denom: customDenom, + average_gas_price: averageGasPrice + } + ] + }, + denom: customDenom, + decimals: customDecimals + }; + + const provider = new WalletProvider(mnemonic, localChainInfo); + return provider.getFormattedPortfolio(runtime); + } else { + // 2B) Otherwise, load chainInfo from chain-registry + const chainData = chains.find(c => c.chain_name === chainName); + if (!chainData) { + throw new Error(`Chain '${chainName}' not found in chain-registry`); + } + + // Optionally store denom/decimals from chainData or env + const chainDenom = chainData.fees?.fee_tokens?.[0]?.denom || "uosmo"; + // We'll parse from chainData, but min 1 is enforced inside fetchPortfolioValue + const chainDecimals = chainData.decimals || 6; + + chainData.denom = chainDenom; + chainData.decimals = chainDecimals; + + if (!chainData.coingecko_id) { + chainData.coingecko_id = coingeckoID; // fallback + } + + const provider = new WalletProvider(mnemonic, chainData as CosmosChainInfo); + return provider.getFormattedPortfolio(runtime); + } + } catch (error) { + console.error("Error in wallet provider:", error); + return null; + } + }, + }; + + export { walletProvider }; diff --git a/packages/plugin-cosmos/src/tests/wallet.test.ts b/packages/plugin-cosmos/src/tests/wallet.test.ts new file mode 100644 index 0000000000..1864e49db6 --- /dev/null +++ b/packages/plugin-cosmos/src/tests/wallet.test.ts @@ -0,0 +1,163 @@ +import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"; +import { walletProvider } from "../providers/wallet"; +import { defaultCharacter } from "@ai16z/eliza"; +import { ModelClass, State } from "@ai16z/eliza"; +import { chains } from 'chain-registry/testnet'; +import { executeTransfer } from "../actions/transfer"; + +// Mock NodeCache so there's no actual caching side effects +vi.mock("node-cache", () => { + return { + default: vi.fn().mockImplementation(() => ({ + set: vi.fn(), + get: vi.fn().mockReturnValue(null), + })), + }; +}); + +// Mock path if needed +vi.mock("path", async () => { + const actual = await vi.importActual("path"); + return { + ...actual, + join: vi.fn().mockImplementation((...args) => args.join("/")), + }; +}); + +// For demonstration, we mock the entire stargate client so no real network calls +vi.mock("@cosmjs/stargate", () => { + return { + // Partial mock with the classes we need + SigningStargateClient: { + connectWithSigner: vi.fn().mockResolvedValue({ + getAllBalances: vi.fn().mockResolvedValue([ + { denom: "uosmo", amount: "1230000" }, // 1.23 OSMO + ]), + // Example account with minimal data + getSignerAccounts: vi.fn().mockResolvedValue([ + { address: "osmo1mock..." }, + ]), + }), + }, + }; +}); + +// (Optional) If you're testing price fetch from Coingecko, you can also mock fetch +vi.mock(globalThis.fetch ? 'node-fetch' : 'cross-fetch', () => ({ + __esModule: true, + default: vi.fn().mockImplementation(() => ({ + ok: true, + json: () => + Promise.resolve({ + osmosis: { usd: 0.9 }, // Example price for OSMO + }), + })), +})); + +describe("Cosmos WalletProvider (getFormattedPortfolio)", () => { + let mockedRuntime: any; + let callbackFn: any; + + beforeEach(() => { + vi.clearAllMocks(); + // Default runtime mock + mockedRuntime = { + character: defaultCharacter, + getSetting: vi.fn(), + }; + }); + + afterEach(() => { + vi.clearAllTimers(); + }); + + it("uses environment variables for RPC, DENOM, and DECIMALS if set", async () => { + // Set environment-based overrides + mockedRuntime.getSetting.mockImplementation((key: string) => { + switch (key) { + case "COSMOS_MNEMONIC": + return "unfold client turtle either pilot stock floor glow toward bullet car science"; + case "COSMOS_CHAIN_NAME": + return "osmosis"; + case "COSMOS_RPC_URL": + return "https://custom.env.rpc/"; + case "COSMOS_CHAIN_DENOM": + return "uenvdenom"; + case "COSMOS_CHAIN_DECIMALS": + return "4"; + case "COSMOS_BECH32_PREFIX": + return "osmo1mock"; + default: + return undefined; + } + }); + + // Execute the provider + const result = await walletProvider.get(mockedRuntime, {} as any); + + // Should mention chain and account address + expect(result).toContain("Chain: osmosis"); + expect(result).toContain("Account Address: osmo1mock"); + + // Should have "Token Balances:" + expect(result).toContain("Token Balances:"); + + // Symbol uppercase from the code => "UENVDENOM" + expect(result).toContain("UENVDENOM"); + + // Should show a total value line (like "Total Value: $1.10" or similar) + // We'll just check the pattern: + expect(result).toMatch(/Total Value: \$[\d,]*\.\d{2}/); + + // Optional: If you want to see the entire result in test logs + // console.log("Portfolio result with env overrides:\n", result); + }); + + it("falls back to chain-registry if env variables are not set", async () => { + // Minimal environment: just mnemonic + chain name + mockedRuntime.getSetting.mockImplementation((key: string) => { + switch (key) { + case "COSMOS_MNEMONIC": + return "unfold client turtle either pilot stock floor glow toward bullet car science"; + case "COSMOS_CHAIN_NAME": + return "osmosistestnet"; + // No COSMOS_RPC_URL, COSMOS_CHAIN_DENOM, COSMOS_CHAIN_DECIMALS + default: + return undefined; + } + }); + + // Confirm chain-registry has 'osmosis' + const chain = chains.find((c) => c.chain_name === "osmosistestnet"); + expect(chain).toBeDefined(); + + // Execute the provider + const result = await walletProvider.get(mockedRuntime, {} as any); + + // Should mention chain and account address + expect(result).toContain("Chain: osmosis"); + expect(result).toContain("Account Address: osmo1"); + + // Should have "Token Balances:" + expect(result).toContain("Token Balances:"); + + // In fallback, the code sets denom to "uosmo", thus symbol => "UOSMO" + expect(result).toContain("UOSMO"); + + // Check total value + expect(result).toMatch(/Total Value: \$[\d,]*\.\d{2}/); + }); + + it("returns null if COSMOS_MNEMONIC is not set", async () => { + // We intentionally do not provide a mnemonic + mockedRuntime.getSetting.mockImplementation((key: string) => { + if (key === "COSMOS_CHAIN_NAME") return "osmosis"; + return undefined; + }); + + const result = await walletProvider.get(mockedRuntime, {} as any); + + // Should return null since the mnemonic is missing + expect(result).toBeNull(); + }); +}); diff --git a/packages/plugin-cosmos/tsconfig.json b/packages/plugin-cosmos/tsconfig.json new file mode 100644 index 0000000000..95cbe371ac --- /dev/null +++ b/packages/plugin-cosmos/tsconfig.json @@ -0,0 +1,21 @@ +{ + "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" + ] +} \ No newline at end of file diff --git a/packages/plugin-cosmos/tsup.config.ts b/packages/plugin-cosmos/tsup.config.ts new file mode 100644 index 0000000000..96d9c23733 --- /dev/null +++ b/packages/plugin-cosmos/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/pnpm-lock.yaml b/pnpm-lock.yaml index 09aa1202d4..bae1514052 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1509,6 +1509,45 @@ importers: specifier: 8.3.5 version: 8.3.5(@swc/core@1.10.1(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) + packages/plugin-osmosis: + dependencies: + '@ai16z/eliza': + specifier: workspace:* + version: link:../core + '@cosmjs/amino': + specifier: ^0.29.2 + version: 0.29.5 + '@cosmjs/stargate': + specifier: ^0.29.2 + version: 0.29.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bignumber.js: + specifier: 9.1.2 + version: 9.1.2 + chain-registry: + specifier: '*' + version: 1.69.71 + cosmjs-utils: + specifier: '*' + version: 0.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + form-data: + specifier: 4.0.1 + version: 4.0.1 + node-cache: + specifier: 5.1.2 + version: 5.1.2 + osmojs: + specifier: 16.15.0 + version: 16.15.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + tsup: + specifier: 8.3.5 + version: 8.3.5(@swc/core@1.10.1(@swc/helpers@0.5.15))(jiti@2.4.2)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) + vitest: + specifier: ^0.34.1 + version: 0.34.6(jsdom@25.0.1(bufferutil@4.0.8)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(playwright@1.48.2)(terser@5.37.0) + whatwg-url: + specifier: 7.1.0 + version: 7.1.0 + packages/plugin-solana: dependencies: '@coral-xyz/anchor': @@ -3008,6 +3047,9 @@ packages: '@cfworker/json-schema@4.0.3': resolution: {integrity: sha512-ZykIcDTVv5UNmKWSTLAs3VukO6NDJkkSKxrgUTDPBkAlORVT3H9n5DbRjRl8xIotklscHdbLIa0b9+y3mQq73g==} + '@chain-registry/types@0.50.41': + resolution: {integrity: sha512-GT1FmCgtJLAkVy2fOD7VOn9SHDOMeLUshiCjtQhmXQiIEoycn3tUJk7HSser5Wf35wq3a2OqeY7f7iKs4/Tlzw==} + '@chevrotain/cst-dts-gen@11.0.3': resolution: {integrity: sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==} @@ -3120,6 +3162,9 @@ packages: resolution: {integrity: sha512-gwRLBLra/Dozj2OywopeuHj2ac26gjGkz2cZ+86cTJOdtWfiRRr4+e77ZDAGc6MDWxaWheI+mAV5TLWWRwqrFg==} engines: {node: '>=v18'} + '@confio/ics23@0.6.8': + resolution: {integrity: sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==} + '@coral-xyz/anchor-errors@0.30.1': resolution: {integrity: sha512-9Mkradf5yS5xiLWrl9WrpjqOrAV+/W2RQHDlbnAZBivoGpOs1ECjoDCkVk4aRG8ZdiFiB8zQEVlxf+8fKkmSfQ==} engines: {node: '>=10'} @@ -3144,6 +3189,87 @@ packages: peerDependencies: '@solana/web3.js': ^1.68.0 + '@cosmjs/amino@0.29.0': + resolution: {integrity: sha512-/ZUVx6nRN5YE36H3SDq9+i8g2nZ8DJQnN9fVRC8rSHQKauNkoEuK4NxTNcQ2o2EBLUT0kyYAFY2550HVsPMrgw==} + + '@cosmjs/amino@0.29.5': + resolution: {integrity: sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw==} + + '@cosmjs/amino@0.32.3': + resolution: {integrity: sha512-G4zXl+dJbqrz1sSJ56H/25l5NJEk/pAPIr8piAHgbXYw88OdAOlpA26PQvk2IbSN/rRgVbvlLTNgX2tzz1dyUA==} + + '@cosmjs/crypto@0.29.0': + resolution: {integrity: sha512-MPJoebRGh7AcZgbfR25ci7iV+XzJiKwVq4wL8n6M5P2QdrIv7DqqniyFXcBbn9dQjMLMHnOSgT9LRv+VXzUVCA==} + + '@cosmjs/crypto@0.29.5': + resolution: {integrity: sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ==} + + '@cosmjs/crypto@0.32.4': + resolution: {integrity: sha512-zicjGU051LF1V9v7bp8p7ovq+VyC91xlaHdsFOTo2oVry3KQikp8L/81RkXmUIT8FxMwdx1T7DmFwVQikcSDIw==} + + '@cosmjs/encoding@0.29.5': + resolution: {integrity: sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ==} + + '@cosmjs/encoding@0.32.4': + resolution: {integrity: sha512-tjvaEy6ZGxJchiizzTn7HVRiyTg1i4CObRRaTRPknm5EalE13SV+TCHq38gIDfyUeden4fCuaBVEdBR5+ti7Hw==} + + '@cosmjs/json-rpc@0.29.5': + resolution: {integrity: sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w==} + + '@cosmjs/json-rpc@0.32.4': + resolution: {integrity: sha512-/jt4mBl7nYzfJ2J/VJ+r19c92mUKF0Lt0JxM3MXEJl7wlwW5haHAWtzRujHkyYMXOwIR+gBqT2S0vntXVBRyhQ==} + + '@cosmjs/math@0.29.5': + resolution: {integrity: sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q==} + + '@cosmjs/math@0.32.4': + resolution: {integrity: sha512-++dqq2TJkoB8zsPVYCvrt88oJWsy1vMOuSOKcdlnXuOA/ASheTJuYy4+oZlTQ3Fr8eALDLGGPhJI02W2HyAQaw==} + + '@cosmjs/proto-signing@0.29.0': + resolution: {integrity: sha512-zAdgDz5vRGAfJ5yyKYuTL7qg5UNUT7v4iV1/ZP8ZQn2fLh9QVxViAIovF4r/Y3EEI4JS5uYj/f8UeHMHQSu8hw==} + + '@cosmjs/proto-signing@0.29.5': + resolution: {integrity: sha512-QRrS7CiKaoETdgIqvi/7JC2qCwCR7lnWaUsTzh/XfRy3McLkEd+cXbKAW3cygykv7IN0VAEIhZd2lyIfT8KwNA==} + + '@cosmjs/proto-signing@0.32.3': + resolution: {integrity: sha512-kSZ0ZUY0DwcRT0NcIn2HkadH4NKlwjfZgbLj1ABwh/4l0RgeT84QCscZCu63tJYq3K6auwqTiZSZERwlO4/nbg==} + + '@cosmjs/socket@0.29.5': + resolution: {integrity: sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ==} + + '@cosmjs/socket@0.32.4': + resolution: {integrity: sha512-davcyYziBhkzfXQTu1l5NrpDYv0K9GekZCC9apBRvL1dvMc9F/ygM7iemHjUA+z8tJkxKxrt/YPjJ6XNHzLrkw==} + + '@cosmjs/stargate@0.29.0': + resolution: {integrity: sha512-BsV3iA3vMclMm/B1LYO0djBYCALr/UIvL6u9HGvM7QvpdtpQiAvskuS4PieVO/gtF9iCCBJLPqa0scwFIgvDyg==} + + '@cosmjs/stargate@0.29.5': + resolution: {integrity: sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw==} + + '@cosmjs/stargate@0.32.3': + resolution: {integrity: sha512-OQWzO9YWKerUinPIxrO1MARbe84XkeXJAW0lyMIjXIEikajuXZ+PwftiKA5yA+8OyditVmHVLtPud6Pjna2s5w==} + + '@cosmjs/stream@0.29.5': + resolution: {integrity: sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA==} + + '@cosmjs/stream@0.32.4': + resolution: {integrity: sha512-Gih++NYHEiP+oyD4jNEUxU9antoC0pFSg+33Hpp0JlHwH0wXhtD3OOKnzSfDB7OIoEbrzLJUpEjOgpCp5Z+W3A==} + + '@cosmjs/tendermint-rpc@0.29.5': + resolution: {integrity: sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w==} + + '@cosmjs/tendermint-rpc@0.32.3': + resolution: {integrity: sha512-xeprW+VR9xKGstqZg0H/KBZoUp8/FfFyS9ljIUTLM/UINjP2MhiwncANPS2KScfJVepGufUKk0/phHUeIBSEkw==} + + '@cosmjs/utils@0.29.5': + resolution: {integrity: sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==} + + '@cosmjs/utils@0.32.4': + resolution: {integrity: sha512-D1Yc+Zy8oL/hkUkFUL/bwxvuDBzRGpc4cF7/SkdhxX4iHpSLgdOuTt1mhCh9+kl6NQREy9t7SYZ6xeW5gFe60w==} + + '@cosmology/lcd@0.13.5': + resolution: {integrity: sha512-CI8KFsJcgp0RINF8wHpv3Y9yR4Fb9ZnGucyoUICjtX2XT4NVBK+fvZuRFj5TP34km8TpEOb+WV2T7IN/pZsD7Q==} + '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} @@ -7334,6 +7460,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==} @@ -7561,6 +7693,9 @@ packages: '@types/lodash@4.17.13': resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} + '@types/long@4.0.2': + resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} + '@types/lru-cache@5.1.1': resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==} @@ -7913,6 +8048,9 @@ packages: vitest: optional: true + '@vitest/expect@0.34.6': + resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==} + '@vitest/expect@2.1.4': resolution: {integrity: sha512-DOETT0Oh1avie/D/o2sgMHGrzYUFFo3zqESB2Hn70z6QB1HrS2IQ9z5DfyTqU8sg4Bpu13zZe9V4+UTNQlUeQA==} @@ -7950,24 +8088,36 @@ 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@2.1.4': resolution: {integrity: sha512-sKRautINI9XICAMl2bjxQM8VfCMTB0EbsBc/EDFA57V6UQevEKY/TOPOF5nzcvCALltiLfXWbq4MaAwWx/YxIA==} '@vitest/runner@2.1.5': resolution: {integrity: sha512-pKHKy3uaUdh7X6p1pxOkgkVAFW7r2I818vHDthYLvUyjRfkKOU6P45PztOch4DZarWQne+VOaIMwA/erSSpB9g==} + '@vitest/snapshot@0.34.6': + resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==} + '@vitest/snapshot@2.1.4': resolution: {integrity: sha512-3Kab14fn/5QZRog5BPj6Rs8dc4B+mim27XaKWFWHWA87R56AKjHTGcBFKpvZKDzC4u5Wd0w/qKsUIio3KzWW4Q==} '@vitest/snapshot@2.1.5': resolution: {integrity: sha512-zmYw47mhfdfnYbuhkQvkkzYroXUumrwWDGlMjpdUr4jBd3HZiV2w7CQHj+z7AAS4VOtWxI4Zt4bWt4/sKcoIjg==} + '@vitest/spy@0.34.6': + resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==} + '@vitest/spy@2.1.4': resolution: {integrity: sha512-4JOxa+UAizJgpZfaCPKK2smq9d8mmjZVPMt2kOsg/R8QkoRzydHH1qHxIYNvr1zlEaFj4SXiaaJWxq/LPLKaLg==} '@vitest/spy@2.1.5': resolution: {integrity: sha512-aWZF3P0r3w6DiYTVskOYuhBc7EMc3jvn1TkBg8ttylFFRqNN2XGD7V5a4aQdk6QiUzZQ4klNBSpCLJgWNdIiNw==} + '@vitest/utils@0.34.6': + resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==} + '@vitest/utils@2.1.4': resolution: {integrity: sha512-MXDnZn0Awl2S86PSNIim5PWXgIAx8CIkzu35mBdSApUip6RFOGXBCf3YFyeEu8n1IHk4bWD46DeYFu9mQlFIRg==} @@ -8530,6 +8680,9 @@ packages: assert@1.5.1: resolution: {integrity: sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==} + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -9159,10 +9312,17 @@ packages: ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} + chai@5.1.2: resolution: {integrity: sha512-aGtmf24DW6MLHHG5gCx4zaI3uBq3KRtxeVs0DjFH6Z0rDNbsvTxFASFvdj79pxjxZ8/5u3PIiN3IwEIQkiiuPw==} engines: {node: '>=12'} + chain-registry@1.69.71: + resolution: {integrity: sha512-2at89COqTRrSfJHLWFQgjuqOi6FX2V8EwE4O9JNgV8tPNcYjoIi4PcZcSofxFj4sgniKqITrzTkuSG9Sa7/NDA==} + chalk@1.1.3: resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} engines: {node: '>=0.10.0'} @@ -9205,6 +9365,9 @@ packages: charm@0.1.2: resolution: {integrity: sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==} + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -9733,6 +9896,18 @@ packages: typescript: optional: true + cosmjs-types@0.5.1: + resolution: {integrity: sha512-NcC58xUIVLlKdIimWWQAmSlmCjiMrJnuHf4i3LiD8PCextfHR0fT3V5/WlXZZreyMgdmh6ML1zPUfGTbbo3Z5g==} + + cosmjs-types@0.5.2: + resolution: {integrity: sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==} + + cosmjs-types@0.9.0: + resolution: {integrity: sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ==} + + cosmjs-utils@0.1.0: + resolution: {integrity: sha512-Ao2YhVXN+FqvbKqNeVN6I4njzRsCe3LVuPiLerMrAr6xr4MMABzvZbnY13AK/CYPrFJFJpmBCssocthAxOi59g==} + crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} @@ -10259,6 +10434,10 @@ packages: babel-plugin-macros: optional: true + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + deep-eql@5.0.2: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} @@ -11473,6 +11652,9 @@ packages: resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} engines: {node: '>=18'} + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + get-intrinsic@1.2.6: resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==} engines: {node: '>= 0.4'} @@ -13203,6 +13385,12 @@ packages: resolution: {integrity: sha512-26zzwoBNAvX9AWOPiqqF6FG4HrSCPsHFkQm7nT+xU1ggAujL/eae81RnCv4CJ2In9q9fh10B88sYSzKCUh/Ghg==} engines: {node: ^16.14.0 || >=18.0.0} + libsodium-sumo@0.7.15: + resolution: {integrity: sha512-5tPmqPmq8T8Nikpm1Nqj0hBHvsLFCXvdhBFV7SGOitQPZAA6jso8XoL0r4L7vmfKXr486fiQInvErHtEvizFMw==} + + libsodium-wrappers-sumo@0.7.15: + resolution: {integrity: sha512-aSWY8wKDZh5TC7rMvEdTHoyppVq/1dTSAeAR7H6pzd6QRT3vQWcT5pGwCotLcpPEOLXX6VvqihSPkpEhYAjANA==} + libsodium-wrappers@0.7.15: resolution: {integrity: sha512-E4anqJQwcfiC6+Yrl01C1m8p99wEhLmJSs0VQqST66SbQXXBoaJY0pF4BNjRYa/sOQAxx6lXAaAFIlx+15tXJQ==} @@ -13290,6 +13478,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'} @@ -13414,6 +13606,9 @@ packages: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} + long@4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + long@5.2.3: resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} @@ -13427,6 +13622,9 @@ packages: lossless-json@4.0.2: resolution: {integrity: sha512-+z0EaLi2UcWi8MZRxA5iTb6m4Ys4E80uftGY+yG5KNFJb5EceQXOhdW/pWJZ8m97s26u7yZZAYMcKWNztSZssA==} + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + loupe@3.1.2: resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==} @@ -14592,6 +14790,9 @@ packages: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} + osmojs@16.15.0: + resolution: {integrity: sha512-ERIXRzSF+EkS+RNFSzhTurr/EfWnpNfV6b1onf0MXd+YA3X3t8WbkboXg9+/ol61HDEGjugEGzRtz6sFvwaC3w==} + otpauth@9.3.6: resolution: {integrity: sha512-eIcCvuEvcAAPHxUKC9Q4uCe0Fh/yRc5jv9z+f/kvyIF2LPrhgAOuLB7J9CssGYhND/BL8M9hlHBTFmffpoQlMQ==} @@ -14889,6 +15090,9 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + pathval@2.0.0: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} @@ -15895,6 +16099,10 @@ packages: proto-list@1.2.4: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + protobufjs@6.11.4: + resolution: {integrity: sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==} + hasBin: true + protobufjs@7.4.0: resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==} engines: {node: '>=12.0.0'} @@ -16279,6 +16487,9 @@ packages: readline@1.3.0: resolution: {integrity: sha512-k2d6ACCkiNYz222Fs/iNze30rRJ1iIicW7JuX/7/cozvih6YCkFZH+J6mAFDVgv0dRBaAyr4jDqC95R2y4IADg==} + readonly-date@1.0.0: + resolution: {integrity: sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==} + real-require@0.1.0: resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} engines: {node: '>= 12.13.0'} @@ -17266,6 +17477,9 @@ packages: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} + strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} + strnum@1.0.5: resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==} @@ -17362,6 +17576,10 @@ packages: peerDependencies: vue: '>=3.2.26 < 4' + symbol-observable@2.0.3: + resolution: {integrity: sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==} + engines: {node: '>=0.10'} + symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} @@ -17549,6 +17767,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@1.0.2: resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -17561,6 +17783,10 @@ packages: resolution: {integrity: sha512-CvvMFgecnQMyg59nOnAD5O4lV83cVj2ooDniJ3j2bYvMajqlK4wQ13k6OUHfA+J5nkInTxbSGJv2olUJIiAtJg==} engines: {node: '>= 18'} + tinyspy@2.2.1: + resolution: {integrity: sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==} + engines: {node: '>=14.0.0'} + tinyspy@3.0.2: resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} engines: {node: '>=14.0.0'} @@ -17851,6 +18077,10 @@ packages: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + type-fest@0.18.1: resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} engines: {node: '>=10'} @@ -18408,6 +18638,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@2.1.4: resolution: {integrity: sha512-kqa9v+oi4HwkG6g8ufRnb5AeplcRw8jUF6/7/Qz1qRQOXHImG8YnLbB+LLszENwFnoBl9xIf9nVdCFzNd7GQEg==} engines: {node: ^18.0.0 || >=20.0.0} @@ -18459,6 +18694,37 @@ packages: terser: 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@2.1.4: resolution: {integrity: sha512-eDjxbVAJw1UJJCHr5xr/xM86Zx+YxIEXGAR+bmnEID7z9qWfoxpHw0zdobz+TQAFOLT+nEXz3+gx6nUJ7RgmlQ==} engines: {node: ^18.0.0 || >=20.0.0} @@ -18967,6 +19233,9 @@ packages: xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + xstream@11.14.0: + resolution: {integrity: sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -20989,6 +21258,8 @@ snapshots: '@cfworker/json-schema@4.0.3': {} + '@chain-registry/types@0.50.41': {} + '@chevrotain/cst-dts-gen@11.0.3': dependencies: '@chevrotain/gast': 11.0.3 @@ -21175,6 +21446,11 @@ snapshots: dependencies: chalk: 4.1.2 + '@confio/ics23@0.6.8': + dependencies: + '@noble/hashes': 1.6.1 + protobufjs: 6.11.4 + '@coral-xyz/anchor-errors@0.30.1': {} '@coral-xyz/anchor@0.29.0(bufferutil@4.0.8)(encoding@0.1.13)(utf-8-validate@5.0.10)': @@ -21232,6 +21508,243 @@ snapshots: bn.js: 5.2.1 buffer-layout: 1.2.2 + '@cosmjs/amino@0.29.0': + dependencies: + '@cosmjs/crypto': 0.29.0 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/utils': 0.29.5 + + '@cosmjs/amino@0.29.5': + dependencies: + '@cosmjs/crypto': 0.29.5 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/utils': 0.29.5 + + '@cosmjs/amino@0.32.3': + dependencies: + '@cosmjs/crypto': 0.32.4 + '@cosmjs/encoding': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/utils': 0.32.4 + + '@cosmjs/crypto@0.29.0': + dependencies: + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/utils': 0.29.5 + '@noble/hashes': 1.6.1 + bn.js: 5.2.1 + elliptic: 6.6.1 + libsodium-wrappers: 0.7.15 + + '@cosmjs/crypto@0.29.5': + dependencies: + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/utils': 0.29.5 + '@noble/hashes': 1.6.1 + bn.js: 5.2.1 + elliptic: 6.6.1 + libsodium-wrappers: 0.7.15 + + '@cosmjs/crypto@0.32.4': + dependencies: + '@cosmjs/encoding': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/utils': 0.32.4 + '@noble/hashes': 1.6.1 + bn.js: 5.2.1 + elliptic: 6.6.1 + libsodium-wrappers-sumo: 0.7.15 + + '@cosmjs/encoding@0.29.5': + 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.29.5': + dependencies: + '@cosmjs/stream': 0.29.5 + xstream: 11.14.0 + + '@cosmjs/json-rpc@0.32.4': + dependencies: + '@cosmjs/stream': 0.32.4 + xstream: 11.14.0 + + '@cosmjs/math@0.29.5': + dependencies: + bn.js: 5.2.1 + + '@cosmjs/math@0.32.4': + dependencies: + bn.js: 5.2.1 + + '@cosmjs/proto-signing@0.29.0': + dependencies: + '@cosmjs/amino': 0.29.5 + '@cosmjs/crypto': 0.29.0 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/utils': 0.29.5 + cosmjs-types: 0.5.1 + long: 4.0.0 + + '@cosmjs/proto-signing@0.29.5': + dependencies: + '@cosmjs/amino': 0.29.5 + '@cosmjs/crypto': 0.29.5 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/utils': 0.29.5 + cosmjs-types: 0.5.2 + long: 4.0.0 + + '@cosmjs/proto-signing@0.32.3': + dependencies: + '@cosmjs/amino': 0.32.3 + '@cosmjs/crypto': 0.32.4 + '@cosmjs/encoding': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/utils': 0.32.4 + cosmjs-types: 0.9.0 + + '@cosmjs/socket@0.29.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/stream': 0.29.5 + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/socket@0.32.4(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/stream': 0.32.4 + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/stargate@0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@confio/ics23': 0.6.8 + '@cosmjs/amino': 0.29.5 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/proto-signing': 0.29.0 + '@cosmjs/stream': 0.29.5 + '@cosmjs/tendermint-rpc': 0.29.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@cosmjs/utils': 0.29.5 + cosmjs-types: 0.5.1 + long: 4.0.0 + protobufjs: 6.11.4 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/stargate@0.29.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@confio/ics23': 0.6.8 + '@cosmjs/amino': 0.29.5 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/proto-signing': 0.29.5 + '@cosmjs/stream': 0.29.5 + '@cosmjs/tendermint-rpc': 0.29.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@cosmjs/utils': 0.29.5 + cosmjs-types: 0.5.2 + long: 4.0.0 + protobufjs: 6.11.4 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/stargate@0.32.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@confio/ics23': 0.6.8 + '@cosmjs/amino': 0.32.3 + '@cosmjs/encoding': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/proto-signing': 0.32.3 + '@cosmjs/stream': 0.32.4 + '@cosmjs/tendermint-rpc': 0.32.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@cosmjs/utils': 0.32.4 + cosmjs-types: 0.9.0 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/stream@0.29.5': + dependencies: + xstream: 11.14.0 + + '@cosmjs/stream@0.32.4': + dependencies: + xstream: 11.14.0 + + '@cosmjs/tendermint-rpc@0.29.5(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/crypto': 0.29.5 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/json-rpc': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/socket': 0.29.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@cosmjs/stream': 0.29.5 + '@cosmjs/utils': 0.29.5 + axios: 0.21.4 + readonly-date: 1.0.0 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/tendermint-rpc@0.32.3(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/crypto': 0.32.4 + '@cosmjs/encoding': 0.32.4 + '@cosmjs/json-rpc': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/socket': 0.32.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@cosmjs/stream': 0.32.4 + '@cosmjs/utils': 0.32.4 + axios: 1.7.9(debug@4.4.0) + readonly-date: 1.0.0 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/utils@0.29.5': {} + + '@cosmjs/utils@0.32.4': {} + + '@cosmology/lcd@0.13.5': + dependencies: + axios: 1.7.4 + transitivePeerDependencies: + - debug + '@cspotcode/source-map-support@0.8.1': dependencies: '@jridgewell/trace-mapping': 0.3.9 @@ -27312,6 +27825,12 @@ snapshots: '@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 @@ -27595,6 +28114,8 @@ snapshots: '@types/lodash@4.17.13': {} + '@types/long@4.0.2': {} + '@types/lru-cache@5.1.1': {} '@types/mdast@4.0.4': @@ -28028,6 +28549,12 @@ snapshots: typescript: 5.6.3 vitest: 2.1.5(@types/node@22.10.2)(jsdom@25.0.1(bufferutil@4.0.8)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(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@2.1.4': dependencies: '@vitest/spy': 2.1.4 @@ -28070,6 +28597,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@2.1.4': dependencies: '@vitest/utils': 2.1.4 @@ -28080,6 +28613,12 @@ snapshots: '@vitest/utils': 2.1.5 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@2.1.4': dependencies: '@vitest/pretty-format': 2.1.4 @@ -28092,6 +28631,10 @@ snapshots: magic-string: 0.30.17 pathe: 1.1.2 + '@vitest/spy@0.34.6': + dependencies: + tinyspy: 2.2.1 + '@vitest/spy@2.1.4': dependencies: tinyspy: 3.0.2 @@ -28100,6 +28643,12 @@ snapshots: dependencies: tinyspy: 3.0.2 + '@vitest/utils@0.34.6': + dependencies: + diff-sequences: 29.6.3 + loupe: 2.3.7 + pretty-format: 29.7.0 + '@vitest/utils@2.1.4': dependencies: '@vitest/pretty-format': 2.1.4 @@ -28944,6 +29493,8 @@ snapshots: object.assign: 4.1.5 util: 0.10.4 + assertion-error@1.1.0: {} + assertion-error@2.0.1: {} ast-types@0.13.4: @@ -29855,6 +30406,16 @@ snapshots: ccount@2.0.1: {} + chai@4.5.0: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 + chai@5.1.2: dependencies: assertion-error: 2.0.1 @@ -29863,6 +30424,10 @@ snapshots: loupe: 3.1.2 pathval: 2.0.0 + chain-registry@1.69.71: + dependencies: + '@chain-registry/types': 0.50.41 + chalk@1.1.3: dependencies: ansi-styles: 2.2.1 @@ -29902,6 +30467,10 @@ snapshots: charm@0.1.2: {} + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + check-error@2.1.1: {} cheerio-select@2.1.0: @@ -30487,6 +31056,31 @@ snapshots: optionalDependencies: typescript: 5.6.3 + cosmjs-types@0.5.1: + dependencies: + long: 4.0.0 + protobufjs: 6.11.4 + + cosmjs-types@0.5.2: + dependencies: + long: 4.0.0 + protobufjs: 6.11.4 + + cosmjs-types@0.9.0: {} + + cosmjs-utils@0.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@babel/runtime': 7.26.0 + '@cosmjs/amino': 0.29.0 + '@cosmjs/crypto': 0.29.0 + '@cosmjs/proto-signing': 0.29.0 + '@cosmjs/stargate': 0.29.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + cosmjs-types: 0.5.1 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + crc-32@1.2.2: {} create-ecdh@4.0.4: @@ -31142,6 +31736,10 @@ snapshots: dedent@1.5.3: {} + deep-eql@4.1.4: + dependencies: + type-detect: 4.1.0 + deep-eql@5.0.2: {} deep-extend@0.6.0: {} @@ -32771,6 +33369,8 @@ snapshots: get-east-asian-width@1.3.0: {} + get-func-name@2.0.2: {} + get-intrinsic@1.2.6: dependencies: call-bind-apply-helpers: 1.0.1 @@ -35253,6 +35853,12 @@ snapshots: transitivePeerDependencies: - supports-color + libsodium-sumo@0.7.15: {} + + libsodium-wrappers-sumo@0.7.15: + dependencies: + libsodium-sumo: 0.7.15 + libsodium-wrappers@0.7.15: dependencies: libsodium: 0.7.15 @@ -35378,6 +35984,8 @@ snapshots: loader-utils@3.3.1: {} + local-pkg@0.4.3: {} + local-pkg@0.5.1: dependencies: mlly: 1.7.3 @@ -35484,6 +36092,8 @@ snapshots: strip-ansi: 7.1.0 wrap-ansi: 9.0.0 + long@4.0.0: {} + long@5.2.3: {} longest-streak@3.1.0: {} @@ -35494,6 +36104,10 @@ snapshots: lossless-json@4.0.2: {} + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + loupe@3.1.2: {} lowdb@7.0.1: @@ -37219,6 +37833,18 @@ snapshots: os-tmpdir@1.0.2: {} + osmojs@16.15.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@cosmjs/amino': 0.32.3 + '@cosmjs/proto-signing': 0.32.3 + '@cosmjs/stargate': 0.32.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@cosmjs/tendermint-rpc': 0.32.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@cosmology/lcd': 0.13.5 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + otpauth@9.3.6: dependencies: '@noble/hashes': 1.6.1 @@ -37531,6 +38157,8 @@ snapshots: pathe@1.1.2: {} + pathval@1.1.1: {} + pathval@2.0.0: {} pbkdf2@3.1.2: @@ -38561,6 +39189,22 @@ snapshots: proto-list@1.2.4: {} + protobufjs@6.11.4: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/long': 4.0.2 + '@types/node': 20.17.9 + long: 4.0.0 + protobufjs@7.4.0: dependencies: '@protobufjs/aspromise': 1.1.2 @@ -39076,6 +39720,8 @@ snapshots: readline@1.3.0: {} + readonly-date@1.0.0: {} + real-require@0.1.0: {} rechoir@0.6.2: @@ -40327,6 +40973,10 @@ snapshots: strip-json-comments@3.1.1: {} + strip-literal@1.3.0: + dependencies: + acorn: 8.14.0 + strnum@1.0.5: {} strong-log-transformer@2.1.0: @@ -40438,6 +41088,8 @@ snapshots: dependencies: vue: 3.5.13(typescript@5.6.3) + symbol-observable@2.0.3: {} + symbol-tree@3.2.4: {} symbol.inspect@1.0.1: {} @@ -40655,12 +41307,16 @@ snapshots: tinyld@1.3.4: {} + tinypool@0.7.0: {} + tinypool@1.0.2: {} tinyrainbow@1.2.0: {} tinyspawn@1.3.3: {} + tinyspy@2.2.1: {} + tinyspy@3.0.2: {} tldts-core@6.1.68: {} @@ -41003,6 +41659,8 @@ snapshots: type-detect@4.0.8: {} + type-detect@4.1.0: {} + type-fest@0.18.1: {} type-fest@0.20.2: {} @@ -41581,6 +42239,25 @@ snapshots: - 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@8.1.1) + 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@2.1.4(@types/node@22.10.2)(terser@5.37.0): dependencies: cac: 6.7.14 @@ -41648,6 +42325,16 @@ snapshots: dependencies: vite: link:client/@tanstack/router-plugin/vite + vite@5.4.11(@types/node@20.17.9)(terser@5.37.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.28.1 + optionalDependencies: + '@types/node': 20.17.9 + fsevents: 2.3.3 + terser: 5.37.0 + vite@5.4.11(@types/node@22.10.2)(terser@5.37.0): dependencies: esbuild: 0.21.5 @@ -41668,6 +42355,45 @@ snapshots: fsevents: 2.3.3 terser: 5.37.0 + vitest@0.34.6(jsdom@25.0.1(bufferutil@4.0.8)(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@8.1.1) + 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: + jsdom: 25.0.1(bufferutil@4.0.8)(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@2.1.4(@types/node@22.10.2)(jsdom@25.0.1(bufferutil@4.0.8)(canvas@2.11.2(encoding@0.1.13))(utf-8-validate@5.0.10))(terser@5.37.0): dependencies: '@vitest/expect': 2.1.4 @@ -42474,6 +43200,11 @@ snapshots: xmlchars@2.2.0: {} + xstream@11.14.0: + dependencies: + globalthis: 1.0.4 + symbol-observable: 2.0.3 + xtend@4.0.2: {} y18n@4.0.3: {}