diff --git a/src/server/routes/transaction/blockchain/get-logs.ts b/src/server/routes/transaction/blockchain/get-logs.ts index 9ce20ef5..5ec55967 100644 --- a/src/server/routes/transaction/blockchain/get-logs.ts +++ b/src/server/routes/transaction/blockchain/get-logs.ts @@ -155,21 +155,28 @@ export async function getTransactionLogs(fastify: FastifyInstance) { // Get the transaction hash from the provided input. let hash: Hex | undefined; if (queueId) { - // Primary lookup - const transaction = await TransactionDB.get(queueId); - if (transaction?.status === "mined") { - hash = transaction.transactionHash; - } - // SPECIAL LOGIC FOR AMEX - // AMEX uses this endpoint to get logs for transactions they didn't receive webhooks for - // the queue ID's were cleaned out of REDIS so we backfilled tx hashes to this backfill table - // see https://github.com/thirdweb-dev/solutions-customer-scripts/blob/main/amex/scripts/load-backfill-via-api.ts - // Fallback to backfill table if enabled and not found - if (!hash && env.ENABLE_TX_BACKFILL_FALLBACK) { + // Backfill table takes priority — entries are intentional overrides for + // queue IDs that are stuck in Redis (e.g. orphaned "queued" transactions). + if (env.ENABLE_TX_BACKFILL_FALLBACK) { const backfill = await TransactionDB.getBackfill(queueId); - if (backfill?.status === "mined" && backfill.transactionHash && isHex(backfill.transactionHash)) { - hash = backfill.transactionHash as Hex; + if (backfill) { + // Backfill entry exists and is authoritative — only set hash if mined. + // If backfill is errored, hash stays undefined and we skip Redis lookup. + if (backfill.status === "mined" && backfill.transactionHash && isHex(backfill.transactionHash)) { + hash = backfill.transactionHash as Hex; + } + } else { + // No backfill entry — fall back to Redis. + const transaction = await TransactionDB.get(queueId); + if (transaction?.status === "mined") { + hash = transaction.transactionHash; + } + } + } else { + const transaction = await TransactionDB.get(queueId); + if (transaction?.status === "mined") { + hash = transaction.transactionHash; } } } else if (transactionHash) { diff --git a/src/server/routes/transaction/status.ts b/src/server/routes/transaction/status.ts index 91f286ce..497f1adf 100644 --- a/src/server/routes/transaction/status.ts +++ b/src/server/routes/transaction/status.ts @@ -145,22 +145,21 @@ export async function getTransactionStatusRoute(fastify: FastifyInstance) { handler: async (request, reply) => { const { queueId } = request.params; - const transaction = await TransactionDB.get(queueId); - if (!transaction) { - // SPECIAL LOGIC FOR AMEX - // AMEX uses this endpoint to check transaction status for queue IDs they didn't receive webhooks for. - // The queue ID's were cleaned out of Redis so we backfilled tx data to this backfill table. - // See https://github.com/thirdweb-dev/solutions-customer-scripts/blob/main/amex/scripts/load-backfill-via-api.ts - // Fallback to backfill table if enabled and not found - if (env.ENABLE_TX_BACKFILL_FALLBACK) { - const backfill = await TransactionDB.getBackfill(queueId); - if (backfill) { - return reply.status(StatusCodes.OK).send({ - result: createBackfillResponse(queueId, backfill), - }); - } + // SPECIAL LOGIC FOR AMEX + // Backfill table takes priority — entries are intentional overrides for + // queue IDs that are stuck in Redis (e.g. orphaned "queued" transactions). + // See https://github.com/thirdweb-dev/solutions-customer-scripts/blob/main/amex/scripts/load-backfill-via-api.ts + if (env.ENABLE_TX_BACKFILL_FALLBACK) { + const backfill = await TransactionDB.getBackfill(queueId); + if (backfill) { + return reply.status(StatusCodes.OK).send({ + result: createBackfillResponse(queueId, backfill), + }); } + } + const transaction = await TransactionDB.get(queueId); + if (!transaction) { throw createCustomError( "Transaction not found.", StatusCodes.BAD_REQUEST, @@ -206,22 +205,20 @@ export async function getTransactionStatusQueryParamRoute( ); } - const transaction = await TransactionDB.get(queueId); - if (!transaction) { - // SPECIAL LOGIC FOR AMEX - // AMEX uses this endpoint to check transaction status for queue IDs they didn't receive webhooks for. - // The queue ID's were cleaned out of Redis so we backfilled tx data to this backfill table. - // See https://github.com/thirdweb-dev/solutions-customer-scripts/blob/main/amex/scripts/load-backfill-via-api.ts - // Fallback to backfill table if enabled and not found - if (env.ENABLE_TX_BACKFILL_FALLBACK) { - const backfill = await TransactionDB.getBackfill(queueId); - if (backfill) { - return reply.status(StatusCodes.OK).send({ - result: createBackfillResponse(queueId, backfill), - }); - } + // SPECIAL LOGIC FOR AMEX + // Backfill table takes priority — entries are intentional overrides for + // queue IDs that are stuck in Redis (e.g. orphaned "queued" transactions). + if (env.ENABLE_TX_BACKFILL_FALLBACK) { + const backfill = await TransactionDB.getBackfill(queueId); + if (backfill) { + return reply.status(StatusCodes.OK).send({ + result: createBackfillResponse(queueId, backfill), + }); } + } + const transaction = await TransactionDB.get(queueId); + if (!transaction) { throw createCustomError( "Transaction not found.", StatusCodes.BAD_REQUEST,