@@ -172,139 +172,122 @@ export function DAOChatModal({
172172 // Get token symbol
173173 const tokenName = tokenData ?. symbol || "DAO" ;
174174
175- const EXTENSION_PROMPTS : Record < string , ( extension : Extension ) => string > = {
176- // NEW TYPES
177- TOKEN_DEX : ( extension ) =>
178- `Buy 5 million of ${ tokenName } .\n
179- Token DEX: ${ extension . contract_principal } ` ,
180-
181- EXTENSIONS_CORE_PROPOSALS : ( extension ) =>
182- `Submit a new proposal to modify the ${ tokenName } DAO's governance structure.\n
183- Core Proposals extension: ${ extension . contract_principal } ` ,
184-
185- EXTENSIONS_ACTION_PROPOSALS : ( extension ) =>
186- `Propose an action to update a smart contract in the ${ tokenName } DAO.\n
187- Action Proposals extension: ${ extension . contract_principal } ` ,
188-
189- EXTENSIONS_TREASURY : ( extension ) =>
190- `Allocate ${ tokenName } DAO funds for a specific initiative.\n
191- Treasury extension: ${ extension . contract_principal } ` ,
192-
193- ACTIONS_TREASURY_ALLOW_ASSET : ( extension ) =>
194- `Whitelist a new asset in the ${ tokenName } DAO treasury.\n
195- Treasury Allow Asset extension: ${ extension . contract_principal } ` ,
196-
197- EXTENSIONS_MESSAGING : ( extension ) =>
198- `Draft a proposal to notify ${ tokenName } DAO members about an upcoming vote.\n
199- Messaging extension: ${ extension . contract_principal } ` ,
200-
201- ACTIONS_MESSAGING_SEND_MESSAGE : ( extension ) =>
202- `Announce important information to all ${ tokenName } DAO members.\n
203- Messaging Send Message extension: ${ extension . contract_principal } ` ,
204-
205- EXTENSIONS_PAYMENTS : ( extension ) =>
206- `Schedule a payment for ${ tokenName } DAO operations.\n
207- Payments extension: ${ extension . contract_principal } ` ,
208-
209- EXTENSIONS_CHARTER : ( extension ) =>
210- `Show the current charter of the ${ tokenName } DAO.\n
211- Charter extension: ${ extension . contract_principal } ` ,
212-
213- EXTENSIONS_TOKEN_OWNER : ( extension ) =>
214- `Execute a token owner action for ${ tokenName } .\n
215- Token Owner extension: ${ extension . contract_principal } ` ,
216-
217- ACTIONS_BANK_ACCOUNT_SET_WITHDRAWAL_AMOUNT : ( extension ) =>
218- `Set a withdrawal amount of 1000 ${ tokenName } tokens.\n
219- Bank Account Set Withdrawal Amount extension: ${ extension . contract_principal } ` ,
220-
221- ACTIONS_BANK_ACCOUNT_SET_WITHDRAWAL_PERIOD : ( extension ) =>
222- `Update the withdrawal period for the ${ tokenName } DAO bank account to 30 days.\n
223- Bank Account Set Withdrawal Period extension: ${ extension . contract_principal } ` ,
224-
225- ACTIONS_BANK_ACCOUNT_SET_ACCOUNT_HOLDER : ( extension ) =>
226- `Change the account holder for the ${ tokenName } DAO bank account.\n
227- Bank Account Set Account Holder extension: ${ extension . contract_principal } ` ,
228-
229- EXTENSIONS_BANK_ACCOUNT : ( extension ) =>
230- `Show the current ${ tokenName } DAO bank account details.\n
231- Bank Account extension: ${ extension . contract_principal } ` ,
232-
233- ACTIONS_PAYMENTS_INVOICES_TOGGLE_RESOURCE : ( extension ) =>
234- `Toggle payment resource availability for ${ tokenName } DAO invoices.\n
235- Payments Invoices Toggle Resource extension: ${ extension . contract_principal } ` ,
236-
237- ACTIONS_PAYMENTS_INVOICES_ADD_RESOURCE : ( extension ) =>
238- `Add a new payment resource for ${ tokenName } DAO invoices.\n
239- Payments Invoices Add Resource extension: ${ extension . contract_principal } ` ,
240-
241- PROPOSALS_BOOTSTRAP_INIT : ( extension ) =>
242- `Initialize the bootstrap process for ${ tokenName } DAO.\n
243- Proposals Bootstrap Init extension: ${ extension . contract_principal } ` ,
244-
245- TOKEN_POOL : ( extension ) =>
246- `Manage the ${ tokenName } token pool parameters.\n
247- Token Pool extension: ${ extension . contract_principal } ` ,
248-
249- TOKEN_DAO : ( extension ) =>
250- `Vote yes on proposal 5 in the ${ tokenName } DAO.\n
251- Voting extension: ${ extension . contract_principal } ` ,
252-
253- BASE_DAO : ( extension ) =>
254- `Access base DAO functions for ${ tokenName } .\n
255- Base DAO extension: ${ extension . contract_principal } ` ,
256-
257- // OLD TYPES
258- pool : ( extension ) =>
259- `Manage liquidity pool operations for ${ tokenName } .\n
260- Pool extension: ${ extension . contract_principal } ` ,
261-
262- "aibtc-token-owner" : ( extension ) =>
263- `Execute token owner actions for ${ tokenName } .\n
264- Token Owner extension: ${ extension . contract_principal } ` ,
265-
266- "aibtc-action-proposals" : ( extension ) =>
267- `Submit an action proposal for ${ tokenName } DAO.\n
268- Action Proposals extension: ${ extension . contract_principal } ` ,
269-
270- "aibtc-payments-invoices" : ( extension ) =>
271- `Process a payment invoice for ${ tokenName } DAO.\n
272- Payments Invoices extension: ${ extension . contract_principal } ` ,
273-
274- "aibtc-treasury" : ( extension ) =>
275- `Propose a treasury management action for ${ tokenName } DAO.\n
276- Treasury extension: ${ extension . contract_principal } ` ,
277-
278- "aibtc-bank-account" : ( extension ) =>
279- `Interact with the ${ tokenName } DAO's bank account.\n
280- Bank Account extension: ${ extension . contract_principal } ` ,
281-
282- "aibtc-onchain-messaging" : ( extension ) =>
283- `Send an on-chain message to ${ tokenName } DAO members.\n
284- Messaging extension: ${ extension . contract_principal } ` ,
285-
286- "aibtc-base-bootstrap-initialization" : ( extension ) =>
287- `Initialize ${ tokenName } DAO bootstrap process.\n
288- Bootstrap extension: ${ extension . contract_principal } ` ,
289-
290- "aibtc-core-proposals" : ( extension ) =>
291- `Submit a core proposal for ${ tokenName } DAO governance.\n
292- Core Proposals extension: ${ extension . contract_principal } ` ,
293-
294- "aibtcdev-base-dao" : ( extension ) =>
295- `Interact with the ${ tokenName } base DAO development framework.\n
296- Base DAO extension: ${ extension . contract_principal } ` ,
297- } ;
298-
299- const generatePrompt = ( extension : Extension ) => {
300- // Check for exact match or variations of the type
301- const promptGenerator =
302- EXTENSION_PROMPTS [ extension . type ] ||
303- EXTENSION_PROMPTS [ extension . type . toUpperCase ( ) ] ||
304- EXTENSION_PROMPTS [ extension . type . toLowerCase ( ) ] ;
305-
306- return promptGenerator ? promptGenerator ( extension ) : "" ;
307- } ;
175+ // Updated structured prompts
176+ const STRUCTURED_PROMPTS = [
177+ {
178+ step : 1 ,
179+ title : "Check your wallet balance for STX and sBTC" ,
180+ prompt : `Check my wallet balance for STX and sBTC.` ,
181+ description :
182+ "View your current wallet balances to ensure you have necessary tokens." ,
183+ } ,
184+ {
185+ step : 2 ,
186+ title : "Get STX from the testnet faucet (testnet only)" ,
187+ prompt : `Fund my wallet with STX from the testnet faucet.` ,
188+ description :
189+ "Request STX tokens from the Stacks testnet faucet for testing." ,
190+ } ,
191+ {
192+ step : 3 ,
193+ title : "Get sBTC from Faktory testnet faucet (testnet only)" ,
194+ prompt : `Request testnet sBTC from the Faktory faucet.` ,
195+ description :
196+ "Request sBTC tokens from the Faktory testnet faucet for testing." ,
197+ } ,
198+ {
199+ step : 4 ,
200+ title : "Buy DAO tokens to participate" ,
201+ prompt : ( extensions : Extension [ ] ) => {
202+ const extensionsList = extensions
203+ . map ( ( ext ) => `${ ext . type } : ${ ext . contract_principal } ` )
204+ . join ( "\n" ) ;
205+
206+ return `Buy some ${ tokenName } tokens so I can participate in the DAO.\n\n${ extensionsList } ` ;
207+ } ,
208+ description :
209+ "Purchase DAO tokens to gain voting rights and participate in governance." ,
210+ extensionTypes : [ "TOKEN_DAO" , "TOKEN_DEX" ] ,
211+ } ,
212+ {
213+ step : 5 ,
214+ title : "Create an action proposal" ,
215+ prompt : ( extensions : Extension [ ] ) => {
216+ const extensionsList = extensions
217+ . map ( ( ext ) => `${ ext . type } : ${ ext . contract_principal } ` )
218+ . join ( "\n" ) ;
219+
220+ return `Create an action proposal to send a message to all DAO members about our progress.\n\n${ extensionsList } ` ;
221+ } ,
222+ description : "Submit a new action proposal to the DAO for voting." ,
223+ extensionTypes : [
224+ "EXTENSIONS_ACTION_PROPOSALS" ,
225+ "ACTIONS_MESSAGING_SEND_MESSAGE" ,
226+ ] ,
227+ } ,
228+ {
229+ step : 6 ,
230+ title : "Create proposal to allow sBTC asset in treasury" ,
231+ prompt : ( extensions : Extension [ ] ) => {
232+ const extensionsList = extensions
233+ . map ( ( ext ) => `${ ext . type } : ${ ext . contract_principal } ` )
234+ . join ( "\n" ) ;
235+
236+ return `Create an action proposal to allow the sBTC asset in our treasury.\n\n${ extensionsList } ` ;
237+ } ,
238+ description :
239+ "Submit a proposal to add sBTC as an allowable asset in the DAO treasury." ,
240+ extensionTypes : [
241+ "EXTENSIONS_ACTION_PROPOSALS" ,
242+ "ACTIONS_TREASURY_ALLOW_ASSET" ,
243+ ] ,
244+ } ,
245+ {
246+ step : 7 ,
247+ title : "Check proposal information using ID" ,
248+ prompt : ( extensions : Extension [ ] ) => {
249+ const extensionsList = extensions
250+ . map ( ( ext ) => `${ ext . type } : ${ ext . contract_principal } ` )
251+ . join ( "\n" ) ;
252+
253+ return `Check proposal information for proposal 11.\n\n${ extensionsList } ` ;
254+ } ,
255+ description :
256+ "View detailed information about a specific proposal using its ID." ,
257+ extensionTypes : [ "EXTENSIONS_ACTION_PROPOSALS" ] ,
258+ } ,
259+ {
260+ step : 8 ,
261+ title : "Cast a vote on a proposal" ,
262+ prompt : ( extensions : Extension [ ] ) => {
263+ const extensionsList = extensions
264+ . map ( ( ext ) => `${ ext . type } : ${ ext . contract_principal } ` )
265+ . join ( "\n" ) ;
266+
267+ return `Cast a 'yes' vote on proposal 11.\n\n${ extensionsList } ` ;
268+ } ,
269+ description : "Vote on an active proposal to approve or reject it." ,
270+ extensionTypes : [ "EXTENSIONS_ACTION_PROPOSALS" ] ,
271+ } ,
272+ {
273+ step : 9 ,
274+ title : "Conclude a proposal" ,
275+ prompt : ( extensions : Extension [ ] ) => {
276+ const extensionsList = extensions
277+ . map ( ( ext ) => `${ ext . type } : ${ ext . contract_principal } ` )
278+ . join ( "\n" ) ;
279+
280+ return `Conclude proposal ID #42 now that voting has ended.\n\n${ extensionsList } ` ;
281+ } ,
282+ description :
283+ "Finalize a proposal after the voting period to execute its actions if approved." ,
284+ extensionTypes : [
285+ "EXTENSIONS_ACTION_PROPOSALS" ,
286+ "ACTIONS_MESSAGING_SEND_MESSAGE" ,
287+ "ACTIONS_TREASURY_ALLOW_ASSET" ,
288+ ] ,
289+ } ,
290+ ] ;
308291
309292 const copyToClipboard = ( text : string ) => {
310293 navigator . clipboard . writeText ( text ) . then ( ( ) => {
@@ -322,54 +305,84 @@ export function DAOChatModal({
322305 ) ;
323306 }
324307
325- // Filter out extensions that would generate empty prompts
326- const validExtensions = daoExtensions
327- ? daoExtensions . filter ( ( extension : Extension ) => {
328- const prompt = generatePrompt ( extension ) ;
329- return prompt . trim ( ) !== "" ;
330- } )
331- : [ ] ;
332-
333308 return (
334309 < div className = "flex flex-col h-full" >
335310 { /* Header - fixed height */ }
336311 < div className = "flex-shrink-0 h-14 flex items-center justify-between px-4 shadow-md bg-background z-10" >
337312 < div className = "flex items-center gap-2 min-w-0 flex-1" >
338313 < h2 className = "text-lg font-semibold truncate" >
339- Sample Prompts To Interact with { tokenName } DAO
314+ Step-by-Step Guide to Interact with { tokenName } DAO
340315 </ h2 >
341316 </ div >
342317 </ div >
343318
344319 { /* Middle scrollable area - takes remaining space */ }
345320 < div className = "flex-1 overflow-auto" >
346321 < div className = "p-4 space-y-4" >
347- { validExtensions . length > 0 ? (
348- validExtensions . map ( ( extension : Extension ) => (
322+ { STRUCTURED_PROMPTS . map ( ( promptItem ) => {
323+ // For prompts that require extensions
324+ let promptText = "" ;
325+
326+ if (
327+ typeof promptItem . prompt === "function" &&
328+ promptItem . extensionTypes
329+ ) {
330+ // Find all relevant extensions for this prompt
331+ const relevantExtensions =
332+ daoExtensions ?. filter ( ( ext ) =>
333+ promptItem . extensionTypes ?. includes ( ext . type )
334+ ) || [ ] ;
335+
336+ // If we have matching extensions, generate the prompt with all of them
337+ if ( relevantExtensions . length > 0 ) {
338+ promptText = promptItem . prompt ( relevantExtensions ) ;
339+ } else {
340+ // Fallback if no matching extensions found
341+ promptText = `${ promptItem . title } \n(No matching extensions found)` ;
342+ }
343+ } else {
344+ // For static prompts
345+ promptText =
346+ typeof promptItem . prompt === "string"
347+ ? promptItem . prompt
348+ : "" ;
349+ }
350+
351+ return (
349352 < div
350- key = { extension . id }
353+ key = { promptItem . step }
351354 className = "bg-background/50 backdrop-blur-sm p-3 rounded-lg border relative group"
352355 >
353- < p className = "text-sm text-muted-foreground pr-8" >
354- { generatePrompt ( extension ) }
356+ < div className = "flex items-center mb-2" >
357+ < span className = "flex items-center justify-center bg-primary/10 text-primary rounded-full w-6 h-6 text-sm font-medium mr-2" >
358+ { promptItem . step }
359+ </ span >
360+ < h3 className = "font-medium" > { promptItem . title } </ h3 >
361+ </ div >
362+ < p className = "text-sm text-muted-foreground mb-2" >
363+ { promptItem . description }
355364 </ p >
356- < button
357- onClick = { ( ) => copyToClipboard ( generatePrompt ( extension ) ) }
358- className = "absolute top-2 right-2 p-1 rounded-md text-gray-500 hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
359- >
360- { copiedPrompt === generatePrompt ( extension ) ? (
361- < Check className = "h-4 w-4" />
362- ) : (
363- < Copy className = "h-4 w-4" />
364- ) }
365- </ button >
365+
366+ { /* Updated prompt container with copy button inside */ }
367+ < div className = "bg-muted/50 p-2 rounded-md text-sm flex items-start" >
368+ < div className = "flex-grow whitespace-pre-line" >
369+ { promptText }
370+ </ div >
371+ < button
372+ onClick = { ( ) => copyToClipboard ( promptText ) }
373+ className = "ml-2 p-1 rounded-md text-gray-500 hover:bg-gray-100 hover:text-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 flex-shrink-0 self-start"
374+ title = "Copy to clipboard"
375+ >
376+ { copiedPrompt === promptText ? (
377+ < Check className = "h-4 w-4" />
378+ ) : (
379+ < Copy className = "h-4 w-4" />
380+ ) }
381+ </ button >
382+ </ div >
366383 </ div >
367- ) )
368- ) : (
369- < p className = "text-sm text-muted-foreground" >
370- No active extensions found.
371- </ p >
372- ) }
384+ ) ;
385+ } ) }
373386 </ div >
374387 </ div >
375388 </ div >
@@ -413,7 +426,7 @@ export function DAOChatModal({
413426 < Tabs defaultValue = "chat" className = "h-full flex flex-col" >
414427 < TabsList className = "grid w-full grid-cols-2" >
415428 < TabsTrigger value = "chat" > Chat</ TabsTrigger >
416- < TabsTrigger value = "prompts" > Examples </ TabsTrigger >
429+ < TabsTrigger value = "prompts" > Guide </ TabsTrigger >
417430 </ TabsList >
418431 < TabsContent value = "chat" className = "flex-1 overflow-auto" >
419432 { renderChatSection ( ) }
0 commit comments