From c6d378b7561625bc962c3fbd5f1ddecb86469373 Mon Sep 17 00:00:00 2001 From: pranjallyad Date: Fri, 10 Jan 2025 13:43:59 +0530 Subject: [PATCH 1/2] Added Lens Testnet Network Support --- .env.example | 4 + agent/package.json | 1 + agent/src/index.ts | 5 + packages/plugin-lensNetwork/README.md | 199 ++++++++++++ packages/plugin-lensNetwork/package.json | 37 +++ .../src/actions/transfer.ts | 292 ++++++++++++++++++ .../src/actions/trasferFromWallet.ts | 217 +++++++++++++ .../plugin-lensNetwork/src/environment.ts | 32 ++ packages/plugin-lensNetwork/src/index.ts | 14 + packages/plugin-lensNetwork/tsconfig.json | 10 + packages/plugin-lensNetwork/tsup.config.ts | 20 ++ 11 files changed, 831 insertions(+) create mode 100644 packages/plugin-lensNetwork/README.md create mode 100644 packages/plugin-lensNetwork/package.json create mode 100644 packages/plugin-lensNetwork/src/actions/transfer.ts create mode 100644 packages/plugin-lensNetwork/src/actions/trasferFromWallet.ts create mode 100644 packages/plugin-lensNetwork/src/environment.ts create mode 100644 packages/plugin-lensNetwork/src/index.ts create mode 100644 packages/plugin-lensNetwork/tsconfig.json create mode 100644 packages/plugin-lensNetwork/tsup.config.ts diff --git a/.env.example b/.env.example index 2c0bdbe3bd..0482e630ea 100644 --- a/.env.example +++ b/.env.example @@ -223,6 +223,10 @@ STARKNET_ADDRESS= STARKNET_PRIVATE_KEY= STARKNET_RPC_URL= +# Lens Network Configuration +LENS_ADDRESS= +LENS_PRIVATE_KEY= + # Intiface Configuration INTIFACE_WEBSOCKET_URL=ws://localhost:12345 diff --git a/agent/package.json b/agent/package.json index f4fa0f33e0..8b08df83f1 100644 --- a/agent/package.json +++ b/agent/package.json @@ -43,6 +43,7 @@ "@elizaos/plugin-gitbook": "workspace:*", "@elizaos/plugin-story": "workspace:*", "@elizaos/plugin-goat": "workspace:*", + "@elizaos/plugin-lensNetwork": "workspace:*", "@elizaos/plugin-icp": "workspace:*", "@elizaos/plugin-image-generation": "workspace:*", "@elizaos/plugin-nft-generation": "workspace:*", diff --git a/agent/src/index.ts b/agent/src/index.ts index 53058cf4ec..6d1a04f7ce 100644 --- a/agent/src/index.ts +++ b/agent/src/index.ts @@ -58,6 +58,7 @@ import { solanaPlugin } from "@elizaos/plugin-solana"; import { suiPlugin } from "@elizaos/plugin-sui"; import { TEEMode, teePlugin } from "@elizaos/plugin-tee"; import { tonPlugin } from "@elizaos/plugin-ton"; +import { lensPlugin } from "@elizaos/plugin-lensNetwork"; import { zksyncEraPlugin } from "@elizaos/plugin-zksync-era"; import { cronosZkEVMPlugin } from "@elizaos/plugin-cronoszkevm"; import { abstractPlugin } from "@elizaos/plugin-abstract"; @@ -592,6 +593,10 @@ export async function createAgent( getSecret(character, "FLOW_PRIVATE_KEY") ? flowPlugin : null, + getSecret(character, "LENS_ADDRESS") && + getSecret(character, "LENS_PRIVATE_KEY") + ? lensPlugin + : null, getSecret(character, "APTOS_PRIVATE_KEY") ? aptosPlugin : null, getSecret(character, "MVX_PRIVATE_KEY") ? multiversxPlugin : null, getSecret(character, "ZKSYNC_PRIVATE_KEY") ? zksyncEraPlugin : null, diff --git a/packages/plugin-lensNetwork/README.md b/packages/plugin-lensNetwork/README.md new file mode 100644 index 0000000000..9a1f0539cf --- /dev/null +++ b/packages/plugin-lensNetwork/README.md @@ -0,0 +1,199 @@ +# @elizaos/plugin-abstract + +A plugin for interacting with the Abstract blockchain network within the ElizaOS ecosystem. + +## Description +The Abstract plugin enables seamless token transfers on the Abstract testnet. It provides functionality to transfer both native ETH and ERC20 tokens using secure wallet operations. + +## Installation + +```bash +pnpm install @elizaos/plugin-abstract +``` + +## Configuration + +The plugin requires the following environment variables to be set: +```typescript +ABSTRACT_ADDRESS= +ABSTRACT_PRIVATE_KEY= +``` + +## Usage + +### Basic Integration + +```typescript +import { abstractPlugin } from '@elizaos/plugin-abstract'; +``` + +### Transfer Examples + +```typescript +// The plugin responds to natural language commands like: + +"Send 100 USDC to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62" +"Transfer 0.1 ETH to 0xbD8679cf79137042214fA4239b02F4022208EE82" +"Pay 50 USDC on Abstract to [address]" +``` + +## API Reference + +### Actions + +#### SEND_TOKEN + +Transfers tokens from the agent's wallet to another address. + +**Aliases:** +- TRANSFER_TOKEN_ON_ABSTRACT +- TRANSFER_TOKENS_ON_ABSTRACT +- SEND_TOKENS_ON_ABSTRACT +- SEND_ETH_ON_ABSTRACT +- PAY_ON_ABSTRACT +- MOVE_TOKENS_ON_ABSTRACT +- MOVE_ETH_ON_ABSTRACT + +## Common Issues & Troubleshooting + +1. **Transaction Failures** + - Verify wallet has sufficient balance + - Check recipient address format + - Ensure private key is correctly set + - Verify network connectivity + +2. **Configuration Issues** + - Verify all required environment variables are set + - Ensure private key format is correct + - Check wallet address format + +## Security Best Practices + +1. **Private Key Management** + - Store private key securely using environment variables + - Never commit private keys to version control + - Use separate wallets for development and production + - Monitor wallet activity regularly + +## Development Guide + +### Setting Up Development Environment + +1. Clone the repository +2. Install dependencies: + +```bash +pnpm install +``` + +3. Build the plugin: + +```bash +pnpm run build +``` + +4. Run the plugin: + +```bash +pnpm run dev +``` + +## Future Enhancements + +1. **Smart Account Features** + - Multi-signature support + - Account recovery mechanisms + - Batch transaction processing + - Advanced permission management + - Account abstraction improvements + - Social recovery options + +2. **CosmWasm Integration** + - Contract deployment templates + - Smart contract verification tools + - Contract upgrade system + - Testing framework improvements + - Gas optimization tools + - Contract interaction templates + +3. **IBC Operations** + - Cross-chain transfer optimization + - IBC relayer monitoring + - Channel management tools + - Packet tracking system + - Timeout handling improvements + - Cross-chain messaging + +4. **DEX Integration** + - Advanced swap routing + - Liquidity pool management + - Yield farming automation + - Price impact analysis + - Slippage protection + - AMM optimization + +5. **Security Enhancements** + - Transaction simulation + - Risk assessment tools + - Rate limiting controls + - Fraud detection system + - Emergency shutdown features + - Audit integration tools + +6. **Developer Tools** + - Enhanced debugging capabilities + - Documentation generator + - CLI tool improvements + - Testing utilities + - Deployment automation + - Performance profiling + +7. **Analytics and Monitoring** + - Transaction tracking dashboard + - Network statistics + - Performance metrics + - Gas usage optimization + - Custom reporting tools + - Real-time monitoring + +8. **Wallet Management** + - Multiple wallet support + - Hardware wallet integration + - Address book features + - Transaction history analysis + - Balance monitoring + - Token management tools + +We welcome community feedback and contributions to help prioritize these enhancements. + +## Contributing + +Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information. + +## Credits + +This plugin integrates with and builds upon several key technologies: + +- [Abstract](https://abstract.money/): Smart account infrastructure +- [CosmWasm](https://cosmwasm.com/): Smart contract platform +- [Cosmos SDK](https://v1.cosmos.network/sdk): Blockchain application framework +- [IBC Protocol](https://ibcprotocol.org/): Inter-blockchain communication +- [Osmosis](https://osmosis.zone/): DEX infrastructure + +Special thanks to: +- The Abstract development team +- The CosmWasm core developers +- The Cosmos SDK maintainers +- The IBC Protocol team +- The Osmosis DEX team +- The Eliza community for their contributions and feedback + +For more information about Abstract capabilities: +- [Abstract Documentation](https://docs.abstract.money/) +- [CosmWasm Documentation](https://docs.cosmwasm.com/) +- [Cosmos SDK Docs](https://docs.cosmos.network/) +- [IBC Protocol Docs](https://ibc.cosmos.network/) + +## License + +This plugin is part of the Eliza project. See the main project repository for license information. diff --git a/packages/plugin-lensNetwork/package.json b/packages/plugin-lensNetwork/package.json new file mode 100644 index 0000000000..d3388c872e --- /dev/null +++ b/packages/plugin-lensNetwork/package.json @@ -0,0 +1,37 @@ +{ + "name": "@elizaos/plugin-lensNetwork", + "version": "0.1.7", + "type": "module", + "main": "dist/index.js", + "module": "dist/index.js", + "types": "dist/index.d.ts", + "exports": { + "./package.json": "./package.json", + ".": { + "import": { + "@elizaos/source": "./src/index.ts", + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + } + }, + "files": [ + "dist" + ], + "dependencies": { + "@elizaos/core": "workspace:*", + "tsup": "^8.3.5", + "web3": "^4.15.0", + "@lens-network/sdk": "^0.0.0-canary-20241203140504", + + "dotenv": "^16.0.3", + "ethers": "^6.0.0", + "zksync-ethers": "^6.0.0" + }, + "scripts": { + "build": "tsup --format esm --dts" + }, + "peerDependencies": { + "whatwg-url": "7.1.0" + } +} diff --git a/packages/plugin-lensNetwork/src/actions/transfer.ts b/packages/plugin-lensNetwork/src/actions/transfer.ts new file mode 100644 index 0000000000..84bb54309c --- /dev/null +++ b/packages/plugin-lensNetwork/src/actions/transfer.ts @@ -0,0 +1,292 @@ +import { + ActionExample, + Content, + HandlerCallback, + IAgentRuntime, + Memory, + ModelClass, + State, + type Action, + elizaLogger, + composeContext, + generateObject, +} from "@elizaos/core"; +import { validateLensConfig } from "../environment"; +import { getDefaultProvider, Network, Wallet } from "@lens-network/sdk/ethers"; +import { ethers, formatEther } from "ethers"; + +import { + Address, + createWalletClient, + erc20Abi, + http, + parseEther, + isAddress, +} from "viem"; + +import { z } from "zod"; + +const TransferSchema = z.object({ + tokenAddress: z.string(), + recipient: z.string(), + amount: z.string(), +}); + +export interface TransferContent extends Content { + tokenAddress: string; + recipient: string; + amount: string | number; +} + +export function isTransferContent( + content: TransferContent +): content is TransferContent { + // Validate types + const validTypes = + + typeof content.recipient === "string" && + (typeof content.amount === "string" || + typeof content.amount === "number"); + if (!validTypes) { + return false; + } + + // Validate addresses + const validAddresses = + + content.recipient.startsWith("0x") && + content.recipient.length === 42; + + return validAddresses; +} + +const transferTemplate = `Respond with a JSON markdown block containing only the extracted values. Use null for any values that cannot be determined. + +Here are several frequently used addresses. Use these for the corresponding tokens: +- ETH/eth: 0x000000000000000000000000000000000000800A + + +Example response: +\`\`\`json +{ + + "recipient": "0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62", + "amount": "1000" +} +\`\`\` + +{{recentMessages}} + +Given the recent messages, extract the following information about the requested token transfer: +- Token contract address +- Recipient wallet address +- Amount to transfer + +Respond with a JSON markdown block containing only the extracted values.`; + +const ETH_ADDRESS = "0x000000000000000000000000000000000000800A"; + +export async function setupProviders() { + // Initialize providers for both L2 (Lens) and L1 (Ethereum) + const lensProvider = getDefaultProvider(Network.Testnet); + const ethProvider = ethers.getDefaultProvider("sepolia"); + + return { lensProvider, ethProvider }; +} + +export async function setupWallet( + lensProvider: any, + ethProvider: any, + key: any +) { + // Create wallet instance with both L2 and L1 providers + const wallet = new Wallet(key, lensProvider, ethProvider); + + return wallet; +} + +export async function transferTokens( + wallet: any, + recipientAddress: string, + amount: string +) { + try { + // Validate recipient address + if (!isAddress(recipientAddress)) { + throw new Error("Invalid recipient address"); + } + + // Create transaction object + const tx = { + to: recipientAddress, + value: parseEther(amount), + }; + + // Send transaction + console.log( + `Initiating transfer of ${amount} tokens to ${recipientAddress}...` + ); + const transaction = await wallet.sendTransaction(tx); + + // Wait for transaction confirmation + console.log(`Transaction hash: ${transaction.hash}`); + const receipt = await transaction.wait(); + + console.log("Transfer completed successfully!"); + console.log("Transaction receipt:", receipt); + + return transaction.hash; + } catch (error) { + console.error("Error transferring tokens:", error); + throw error; + } +} + +export default { + name: "SEND_TOKEN", + similes: [ + "TRANSFER_TOKEN_ON_LENS", + "TRANSFER_TOKENS_ON_LENS", + "SEND_TOKENS_ON_LENS", + "SEND_GRASS_ON_LENS", + "PAY_ON_LENS", + "MOVE_TOKENS_ON_LENS", + "MOVE_GRASS_ON_LENS", + ], + validate: async (runtime: IAgentRuntime, message: Memory) => { + await validateLensConfig(runtime); + return true; + }, + description: "Transfer tokens from the agent's wallet to another address", + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + _options: { [key: string]: unknown }, + callback?: HandlerCallback + ): Promise => { + elizaLogger.log("Starting LENS SEND_TOKEN handler..."); + + // Initialize or update state + if (!state) { + state = (await runtime.composeState(message)) as State; + } else { + state = await runtime.updateRecentMessageState(state); + } + + // Compose transfer context + const transferContext = composeContext({ + state, + template: transferTemplate, + }); + + // Generate transfer content + const content = ( + await generateObject({ + runtime, + context: transferContext, + modelClass: ModelClass.SMALL, + schema: TransferSchema, + }) + ).object as unknown as TransferContent; + + // Validate transfer content + if (!isTransferContent(content)) { + console.error("Invalid content for TRANSFER_TOKEN action."); + if (callback) { + callback({ + text: "Unable to process transfer request. Invalid content provided.", + content: { error: "Invalid transfer content" }, + }); + } + return false; + } + + try { + const PRIVATE_KEY = runtime.getSetting("LENS_PRIVATE_KEY")!; + const { lensProvider, ethProvider } = await setupProviders(); + const wallet = await setupWallet( + lensProvider, + ethProvider, + PRIVATE_KEY + ); + const amount = content.amount.toString(); + + let hash; + + hash = await transferTokens( + wallet, + content.recipient as Address, + amount + ); + + elizaLogger.success( + "Transfer completed successfully! Transaction hash: " + hash + ); + if (callback) { + callback({ + text: + "Transfer completed successfully! Transaction hash: " + + hash, + content: {}, + }); + } + + return true; + } catch (error) { + elizaLogger.error("Error during token transfer:", error); + if (callback) { + callback({ + text: `Error transferring tokens: ${error.message}`, + content: { error: error.message }, + }); + } + return false; + } + }, + + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Send 1 Grass to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62", + }, + }, + { + user: "{{agent}}", + content: { + text: "Sure, I'll send 1 Grass to that address now.", + action: "SEND_TOKEN", + }, + }, + { + user: "{{agent}}", + content: { + text: "Successfully sent 1 Grass to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62\nTransaction: 0x4fed598033f0added272c3ddefd4d83a521634a738474400b27378db462a76ec", + }, + }, + ], + [ + { + user: "{{user1}}", + content: { + text: "Please send 0.1 GRASS to 0xbD8679cf79137042214fA4239b02F4022208EE82", + }, + }, + { + user: "{{agent}}", + content: { + text: "Of course. Sending 0.1 Grass to that address now.", + action: "SEND_TOKEN", + }, + }, + { + user: "{{agent}}", + content: { + text: "Successfully sent 0.1 Grass to 0xbD8679cf79137042214fA4239b02F4022208EE82\nTransaction: 0x0b9f23e69ea91ba98926744472717960cc7018d35bc3165bdba6ae41670da0f0", + }, + }, + ], + ] as ActionExample[][], +} as Action; diff --git a/packages/plugin-lensNetwork/src/actions/trasferFromWallet.ts b/packages/plugin-lensNetwork/src/actions/trasferFromWallet.ts new file mode 100644 index 0000000000..bf2a75c9d9 --- /dev/null +++ b/packages/plugin-lensNetwork/src/actions/trasferFromWallet.ts @@ -0,0 +1,217 @@ +import { + ActionExample, + Content, + HandlerCallback, + IAgentRuntime, + Memory, + ModelClass, + State, + type Action, + elizaLogger, + composeContext, + generateObject, +} from "@elizaos/core"; +import { z } from "zod"; +import { validateLensConfig } from "../environment"; +import { isAddress } from "viem"; + +// Enhanced schema with stricter validation +const TransferSchema = z.object({ + recipient: z.string().refine( + (val) => isAddress(val), + { message: "Invalid Ethereum address format" } + ), + amount: z.string().refine( + (val) => { + const num = parseFloat(val); + return !isNaN(num) && num > 0; + }, + { message: "Amount must be a positive number" } + ), +}); + +export interface TransferContent extends Content { + recipient: string; + amount: string | number; +} + +// Enhanced validation function +export function isTransferContent( + content: TransferContent +): content is TransferContent { + try { + // Check if content exists + if (!content || !content.recipient || content.amount === undefined) { + elizaLogger.error("Missing required transfer content"); + return false; + } + + // Validate types + if (typeof content.recipient !== "string" || + (typeof content.amount !== "string" && typeof content.amount !== "number")) { + elizaLogger.error("Invalid content types"); + return false; + } + + // Validate address format + if (!content.recipient.startsWith("0x") || + content.recipient.length !== 42 || + !isAddress(content.recipient)) { + elizaLogger.error("Invalid recipient address format"); + return false; + } + + // Validate amount + const amountNum = typeof content.amount === "string" ? + parseFloat(content.amount) : content.amount; + + if (isNaN(amountNum) || amountNum <= 0) { + elizaLogger.error("Invalid amount"); + return false; + } + + return true; + } catch (error) { + elizaLogger.error("Validation error:", error); + return false; + } +} + +const transferTemplate = `Respond with a JSON markdown block containing only the extracted values. Use null for any values that cannot be determined. + +Extract the following information about the requested token transfer: +- Recipient wallet address (must be a valid Ethereum address) +- Amount of Grass to transfer (must be a positive number) + +Example response: +\`\`\`json +{ + "recipient": "0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62", + "amount": "1000" +} +\`\`\` + +{{recentMessages}}`; + +export default { + name: "SIMULATE_GRASS_TRANSFER", + similes: [ + "TRANSFER_GRASS", + "SEND_GRASS", + "MOVE_GRASS", + "PAY_GRASS", + ], + validate: async (runtime: IAgentRuntime, message: Memory) => { + await validateLensConfig(runtime); + return true; + }, + description: "Simulate transferring Grass tokens to another address", + handler: async ( + runtime: IAgentRuntime, + message: Memory, + state: State, + _options: { [key: string]: unknown }, + callback?: HandlerCallback + ): Promise => { + elizaLogger.log("Starting simulated Grass transfer handler with validation..."); + + try { + // Initialize or update state + if (!state) { + state = (await runtime.composeState(message)) as State; + } else { + state = await runtime.updateRecentMessageState(state); + } + + // Compose transfer context + const transferContext = composeContext({ + state, + template: transferTemplate, + }); + + // Generate and validate transfer content + const content = ( + await generateObject({ + runtime, + context: transferContext, + modelClass: ModelClass.SMALL, + schema: TransferSchema, + }) + ).object as unknown as TransferContent; + + // Additional validation check + if (!isTransferContent(content)) { + throw new Error("Transfer content validation failed"); + } + + // Log validation success + elizaLogger.log("Transfer content validated successfully"); + + // Format amount to handle both string and number types + const formattedAmount = typeof content.amount === "string" ? + content.amount : + content.amount.toString(); + + // Log the simulation success + elizaLogger.success( + `[SIMULATION] Transfer validation passed: ${formattedAmount} Grass to ${content.recipient}` + ); + + // Return transfer details for confirmation + if (callback) { + callback({ + text: `Please confirm in your wallet: Transfer of ${formattedAmount} Grass to ${content.recipient} + [handleTransfer,${content.recipient} ,${formattedAmount}]`, + content: { + simulatedTransfer: [formattedAmount, content.recipient] + }, + }); + } + + return true; + + } catch (error) { + elizaLogger.error("Error in transfer validation/simulation:", error); + if (callback) { + callback({ + text: `Unable to process transfer: ${error.message}`, + content: { error: error.message }, + }); + } + return false; + } + }, + + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Transfer 1 Grass to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62", + }, + }, + { + user: "{{agent}}", + content: { + text: "Please confirm in your wallet: Transfer of 1 Grass to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62", + action: "SIMULATE_GRASS_TRANSFER", + }, + }, + ], + [ + { + user: "{{user1}}", + content: { + text: "Send 0.5 Grass to 0xbD8679cf79137042214fA4239b02F4022208EE82", + }, + }, + { + user: "{{agent}}", + content: { + text: "Please confirm in your wallet: Transfer of 0.5 Grass to 0xbD8679cf79137042214fA4239b02F4022208EE82", + action: "SIMULATE_GRASS_TRANSFER", + }, + }, + ], + ] as ActionExample[][], +} as Action; \ No newline at end of file diff --git a/packages/plugin-lensNetwork/src/environment.ts b/packages/plugin-lensNetwork/src/environment.ts new file mode 100644 index 0000000000..823fb3b892 --- /dev/null +++ b/packages/plugin-lensNetwork/src/environment.ts @@ -0,0 +1,32 @@ +import { IAgentRuntime } from "@elizaos/core"; +import { z } from "zod"; + +export const lensEnvSchema = z.object({ + LENS_ADDRESS: z.string().min(1, "LENS address is required"), + LENS_PRIVATE_KEY: z.string().min(1, "LENS private key is required"), +}); + +export type LensConfig = z.infer; + +export async function validateLensConfig( + runtime: IAgentRuntime +): Promise { + try { + const config = { + LENS_ADDRESS: runtime.getSetting("LENS_ADDRESS"), + LENS_PRIVATE_KEY: runtime.getSetting("LENS_PRIVATE_KEY"), + }; + + return lensEnvSchema.parse(config); + } catch (error) { + if (error instanceof z.ZodError) { + const errorMessages = error.errors + .map((err) => `${err.path.join(".")}: ${err.message}`) + .join("\n"); + throw new Error( + `Lens configuration validation failed:\n${errorMessages}` + ); + } + throw error; + } +} diff --git a/packages/plugin-lensNetwork/src/index.ts b/packages/plugin-lensNetwork/src/index.ts new file mode 100644 index 0000000000..2e23a01c39 --- /dev/null +++ b/packages/plugin-lensNetwork/src/index.ts @@ -0,0 +1,14 @@ +import { Plugin } from "@elizaos/core"; + +import transfer from "./actions/transfer.ts"; +import trasferFromWallet from "./actions/trasferFromWallet.ts"; + +export const LensPlugin: Plugin = { + name: "Lens", + description: "Lens Plugin for Eliza", + actions: [transfer,trasferFromWallet], + evaluators: [], + providers: [], +}; + +export default LensPlugin; diff --git a/packages/plugin-lensNetwork/tsconfig.json b/packages/plugin-lensNetwork/tsconfig.json new file mode 100644 index 0000000000..73993deaaf --- /dev/null +++ b/packages/plugin-lensNetwork/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../core/tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + }, + "include": [ + "src/**/*.ts" + ] +} \ No newline at end of file diff --git a/packages/plugin-lensNetwork/tsup.config.ts b/packages/plugin-lensNetwork/tsup.config.ts new file mode 100644 index 0000000000..e42bf4efea --- /dev/null +++ b/packages/plugin-lensNetwork/tsup.config.ts @@ -0,0 +1,20 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist", + sourcemap: true, + clean: true, + format: ["esm"], // Ensure you're targeting CommonJS + external: [ + "dotenv", // Externalize dotenv to prevent bundling + "fs", // Externalize fs to use Node.js built-in module + "path", // Externalize other built-ins if necessary + "@reflink/reflink", + "@node-llama-cpp", + "https", + "http", + "agentkeepalive", + // Add other modules you want to externalize + ], +}); From f4fa049c0f8796f34979110c0170bffc7c67ec5c Mon Sep 17 00:00:00 2001 From: pranjallyad Date: Fri, 10 Jan 2025 14:34:28 +0530 Subject: [PATCH 2/2] Added Lens Testnet Network Support --- packages/plugin-lensNetwork/README.md | 126 ++-------- .../src/actions/trasferFromWallet.ts | 217 ------------------ packages/plugin-lensNetwork/src/index.ts | 4 +- 3 files changed, 15 insertions(+), 332 deletions(-) delete mode 100644 packages/plugin-lensNetwork/src/actions/trasferFromWallet.ts diff --git a/packages/plugin-lensNetwork/README.md b/packages/plugin-lensNetwork/README.md index 9a1f0539cf..3bf8e2e48e 100644 --- a/packages/plugin-lensNetwork/README.md +++ b/packages/plugin-lensNetwork/README.md @@ -8,15 +8,15 @@ The Abstract plugin enables seamless token transfers on the Abstract testnet. It ## Installation ```bash -pnpm install @elizaos/plugin-abstract +pnpm install @elizaos/plugin-lensNetwork ``` ## Configuration The plugin requires the following environment variables to be set: ```typescript -ABSTRACT_ADDRESS= -ABSTRACT_PRIVATE_KEY= +LENS_ADDRESS= +LENS_PRIVATE_KEY= ``` ## Usage @@ -24,7 +24,7 @@ ABSTRACT_PRIVATE_KEY= ### Basic Integration ```typescript -import { abstractPlugin } from '@elizaos/plugin-abstract'; +import { lensPlugin } from '@elizaos/plugin-lensNetwork'; ``` ### Transfer Examples @@ -32,9 +32,8 @@ import { abstractPlugin } from '@elizaos/plugin-abstract'; ```typescript // The plugin responds to natural language commands like: -"Send 100 USDC to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62" -"Transfer 0.1 ETH to 0xbD8679cf79137042214fA4239b02F4022208EE82" -"Pay 50 USDC on Abstract to [address]" +"Send 1 Grass to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62" + ``` ## API Reference @@ -46,13 +45,13 @@ import { abstractPlugin } from '@elizaos/plugin-abstract'; Transfers tokens from the agent's wallet to another address. **Aliases:** -- TRANSFER_TOKEN_ON_ABSTRACT -- TRANSFER_TOKENS_ON_ABSTRACT -- SEND_TOKENS_ON_ABSTRACT -- SEND_ETH_ON_ABSTRACT -- PAY_ON_ABSTRACT -- MOVE_TOKENS_ON_ABSTRACT -- MOVE_ETH_ON_ABSTRACT +- TRANSFER_TOKEN_ON_LENS +- TRANSFER_TOKENS_ON_LENS +- SEND_TOKENS_ON_LENS +- SEND_ETH_ON_LENS +- PAY_ON_LENS +- MOVE_TOKENS_ON_LENS +- MOVE_ETH_ON_LENS ## Common Issues & Troubleshooting @@ -98,102 +97,3 @@ pnpm run build pnpm run dev ``` -## Future Enhancements - -1. **Smart Account Features** - - Multi-signature support - - Account recovery mechanisms - - Batch transaction processing - - Advanced permission management - - Account abstraction improvements - - Social recovery options - -2. **CosmWasm Integration** - - Contract deployment templates - - Smart contract verification tools - - Contract upgrade system - - Testing framework improvements - - Gas optimization tools - - Contract interaction templates - -3. **IBC Operations** - - Cross-chain transfer optimization - - IBC relayer monitoring - - Channel management tools - - Packet tracking system - - Timeout handling improvements - - Cross-chain messaging - -4. **DEX Integration** - - Advanced swap routing - - Liquidity pool management - - Yield farming automation - - Price impact analysis - - Slippage protection - - AMM optimization - -5. **Security Enhancements** - - Transaction simulation - - Risk assessment tools - - Rate limiting controls - - Fraud detection system - - Emergency shutdown features - - Audit integration tools - -6. **Developer Tools** - - Enhanced debugging capabilities - - Documentation generator - - CLI tool improvements - - Testing utilities - - Deployment automation - - Performance profiling - -7. **Analytics and Monitoring** - - Transaction tracking dashboard - - Network statistics - - Performance metrics - - Gas usage optimization - - Custom reporting tools - - Real-time monitoring - -8. **Wallet Management** - - Multiple wallet support - - Hardware wallet integration - - Address book features - - Transaction history analysis - - Balance monitoring - - Token management tools - -We welcome community feedback and contributions to help prioritize these enhancements. - -## Contributing - -Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information. - -## Credits - -This plugin integrates with and builds upon several key technologies: - -- [Abstract](https://abstract.money/): Smart account infrastructure -- [CosmWasm](https://cosmwasm.com/): Smart contract platform -- [Cosmos SDK](https://v1.cosmos.network/sdk): Blockchain application framework -- [IBC Protocol](https://ibcprotocol.org/): Inter-blockchain communication -- [Osmosis](https://osmosis.zone/): DEX infrastructure - -Special thanks to: -- The Abstract development team -- The CosmWasm core developers -- The Cosmos SDK maintainers -- The IBC Protocol team -- The Osmosis DEX team -- The Eliza community for their contributions and feedback - -For more information about Abstract capabilities: -- [Abstract Documentation](https://docs.abstract.money/) -- [CosmWasm Documentation](https://docs.cosmwasm.com/) -- [Cosmos SDK Docs](https://docs.cosmos.network/) -- [IBC Protocol Docs](https://ibc.cosmos.network/) - -## License - -This plugin is part of the Eliza project. See the main project repository for license information. diff --git a/packages/plugin-lensNetwork/src/actions/trasferFromWallet.ts b/packages/plugin-lensNetwork/src/actions/trasferFromWallet.ts deleted file mode 100644 index bf2a75c9d9..0000000000 --- a/packages/plugin-lensNetwork/src/actions/trasferFromWallet.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { - ActionExample, - Content, - HandlerCallback, - IAgentRuntime, - Memory, - ModelClass, - State, - type Action, - elizaLogger, - composeContext, - generateObject, -} from "@elizaos/core"; -import { z } from "zod"; -import { validateLensConfig } from "../environment"; -import { isAddress } from "viem"; - -// Enhanced schema with stricter validation -const TransferSchema = z.object({ - recipient: z.string().refine( - (val) => isAddress(val), - { message: "Invalid Ethereum address format" } - ), - amount: z.string().refine( - (val) => { - const num = parseFloat(val); - return !isNaN(num) && num > 0; - }, - { message: "Amount must be a positive number" } - ), -}); - -export interface TransferContent extends Content { - recipient: string; - amount: string | number; -} - -// Enhanced validation function -export function isTransferContent( - content: TransferContent -): content is TransferContent { - try { - // Check if content exists - if (!content || !content.recipient || content.amount === undefined) { - elizaLogger.error("Missing required transfer content"); - return false; - } - - // Validate types - if (typeof content.recipient !== "string" || - (typeof content.amount !== "string" && typeof content.amount !== "number")) { - elizaLogger.error("Invalid content types"); - return false; - } - - // Validate address format - if (!content.recipient.startsWith("0x") || - content.recipient.length !== 42 || - !isAddress(content.recipient)) { - elizaLogger.error("Invalid recipient address format"); - return false; - } - - // Validate amount - const amountNum = typeof content.amount === "string" ? - parseFloat(content.amount) : content.amount; - - if (isNaN(amountNum) || amountNum <= 0) { - elizaLogger.error("Invalid amount"); - return false; - } - - return true; - } catch (error) { - elizaLogger.error("Validation error:", error); - return false; - } -} - -const transferTemplate = `Respond with a JSON markdown block containing only the extracted values. Use null for any values that cannot be determined. - -Extract the following information about the requested token transfer: -- Recipient wallet address (must be a valid Ethereum address) -- Amount of Grass to transfer (must be a positive number) - -Example response: -\`\`\`json -{ - "recipient": "0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62", - "amount": "1000" -} -\`\`\` - -{{recentMessages}}`; - -export default { - name: "SIMULATE_GRASS_TRANSFER", - similes: [ - "TRANSFER_GRASS", - "SEND_GRASS", - "MOVE_GRASS", - "PAY_GRASS", - ], - validate: async (runtime: IAgentRuntime, message: Memory) => { - await validateLensConfig(runtime); - return true; - }, - description: "Simulate transferring Grass tokens to another address", - handler: async ( - runtime: IAgentRuntime, - message: Memory, - state: State, - _options: { [key: string]: unknown }, - callback?: HandlerCallback - ): Promise => { - elizaLogger.log("Starting simulated Grass transfer handler with validation..."); - - try { - // Initialize or update state - if (!state) { - state = (await runtime.composeState(message)) as State; - } else { - state = await runtime.updateRecentMessageState(state); - } - - // Compose transfer context - const transferContext = composeContext({ - state, - template: transferTemplate, - }); - - // Generate and validate transfer content - const content = ( - await generateObject({ - runtime, - context: transferContext, - modelClass: ModelClass.SMALL, - schema: TransferSchema, - }) - ).object as unknown as TransferContent; - - // Additional validation check - if (!isTransferContent(content)) { - throw new Error("Transfer content validation failed"); - } - - // Log validation success - elizaLogger.log("Transfer content validated successfully"); - - // Format amount to handle both string and number types - const formattedAmount = typeof content.amount === "string" ? - content.amount : - content.amount.toString(); - - // Log the simulation success - elizaLogger.success( - `[SIMULATION] Transfer validation passed: ${formattedAmount} Grass to ${content.recipient}` - ); - - // Return transfer details for confirmation - if (callback) { - callback({ - text: `Please confirm in your wallet: Transfer of ${formattedAmount} Grass to ${content.recipient} - [handleTransfer,${content.recipient} ,${formattedAmount}]`, - content: { - simulatedTransfer: [formattedAmount, content.recipient] - }, - }); - } - - return true; - - } catch (error) { - elizaLogger.error("Error in transfer validation/simulation:", error); - if (callback) { - callback({ - text: `Unable to process transfer: ${error.message}`, - content: { error: error.message }, - }); - } - return false; - } - }, - - examples: [ - [ - { - user: "{{user1}}", - content: { - text: "Transfer 1 Grass to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62", - }, - }, - { - user: "{{agent}}", - content: { - text: "Please confirm in your wallet: Transfer of 1 Grass to 0xCCa8009f5e09F8C5dB63cb0031052F9CB635Af62", - action: "SIMULATE_GRASS_TRANSFER", - }, - }, - ], - [ - { - user: "{{user1}}", - content: { - text: "Send 0.5 Grass to 0xbD8679cf79137042214fA4239b02F4022208EE82", - }, - }, - { - user: "{{agent}}", - content: { - text: "Please confirm in your wallet: Transfer of 0.5 Grass to 0xbD8679cf79137042214fA4239b02F4022208EE82", - action: "SIMULATE_GRASS_TRANSFER", - }, - }, - ], - ] as ActionExample[][], -} as Action; \ No newline at end of file diff --git a/packages/plugin-lensNetwork/src/index.ts b/packages/plugin-lensNetwork/src/index.ts index 2e23a01c39..e3406599e6 100644 --- a/packages/plugin-lensNetwork/src/index.ts +++ b/packages/plugin-lensNetwork/src/index.ts @@ -1,12 +1,12 @@ import { Plugin } from "@elizaos/core"; import transfer from "./actions/transfer.ts"; -import trasferFromWallet from "./actions/trasferFromWallet.ts"; + export const LensPlugin: Plugin = { name: "Lens", description: "Lens Plugin for Eliza", - actions: [transfer,trasferFromWallet], + actions: [transfer], evaluators: [], providers: [], };