diff --git a/.env.example b/.env.example index aea627fee73..0e6c1883d42 100644 --- a/.env.example +++ b/.env.example @@ -275,3 +275,7 @@ AWS_S3_UPLOAD_PATH= # Deepgram DEEPGRAM_API_KEY= + +# Sui +SUI_PRIVATE_KEY= # Sui Mnemonic Seed Phrase (`sui keytool generate ed25519`) +SUI_NETWORK= # must be one of mainnet, testnet, devnet, localnet diff --git a/agent/package.json b/agent/package.json index e27d4aa5ee5..0c7425c7018 100644 --- a/agent/package.json +++ b/agent/package.json @@ -40,6 +40,7 @@ "@ai16z/plugin-node": "workspace:*", "@ai16z/plugin-solana": "workspace:*", "@ai16z/plugin-starknet": "workspace:*", + "@ai16z/plugin-sui": "workspace:*", "@ai16z/plugin-tee": "workspace:*", "readline": "1.3.0", "ws": "8.18.0", diff --git a/agent/src/index.ts b/agent/src/index.ts index be33768a509..3722c36f805 100644 --- a/agent/src/index.ts +++ b/agent/src/index.ts @@ -44,6 +44,7 @@ import { solanaPlugin } from "@ai16z/plugin-solana"; import { teePlugin, TEEMode } from "@ai16z/plugin-tee"; import { aptosPlugin, TransferAptosToken } from "@ai16z/plugin-aptos"; import { flowPlugin } from "@ai16z/plugin-flow"; +import { suiPlugin } from "@ai16z/plugin-sui"; import Database from "better-sqlite3"; import fs from "fs"; import path from "path"; @@ -491,6 +492,7 @@ export async function createAgent( ? flowPlugin : null, getSecret(character, "APTOS_PRIVATE_KEY") ? aptosPlugin : null, + getSecret(character, "SUI_PRIVATE_KEY") ? suiPlugin : null, ].filter(Boolean), providers: [], actions: [], diff --git a/packages/plugin-sui/.npmignore b/packages/plugin-sui/.npmignore new file mode 100644 index 00000000000..078562eceab --- /dev/null +++ b/packages/plugin-sui/.npmignore @@ -0,0 +1,6 @@ +* + +!dist/** +!package.json +!readme.md +!tsup.config.ts \ No newline at end of file diff --git a/packages/plugin-sui/eslint.config.mjs b/packages/plugin-sui/eslint.config.mjs new file mode 100644 index 00000000000..92fe5bbebef --- /dev/null +++ b/packages/plugin-sui/eslint.config.mjs @@ -0,0 +1,3 @@ +import eslintGlobalConfig from "../../eslint.config.mjs"; + +export default [...eslintGlobalConfig]; diff --git a/packages/plugin-sui/package.json b/packages/plugin-sui/package.json new file mode 100644 index 00000000000..1aee92e29b8 --- /dev/null +++ b/packages/plugin-sui/package.json @@ -0,0 +1,26 @@ +{ + "name": "@ai16z/plugin-sui", + "version": "0.1.5-alpha.5", + "main": "dist/index.js", + "type": "module", + "types": "dist/index.d.ts", + "dependencies": { + "@ai16z/eliza": "workspace:*", + "@ai16z/plugin-trustdb": "workspace:*", + "@mysten/sui": "^1.16.0", + "bignumber": "1.1.0", + "bignumber.js": "9.1.2", + "node-cache": "5.1.2", + "tsup": "8.3.5", + "vitest": "2.1.4" + }, + "scripts": { + "build": "tsup --format esm --dts", + "lint": "eslint . --fix", + "test": "vitest run" + }, + "peerDependencies": { + "form-data": "4.0.1", + "whatwg-url": "7.1.0" + } +} diff --git a/packages/plugin-sui/src/actions/transfer.ts b/packages/plugin-sui/src/actions/transfer.ts new file mode 100644 index 00000000000..7bd68b557df --- /dev/null +++ b/packages/plugin-sui/src/actions/transfer.ts @@ -0,0 +1,214 @@ +import { elizaLogger } from "@ai16z/eliza"; +import { + ActionExample, + Content, + HandlerCallback, + IAgentRuntime, + Memory, + ModelClass, + State, + type Action, +} from "@ai16z/eliza"; +import { composeContext } from "@ai16z/eliza"; +import { generateObjectV2 } from "@ai16z/eliza"; +import { z } from "zod"; + +import { SuiClient, getFullnodeUrl } from "@mysten/sui/client"; +import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519"; +import { SUI_DECIMALS } from "@mysten/sui/utils"; +import { Transaction } from "@mysten/sui/transactions"; + +import { walletProvider } from "../providers/wallet"; + +type SuiNetwork = "mainnet" | "testnet" | "devnet" | "localnet"; + +export interface TransferContent extends Content { + recipient: string; + amount: string | number; +} + +function isTransferContent(content: Content): content is TransferContent { + console.log("Content for transfer", content); + 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": "0xaa000b3651bd1e57554ebd7308ca70df7c8c0e8e09d67123cc15c8a8a79342b3", + "amount": "1" +} +\`\`\` + +{{recentMessages}} + +Given the recent messages, extract the following information about the requested token transfer: +- Recipient wallet address +- Amount to transfer + +Respond with a JSON markdown block containing only the extracted values.`; + +export default { + name: "SEND_TOKEN", + similes: [ + "TRANSFER_TOKEN", + "TRANSFER_TOKENS", + "SEND_TOKENS", + "SEND_SUI", + "PAY", + ], + validate: async (runtime: IAgentRuntime, message: Memory) => { + console.log("Validating sui transfer from user:", message.userId); + //add custom validate logic here + /* + const adminIds = runtime.getSetting("ADMIN_USER_IDS")?.split(",") || []; + //console.log("Admin IDs from settings:", adminIds); + + const isAdmin = adminIds.includes(message.userId); + + if (isAdmin) { + //console.log(`Authorized transfer from user: ${message.userId}`); + return true; + } + else + { + //console.log(`Unauthorized transfer attempt from user: ${message.userId}`); + return false; + } + */ + 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 SEND_TOKEN handler..."); + + const walletInfo = await walletProvider.get(runtime, message, state); + state.walletInfo = walletInfo; + + // Initialize or update state + if (!state) { + state = (await runtime.composeState(message)) as State; + } else { + state = await runtime.updateRecentMessageState(state); + } + + // Define the schema for the expected output + const transferSchema = z.object({ + recipient: z.string(), + amount: z.union([z.string(), z.number()]), + }); + + // Compose transfer context + const transferContext = composeContext({ + state, + template: transferTemplate, + }); + + // Generate transfer content with the schema + const content = await generateObjectV2({ + runtime, + context: transferContext, + schema: transferSchema, + modelClass: ModelClass.SMALL, + }); + + const transferContent = content.object as TransferContent; + + // Validate transfer content + if (!isTransferContent(transferContent)) { + 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 privateKey = runtime.getSetting("SUI_PRIVATE_KEY"); + const suiAccount = Ed25519Keypair.deriveKeypair(privateKey); + const network = runtime.getSetting("SUI_NETWORK"); + const suiClient = new SuiClient({ + url: getFullnodeUrl(network as SuiNetwork), + }); + + const adjustedAmount = BigInt( + Number(transferContent.amount) * Math.pow(10, SUI_DECIMALS) + ); + console.log( + `Transferring: ${transferContent.amount} tokens (${adjustedAmount} base units)` + ); + const tx = new Transaction(); + const [coin] = tx.splitCoins(tx.gas, [adjustedAmount]); + tx.transferObjects([coin], transferContent.recipient); + const executedTransaction = + await suiClient.signAndExecuteTransaction({ + signer: suiAccount, + transaction: tx, + }); + + console.log("Transfer successful:", executedTransaction.digest); + + if (callback) { + callback({ + text: `Successfully transferred ${transferContent.amount} SUI to ${transferContent.recipient}, Transaction: ${executedTransaction.digest}`, + content: { + success: true, + hash: executedTransaction.digest, + amount: transferContent.amount, + recipient: transferContent.recipient, + }, + }); + } + + 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 1 SUI tokens to 0x4f2e63be8e7fe287836e29cde6f3d5cbc96eefd0c0e3f3747668faa2ae7324b0", + }, + }, + { + user: "{{user2}}", + content: { + text: "I'll send 1 SUI tokens now...", + action: "SEND_TOKEN", + }, + }, + { + user: "{{user2}}", + content: { + text: "Successfully sent 1 SUI tokens to 0x4f2e63be8e7fe287836e29cde6f3d5cbc96eefd0c0e3f3747668faa2ae7324b0, Transaction: 0x39a8c432d9bdad993a33cc1faf2e9b58fb7dd940c0425f1d6db3997e4b4b05c0", + }, + }, + ], + ] as ActionExample[][], +} as Action; diff --git a/packages/plugin-sui/src/enviroment.ts b/packages/plugin-sui/src/enviroment.ts new file mode 100644 index 00000000000..5c1fadc31af --- /dev/null +++ b/packages/plugin-sui/src/enviroment.ts @@ -0,0 +1,36 @@ +import { IAgentRuntime } from "@ai16z/eliza"; +import { z } from "zod"; + +export const suiEnvSchema = z.object({ + SUI_PRIVATE_KEY: z.string().min(1, "Sui private key is required"), + SUI_NETWORK: z.enum(["mainnet", "testnet"]), +}); + +export type SuiConfig = z.infer; + +export async function validateSuiConfig( + runtime: IAgentRuntime +): Promise { + try { + const config = { + SUI_PRIVATE_KEY: + runtime.getSetting("SUI_PRIVATE_KEY") || + process.env.SUI_PRIVATE_KEY, + SUI_NETWORK: + runtime.getSetting("SUI_NETWORK") || + process.env.SUI_NETWORK, + }; + + return suiEnvSchema.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( + `Sui configuration validation failed:\n${errorMessages}` + ); + } + throw error; + } +} diff --git a/packages/plugin-sui/src/index.ts b/packages/plugin-sui/src/index.ts new file mode 100644 index 00000000000..964003a18d0 --- /dev/null +++ b/packages/plugin-sui/src/index.ts @@ -0,0 +1,15 @@ +import { Plugin } from "@ai16z/eliza"; +import transferToken from "./actions/transfer.ts"; +import { WalletProvider, walletProvider } from "./providers/wallet.ts"; + +export { WalletProvider, transferToken as TransferSuiToken }; + +export const suiPlugin: Plugin = { + name: "sui", + description: "Sui Plugin for Eliza", + actions: [transferToken], + evaluators: [], + providers: [walletProvider], +}; + +export default suiPlugin; diff --git a/packages/plugin-sui/src/providers/wallet.ts b/packages/plugin-sui/src/providers/wallet.ts new file mode 100644 index 00000000000..70038c6128f --- /dev/null +++ b/packages/plugin-sui/src/providers/wallet.ts @@ -0,0 +1,246 @@ +import { + IAgentRuntime, + ICacheManager, + Memory, + Provider, + State, +} from "@ai16z/eliza"; + + +import { getFullnodeUrl, SuiClient } from "@mysten/sui/client"; +import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519'; + +import { MIST_PER_SUI } from "@mysten/sui/utils"; +import BigNumber from "bignumber.js"; +import NodeCache from "node-cache"; +import * as path from "path"; + +// Provider configuration +const PROVIDER_CONFIG = { + MAX_RETRIES: 3, + RETRY_DELAY: 2000, +}; + +interface WalletPortfolio { + totalUsd: string; + totalSui: string; +} + +interface Prices { + sui: { usd: string }; +} + +type SuiNetwork = "mainnet" | "testnet" | "devnet" | "localnet"; + +export class WalletProvider { + private cache: NodeCache; + private cacheKey: string = "sui/wallet"; + + constructor( + private suiClient: SuiClient, + private address: string, + private cacheManager: ICacheManager + ) { + this.cache = new NodeCache({ stdTTL: 300 }); // Cache TTL set to 5 minutes + } + + private async readFromCache(key: string): Promise { + const cached = await this.cacheManager.get( + path.join(this.cacheKey, key) + ); + return cached; + } + + private async writeToCache(key: string, data: T): Promise { + await this.cacheManager.set(path.join(this.cacheKey, key), data, { + expires: Date.now() + 5 * 60 * 1000, + }); + } + + + private async getCachedData(key: string): Promise { + // Check in-memory cache first + const cachedData = this.cache.get(key); + if (cachedData) { + return cachedData; + } + + // Check file-based cache + const fileCachedData = await this.readFromCache(key); + if (fileCachedData) { + // Populate in-memory cache + this.cache.set(key, fileCachedData); + return fileCachedData; + } + + return null; + } + + private async setCachedData(cacheKey: string, data: T): Promise { + // Set in-memory cache + this.cache.set(cacheKey, data); + + // Write to file-based cache + await this.writeToCache(cacheKey, data); + } + + private async fetchPricesWithRetry() { + let lastError: Error; + + for (let i = 0; i < PROVIDER_CONFIG.MAX_RETRIES; i++) { + try { + const cetusSuiUsdcPoolAddr = + "0x51e883ba7c0b566a26cbc8a94cd33eb0abd418a77cc1e60ad22fd9b1f29cd2ab"; + const response = await fetch( + `https://api.dexscreener.com/latest/dex/pairs/sui/${cetusSuiUsdcPoolAddr}` + ); + + if (!response.ok) { + const errorText = await response.text(); + throw new Error( + `HTTP error! status: ${response.status}, message: ${errorText}` + ); + } + + const data = await response.json(); + return data; + } catch (error) { + console.error(`Attempt ${i + 1} failed:`, error); + lastError = error; + if (i < PROVIDER_CONFIG.MAX_RETRIES - 1) { + const delay = PROVIDER_CONFIG.RETRY_DELAY * Math.pow(2, i); + await new Promise((resolve) => setTimeout(resolve, delay)); + continue; + } + } + } + + console.error( + "All attempts failed. Throwing the last error:", + lastError + ); + throw lastError; + } + + async fetchPortfolioValue(): Promise { + try { + const cacheKey = `portfolio-${this.address}`; + const cachedValue = + await this.getCachedData(cacheKey); + + if (cachedValue) { + console.log("Cache hit for fetchPortfolioValue", cachedValue); + return cachedValue; + } + console.log("Cache miss for fetchPortfolioValue"); + + const prices = await this.fetchPrices().catch((error) => { + console.error("Error fetching SUI price:", error); + throw error; + }); + const suiAmountOnChain = await this.suiClient + .getBalance({ + owner: this.address, + }) + .catch((error) => { + console.error("Error fetching SUI amount:", error); + throw error; + }); + + const suiAmount = + Number.parseInt(suiAmountOnChain.totalBalance) / + Number(MIST_PER_SUI); + const totalUsd = new BigNumber(suiAmount).times(prices.sui.usd); + + const portfolio = { + totalUsd: totalUsd.toString(), + totalSui: suiAmount.toString(), + }; + this.setCachedData(cacheKey, portfolio); + console.log("Fetched portfolio:", portfolio); + return portfolio; + } catch (error) { + console.error("Error fetching portfolio:", error); + throw error; + } + } + + async fetchPrices(): Promise { + try { + const cacheKey = "prices"; + const cachedValue = await this.getCachedData(cacheKey); + + if (cachedValue) { + console.log("Cache hit for fetchPrices"); + return cachedValue; + } + console.log("Cache miss for fetchPrices"); + + const suiPriceData = await this.fetchPricesWithRetry().catch( + (error) => { + console.error("Error fetching SUI price:", error); + throw error; + } + ); + const prices: Prices = { + sui: { usd: suiPriceData.pair.priceUsd }, + }; + this.setCachedData(cacheKey, prices); + return prices; + } catch (error) { + console.error("Error fetching prices:", error); + throw error; + } + } + + formatPortfolio(runtime, portfolio: WalletPortfolio): string { + let output = `${runtime.character.name}\n`; + output += `Wallet Address: ${this.address}\n`; + + const totalUsdFormatted = new BigNumber(portfolio.totalUsd).toFixed(2); + const totalSuiFormatted = new BigNumber(portfolio.totalSui).toFixed(4); + + output += `Total Value: $${totalUsdFormatted} (${totalSuiFormatted} SUI)\n`; + + return output; + } + + async getFormattedPortfolio(runtime): Promise { + try { + const portfolio = await this.fetchPortfolioValue(); + return this.formatPortfolio(runtime, portfolio); + } catch (error) { + console.error("Error generating portfolio report:", error); + return "Unable to fetch wallet information. Please try again later."; + } + } +} + +const walletProvider: Provider = { + get: async ( + runtime: IAgentRuntime, + _message: Memory, + _state?: State + ): Promise => { + const privateKey = runtime.getSetting("SUI_PRIVATE_KEY"); + const suiAccount = Ed25519Keypair.deriveKeypair(privateKey); + + try { + const suiClient = new SuiClient({ + url: getFullnodeUrl(runtime.getSetting("SUI_NETWORK") as SuiNetwork), + }); + const provider = new WalletProvider( + suiClient, + suiAccount.toSuiAddress(), + runtime.cacheManager + ); + return await provider.getFormattedPortfolio(runtime); + } catch (error) { + console.error("Error in wallet provider:", error); + return null; + } + }, +}; + +// Module exports +export { walletProvider }; diff --git a/packages/plugin-sui/src/tests/wallet.test.ts b/packages/plugin-sui/src/tests/wallet.test.ts new file mode 100644 index 00000000000..387f9001458 --- /dev/null +++ b/packages/plugin-sui/src/tests/wallet.test.ts @@ -0,0 +1,92 @@ +import { describe, it, expect, beforeEach, vi, afterEach } from "vitest"; +import { WalletProvider } from "../providers/wallet.ts"; + +import { defaultCharacter } from "@ai16z/eliza"; +import BigNumber from "bignumber.js"; +import { SUI_DECIMALS } from "@mysten/sui/utils"; +import { SuiClient, getFullnodeUrl } from "@mysten/sui/client"; +import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519"; +// Mock NodeCache +vi.mock("node-cache", () => { + return { + default: vi.fn().mockImplementation(() => ({ + set: vi.fn(), + get: vi.fn().mockReturnValue(null), + })), + }; +}); + +// Mock path module +vi.mock("path", async () => { + const actual = await vi.importActual("path"); + return { + ...actual, + join: vi.fn().mockImplementation((...args) => args.join("/")), + }; +}); + +// Mock the ICacheManager +const mockCacheManager = { + get: vi.fn().mockResolvedValue(null), + set: vi.fn(), + delete: vi.fn(), +}; + +describe("WalletProvider", () => { + let walletProvider; + let mockedRuntime; + + beforeEach(() => { + vi.clearAllMocks(); + mockCacheManager.get.mockResolvedValue(null); + + const suiClient = new SuiClient({ + url: getFullnodeUrl("testnet"), + }); + + const suiAccount = Ed25519Keypair.deriveKeypair( + // 0x69c67de128b241be288d6f3f7d898f0ffb6c1976879b721e68e7b156dd419e3f + "gaze throw also reveal kite load tennis tone club cloth chaos picture" + ); + + + // Create new instance of TokenProvider with mocked dependencies + walletProvider = new WalletProvider( + suiClient, + suiAccount.toSuiAddress(), + mockCacheManager + ); + + mockedRuntime = { + character: defaultCharacter, + }; + }); + + afterEach(() => { + vi.clearAllTimers(); + }); + + describe("Wallet Integration", () => { + it("should check wallet address", async () => { + const result = + await walletProvider.getFormattedPortfolio(mockedRuntime); + + const prices = await walletProvider.fetchPrices(); + const mistAmountOnChain = await walletProvider.suiClient.getBalance({ + owner: walletProvider.address, + }); + + const suiAmount = new BigNumber(mistAmountOnChain.totalBalance) + .div(new BigNumber(10).pow(SUI_DECIMALS)) + .toFixed(4); + const totalUsd = new BigNumber(suiAmount) + .times(prices.sui.usd) + .toFixed(2); + + expect(result).toEqual( + `Eliza\nWallet Address: ${walletProvider.address}\n` + + `Total Value: $${totalUsd} (${suiAmount} SUI)\n` + ); + }); + }); +}); diff --git a/packages/plugin-sui/tsconfig.json b/packages/plugin-sui/tsconfig.json new file mode 100644 index 00000000000..73993deaaf7 --- /dev/null +++ b/packages/plugin-sui/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-sui/tsup.config.ts b/packages/plugin-sui/tsup.config.ts new file mode 100644 index 00000000000..dd25475bb63 --- /dev/null +++ b/packages/plugin-sui/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/pnpm-lock.yaml b/pnpm-lock.yaml index 589f0bc3f18..b156fb049f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -171,6 +171,9 @@ importers: '@ai16z/plugin-starknet': specifier: workspace:* version: link:../packages/plugin-starknet + '@ai16z/plugin-sui': + specifier: workspace:* + version: link:../packages/plugin-sui '@ai16z/plugin-tee': specifier: workspace:* version: link:../packages/plugin-tee @@ -1351,6 +1354,39 @@ importers: specifier: 7.1.0 version: 7.1.0 + packages/plugin-sui: + dependencies: + '@ai16z/eliza': + specifier: workspace:* + version: link:../core + '@ai16z/plugin-trustdb': + specifier: workspace:* + version: link:../plugin-trustdb + '@mysten/sui': + specifier: ^1.16.0 + version: 1.16.2(typescript@5.6.3) + bignumber: + specifier: 1.1.0 + version: 1.1.0 + bignumber.js: + specifier: 9.1.2 + version: 9.1.2 + form-data: + specifier: 4.0.1 + version: 4.0.1 + node-cache: + specifier: 5.1.2 + version: 5.1.2 + tsup: + specifier: 8.3.5 + version: 8.3.5(@swc/core@1.10.1(@swc/helpers@0.5.15))(jiti@2.4.0)(postcss@8.4.49)(typescript@5.6.3)(yaml@2.6.1) + vitest: + specifier: 2.1.4 + version: 2.1.4(@types/node@22.8.4)(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) + whatwg-url: + specifier: 7.1.0 + version: 7.1.0 + packages/plugin-tee: dependencies: '@ai16z/eliza': @@ -1477,6 +1513,20 @@ packages: peerDependencies: ethers: 6.13.1 + '@0no-co/graphql.web@1.0.12': + resolution: {integrity: sha512-BTDjjsV/zSPy5fqItwm+KWUfh9CSe9tTtR6rCB72ddtkAxdcHbi4Ir4r/L1Et4lyxmL+i7Rb3m9sjLLi9tYrzA==} + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 + peerDependenciesMeta: + graphql: + optional: true + + '@0no-co/graphqlsp@1.12.16': + resolution: {integrity: sha512-B5pyYVH93Etv7xjT6IfB7QtMBdaaC07yjbhN6v8H7KgFStMkPvi+oWYBTibMFRMY89qwc9H8YixXg8SXDVgYWw==} + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 + '@acuminous/bitsyntax@0.1.2': resolution: {integrity: sha512-29lUK80d1muEQqiUsSo+3A0yP6CdspgC95EnKBMi22Xlwt79i/En4Vr67+cXhU+cZjbti3TgGGC5wy1stIywVQ==} engines: {node: '>=0.8'} @@ -3932,6 +3982,31 @@ packages: resolution: {integrity: sha512-pJSUG3r5QIvCFNfkz7/y7kEqvEJaVAk0jZbZoKbcPCRUnXaUeAq7p8I0oklqetGyxbUcZ2FOGpt+Y+4uIltVPg==} engines: {node: '>=18.0.0'} + '@gql.tada/cli-utils@1.6.3': + resolution: {integrity: sha512-jFFSY8OxYeBxdKi58UzeMXG1tdm4FVjXa8WHIi66Gzu9JWtCE6mqom3a8xkmSw+mVaybFW5EN2WXf1WztJVNyQ==} + peerDependencies: + '@0no-co/graphqlsp': ^1.12.13 + '@gql.tada/svelte-support': 1.0.1 + '@gql.tada/vue-support': 1.0.1 + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 + peerDependenciesMeta: + '@gql.tada/svelte-support': + optional: true + '@gql.tada/vue-support': + optional: true + + '@gql.tada/internal@1.0.8': + resolution: {integrity: sha512-XYdxJhtHC5WtZfdDqtKjcQ4d7R1s0d1rnlSs3OcBEUbYiPoJJfZU7tWsVXuv047Z6msvmr4ompJ7eLSK5Km57g==} + peerDependencies: + graphql: ^15.5.0 || ^16.0.0 || ^17.0.0 + typescript: ^5.0.0 + + '@graphql-typed-document-node/core@3.2.0': + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + 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 + '@hapi/hoek@9.3.0': resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} @@ -4316,6 +4391,13 @@ packages: resolution: {integrity: sha512-y+l1PNV0XDyY8sM3YtuMLK5vE3/hkfId+Do8pLo/OPxfxuFAUwcGz3oiiUuV46/aBpwTzZ+mRWVMtlSKbradhw==} engines: {node: '>= 14'} + '@mysten/bcs@1.2.0': + resolution: {integrity: sha512-LuKonrGdGW7dq/EM6U2L9/as7dFwnhZnsnINzB/vu08Xfrj0qzWwpLOiXagAa5yZOPLK7anRZydMonczFkUPzA==} + + '@mysten/sui@1.16.2': + resolution: {integrity: sha512-1Nfm7iTs3IVsiCXFPrnci9Y7fP9ldtwNOTe7JRkaHTg58VRhSe/nhHOvt6UsYiswVPUBqlsSF73KER5MpirCvw==} + engines: {node: '>=18'} + '@napi-rs/wasm-runtime@0.2.4': resolution: {integrity: sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==} @@ -6089,6 +6171,9 @@ packages: '@starknet-io/types-js@0.7.10': resolution: {integrity: sha512-1VtCqX4AHWJlRRSYGSn+4X1mqolI1Tdq62IwzoU2vUuEE72S1OlEeGhpvd6XsdqXcfHmVzYfj8k1XtKBQqwo9w==} + '@suchipi/femver@1.0.0': + resolution: {integrity: sha512-bprE8+K5V+DPX7q2e2K57ImqNBdfGHDIWaGI5xHxZoxbKOuQZn4wzPiUxOAHnsUr3w3xHrWXwN7gnG/iIuEMIg==} + '@supabase/auth-js@2.65.1': resolution: {integrity: sha512-IA7i2Xq2SWNCNMKxwmPlHafBQda0qtnFr8QnyyBr+KaSxoXXqEzFCnQ1dGTy6bsZjVBgXu++o3qrDypTspaAPw==} @@ -10321,6 +10406,12 @@ packages: resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} engines: {node: '>=14.16'} + gql.tada@1.8.10: + resolution: {integrity: sha512-FrvSxgz838FYVPgZHGOSgbpOjhR+yq44rCzww3oOPJYi0OvBJjAgCiP6LEokZIYND2fUTXzQAyLgcvgw1yNP5A==} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + graceful-fs@4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -10334,6 +10425,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + graphql@16.9.0: + resolution: {integrity: sha512-GGTKBX4SD7Wdb8mqeDLni2oaRGYQWjWHGKPQ24ZMnUtKfcsVoiv4uX8+LJr1K6U5VW2Lu1BwJnj7uiori0YtRw==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + gray-matter@4.0.3: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} @@ -11266,6 +11361,9 @@ packages: joi@17.13.3: resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + jose@5.9.6: + resolution: {integrity: sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ==} + joycon@3.1.1: resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} engines: {node: '>=10'} @@ -15861,6 +15959,9 @@ packages: tweetnacl@0.14.5: resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + twitter-api-v2@1.18.2: resolution: {integrity: sha512-ggImmoAeVgETYqrWeZy+nWnDpwgTP+IvFEc03Pitt1HcgMX+Yw17rP38Fb5FFTinuyNvS07EPtAfZ184uIyB0A==} @@ -16280,6 +16381,9 @@ packages: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} + valibot@0.36.0: + resolution: {integrity: sha512-CjF1XN4sUce8sBK9TixrDqFM7RwNkuXdJu174/AwmQUB62QbCQADg5lLe8ldBalFgtj1uKj+pKwDJiNo4Mn+eQ==} + valibot@0.38.0: resolution: {integrity: sha512-RCJa0fetnzp+h+KN9BdgYOgtsMAG9bfoJ9JSjIhFHobKWVWyzM3jjaeNTdpFK9tQtf3q1sguXeERJ/LcmdFE7w==} peerDependencies: @@ -16913,6 +17017,16 @@ snapshots: - supports-color - utf-8-validate + '@0no-co/graphql.web@1.0.12(graphql@16.9.0)': + optionalDependencies: + graphql: 16.9.0 + + '@0no-co/graphqlsp@1.12.16(graphql@16.9.0)(typescript@5.6.3)': + dependencies: + '@gql.tada/internal': 1.0.8(graphql@16.9.0)(typescript@5.6.3) + graphql: 16.9.0 + typescript: 5.6.3 + '@acuminous/bitsyntax@0.1.2': dependencies: buffer-more-ints: 1.0.0 @@ -20750,6 +20864,23 @@ snapshots: - encoding - supports-color + '@gql.tada/cli-utils@1.6.3(@0no-co/graphqlsp@1.12.16(graphql@16.9.0)(typescript@5.6.3))(graphql@16.9.0)(typescript@5.6.3)': + dependencies: + '@0no-co/graphqlsp': 1.12.16(graphql@16.9.0)(typescript@5.6.3) + '@gql.tada/internal': 1.0.8(graphql@16.9.0)(typescript@5.6.3) + graphql: 16.9.0 + typescript: 5.6.3 + + '@gql.tada/internal@1.0.8(graphql@16.9.0)(typescript@5.6.3)': + dependencies: + '@0no-co/graphql.web': 1.0.12(graphql@16.9.0) + graphql: 16.9.0 + typescript: 5.6.3 + + '@graphql-typed-document-node/core@3.2.0(graphql@16.9.0)': + dependencies: + graphql: 16.9.0 + '@hapi/hoek@9.3.0': {} '@hapi/topo@5.1.0': @@ -21397,6 +21528,31 @@ snapshots: '@msgpack/msgpack@3.0.0-beta2': {} + '@mysten/bcs@1.2.0': + dependencies: + bs58: 6.0.0 + + '@mysten/sui@1.16.2(typescript@5.6.3)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.9.0) + '@mysten/bcs': 1.2.0 + '@noble/curves': 1.7.0 + '@noble/hashes': 1.6.1 + '@scure/bip32': 1.6.0 + '@scure/bip39': 1.5.0 + '@suchipi/femver': 1.0.0 + bech32: 2.0.0 + gql.tada: 1.8.10(graphql@16.9.0)(typescript@5.6.3) + graphql: 16.9.0 + jose: 5.9.6 + poseidon-lite: 0.2.1 + tweetnacl: 1.0.3 + valibot: 0.36.0 + transitivePeerDependencies: + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - typescript + '@napi-rs/wasm-runtime@0.2.4': dependencies: '@emnapi/core': 1.3.1 @@ -23712,6 +23868,8 @@ snapshots: '@starknet-io/types-js@0.7.10': {} + '@suchipi/femver@1.0.0': {} + '@supabase/auth-js@2.65.1': dependencies: '@supabase/node-fetch': 2.6.15 @@ -28997,6 +29155,18 @@ snapshots: p-cancelable: 3.0.0 responselike: 3.0.0 + gql.tada@1.8.10(graphql@16.9.0)(typescript@5.6.3): + dependencies: + '@0no-co/graphql.web': 1.0.12(graphql@16.9.0) + '@0no-co/graphqlsp': 1.12.16(graphql@16.9.0)(typescript@5.6.3) + '@gql.tada/cli-utils': 1.6.3(@0no-co/graphqlsp@1.12.16(graphql@16.9.0)(typescript@5.6.3))(graphql@16.9.0)(typescript@5.6.3) + '@gql.tada/internal': 1.0.8(graphql@16.9.0)(typescript@5.6.3) + typescript: 5.6.3 + transitivePeerDependencies: + - '@gql.tada/svelte-support' + - '@gql.tada/vue-support' + - graphql + graceful-fs@4.2.10: {} graceful-fs@4.2.11: {} @@ -29005,6 +29175,8 @@ snapshots: graphemer@1.4.0: {} + graphql@16.9.0: {} + gray-matter@4.0.3: dependencies: js-yaml: 3.14.1 @@ -30331,6 +30503,8 @@ snapshots: '@sideway/formula': 3.0.1 '@sideway/pinpoint': 2.0.0 + jose@5.9.6: {} + joycon@3.1.1: {} jpeg-js@0.3.7: {} @@ -35950,6 +36124,8 @@ snapshots: tweetnacl@0.14.5: {} + tweetnacl@1.0.3: {} + twitter-api-v2@1.18.2: {} tx2@1.0.5: @@ -36343,6 +36519,8 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 + valibot@0.36.0: {} + valibot@0.38.0(typescript@5.6.3): optionalDependencies: typescript: 5.6.3