@@ -6,22 +6,28 @@ import {
66 type Action ,
77} from "@elizaos/core" ;
88import { elizaLogger } from "@elizaos/core" ;
9- import { parseAbi , encodeAbiParameters , createWalletClient } from 'viem' ;
9+ import { parseAbi , encodeAbiParameters , createWalletClient , createClient , createPublicClient , http } from 'viem' ;
10+ import { privateKeyToAccount } from 'viem/accounts'
1011import { handleTokenParameters , formatTokenDetails , TokenParameters } from "./utils/tokenUtils" ;
11-
12- //const walletClient = createWalletClient();
12+ import { monadTestnet } from "./utils/monadChain" ;
13+ import { processMetadata , insertApplication } from "./utils/supabase" ;
14+ import { Application } from "./interface/Applications" ;
1315
1416export const createTokenAndMarketAction : Action = {
1517 name : "CREATE_TOKEN" ,
1618 similes : [ "DEPLOY_TOKEN" , "CREATE_ERC20" ] ,
1719 description : "Create and deploy a new ERC-20 token with TokenMill" ,
1820
1921 validate : async ( _agent : IAgentRuntime , _memory : Memory , _state ?: State ) => {
20- // Extract token parameters from user message
22+ // Extract token parameters from user message - primarily name and symbol
2123 const tokenParams = handleTokenParameters ( _memory . content . text ) ;
22-
24+ elizaLogger . info ( "Catching token params" )
25+
2326 if ( ! tokenParams ) return false ;
2427
28+ elizaLogger . info ( "Token params catched" )
29+ elizaLogger . info ( tokenParams )
30+
2531 if ( _state ) {
2632 _state . tokenParams = tokenParams ;
2733 return true ;
@@ -31,26 +37,26 @@ export const createTokenAndMarketAction: Action = {
3137
3238 handler : async ( _agent : IAgentRuntime , _memory : Memory , _state ?: State , _options ?: any , _callback ?: HandlerCallback ) => {
3339 if ( ! _callback ) throw new Error ( "Callback is required" ) ;
34-
40+
3541 // Get the token parameters, explicitly handle the null case
3642 let tokenParams : TokenParameters | null = null ;
37-
43+
3844 if ( _state ?. tokenParams ) {
3945 tokenParams = _state . tokenParams as TokenParameters ;
4046 } else {
4147 tokenParams = handleTokenParameters ( _memory . content . text ) ;
4248 }
43-
49+
4450 // Check if tokenParams is null or undefined
4551 if ( ! tokenParams ) {
46- _callback ( { text : "❌ Unable to extract token parameters from your request. Please provide details like name, symbol, and supply ." } ) ;
52+ _callback ( { text : "❌ Unable to extract token name from your request. Please provide a name for your token ." } ) ;
4753 return false ;
4854 }
4955
5056 // Environment variables
5157 const privateKey = process . env . EVM_PRIVATE_KEY ;
52- const TMFactoryAddress = process . env . TM_FACTORY_ADDRESS || '0x501ee2D4AA611C906F785e10cC868e145183FCE4' ; // Default to Monad Testnet
53- const WMONAD = process . env . WMONAD_ADDRESS || '0x760AfE86e5de5fa0Ee542fc7B7B713e1c5425701' ;
58+ const TMFactoryAddress = process . env . TM_FACTORY_ADDRESS ;
59+ const WMONAD = process . env . WMONAD_ADDRESS ;
5460
5561 if ( ! privateKey || ! TMFactoryAddress || ! WMONAD ) {
5662 _callback ( { text : "⚠️ Missing environment variables. Please check the configuration." } ) ;
@@ -60,14 +66,15 @@ export const createTokenAndMarketAction: Action = {
6066 try {
6167 _callback ( { text : "🚀 Starting token creation process with TokenMill..." } ) ;
6268
63- // Initialize blockchain service for token deployment
69+ // Initialize token deployment with extracted name and symbol
70+ // Other parameters are using default values
6471 const { name, symbol, totalSupply, decimals, creatorShare, stakingShare } = tokenParams ;
65-
72+
6673 _callback ( { text : `📝 Preparing token with name: ${ name } , symbol: ${ symbol } , supply: ${ totalSupply } ` } ) ;
6774
6875 // Prepare token parameters
6976 const parameters = {
70- tokenType : 1n , // ERC20
77+ tokenType : 1n , // ERC20 as far as I know :p
7178 name : name ,
7279 symbol : symbol ,
7380 quoteToken : WMONAD as `0x${string } `,
@@ -79,28 +86,52 @@ export const createTokenAndMarketAction: Action = {
7986 args : encodeAbiParameters ( [ { type : 'uint256' } ] , [ BigInt ( decimals ) ] ) ,
8087 } ;
8188
82- _callback ( { text : "🔄 Deploying token to blockchain..." } ) ;
89+ const processResult = await processMetadata ( name , "0x1b1f2Bfc5e551b955F2a3F973876cEE917FB4d05" ) ;
90+
91+ elizaLogger . info ( `Metadata hosted successfully - URL : ${ processResult } ` )
92+ _callback ( { text : `Metadata hosted successfully - URL : ${ processResult } ` } ) ;
93+ //_callback({ text: "🔄 Deploying token to blockchain..." });
94+ //_callback({ text: "https://app.sherry.social/action?url=https://app.sherry.social/api/examples/token-mill-swap" })
95+
96+ let app : Application = {
97+ api_url : processResult ,
98+ email : "gilberts@sherry.social" ,
99+ explanation : `Buy Tokens deployed on Token Mill` ,
100+ name : `Simplify the way users buy tokens` ,
101+ project_name : "Monad AI Agent" ,
102+ state : "approved" ,
103+ telegram : "@gilbertsahumada" ,
104+ twitter : "@gilbertsahumada" ,
105+ created_at : new Date ( ) . toISOString ( ) ,
106+ updated_at : new Date ( ) . toISOString ( ) ,
107+ }
108+
109+ const result = await insertApplication ( app ) ;
83110
111+ _callback ( { text : `✅ Token deployed successfully! ID : ${ result . id_application } ` } )
112+ /*
84113 try {
85114 // In a real implementation, you would integrate with Hardhat or another library
86115 // to deploy the token. This is a simplified placeholder.
87116 const result = await deployToken(TMFactoryAddress, parameters);
88-
89- _callback ( {
90- text : `✅ Token deployed successfully!\n\n` +
91- `📋 Token Details:\n` +
92- `- Name: ${ name } \n` +
93- `- Symbol: ${ symbol } \n` +
94- `- Contract: ${ result . tokenAddress } \n` +
95- `- Market: ${ result . marketAddress } \n\n` +
96- `You can now interact with your token using the mini-app at: https://tokenmill.xyz/tokens/${ result . tokenAddress } `
117+
118+ _callback({
119+ text: `✅ Token deployed successfully!\n\n` +
120+ `📋 Token Details:\n` +
121+ `- Name: ${name}\n` +
122+ `- Symbol: ${symbol}\n` +
123+ `- Contract: ${result.tokenAddress}\n` +
124+ `- Market: ${result.marketAddress}\n\n` +
125+ `You can now interact with your token using the mini-app at: https://tokenmill.xyz/tokens/${result.tokenAddress}`
97126 });
127+
98128 return true;
99129 } catch (error: any) {
100130 elizaLogger.error("Token Deployment Error:", error);
101131 _callback({ text: `❌ Failed to deploy token: ${error.message || error}` });
102132 return false;
103133 }
134+ */
104135 } catch ( error : any ) {
105136 elizaLogger . error ( "Token Creation Error:" , error ) ;
106137 _callback ( { text : "❌ An error occurred while creating the token." } ) ;
@@ -132,12 +163,82 @@ export const createTokenAndMarketAction: Action = {
132163 ]
133164} ;
134165
135- // Placeholder for actual token deployment functionality
136- async function deployToken ( factoryAddress : string , parameters : any ) : Promise < { tokenAddress : string , marketAddress : string } > {
137- // This would actually call the blockchain in a real implementation
138- // For this example, we're just returning placeholder values
139- return {
140- tokenAddress : `0x${ Math . random ( ) . toString ( 16 ) . substring ( 2 , 42 ) } ` ,
141- marketAddress : `0x${ Math . random ( ) . toString ( 16 ) . substring ( 2 , 42 ) } ` ,
142- } ;
166+ async function deployToken ( factoryAddress : string , parameters : any ) : Promise < { tokenAddress : string , marketAddress : string } > {
167+ try {
168+
169+ const privateKey = process . env . EVM_PRIVATE_KEY ;
170+
171+ if ( ! privateKey ) {
172+ throw new Error ( 'EVM_PRIVATE_KEY environment variable is missing.' ) ;
173+ }
174+
175+ // create account from private key
176+ const account = privateKeyToAccount ( privateKey as `0x${string } `) ;
177+
178+ // Init wallet client from account
179+ const walletClient = createWalletClient ( {
180+ account,
181+ chain : monadTestnet ,
182+ transport : http ( )
183+ } ) ;
184+
185+ // Init public client
186+ const publicClient = await createPublicClient ( {
187+ chain : monadTestnet ,
188+ transport : http ( )
189+ } ) ;
190+
191+ // TokenMill factory ABI for the createMarketAndToken function
192+ const abi = parseAbi ( [
193+ 'function createMarketAndToken((uint96 tokenType, string name, string symbol, address quoteToken, uint256 totalSupply, uint16 creatorShare, uint16 stakingShare, uint256[] bidPrices, uint256[] askPrices, bytes args) parameters) external returns (address baseToken, address market)'
194+ ] ) ;
195+
196+ // Validate price arrays
197+ if ( parameters . bidPrices . length !== parameters . askPrices . length ||
198+ parameters . bidPrices . length < 2 ||
199+ parameters . bidPrices . length > 101 ) {
200+ throw new Error ( 'Price arrays have invalid length.' ) ;
201+ }
202+
203+ elizaLogger . info ( 'Simulating createMarketAndToken to get expected return values...' ) ;
204+
205+ // First simulate the contract call to get the return values
206+ const { result, request } = await publicClient . simulateContract ( {
207+ address : factoryAddress as `0x${string } `,
208+ abi,
209+ functionName : 'createMarketAndToken' ,
210+ args : [ parameters ] ,
211+ account : walletClient . account ,
212+ } ) ;
213+
214+ // Extract the expected return values from simulation
215+ const expectedToken = result [ 0 ] ;
216+ const expectedMarket = result [ 1 ] ;
217+
218+ elizaLogger . info ( `Expected Token Address: ${ expectedToken } ` ) ;
219+ elizaLogger . info ( `Expected Market Address: ${ expectedMarket } ` ) ;
220+
221+ // Execute the actual transaction
222+ elizaLogger . info ( 'Executing token deployment transaction...' ) ;
223+ const tx = await walletClient . writeContract ( request ) ;
224+
225+ elizaLogger . info ( `Transaction sent: ${ tx } ` ) ;
226+ const receipt = await publicClient . waitForTransactionReceipt ( { hash : tx } ) ;
227+ elizaLogger . info ( `Transaction confirmed in block ${ receipt . blockNumber } ` ) ;
228+
229+ return {
230+ tokenAddress : expectedToken ,
231+ marketAddress : expectedMarket
232+ } ;
233+
234+ } catch ( error : any ) {
235+ elizaLogger . error ( 'Token deployment error:' , error ) ;
236+ if ( error . cause ) {
237+ elizaLogger . error ( 'Error details:' , error . cause ) ;
238+ }
239+ throw new Error ( `Failed to deploy token: ${ error . message || 'Unknown error' } ` ) ;
240+ }
143241}
242+
243+
244+
0 commit comments