Skip to content

Commit 17d40af

Browse files
committed
Dashboard: fix payments tx history table crashing on onramp type purchase (#7982)
<!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR focuses on refactoring the payment-related types and logic in the application to improve type safety and clarity. It introduces a new `BridgePayment` type, updates the `TableRow` component, and modifies how payments are filtered and processed. ### Detailed summary - Changed `Payment` type to `BridgePayment` in `TableRow` component. - Updated `originAmount` and `destinationAmount` to use `BigInt`. - Introduced `BridgePaymentType` and `OnrampPaymentType`. - Modified `getCSVData` to accept only `BridgePayment` types. - Added `isBridgePayment` function to filter payments. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex --> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - New Features - Payments views and CSV export now explicitly show only bridge payments; onramp entries are excluded. - Bug Fixes - Improved accuracy for large origin/destination amounts by converting amounts to integer form before token conversion. - Consistent token conversions across table, links, and CSV exports. - Refactor - Payment data reorganized into distinct bridge vs onramp variants to improve filtering and export consistency. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent bc6309d commit 17d40af

File tree

4 files changed

+62
-35
lines changed

4 files changed

+62
-35
lines changed

apps/dashboard/src/@/api/universal-bridge/developer.ts

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -297,38 +297,53 @@ export type PaymentsResponse = {
297297
totalCount: number;
298298
};
299299
};
300+
301+
type BridgePaymentType = "buy" | "sell" | "transfer";
302+
type OnrampPaymentType = "onramp";
303+
300304
export type Payment = {
305+
// common
301306
id: string;
302-
blockNumber?: bigint;
303-
transactionId: string;
307+
createdAt: string;
304308
clientId: string;
305-
sender: string;
306309
receiver: string;
307-
developerFeeRecipient: string;
308-
developerFeeBps: number;
309310
transactions: Array<{
310311
chainId: number;
311312
transactionHash: string;
312313
}>;
313314
status: "PENDING" | "COMPLETED" | "FAILED" | "NOT_FOUND";
314-
type: "buy" | "sell" | "transfer";
315-
originAmount: bigint;
316-
destinationAmount: bigint;
317-
purchaseData: unknown;
318-
originToken: {
319-
address: string;
320-
symbol: string;
321-
decimals: number;
322-
chainId: number;
323-
};
315+
316+
destinationAmount: string;
324317
destinationToken: {
325318
address: string;
326319
symbol: string;
327320
decimals: number;
328321
chainId: number;
329322
};
330-
createdAt: string;
331-
};
323+
purchaseData: unknown;
324+
} & (
325+
| {
326+
type: BridgePaymentType;
327+
transactionId: string;
328+
blockNumber?: string;
329+
sender: string;
330+
developerFeeRecipient: string;
331+
developerFeeBps: number;
332+
originAmount: string;
333+
originToken: {
334+
address: string;
335+
symbol: string;
336+
decimals: number;
337+
chainId: number;
338+
};
339+
}
340+
| {
341+
onrampId: string;
342+
type: OnrampPaymentType;
343+
}
344+
);
345+
346+
export type BridgePayment = Extract<Payment, { type: BridgePaymentType }>;
332347

333348
export async function getPayments(props: {
334349
clientId: string;

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/payments/components/PaymentHistory.client.tsx

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { format } from "date-fns";
44
import { useMemo, useState } from "react";
55
import { type ThirdwebClient, toTokens } from "thirdweb";
66
import {
7+
type BridgePayment,
78
getPayments,
89
type Payment,
910
type PaymentsResponse,
@@ -59,7 +60,9 @@ export function PaymentHistory(props: {
5960
<ExportToCSVButton
6061
fileName="transaction_history"
6162
getData={async () => {
62-
return getCSVData(payPurchaseData?.data || []);
63+
return getCSVData(
64+
payPurchaseData?.data.filter(isBridgePayment) || [],
65+
);
6366
}}
6467
/>
6568
</div>
@@ -82,15 +85,17 @@ export function PaymentHistory(props: {
8285
<tbody>
8386
{(!isEmpty || isLoading) &&
8487
(payPurchaseData && !isLoading
85-
? payPurchaseData.data.map((purchase) => {
86-
return (
87-
<TableRow
88-
client={props.client}
89-
key={purchase.id}
90-
purchase={purchase}
91-
/>
92-
);
93-
})
88+
? payPurchaseData.data
89+
.filter(isBridgePayment)
90+
.map((purchase) => {
91+
return (
92+
<TableRow
93+
client={props.client}
94+
key={purchase.id}
95+
purchase={purchase}
96+
/>
97+
);
98+
})
9499
: new Array(pageSize).fill(0).map((_, i) => (
95100
// biome-ignore lint/suspicious/noArrayIndexKey: ok
96101
<SkeletonTableRow key={i} />
@@ -119,16 +124,20 @@ export function PaymentHistory(props: {
119124
);
120125
}
121126

122-
function getCSVData(data: Payment[]) {
127+
function isBridgePayment(purchase: Payment): purchase is BridgePayment {
128+
return purchase.type !== "onramp";
129+
}
130+
131+
function getCSVData(data: BridgePayment[]) {
123132
const header = ["Type", "Bought", "Paid", "Status", "Recipient", "Date"];
124133

125134
const rows: string[][] = data.map((purchase) => {
126135
const toAmount = toTokens(
127-
purchase.destinationAmount,
136+
BigInt(purchase.destinationAmount),
128137
purchase.destinationToken.decimals,
129138
);
130139
const fromAmount = toTokens(
131-
purchase.originAmount,
140+
BigInt(purchase.originAmount),
132141
purchase.originToken.decimals,
133142
);
134143
const type = (() => {

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/payments/components/PaymentsTableRow.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
import { format } from "date-fns";
22
import { type ThirdwebClient, toTokens } from "thirdweb";
3-
import type { Payment } from "@/api/universal-bridge/developer";
3+
import type { BridgePayment } from "@/api/universal-bridge/developer";
44
import { WalletAddress } from "@/components/blocks/wallet-address";
55
import { Badge } from "@/components/ui/badge";
66
import { cn } from "@/lib/utils";
77
import { TableData } from "./common";
88
import { formatTokenAmount } from "./format";
99

10-
export function TableRow(props: { purchase: Payment; client: ThirdwebClient }) {
10+
export function TableRow(props: {
11+
purchase: BridgePayment;
12+
client: ThirdwebClient;
13+
}) {
1114
const { purchase } = props;
1215
const originAmount = toTokens(
13-
purchase.originAmount,
16+
BigInt(purchase.originAmount),
1417
purchase.originToken.decimals,
1518
);
1619
const destinationAmount = toTokens(
17-
purchase.destinationAmount,
20+
BigInt(purchase.destinationAmount),
1821
purchase.destinationToken.decimals,
1922
);
2023
const type = (() => {

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/payments/links/components/PaymentLinksTable.client.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ function PaymentLinksTableInner(props: { clientId: string; teamId: string }) {
192192
acc +
193193
Number(
194194
toTokens(
195-
curr.destinationAmount,
195+
BigInt(curr.destinationAmount),
196196
curr.destinationToken.decimals,
197197
),
198198
),

0 commit comments

Comments
 (0)