Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/dashboard/src/app/nebula-app/(app)/api/chat.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NEXT_PUBLIC_NEBULA_URL } from "@/constants/env";
// TODO - copy the source of this library to dashboard
import { stream } from "fetch-event-stream";
import type { SendTransactionOption } from "thirdweb/dist/types/wallets/interfaces/wallet";
import type { NebulaTxData } from "../components/Chats";
import type { ExecuteConfig } from "./types";

export type ContextFilters = {
Expand Down Expand Up @@ -140,7 +140,7 @@ type ChatStreamedResponse =
| {
event: "action";
type: "sign_transaction" & (string & {});
data: SendTransactionOption;
data: NebulaTxData;
};

type ChatStreamedEvent =
Expand Down
2 changes: 1 addition & 1 deletion apps/dashboard/src/app/nebula-app/(app)/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export type SessionInfo = {
created_at: string;
deleted_at: string | null;
history: Array<{
role: "user" | "assistant"; // role: action is coming up
role: "user" | "assistant" | "action";
content: string;
timestamp: number;
}> | null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,44 @@ export function ChatPageContent(props: {
const [userHasSubmittedMessage, setUserHasSubmittedMessage] = useState(false);
const [messages, setMessages] = useState<Array<ChatMessage>>(() => {
if (props.session?.history) {
return props.session.history.map((message) => ({
text: message.content,
type: message.role,
request_id: undefined,
}));
const _messages: ChatMessage[] = [];

for (const message of props.session.history) {
if (message.role === "action") {
try {
const content = JSON.parse(message.content) as {
session_id: string;
request_id: string;
data: string;
type: "sign_transaction" | (string & {});
};

if (content.type === "sign_transaction") {
const txData = JSON.parse(content.data);
if (
typeof txData === "object" &&
txData !== null &&
txData.chainId
) {
_messages.push({
type: "send_transaction",
data: txData,
});
}
}
} catch {
// ignore
}
} else {
_messages.push({
text: message.content,
type: message.role,
request_id: undefined,
});
}
}

return _messages;
}
return [];
});
Expand Down
26 changes: 16 additions & 10 deletions apps/dashboard/src/app/nebula-app/(app)/components/Chats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@ import {
} from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { toast } from "sonner";
import type { ThirdwebClient } from "thirdweb";
import { type ThirdwebClient, prepareTransaction } from "thirdweb";
import { useSendTransaction } from "thirdweb/react";
import type { Account } from "thirdweb/wallets";
import { TransactionButton } from "../../../../components/buttons/TransactionButton";
import { MarkdownRenderer } from "../../../../components/contract-components/published-contract/markdown-renderer";
import { useV5DashboardChain } from "../../../../lib/v5-adapter";
import { submitFeedback } from "../api/feedback";
import { NebulaIcon } from "../icons/NebulaIcon";

type SendTransactionOption = Parameters<Account["sendTransaction"]>[0];
export type NebulaTxData = {
chainId: number;
data: `0x${string}`;
to: string;
value: string;
};

export type ChatMessage =
| {
Expand All @@ -39,7 +43,7 @@ export type ChatMessage =
}
| {
type: "send_transaction";
data: SendTransactionOption | null;
data: NebulaTxData | null;
};

export function Chats(props: {
Expand Down Expand Up @@ -203,7 +207,7 @@ export function Chats(props: {
}

function ExecuteTransaction(props: {
txData: SendTransactionOption | null;
txData: NebulaTxData | null;
twAccount: TWAccount;
client: ThirdwebClient;
}) {
Expand Down Expand Up @@ -319,7 +323,7 @@ function MessageActions(props: {
}

function SendTransactionButton(props: {
txData: SendTransactionOption;
txData: NebulaTxData;
twAccount: TWAccount;
client: ThirdwebClient;
}) {
Expand All @@ -333,14 +337,16 @@ function SendTransactionButton(props: {
transactionCount={1}
txChainID={txData.chainId}
onClick={() => {
const promise = sendTransaction.mutateAsync({
...props.txData,
nonce: Number(txData.nonce),
to: txData.to || undefined, // Get rid of the potential null value
const tx = prepareTransaction({
chain: chain,
client: props.client,
data: txData.data,
to: txData.to,
value: BigInt(txData.value),
});

const promise = sendTransaction.mutateAsync(tx);

toast.promise(promise, {
success: "Transaction sent successfully",
error: "Failed to send transaction",
Expand Down
Loading