Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sepolia requests to Request Scan #79

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
80 changes: 46 additions & 34 deletions src/app/request/[id]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
/** @format */
'use client';
"use client";

import { TransactionsAndPaymentsTable } from '@/components/transactions-and-payments-table';
import { Button } from '@/components/ui/button';
import { TransactionsAndPaymentsTable } from "@/components/transactions-and-payments-table";
import { Button } from "@/components/ui/button";
import {
Card,
CardHeader,
CardTitle,
CardContent,
CardFooter,
} from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
import { fetchRequest } from '@/lib/queries/channel';
import { fetchRequestPayments } from '@/lib/queries/request-payments';
} from "@/components/ui/card";
import { Skeleton } from "@/components/ui/skeleton";
import { fetchRequest } from "@/lib/queries/channel";
import { fetchRequestPayments } from "@/lib/queries/request-payments";
import {
calculateLongPaymentReference,
calculateShortPaymentReference,
Expand All @@ -25,31 +25,39 @@ import {
getPaymentDataFromCreateTransaction,
getTransactionCreateParameters,
renderAddress,
} from '@/lib/utils';
import { ActorInfo } from '@requestnetwork/data-format';
import { useQuery } from '@tanstack/react-query';
import { Copy, File, Loader2 } from 'lucide-react';
import Link from 'next/link';
import { redirect } from 'next/navigation';
import TimeAgo from 'timeago-react';
import { JsonEditor } from 'json-edit-react';
import useExportPDF from '@/lib/hooks/use-export-pdf';
import { useState } from 'react';
} from "@/lib/utils";
import { ActorInfo } from "@requestnetwork/data-format";
import { useQuery } from "@tanstack/react-query";
import { Copy, File, Loader2 } from "lucide-react";
import Link from "next/link";
import { redirect } from "next/navigation";
import TimeAgo from "timeago-react";
import { JsonEditor } from "json-edit-react";
import useExportPDF from "@/lib/hooks/use-export-pdf";
import { useState } from "react";
import { Channel } from "@/lib/types";

interface RequestPageProps {
params: {
id: string;
};
}

const getGateway = (request: Channel | null) => {
if (request?.source === "storage_sepolia") {
return "sepolia.gateway.request.network";
}
return "gnosis.gateway.request.network";
};

const ActorInfoSection = ({ actorInfo }: { actorInfo?: ActorInfo }) => {
if (
!actorInfo ||
Object.keys(actorInfo).every(
(k) => !Object.keys((actorInfo as any)[k]).length,
(k) => !Object.keys((actorInfo as any)[k]).length
)
) {
return 'N/A';
return "N/A";
}

return (
Expand Down Expand Up @@ -113,7 +121,7 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
const [isDownloading, setIsDownloading] = useState(false);

const { data: request, isLoading: isLoadingRequest } = useQuery({
queryKey: ['request', id],
queryKey: ["request", id],
queryFn: () => fetchRequest({ id }),
...commonQueryOptions,
});
Expand All @@ -122,19 +130,19 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
? calculateShortPaymentReference(
id,
request?.transactions[0].dataObject.data.parameters.extensionsData[0]
.parameters.salt || '',
.parameters.salt || "",
request?.transactions[0].dataObject.data.parameters.extensionsData[0]
.parameters.paymentAddress || '',
.parameters.paymentAddress || ""
)
: '';
: "";

const longPaymentReference = shortPaymentReference
? calculateLongPaymentReference(shortPaymentReference)
: '';
: "";

const { data: requestPayments, isLoading: isLoadingRequestPayments } =
useQuery({
queryKey: ['request-payments', longPaymentReference],
queryKey: ["request-payments", longPaymentReference],
queryFn: () => fetchRequestPayments({ reference: longPaymentReference }),
...commonQueryOptions,
});
Expand All @@ -144,7 +152,7 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
}

if (!request) {
redirect('/not-found');
redirect("/not-found");
}

const firstTransaction = request?.transactions[0];
Expand All @@ -160,14 +168,14 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
const balanceCurrency =
paymentData?.acceptedTokens?.length > 0
? paymentData.acceptedTokens[0]
: '';
: "";

const buyerData = contentData?.buyerInfo;
const sellerData = contentData?.sellerInfo;

const status =
balance >= BigInt(createParameters.expectedAmount)
? 'Paid'
? "Paid"
: lastTransaction?.dataObject?.data?.name;

const modifiedTimestamp =
Expand All @@ -190,7 +198,7 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
paymentData,
});
} catch (error) {
console.error('Error exporting PDF:', error);
console.error("Error exporting PDF:", error);
} finally {
setIsDownloading(false);
}
Expand Down Expand Up @@ -240,6 +248,10 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
<td className="text-muted-foreground">Status:</td>
<td className="pl-16">{status}</td>
</tr>
<tr>
<td className="text-muted-foreground">Gateway:</td>
<td className="pl-16">{getGateway(request)}</td>
</tr>
<tr>
<td className="text-muted-foreground">Payee:</td>
<td className="pl-16">
Expand Down Expand Up @@ -277,7 +289,7 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
<td className="pl-16">
{getAmountWithCurrencySymbol(
BigInt(createParameters.expectedAmount),
createParameters.currency.value,
createParameters.currency.value
)}
</td>
</tr>
Expand All @@ -286,7 +298,7 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
<td className="pl-16">
{getAmountWithCurrencySymbol(
BigInt(balance),
balanceCurrency || '',
balanceCurrency || ""
)}
</td>
</tr>
Expand All @@ -296,7 +308,7 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
<TimeAgo
datetime={firstTransaction.blockTimestamp * 1000}
locale="en_short"
/>{' '}
/>{" "}
({formatTimestamp(firstTransaction.blockTimestamp)})
</td>
</tr>
Expand All @@ -306,7 +318,7 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
<TimeAgo
datetime={modifiedTimestamp * 1000}
locale="en_short"
/>{' '}
/>{" "}
({formatTimestamp(modifiedTimestamp)})
</td>
</tr>
Expand All @@ -319,7 +331,7 @@ export default function RequestPage({ params: { id } }: RequestPageProps) {
<td className="pl-16">
{paymentData?.network
? capitalize(paymentData?.network)
: ''}
: ""}
</td>
</tr>
<tr>
Expand Down
55 changes: 45 additions & 10 deletions src/lib/queries/address-transactions.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/** @format */

