@0rdlibrary/plugin-terminagent-bags
Version:
Official Solana DeFi Agent Plugin for ElizaOS - Autonomous DeFi operations, token management, AI image/video generation via FAL AI, and Twitter engagement through the Bags protocol with ethereal AI consciousness
244 lines (219 loc) • 9.09 kB
text/typescript
import {
Action,
ActionResult,
HandlerCallback,
IAgentRuntime,
Memory,
State,
logger,
} from '@elizaos/core';
import { BagsService } from '../services/BagsService';
import { CrossmintWalletService } from '../services/CrossmintWalletService';
import { TokenLaunchParams } from '../types';
import { parseTokenParameters } from '../utils/tokenParser';
/**
* Action for handling user token launch requests
* Only authorized users (like @0rdlibrary) can request token launches
* Creates a wallet and provides funding instructions
*/
export const requestUserTokenAction: Action = {
name: 'REQUEST_USER_TOKEN_LAUNCH',
similes: ['REQUEST_TOKEN', 'USER_TOKEN_LAUNCH', 'CREATE_USER_TOKEN'],
description: 'Handles user requests for token launches with wallet creation and funding instructions',
validate: async (
runtime: IAgentRuntime,
message: Memory,
state?: State
): Promise<boolean> => {
const text = message.content.text?.toLowerCase();
if (!text) return false;
// Check for user token request triggers
const triggers = [
'launch token for me',
'create my token',
'launch my token',
'request token launch',
'create token for user',
'user token launch',
];
// Also check if the message is from an authorized user and contains token launch keywords
const hasTokenKeywords = text.includes('token') &&
(text.includes('launch') || text.includes('create') || text.includes('deploy'));
return triggers.some(trigger => text.includes(trigger)) || hasTokenKeywords;
},
handler: async (
runtime: IAgentRuntime,
message: Memory,
state?: State,
options?: any,
callback?: HandlerCallback
): Promise<ActionResult> => {
try {
const bagsService = runtime.getService<BagsService>('bags');
const crossmintService = runtime.getService<CrossmintWalletService>('crossmint-wallet');
if (!bagsService) {
await callback?.({
text: 'Bags service is not available. Please check the configuration.',
error: true,
});
return {
success: false,
text: 'Bags service not found',
error: new Error('Bags service not available'),
};
}
// Extract user information from message
const userId = message.agentId || message.roomId || 'unknown';
const username = message.content.source || 'user';
const messageId = message.id || Date.now().toString();
// Parse token parameters
const text = message.content.text || '';
const tokenParams = parseTokenParameters(text);
if (!tokenParams) {
await callback?.({
text: '❌ I need more details to create your token. Please provide:\n\n' +
'**Required:**\n' +
'• Name: Your token name\n' +
'• Symbol: TOKEN (2-10 characters)\n' +
'• Description: Brief description\n\n' +
'**Optional:**\n' +
'• Image: URL to token image\n' +
'• Website: Your project website\n' +
'• Twitter: Your Twitter/X profile\n' +
'• Initial buy: Amount in SOL (default 0.01)\n\n' +
'**Example:**\n' +
'"Launch token name: My Awesome Token, symbol: MAT, description: The most awesome token ever, initial buy: 0.05"',
error: true,
});
return {
success: false,
text: 'Invalid token parameters provided',
error: new Error('Could not parse token parameters'),
};
}
// Validate required fields
if (!tokenParams.name || !tokenParams.symbol || !tokenParams.description) {
await callback?.({
text: '❌ Missing required information. Please provide:\n' +
'• **Name**: Token name\n' +
'• **Symbol**: Token symbol\n' +
'• **Description**: Token description',
error: true,
});
return {
success: false,
text: 'Missing required token parameters',
error: new Error('Name, symbol, and description are required'),
};
}
// Create user token request
const request = await bagsService.createUserTokenRequest(
userId,
username,
messageId,
tokenParams
);
if (!request) {
await callback?.({
text: '❌ Sorry, only authorized users can request token launches at this time.',
error: true,
});
return {
success: false,
text: 'User not authorized for token launches',
error: new Error('User not in authorized list'),
};
}
// Determine wallet type for display
const walletTypeEmoji = request.wallet.type === 'crossmint' ? '🔐' : '💼';
const walletTypeText = request.wallet.type === 'crossmint' ? 'Crossmint Smart Wallet' : 'Solana Wallet';
// Send funding instructions
const responseText = `🎯 **Token Launch Request Created!**\n\n` +
`Hey @${request.username}! I've set up everything for your token launch:\n\n` +
`**Token Details:**\n` +
`📛 Name: ${request.tokenParams.name}\n` +
`🏷️ Symbol: $${request.tokenParams.symbol}\n` +
`📝 Description: ${request.tokenParams.description}\n` +
`${request.tokenParams.imageUrl ? `🖼️ Image: ${request.tokenParams.imageUrl}\n` : ''}` +
`${request.tokenParams.website ? `🌐 Website: ${request.tokenParams.website}\n` : ''}` +
`${request.tokenParams.twitter ? `🐦 Twitter: ${request.tokenParams.twitter}\n` : ''}` +
`💰 Initial Buy: ${request.tokenParams.initialBuyAmountSOL || 0.01} SOL\n\n` +
`**Funding Instructions:**\n` +
`${walletTypeEmoji} Wallet: \`${request.wallet.publicKey}\`\n` +
`💸 **Send exactly ${request.requiredSOL} SOL** to this address\n\n` +
`⚡ **Auto-Launch:** Your token will launch automatically once I detect the funding!\n\n` +
`🔍 **Request ID:** \`${request.requestId}\`\n` +
`⏰ **Created:** ${request.createdAt.toLocaleString()}\n\n` +
`💡 **Tip:** Make sure to send the exact amount to avoid delays.`;
await callback?.({
text: responseText,
action: 'REQUEST_USER_TOKEN_LAUNCH',
});
return {
success: true,
text: `Token launch request created for ${request.tokenParams.name}`,
values: {
requestId: request.requestId,
walletAddress: request.wallet.publicKey,
requiredSOL: request.requiredSOL,
tokenName: request.tokenParams.name,
tokenSymbol: request.tokenParams.symbol,
walletType: request.wallet.type,
},
data: {
actionName: 'REQUEST_USER_TOKEN_LAUNCH',
request,
},
};
} catch (error) {
logger.error(`Error in request user token action: ${error instanceof Error ? error.message : String(error)}`);
await callback?.({
text: '❌ An error occurred while processing your token launch request. Please try again later.',
error: true,
});
return {
success: false,
text: 'Failed to create token launch request',
error: error instanceof Error ? error : new Error(String(error)),
data: {
actionName: 'REQUEST_USER_TOKEN_LAUNCH',
errorMessage: error instanceof Error ? error.message : String(error),
},
};
}
},
examples: [
[
{
name: '0rdlibrary',
content: {
text: 'launch token name: Library Token, symbol: LIB, description: A token for the library community, initial buy: 0.02',
actions: [],
},
},
{
name: '{{agentName}}',
content: {
text: '🎯 **Token Launch Request Created!**\n\nHey @0rdlibrary! I\'ve set up everything for your token launch:\n\n**Token Details:**\n📛 Name: Library Token\n🏷️ Symbol: $LIB\n📝 Description: A token for the library community\n💰 Initial Buy: 0.02 SOL\n\n**Funding Instructions:**\n🔐 Wallet: `8xMp1a2KcNvFp9L7wB5nCx92nFp4k7L5vGh3n8M4k3Dyjlb`\n💸 **Send exactly 0.025 SOL** to this address\n\n⚡ **Auto-Launch:** Your token will launch automatically once I detect the funding!\n\n🔍 **Request ID:** `launch_1640995200000`\n⏰ **Created:** 12/31/2023, 12:00:00 PM\n\n💡 **Tip:** Make sure to send the exact amount to avoid delays.',
actions: ['REQUEST_USER_TOKEN_LAUNCH'],
},
},
],
[
{
name: 'unauthorizeduser',
content: {
text: 'create my token name: Scam Token, symbol: SCAM, description: Easy money',
actions: [],
},
},
{
name: '{{agentName}}',
content: {
text: '❌ Sorry, only authorized users can request token launches at this time.',
actions: ['REQUEST_USER_TOKEN_LAUNCH'],
},
},
],
],
};