Skip to content

Commit

Permalink
gm
Browse files Browse the repository at this point in the history
  • Loading branch information
IkigaiLabsETH committed Dec 20, 2024
1 parent ce18601 commit d53e365
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 250 deletions.
52 changes: 52 additions & 0 deletions packages/plugin-nft-collections/src/actions/get-collections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Action, IAgentRuntime, Memory } from "@ai16z/eliza";
import { nftCollectionProvider } from "../providers/nft-collections";

export const getCollectionsAction: Action = {
name: "GET_NFT_COLLECTIONS",
similes: ["LIST_NFT_COLLECTIONS", "SHOW_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 response = await nftCollectionProvider.get(runtime, message);
await runtime.messageManager.createMemory({
id: message.id,
content: { text: response },
roomId: message.roomId,
userId: message.userId,
agentId: runtime.agentId,
});
return true;
} catch (error) {
console.error("Error fetching NFT collections:", error);
await runtime.messageManager.createMemory({
id: message.id,
content: { text: "Failed to fetch NFT collection data." },
roomId: message.roomId,
userId: message.userId,
agentId: runtime.agentId,
});
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",
},
},
],
],
};
119 changes: 119 additions & 0 deletions packages/plugin-nft-collections/src/actions/sweep-floor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Action, IAgentRuntime, Memory, State } from "@ai16z/eliza";
import { NFTService } from "../types";

// Helper function to extract NFT details from the message
function extractNFTDetails(text: string): {
collectionAddress: string | null;
quantity: number;
} {
const addressMatch = text.match(/0x[a-fA-F0-9]{40}/);
const quantityMatch = text.match(/\d+/);

return {
collectionAddress: addressMatch ? addressMatch[0] : null,
quantity: quantityMatch ? parseInt(quantityMatch[0]) : 1,
};
}

export const sweepFloorAction: Action = {
name: "SWEEP_FLOOR_NFT",
similes: ["BUY_FLOOR_NFT", "PURCHASE_FLOOR_NFT"],
description:
"Sweeps the floor of a specified EVM NFT collection by purchasing the lowest-priced available NFTs.",

validate: async (runtime: IAgentRuntime, message: Memory) => {
const content = message.content.text.toLowerCase();
return (
(content.includes("sweep") || content.includes("buy")) &&
content.includes("nft") &&
(content.includes("0x") || content.includes("floor"))
);
},

handler: async (runtime: IAgentRuntime, message: Memory, state?: State) => {
try {
const { collectionAddress, quantity } = extractNFTDetails(
message.content.text
);

if (!collectionAddress) {
throw new Error("No valid collection address found in message");
}

const nftService = runtime.services.get("nft") as any as NFTService;
if (!nftService) {
throw new Error("NFT service not found");
}

// Get floor listings sorted by price
const floorListings = await nftService.getFloorListings({
collection: collectionAddress,
limit: quantity,
sortBy: "price",
});

if (floorListings.length < quantity) {
throw new Error(
`Only ${floorListings.length} NFTs available at floor price`
);
}

// Execute the buy transaction
const result = await nftService.executeBuy({
listings: floorListings,
taker: message.userId, // Assuming userId is the wallet address
});

const totalPrice = floorListings.reduce(
(sum, listing) => sum + listing.price,
0
);
const response =
`Successfully initiated sweep of ${quantity} NFTs from collection ${collectionAddress}:\n` +
`• Total Cost: ${totalPrice} ETH\n` +
`• Average Price: ${(totalPrice / quantity).toFixed(4)} ETH\n` +
`• Transaction Path: ${result.path}\n` +
`• Status: ${result.steps.map((step) => `${step.action} - ${step.status}`).join(", ")}`;

await runtime.messageManager.createMemory({
id: message.id,
content: { text: response },
roomId: message.roomId,
userId: message.userId,
agentId: runtime.agentId,
});

return true;
} catch (error) {
console.error("Floor sweep failed:", error);
await runtime.messageManager.createMemory({
id: message.id,
content: {
text: `Failed to sweep floor NFTs: ${error.message}`,
},
roomId: message.roomId,
userId: message.userId,
agentId: runtime.agentId,
});
return false;
}
},

examples: [
[
{
user: "{{user1}}",
content: {
text: "Sweep 5 NFTs from collection 0x1234...abcd at floor price",
},
},
{
user: "{{user2}}",
content: {
text: "Executing floor sweep for 5 NFTs...",
action: "SWEEP_FLOOR_NFT",
},
},
],
],
};
54 changes: 54 additions & 0 deletions packages/plugin-nft-collections/src/evaluators/nft-knowledge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Evaluator, IAgentRuntime, Memory, State } from "@ai16z/eliza";
import { NFTKnowledge } from "../types";

export const nftKnowledgeEvaluator: Evaluator = {
name: "nft-collection-evaluator",
description: "Evaluates NFT-related content in messages",
similes: ["nft-evaluator", "nft-knowledge"],
alwaysRun: false,
validate: async (runtime: IAgentRuntime, message: Memory) => {
const content = message.content.text.toLowerCase();
return content.includes("nft") || content.includes("collection");
},
handler: async (runtime: IAgentRuntime, message: Memory, state: State) => {
const content = message.content.text.toLowerCase();

// Extract relevant NFT information
const extractedInfo: NFTKnowledge = {
mentionsCollection:
content.includes("collection") || content.includes("nft"),
mentionsFloorPrice:
content.includes("floor price") || content.includes("floor"),
mentionsVolume:
content.includes("volume") ||
content.includes("trading volume"),
mentionsRarity:
content.includes("rare") || content.includes("rarity"),
};

// Update state with extracted information
return {
...state,
nftKnowledge: extractedInfo,
};
},
examples: [
{
context: "Evaluating NFT-related content in messages",
messages: [
{
user: "{{user1}}",
content: { text: "Tell me about NFT collections" },
},
{
user: "{{user2}}",
content: {
text: "I'll help you understand NFT collections.",
},
},
],
outcome:
"The message contains NFT-related content and should be evaluated.",
},
],
};
Loading

0 comments on commit d53e365

Please sign in to comment.