From b5838f199c79cc79d19f84f9203c8130a0bb9308 Mon Sep 17 00:00:00 2001 From: nicholas ma Date: Tue, 12 Nov 2024 15:20:02 -0800 Subject: [PATCH 1/3] fix: filtered out transaction error messages for agent tokens --- src/lib/transactions.ts | 32 +++++++++++++++++++++++++++-- src/notifications/utils.ts | 33 ++++++++++++++++++++++++++++++ src/routes/popup/notifications.tsx | 7 +++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/src/lib/transactions.ts b/src/lib/transactions.ts index 295e17e4..18409de8 100644 --- a/src/lib/transactions.ts +++ b/src/lib/transactions.ts @@ -1,6 +1,6 @@ import type GQLResultInterface from "ar-gql/dist/faces"; import type { GQLEdgeInterface } from "ar-gql/dist/faces"; -import type { RawTransaction } from "~notifications/api"; +import type { RawTransaction, Transaction } from "~notifications/api"; import { timeoutPromise, type TokenInfo } from "~tokens/aoTokens/ao"; import { formatAddress } from "~utils/format"; import { ExtensionStorage } from "~utils/storage"; @@ -9,10 +9,16 @@ import type { Token } from "~tokens/token"; import BigNumber from "bignumber.js"; import browser from "webextension-polyfill"; import { balanceToFractioned, formatFiatBalance } from "~tokens/currency"; +import { AF_ERROR_QUERY } from "~notifications/utils"; +import { gql } from "~gateways/api"; +import { txHistoryGateways } from "~gateways/gateway"; +import { retryWithDelay } from "~utils/retry"; let tokens: TokenInfo[] = null; export let tokenInfoMap = new Map(); +const AGENT_TOKEN_ADDRESS = "JwjzLSbwIDIouY0iIMyVEbjMbVMOkL2TTEzdJWwtly8"; + export type ExtendedTransaction = RawTransaction & { cursor: string; month: number; @@ -87,10 +93,32 @@ const processTransaction = (transaction: GQLEdgeInterface, type: string) => ({ date: "" }); +export async function checkTransactionError( + transaction: GQLEdgeInterface | Transaction +): Promise { + if (transaction.node.owner.address !== AGENT_TOKEN_ADDRESS) { + return false; + } + + return retryWithDelay(async (attempt) => { + const data = await gql( + AF_ERROR_QUERY, + { messageId: transaction.node.id }, + txHistoryGateways[attempt % txHistoryGateways.length] + ); + return data.data.transactions.edges.length > 0; + }, 2); +} + const processAoTransaction = async ( transaction: GQLEdgeInterface, type: string ) => { + const hasError = await checkTransactionError(transaction); + if (hasError) { + return null; + } + const tokenData = await timeoutPromise( fetchTokenByProcessId(transaction.node.recipient), 10000 @@ -124,7 +152,7 @@ export const processTransactions = async ( if (isAo) { return Promise.all( edges.map((transaction) => processAoTransaction(transaction, type)) - ); + ).then((transactions) => transactions.filter(Boolean)); } else { return edges.map((transaction) => processTransaction(transaction, type)); } diff --git a/src/notifications/utils.ts b/src/notifications/utils.ts index 581e4c86..85d2ffad 100644 --- a/src/notifications/utils.ts +++ b/src/notifications/utils.ts @@ -69,6 +69,39 @@ query($address: String!) { } `; +export const AF_ERROR_QUERY = ` +query { + transactions( + first: 10, + tags: [ + {name: "Data-Protocol", values: ["ao"]}, + {name: "Action", values: ["Transfer-Error"]}, + {name: "Message-Id", values: ["L-nExyvrfVv5oJQtBnk6VD7-Hgisf-WLC55MMCqQq7A"]}, + ] + ) { + edges { + cursor + node { + recipient + id + owner { + address + } + block { + timestamp + height + } + tags { + name + value + } + } + } + } +} + +`; + export const AO_SENT_QUERY = ` query($address: String!) { transactions( diff --git a/src/routes/popup/notifications.tsx b/src/routes/popup/notifications.tsx index 58db1b73..3b1deb56 100644 --- a/src/routes/popup/notifications.tsx +++ b/src/routes/popup/notifications.tsx @@ -22,6 +22,7 @@ import { SubscriptionStatus, type SubscriptionData } from "~subscriptions/subscription"; +import { checkTransactionError } from "~lib/transactions"; export default function Notifications() { const [notifications, setNotifications] = useState([]); @@ -86,9 +87,15 @@ export default function Notifications() { formattedNotifications: Transaction[]; }> => { const address = await getActiveAddress(); + let formattedNotifications = await Promise.all( notifications.map(async (notification) => { try { + const hasError = await checkTransactionError(notification); + if (hasError) { + return { formattedMessage: null, notification }; + } + let formattedMessage: string = ""; if (notification.transactionType === "PrintArchive") { formattedMessage = browser.i18n.getMessage("print_archived"); From 7d2b121cff8a86de8397bdf005ae60533483ac46 Mon Sep 17 00:00:00 2001 From: nicholas ma Date: Wed, 13 Nov 2024 12:55:41 -0800 Subject: [PATCH 2/3] fix: removed static gql query and added error handling --- src/lib/transactions.ts | 5 +++++ src/notifications/utils.ts | 5 ++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/lib/transactions.ts b/src/lib/transactions.ts index 18409de8..c424089c 100644 --- a/src/lib/transactions.ts +++ b/src/lib/transactions.ts @@ -106,6 +106,11 @@ export async function checkTransactionError( { messageId: transaction.node.id }, txHistoryGateways[attempt % txHistoryGateways.length] ); + + if (data?.data === null && (data as any)?.errors?.length > 0) { + throw new Error((data as any)?.errors?.[0]?.message || "GraphQL Error"); + } + return data.data.transactions.edges.length > 0; }, 2); } diff --git a/src/notifications/utils.ts b/src/notifications/utils.ts index 85d2ffad..2c2f63d1 100644 --- a/src/notifications/utils.ts +++ b/src/notifications/utils.ts @@ -70,13 +70,13 @@ query($address: String!) { `; export const AF_ERROR_QUERY = ` -query { +query($messageId: String!) { transactions( first: 10, tags: [ {name: "Data-Protocol", values: ["ao"]}, {name: "Action", values: ["Transfer-Error"]}, - {name: "Message-Id", values: ["L-nExyvrfVv5oJQtBnk6VD7-Hgisf-WLC55MMCqQq7A"]}, + {name: "Message-Id", values: [$messageId]}, ] ) { edges { @@ -99,7 +99,6 @@ query { } } } - `; export const AO_SENT_QUERY = ` From 173875c7dc80f9494200d371b50cdceb5c4d216b Mon Sep 17 00:00:00 2001 From: nicholas ma Date: Wed, 13 Nov 2024 21:16:05 -0800 Subject: [PATCH 3/3] fix: address and .catch --- src/lib/transactions.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/transactions.ts b/src/lib/transactions.ts index c424089c..ce41009f 100644 --- a/src/lib/transactions.ts +++ b/src/lib/transactions.ts @@ -17,7 +17,7 @@ import { retryWithDelay } from "~utils/retry"; let tokens: TokenInfo[] = null; export let tokenInfoMap = new Map(); -const AGENT_TOKEN_ADDRESS = "JwjzLSbwIDIouY0iIMyVEbjMbVMOkL2TTEzdJWwtly8"; +const AGENT_TOKEN_ADDRESS = "8rbAftv7RaPxFjFk5FGUVAVCSjGQB4JHDcb9P9wCVhQ"; export type ExtendedTransaction = RawTransaction & { cursor: string; @@ -96,7 +96,7 @@ const processTransaction = (transaction: GQLEdgeInterface, type: string) => ({ export async function checkTransactionError( transaction: GQLEdgeInterface | Transaction ): Promise { - if (transaction.node.owner.address !== AGENT_TOKEN_ADDRESS) { + if (transaction.node.recipient !== AGENT_TOKEN_ADDRESS) { return false; } @@ -112,7 +112,7 @@ export async function checkTransactionError( } return data.data.transactions.edges.length > 0; - }, 2); + }, 2).catch(() => false); } const processAoTransaction = async (