diff --git a/packages/plugin-nft-collections/package.json b/packages/plugin-nft-collections/package.json new file mode 100644 index 0000000000..d36801e3f4 --- /dev/null +++ b/packages/plugin-nft-collections/package.json @@ -0,0 +1,19 @@ +{ + "name": "@ai16z/plugin-nft-collections", + "version": "0.1.0", + "description": "NFT collections plugin for Eliza", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc", + "test": "jest" + }, + "dependencies": { + "@ai16z/eliza": "workspace:*", + "axios": "^1.6.7" + }, + "devDependencies": { + "typescript": "^5.3.3", + "@types/node": "^20.11.16" + } +} diff --git a/packages/plugin-nft-collections/src/index.ts b/packages/plugin-nft-collections/src/index.ts new file mode 100644 index 0000000000..75b0f88cd9 --- /dev/null +++ b/packages/plugin-nft-collections/src/index.ts @@ -0,0 +1,108 @@ +import { + Plugin, + Action, + Provider, + IAgentRuntime, + Memory, + State, +} from "@ai16z/eliza"; +import axios from "axios"; + +interface NFTCollection { + name: string; + totalSupply: number; + floorPrice: number; + volume24h: number; +} + +const fetchNFTCollections = async (): Promise => { + const API_KEY = process.env.RESERVOIR_API_KEY; + const response = await axios.get( + "https://api.reservoir.tools/collections/v6", + { + headers: { + accept: "application/json", + "x-api-key": API_KEY, + }, + } + ); + return response.data.collections.map((collection: any) => ({ + name: collection.name, + totalSupply: collection.totalSupply, + floorPrice: collection.floorAsk.price.amount.native, + volume24h: collection.volume["1day"], + })); +}; + +const nftCollectionAction: Action = { + name: "GET_NFT_COLLECTIONS", + description: + "Fetches information about curated NFT collections on Ethereum", + validate: async (runtime: IAgentRuntime, message: Memory) => { + return message.content.text.toLowerCase().includes("nft collections"); + }, + handler: async (runtime: IAgentRuntime, message: Memory) => { + try { + const collections = await fetchNFTCollections(); + const response = collections + .map( + (c) => + `${c.name}: Supply: ${c.totalSupply}, Floor: ${c.floorPrice.toFixed(2)} ETH, 24h Volume: ${c.volume24h.toFixed(2)} ETH` + ) + .join("\n"); + await runtime.sendMessage(message.roomId, response); + return true; + } catch (error) { + console.error("Error fetching NFT collections:", error); + await runtime.sendMessage( + message.roomId, + "Failed to fetch NFT collection data." + ); + return false; + } + }, + examples: [ + [ + { + user: "{{user1}}", + content: { + text: "Can you tell me about the top NFT collections?", + }, + }, + { + user: "{{user2}}", + content: { + text: "Certainly! Here are the top NFT collections on Ethereum:", + action: "GET_NFT_COLLECTIONS", + }, + }, + ], + ], +}; + +const nftCollectionProvider: Provider = { + get: async (runtime: IAgentRuntime, message: Memory, state?: State) => { + try { + const collections = await fetchNFTCollections(); + return `Current top NFT collections on Ethereum:\n${collections + .map( + (c) => + `${c.name}: Supply: ${c.totalSupply}, Floor: ${c.floorPrice.toFixed(2)} ETH, 24h Volume: ${c.volume24h.toFixed(2)} ETH` + ) + .join("\n")}`; + } catch (error) { + console.error("Error in NFT collection provider:", error); + return "Unable to fetch NFT collection data at the moment."; + } + }, +}; + +const nftCollectionPlugin: Plugin = { + name: "nft-collection-plugin", + description: + "Provides information about curated NFT collections on Ethereum", + actions: [nftCollectionAction], + providers: [nftCollectionProvider], +}; + +export default nftCollectionPlugin; diff --git a/packages/plugin-nft-collections/tsconfig.json b/packages/plugin-nft-collections/tsconfig.json new file mode 100644 index 0000000000..4f98b59fb1 --- /dev/null +++ b/packages/plugin-nft-collections/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "dist" + ] +} \ No newline at end of file