diff --git a/src/app/api/chainhooks/stackingdao/deposit/route.ts b/src/app/api/chainhooks/stackingdao/deposit/route.ts
index e0da5da..9ba5530 100644
--- a/src/app/api/chainhooks/stackingdao/deposit/route.ts
+++ b/src/app/api/chainhooks/stackingdao/deposit/route.ts
@@ -45,10 +45,10 @@ export async function POST(request: Request) {
sender,
action: "stackingdao-deposit",
data: {
- inAmount: BigInt(stxTransferEvent.data.amount),
- inToken: "STX",
- outAmount: BigInt(stStxMintEvent.data.amount),
- outToken: stStxMintEvent.data.asset_identifier,
+ outAmount: BigInt(stxTransferEvent.data.amount),
+ outToken: "STX",
+ inAmount: BigInt(stStxMintEvent.data.amount),
+ inToken: stStxMintEvent.data.asset_identifier,
},
} satisfies InsertTransaction;
});
diff --git a/src/app/api/chainhooks/stackingdao/withdraw/route.ts b/src/app/api/chainhooks/stackingdao/withdraw/route.ts
new file mode 100644
index 0000000..b628f17
--- /dev/null
+++ b/src/app/api/chainhooks/stackingdao/withdraw/route.ts
@@ -0,0 +1,72 @@
+import { db } from "@/db/db";
+import { type InsertTransaction, transactionTable } from "@/db/schema";
+import { conflictUpdateSetAllColumns } from "@/db/utils";
+import type {
+ ChainhookPayload,
+ ChainhookReceiptEventFTBurnEvent,
+ ChainhookReceiptEventSTXTransferEvent,
+} from "@/lib/chainhooks";
+import { getOrInsertToken } from "@/lib/currencies";
+
+export const dynamic = "force-dynamic";
+
+export async function POST(request: Request) {
+ const data: ChainhookPayload = await request.json();
+
+ const transactionsToInsert = data.apply[0].transactions
+ .filter((transactionToProcess) => transactionToProcess.metadata.success)
+ .map((transactionToProcess) => {
+ const sender = transactionToProcess.metadata.sender;
+ const transferEvents = transactionToProcess.metadata.receipt.events
+ // Events are not always in order so we sort them by index
+ .sort((a, b) => a.position.index - b.position.index)
+ .filter(
+ (
+ event,
+ ): event is
+ | ChainhookReceiptEventSTXTransferEvent
+ | ChainhookReceiptEventFTBurnEvent =>
+ event.type === "STXTransferEvent" || event.type === "FTBurnEvent",
+ );
+ const stxTransferEvent = transferEvents.filter(
+ (event) =>
+ event.type === "STXTransferEvent" && event.data.recipient === sender,
+ )[0];
+ const stStxBurnEvent = transferEvents.filter(
+ (event): event is ChainhookReceiptEventFTBurnEvent =>
+ event.type === "FTBurnEvent",
+ )[0];
+
+ return {
+ txId: transactionToProcess.transaction_identifier.hash,
+ protocol: "stackingdao",
+ blockHeight: BigInt(data.apply[0].block_identifier.index),
+ timestamp: new Date(data.apply[0].timestamp * 1000),
+ sender,
+ action: "stackingdao-withdraw",
+ data: {
+ inAmount: BigInt(stxTransferEvent.data.amount),
+ inToken: "STX",
+ outAmount: BigInt(stStxBurnEvent.data.amount),
+ outToken: stStxBurnEvent.data.asset_identifier,
+ },
+ } satisfies InsertTransaction;
+ });
+
+ for (const transaction of transactionsToInsert) {
+ await getOrInsertToken(transaction.data.inToken);
+ await getOrInsertToken(transaction.data.outToken);
+ }
+
+ if (transactionsToInsert.length > 0) {
+ await db
+ .insert(transactionTable)
+ .values(transactionsToInsert)
+ .onConflictDoUpdate({
+ target: transactionTable.txId,
+ set: conflictUpdateSetAllColumns(transactionTable),
+ });
+ }
+
+ return Response.json({ ok: true });
+}
diff --git a/src/components/Transaction/Action/StackingDAO.tsx b/src/components/Transaction/Action/StackingDAO.tsx
new file mode 100644
index 0000000..ca051bd
--- /dev/null
+++ b/src/components/Transaction/Action/StackingDAO.tsx
@@ -0,0 +1,28 @@
+import type {
+ SelectTransactionActionStackingDAODeposit,
+ SelectTransactionActionStackingDAOWithdraw,
+} from "@/db/transactions";
+import { displayPrice } from "@/lib/currencies";
+import { Text } from "@radix-ui/themes";
+
+interface TransactionActionStackingDAOProps {
+ transaction:
+ | SelectTransactionActionStackingDAODeposit
+ | SelectTransactionActionStackingDAOWithdraw;
+}
+
+export const TransactionActionStackingDAO = ({
+ transaction,
+}: TransactionActionStackingDAOProps) => {
+ return (
+ <>
+
+ {transaction.action === "stackingdao-deposit" ? "Deposit" : "Withdraw"}
+ {" "}
+ {displayPrice(transaction.data.outAmount, transaction.outToken.decimals)}{" "}
+ {transaction.outToken.symbol} for{" "}
+ {displayPrice(transaction.data.inAmount, transaction.inToken.decimals)}{" "}
+ {transaction.inToken.symbol}
+ >
+ );
+};
diff --git a/src/components/Transaction/Action/StackingDAODeposit.tsx b/src/components/Transaction/Action/StackingDAODeposit.tsx
deleted file mode 100644
index ab04000..0000000
--- a/src/components/Transaction/Action/StackingDAODeposit.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import type { SelectTransactionActionStackingDAODeposit } from "@/db/transactions";
-import { displayPrice } from "@/lib/currencies";
-import { Text } from "@radix-ui/themes";
-
-interface TransactionActionStackingDAODepositProps {
- transaction: SelectTransactionActionStackingDAODeposit;
-}
-
-export const TransactionActionStackingDAODeposit = ({
- transaction,
-}: TransactionActionStackingDAODepositProps) => {
- console.log(transaction);
- return (
- <>
- Deposit{" "}
- {displayPrice(transaction.data.outAmount, transaction.outToken.decimals)}{" "}
- {transaction.inToken.symbol} for{" "}
- {displayPrice(transaction.data.inAmount, transaction.inToken.decimals)}{" "}
- {transaction.outToken.symbol}
- >
- );
-};
diff --git a/src/components/Transaction/TransactionRow.tsx b/src/components/Transaction/TransactionRow.tsx
index 45b616c..0b000fa 100644
--- a/src/components/Transaction/TransactionRow.tsx
+++ b/src/components/Transaction/TransactionRow.tsx
@@ -6,7 +6,7 @@ import Link from "next/link";
import { TimeAgo } from "../Shared/TimeAgo";
import { TransactionActionAddLiquidity } from "./Action/AddLiquidity";
import { TransactionActionRemoveLiquidity } from "./Action/RemoveLiquidity";
-import { TransactionActionStackingDAODeposit } from "./Action/StackingDAODeposit";
+import { TransactionActionStackingDAO } from "./Action/StackingDAO";
import { TransactionActionSwap } from "./Action/Swap";
interface TransactionRowProps {
@@ -87,8 +87,9 @@ export const TransactionRow = ({ transaction }: TransactionRowProps) => {
{transaction.action === "remove-liquidity" ? (
) : null}
- {transaction.action === "stackingdao-deposit" ? (
-
+ {transaction.action === "stackingdao-deposit" ||
+ transaction.action === "stackingdao-withdraw" ? (
+
) : null}
diff --git a/src/lib/chainhooks.ts b/src/lib/chainhooks.ts
index 9ad3441..f160afd 100644
--- a/src/lib/chainhooks.ts
+++ b/src/lib/chainhooks.ts
@@ -54,6 +54,7 @@ type ChainhookReceiptEvent =
| ChainhookReceiptEventSTXTransferEvent
| ChainhookReceiptEventFTTransferEvent
| ChainhookReceiptEventFTMintEvent
+ | ChainhookReceiptEventFTBurnEvent
| ChainhookReceiptEventSmartContractEvent;
export interface ChainhookReceiptEventSTXTransferEvent {
@@ -93,6 +94,18 @@ export interface ChainhookReceiptEventFTMintEvent {
type: "FTMintEvent";
}
+export interface ChainhookReceiptEventFTBurnEvent {
+ data: {
+ amount: string;
+ asset_identifier: string;
+ recipient: string;
+ };
+ position: {
+ index: number;
+ };
+ type: "FTBurnEvent";
+}
+
export interface ChainhookReceiptEventSmartContractEvent {
data: unknown;
position: {