Skip to content

Commit e46b0fa

Browse files
TinaCMS content update
1 parent 0529be8 commit e46b0fa

File tree

1 file changed

+164
-5
lines changed

1 file changed

+164
-5
lines changed

docs/developers/building-on-fuse/Edison AI: No-Code Fuse Integration/Beyond-ElizaOS-Additional-Functionality.mdx

+164-5
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,171 @@ export const getBalanceAction = {
8181

8282
In this instance, we have replaced Eliza’s hardcoded private key with the user’s connected wallet, enabling the user to transfer the FUSE token on the blockchain via Edison themselves.
8383

84-
ElizaOS/Backend
84+
ElizaOS/Backend:
8585

86-
\[[https://github.com/fuseio/eliza/blob/836f2c95835aace18b09df43c7dc62fd24d26c23/packages/plugin-evm/sr](https://github.com/fuseio/eliza/blob/836f2c95835aace18b09df43c7dc62fd24d26c23/packages/plugin-evm/sr)...
87-
88-
]\([https://github.com/fuseio/eliza/blob/836f2c95835aace18b09df43c7dc62fd24d26c23/packages/plugin-evm/src/actions/transfer.ts#L34-L87](https://github.com/fuseio/eliza/blob/836f2c95835aace18b09df43c7dc62fd24d26c23/packages/plugin-evm/src/actions/transfer.ts#L34-L87))
86+
```javascript
87+
export const transferAction = {
88+
name: "transfer",
89+
description: "Transfer tokens between addresses on the same chain",
90+
handler: async (
91+
runtime: IAgentRuntime,
92+
_message: Memory,
93+
state: State,
94+
_options: any,
95+
callback?: HandlerCallback
96+
) => {
97+
const transferDetails = await buildTransferDetails(state, runtime);
98+
99+
try {
100+
if (callback) {
101+
callback({
102+
text: `You are about to transfer ${transferDetails.amount} to ${transferDetails.toAddress}`,
103+
content: transferDetails,
104+
action: "SEND_TOKENS"
105+
});
106+
}
107+
return true;
108+
} catch (error) {
109+
console.error("Error during token transfer:", error);
110+
if (callback) {
111+
callback({
112+
text: `Error transferring tokens: ${error.message}`,
113+
content: { error: error.message },
114+
});
115+
}
116+
return false;
117+
}
118+
},
119+
template: transferTemplate,
120+
validate: async (runtime: IAgentRuntime) => true,
121+
examples: [
122+
[
123+
{
124+
user: "assistant",
125+
content: {
126+
text: "I'll help you transfer 1 ETH to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
127+
action: "SEND_TOKENS",
128+
},
129+
},
130+
{
131+
user: "user",
132+
content: {
133+
text: "Transfer 1 ETH to 0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
134+
action: "SEND_TOKENS",
135+
},
136+
},
137+
],
138+
],
139+
similes: ["SEND_TOKENS", "TOKEN_TRANSFER", "MOVE_TOKENS"],
140+
};
141+
```
89142

90143
Frontend: 
91144

92-
[https://github.com/fuseio/console-dapp/blob/8f2f8945c975bc959a68e879bc937da9eb6cc0e5/components/ai-a...](https://github.com/fuseio/console-dapp/blob/8f2f8945c975bc959a68e879bc937da9eb6cc0e5/components/ai-agent/ChatMessage.tsx#L14-L118)
145+
```javascript
146+
type ChatMessageProps = {
147+
message: TextResponse;
148+
setMessages: React.Dispatch<React.SetStateAction<TextResponse[]>>
149+
};
150+
151+
type SendTokensContent = {
152+
amount: string;
153+
toAddress: Address;
154+
}
155+
156+
const Spinner = () => {
157+
return (
158+
<span className="animate-spin border-2 border-gray border-t-2 border-t-dark-gray rounded-full w-4 h-4"></span>
159+
)
160+
}
161+
162+
const Button = ({ message, setMessages }: ChatMessageProps) => {
163+
const dispatch = useAppDispatch();
164+
const { isConnected } = useAccount();
165+
const content = message.content as SendTokensContent;
166+
167+
const {
168+
data: hash,
169+
error,
170+
isPending,
171+
sendTransaction
172+
} = useSendTransaction()
173+
174+
const { isLoading: isConfirming, isSuccess: isConfirmed } =
175+
useWaitForTransactionReceipt({
176+
hash,
177+
})
178+
179+
const isLoading = isPending || isConfirming;
180+
181+
useEffect(() => {
182+
if (isConfirmed && hash) {
183+
setMessages((prevMessages) => {
184+
const updatedMessages = [...prevMessages];
185+
const lastSendTokensIndex = updatedMessages
186+
.slice()
187+
.reverse()
188+
.findIndex((msg) => msg.text === message.text);
189+
190+
if (lastSendTokensIndex !== -1) {
191+
const actualIndex = updatedMessages.length - 1 - lastSendTokensIndex;
192+
updatedMessages[actualIndex] = {
193+
...updatedMessages[actualIndex],
194+
hash,
195+
};
196+
}
197+
198+
return updatedMessages as TextResponse[];
199+
});
200+
}
201+
}, [hash, isConfirmed, message.text, setMessages]);
202+
203+
return (
204+
<button
205+
className={`transition ease-in-out flex items-center gap-2 w-fit px-4 py-3 text-lg leading-none font-semibold rounded-full hover:bg-[transparent] hover:text-black ${error?.message ? "bg-[#FFEBE9] border border-[#FD0F0F] text-[#FD0F0F]" : "bg-black border border-black text-white"}`}
206+
onClick={() => {
207+
if (message.hash) {
208+
window.open(`${fuse.blockExplorers.default.url}/tx/${hash}`, "_blank");
209+
} else if (isConnected) {
210+
sendTransaction({
211+
to: content.toAddress,
212+
value: parseEther(content.amount),
213+
});
214+
} else {
215+
dispatch(setIsWalletModalOpen(true));
216+
}
217+
}}
218+
>
219+
{message.hash ? "View on Explorer" : isConnected ? "Sign Transaction" : "Connect Wallet"}
220+
{isLoading && <Spinner />}
221+
{message.hash && <ExternalArrow />}
222+
</button>
223+
);
224+
};
225+
226+
const ChatMessage = ({ message, setMessages }: ChatMessageProps) => {
227+
const isUser = message.user === "user";
228+
const isButton = message.action === "SEND_TOKENS";
229+
230+
return (
231+
<div className={`flex gap-3 mb-4 ${isUser ? "justify-end" : ""}`}>
232+
{!isUser && (
233+
<div className="w-11 h-11 rounded-full overflow-hidden">
234+
<Image src={edisonLogo} alt="AI Assistant" width={50} height={50} />
235+
</div>
236+
)}
237+
<div
238+
className={`max-w-[85%] p-4 flex flex-col gap-2 ${isUser
239+
? "bg-[#E4E4E4] text-black rounded-l-[20px] rounded-br-[20px]"
240+
: ""
241+
}`}
242+
>
243+
<p className="text-sm">{message.text}</p>
244+
{isButton && <Button message={message} setMessages={setMessages} />}
245+
</div>
246+
</div>
247+
);
248+
};
249+
250+
export default ChatMessage;
251+
```

0 commit comments

Comments
 (0)