Create a DexAppBuilder plugin
To create a DexAppBuilder Plugin you need to implement the follow functions:
function render({data}: {data: T}): React.ReactNode
- renders the component on DexAppBuilderfunction renderControls(onChange({data}: {data: T}): void, onSave({data}: {data: T}): void ): React.ReactNode
- renders form on DexAppBuilder Admin dashboard
and add Metadata to describe your plugin:
const metadata = {
type: "plugin",
title: string,
subtitle: string,
icon: string | React.ReactNode,
};
All these functions and metadata should be exported from a index.tsx file on packages plugin under your-username/Plugin-name
Create your first plugin
We will create a plugin with dexkit username and called ExampleButton
First we create a folder dexkit/ExampleButton
at packages/plugins
, then inside the folder we create a file index.tsx
.
Now we create the render function
import Grid from "@mui/material/Grid";
import TextField from "@mui/material/TextField";
import Button from "@mui/material/Button";
import ExtensionIcon from "@mui/icons-material/Extension";
import { useState } from "react";
interface Props {
data: {
message: string,
};
}
interface ControlProps {
onSave(data: Props): void;
onChange(data: Props): void;
}
const PluginButton = ({ data }: Props) => {
return <button onClick={() => alert(data.message)}>message</button>;
};
/**
* We export render function to be called by DexAppBuilder dinamically
* @param data
* @returns
*/
export function render({ data }: Props) {
return <PluginButton data={data} />;
}
We created our PluginButton
component and exported a function render
to render this component on DexAppBuilder section. We defined data
interfaces to be used on render
and renderControls
.
Now we want to create the form to help us inject data in our plugin on DexAppBuilder admin dashbboard, for that we need to create a renderControls
function and export on the index.tsx . OnChange
function add us preview capabilities and the OnSave
generates the config file to be saved on DexAppBuilder server.
const defaultValues = {
message: "dexkit rocks",
};
/**
* Render controls is called by DexAppBuilder to render a form to update this section and add data
* @param controls
* @returns
*/
export function renderControls(controls: ControlProps) {
const [formValues, setFormValues] = useState(defaultValues);
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormValues({
...formValues,
[name]: value,
});
controls.onChange({ data: defaultValues });
};
const handleSubmit = (event) => {
event.preventDefault();
controls.onSave({ data: defaultValues });
};
return (
<form onSubmit={handleSubmit}>
<Grid container alignItems="center" direction="column">
<Grid item>
<TextField
id="message-input"
name="message"
label="Name"
type="text"
value={formValues.message}
onChange={handleInputChange}
/>
</Grid>
<Button variant="contained" color="primary" type="submit">
Submit
</Button>
</Grid>
</form>
);
}
Now we have our render function and render Controls function done, we go to define the metadata of our plugin
/**
* Metadata used to display plugin on DexAppBuilder
*/
export const metadata = {
type: "plugin",
title: "Example Button",
subtitle: "Example Button to be used inside DexAppBuilder",
category: "misc", // misc, swap, nft, exchange, web3
icon: <ExtensionIcon />,
};
The metadata values help us describe our plugin on DexAppBuilder Dashboard.
Congrats, you built your first plugin. To help you build more powerfull plugins you can import UI components, hooks and services from @dexkit
npm packages: @dexkit/ui
, @dexkit/core
, @dexkit/web3forms
, @dexkit/widgets
.
Run and test your plugin in action
You have done your first plugin and want to see how it renders on DexAppBuilder
. You can use apps/dexapp
to run a test instance how DexAppBuilder will run your plugin
import { GetStaticProps, NextPage } from "next";
import { RenderDexAppBuilderFromConfig } from "@dexkit/dexappbuilder-viewer";
import { QueryClient, dehydrate } from "@tanstack/react-query";
import { useAppConfig } from "@dexkit/ui/hooks";
import { getConfig } from "@dexkit/ui/services/whitelabel";
import { AppPageSection } from "@dexkit/dexappbuilder-viewer/types";
import { AppConfig } from "@dexkit/ui/types/config";
const ExamplePage: NextPage = () => {
// We can pass here directly JSON file if wanted
const appConfig = useAppConfig();
return (
<>
<RenderDexAppBuilderFromConfig config={appConfig} withLayout={true} />;
</>
);
};
export const getStaticProps: GetStaticProps = async () => {
const queryClient = new QueryClient();
const configResponse = await (
await getConfig({ slug: "wizard", appPage: "home" })
).data;
const config = {
appConfig: JSON.parse(configResponse.config) as AppConfig,
appNFT: configResponse.nft === undefined ? null : configResponse.nft,
siteId: configResponse?.id,
};
// inject our created plugin on the sections
config.appConfig.pages.home.sections = [
{
type: "plugin",
data: { message: "DexKit rocks" },
pluginPath: "dexkit/ExampleButton",
},
] as AppPageSection[];
return {
props: {
dehydratedState: dehydrate(queryClient),
...config,
},
revalidate: 300,
};
};
export default ExamplePage;
Congrats you built and tested your first DexAppBuilder plugin.