import { gql } from 'graphql-request';
import { graphQLClient } from '../graphQlClient';
import { Transaction } from '../types';
import { groupBy } from '../utils';
import { getAddress } from 'viem';
import { gql } from "graphql-request";
import { graphQLClient } from "../graphQlClient";
import { Transaction } from "../types";
import { groupBy } from "../utils";
import { getAddress } from "viem";

export const ADDRESS_TRANSACTIONS_QUERY = gql`
query AddressTransactionsQuery(
Expand Down Expand Up @@ -37,6 +37,30 @@ export const ADDRESS_TRANSACTIONS_QUERY = gql`
smartContractAddress
}
}
storage_sepolia {
transactions(
first: $first
skip: $skip
orderBy: blockNumber
orderDirection: desc
where: {
or: [
{ data_contains: $checksumAddress }
{ data_contains: $lowercaseAddress }
]
}
) {
blockNumber
blockTimestamp
channelId
data
dataHash
hash
id
size
smartContractAddress
}
}
}
`;

Expand All @@ -54,18 +78,29 @@ export const fetchAddressRequests = async (variables: {
lowercaseAddress: variables.address.toLowerCase(),
};

const data: { storage: { transactions: Transaction[] } } =
await graphQLClient.request(ADDRESS_TRANSACTIONS_QUERY, formatedVariables);
const data: {
storage: { transactions: Transaction[] };
storage_sepolia: { transactions: Transaction[] };
} = await graphQLClient.request(
ADDRESS_TRANSACTIONS_QUERY,
formatedVariables
);

// Combine transactions from both networks
const allTransactions = [
...(data?.storage?.transactions || []),
...(data?.storage_sepolia?.transactions || []),
];
aimensahnoun marked this conversation as resolved.
Show resolved Hide resolved

return data?.storage.transactions
return allTransactions.length
? groupBy(
data?.storage.transactions.map((transaction: Transaction) => {
allTransactions.map((transaction: Transaction) => {
return {
...transaction,
dataObject: JSON.parse(transaction.data),
};
}),
'channelId',
"channelId"
aimensahnoun marked this conversation as resolved.
Show resolved Hide resolved
)
: [];
};
93 changes: 69 additions & 24 deletions src/lib/queries/channel.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/** @format */

import { gql } from 'graphql-request';
import { graphQLClient } from '../graphQlClient';
import { Channel, Transaction } from '../types';
import { gql } from "graphql-request";
import { graphQLClient } from "../graphQlClient";
import { Channel, Transaction } from "../types";

export const CHANNEL_QUERY = gql`
query ChannelQuery($id: ID!) @cached {
Expand All @@ -29,35 +29,80 @@ export const CHANNEL_QUERY = gql`
}
}
}
storage_sepolia {
channel(id: $id) {
id
topics
transactions {
data
blockNumber
blockTimestamp
channelId
dataHash
encryptedData
encryptedKeys
encryptionMethod
hash
id
publicKeys
size
smartContractAddress
topics
transactionHash
}
}
}
}
`;

export const fetchRequest = async (variables: {
id: string;
}): Promise<Channel | null> => {
const data: { storage: { channel: Channel } } = await graphQLClient.request(
CHANNEL_QUERY,
variables,
);
const data: {
storage: { channel: Channel };
storage_sepolia: { channel: Channel };
} = await graphQLClient.request(CHANNEL_QUERY, variables);

if (!data?.storage.channel) {
return null;
// Check which storage has the channel
if (data?.storage?.channel) {
return {
...data.storage.channel,
source: "storage",
transactions: data.storage.channel.transactions.map(
(transaction: Transaction) => {
try {
return {
...transaction,
dataObject: JSON.parse(transaction.data),
};
} catch (error: any) {
console.error(`Error parsing transaction data: ${error.message}`);
return transaction;
}
}
),
};
aimensahnoun marked this conversation as resolved.
Show resolved Hide resolved
}

return {
...data.storage.channel,
transactions: data?.storage.channel.transactions.map(
(transaction: Transaction) => {
try {
return {
...transaction,
dataObject: JSON.parse(transaction.data),
};
} catch (error: any) {
console.error(`Error parsing transaction data: ${error.message}`);
return transaction;
if (data?.storage_sepolia?.channel) {
return {
...data.storage_sepolia.channel,
source: "storage_sepolia",
transactions: data.storage_sepolia.channel.transactions.map(
(transaction: Transaction) => {
try {
return {
...transaction,
dataObject: JSON.parse(transaction.data),
};
} catch (error: any) {
console.error(`Error parsing transaction data: ${error.message}`);
return transaction;
}
}
},
),
};
),
};
}

return null;
};
Loading