Pinnable Widgets
Create persistent UI widgets for your DAIN service
Overview
Pinnable widgets are persistent UI elements that remain visible and accessible whenever a user is connected to your service. They provide quick access to frequently used features without requiring AI assistance.
Configuration
A pinnable widget is defined using the ServicePinnable
type:
interface ServicePinnable {
id: string; // Unique identifier
name: string; // Display name
description: string; // Description of functionality
type: "widget"; // Type of pinnable
label: string; // Widget label
icon: string; // Icon identifier
getWidget: (agentInfo: AgentInfo) => Promise<DainResponse>; // UI generator
}
Add widgets to your service configuration:
const dainService = defineDAINService({
// ... other config
pinnables: [marketOverviewWidget] // Array of pinnable widgets
});
Example: Market Overview Widget
import {
CardUIBuilder,
TableUIBuilder,
ChartUIBuilder,
FormUIBuilder,
AlertUIBuilder
} from '@dainprotocol/utils';
const getMarketOverviewWidget: ServicePinnable = {
id: "marketOverview",
name: "Market Overview",
description: "Shows current status of major market indices",
type: "widget",
label: "Markets",
icon: "chart-line",
getWidget: async () => {
try {
// Fetch market data
const results = await fetchMarketData();
// Create table of market indices
const tableUI = new TableUIBuilder()
.addColumns([
{ key: 'name', header: 'Index' },
{ key: 'price', header: 'Price' },
{ key: 'change', header: 'Change' },
{ key: 'changePercent', header: '%' }
])
.rows(results);
// Create quick lookup form
const formUI = new FormUIBuilder()
.title('Get Stock Price')
.addField({
name: 'ticker',
label: 'Stock Symbol',
type: 'string',
required: true,
})
.onSubmit({
tool: 'get-stock-price',
paramSchema: {
ticker: { type: 'string' }
}
});
// Create overview chart
const chartUI = new ChartUIBuilder()
.type('line')
.title('Market Trends')
.chartData(results)
.dataKeys({
x: 'time',
y: 'price'
});
// Compose final layout
const cardUI = new CardUIBuilder()
.addChild(formUI.build())
.addChild(tableUI.build())
.addChild(chartUI.build());
return new DainResponse({
text: "Market overview data loaded",
data: results,
ui: cardUI.build()
});
} catch (error) {
return new DainResponse({
text: "Failed to load market overview",
data: null,
ui: new AlertUIBuilder()
.variant('error')
.message('Unable to load market data')
.build()
});
}
}
};
Common Use Cases
Pinnable widgets are ideal for:
- Data dashboards
- Quick search forms
- Status monitors
- Activity feeds
- User preferences
- Recent items
- Quick actions
- Analytics views