From 6841e02b650c2de943c8608d23c1d371dccb26a0 Mon Sep 17 00:00:00 2001 From: moggr Date: Fri, 23 Aug 2024 09:13:51 -0700 Subject: [PATCH] Update status codes on proofs API for better monitoring (#922) * Update status codes for better monitoring * move the try/catch scope * error on missing trustedSignerAddress * update avatar upload status code --- apps/web/pages/api/basenames/avatar/upload.ts | 2 +- .../pages/api/proofs/baseEthHolders/index.ts | 2 +- apps/web/pages/api/proofs/bns/index.ts | 2 +- apps/web/pages/api/proofs/cb1/index.ts | 14 ++--- apps/web/pages/api/proofs/cbid/index.ts | 2 +- apps/web/pages/api/proofs/coinbase/index.ts | 18 ++++-- .../web/pages/api/proofs/earlyAccess/index.ts | 2 +- apps/web/src/utils/proofs/requests.ts | 2 +- apps/web/src/utils/proofs/sybil_resistance.ts | 60 +++++++++++-------- 9 files changed, 59 insertions(+), 45 deletions(-) diff --git a/apps/web/pages/api/basenames/avatar/upload.ts b/apps/web/pages/api/basenames/avatar/upload.ts index 5de5da543b..46d45072ef 100644 --- a/apps/web/pages/api/basenames/avatar/upload.ts +++ b/apps/web/pages/api/basenames/avatar/upload.ts @@ -46,6 +46,6 @@ export default async function handler(request: NextApiRequest, response: NextApi return response.status(200).json(jsonResponse); } catch (error) { - return response.status(400).json({ error: (error as Error).message }); + return response.status(500).json({ error: (error as Error).message }); } } diff --git a/apps/web/pages/api/proofs/baseEthHolders/index.ts b/apps/web/pages/api/proofs/baseEthHolders/index.ts index 70adb4d8da..9582037910 100644 --- a/apps/web/pages/api/proofs/baseEthHolders/index.ts +++ b/apps/web/pages/api/proofs/baseEthHolders/index.ts @@ -42,5 +42,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) } // If error is not an instance of Error, return a generic error message - return res.status(409).json({ error: 'An unexpected error occurred' }); + return res.status(500).json({ error: 'An unexpected error occurred' }); } diff --git a/apps/web/pages/api/proofs/bns/index.ts b/apps/web/pages/api/proofs/bns/index.ts index 9dd260a5d2..bbf6698664 100644 --- a/apps/web/pages/api/proofs/bns/index.ts +++ b/apps/web/pages/api/proofs/bns/index.ts @@ -43,5 +43,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) } // If error is not an instance of Error, return a generic error message - return res.status(409).json({ error: 'An unexpected error occurred' }); + return res.status(500).json({ error: 'An unexpected error occurred' }); } diff --git a/apps/web/pages/api/proofs/cb1/index.ts b/apps/web/pages/api/proofs/cb1/index.ts index ec1e4a3146..1919a4cf14 100644 --- a/apps/web/pages/api/proofs/cb1/index.ts +++ b/apps/web/pages/api/proofs/cb1/index.ts @@ -1,5 +1,5 @@ import { trustedSignerPKey } from 'apps/web/src/constants'; -import { DiscountType, proofValidation } from 'apps/web/src/utils/proofs'; +import { DiscountType, ProofsException, proofValidation } from 'apps/web/src/utils/proofs'; import { sybilResistantUsernameSigning } from 'apps/web/src/utils/proofs/sybil_resistance'; import type { NextApiRequest, NextApiResponse } from 'next'; @@ -52,12 +52,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) ); return res.status(200).json(result); } catch (error) { - console.error(error); - if (error instanceof Error) { - return res.status(409).json({ error: error.message }); + if (error instanceof ProofsException) { + return res.status(error.statusCode).json({ error: error.message }); } - - // If error is not an instance of Error, return a generic error message - return res.status(409).json({ error: 'An unexpected error occurred' }); + console.error(error); } + + // If error is not an instance of Error, return a generic error message + return res.status(500).json({ error: 'An unexpected error occurred' }); } diff --git a/apps/web/pages/api/proofs/cbid/index.ts b/apps/web/pages/api/proofs/cbid/index.ts index e0e0a13ae0..81e843ff4c 100644 --- a/apps/web/pages/api/proofs/cbid/index.ts +++ b/apps/web/pages/api/proofs/cbid/index.ts @@ -44,5 +44,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) console.error(error); } // If error is not an instance of Error, return a generic error message - return res.status(409).json({ error: 'An unexpected error occurred' }); + return res.status(500).json({ error: 'An unexpected error occurred' }); } diff --git a/apps/web/pages/api/proofs/coinbase/index.ts b/apps/web/pages/api/proofs/coinbase/index.ts index 5107e346d5..bd2d78b70d 100644 --- a/apps/web/pages/api/proofs/coinbase/index.ts +++ b/apps/web/pages/api/proofs/coinbase/index.ts @@ -1,5 +1,10 @@ import { trustedSignerPKey } from 'apps/web/src/constants'; -import { DiscountType, proofValidation, VerifiedAccount } from 'apps/web/src/utils/proofs'; +import { + DiscountType, + ProofsException, + proofValidation, + VerifiedAccount, +} from 'apps/web/src/utils/proofs'; import { sybilResistantUsernameSigning } from 'apps/web/src/utils/proofs/sybil_resistance'; import type { NextApiRequest, NextApiResponse } from 'next'; import { Address } from 'viem'; @@ -54,11 +59,12 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) return res.status(200).json(result); } catch (error) { console.error(error); - if (error instanceof Error) { - return res.status(409).json({ error: error.message }); + if (error instanceof ProofsException) { + return res.status(error.statusCode).json({ error: error.message }); } - - // If error is not an instance of Error, return a generic error message - return res.status(409).json({ error: 'An unexpected error occurred' }); + console.error(error); } + + // If error is not an instance of Error, return a generic error message + return res.status(500).json({ error: 'An unexpected error occurred' }); } diff --git a/apps/web/pages/api/proofs/earlyAccess/index.ts b/apps/web/pages/api/proofs/earlyAccess/index.ts index aa1b7b797f..e4c2db7142 100644 --- a/apps/web/pages/api/proofs/earlyAccess/index.ts +++ b/apps/web/pages/api/proofs/earlyAccess/index.ts @@ -42,5 +42,5 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse) console.error(error); } // If error is not an instance of Error, return a generic error message - return res.status(409).json({ error: 'An unexpected error occurred' }); + return res.status(500).json({ error: 'An unexpected error occurred' }); } diff --git a/apps/web/src/utils/proofs/requests.ts b/apps/web/src/utils/proofs/requests.ts index 1bf824528d..7c8e06bafa 100644 --- a/apps/web/src/utils/proofs/requests.ts +++ b/apps/web/src/utils/proofs/requests.ts @@ -49,7 +49,7 @@ export async function getWalletProofs( const hasPreviouslyRegistered = await hasRegisteredWithDiscount([address], chain); // if any linked address registered previously return an error if (hasPreviouslyRegistered) { - throw new ProofsException('This address has already claimed a username.', 400); + throw new ProofsException('This address has already claimed a username.', 409); } const [content] = await getProofsByNamespaceAndAddress(address, namespace, caseInsensitive); const proofs = content?.proofs ? (JSON.parse(content.proofs) as `0x${string}`[]) : []; diff --git a/apps/web/src/utils/proofs/sybil_resistance.ts b/apps/web/src/utils/proofs/sybil_resistance.ts index 87054f2181..423a9b9336 100644 --- a/apps/web/src/utils/proofs/sybil_resistance.ts +++ b/apps/web/src/utils/proofs/sybil_resistance.ts @@ -20,6 +20,7 @@ import { DiscountTypes, PreviousClaim, PreviousClaims, + ProofsException, VerifiedAccount, } from 'apps/web/src/utils/proofs/types'; import { REGISTER_CONTRACT_ADDRESSES } from 'apps/web/src/utils/usernames'; @@ -86,6 +87,9 @@ async function signMessageWithTrustedSigner( targetAddress: Address, expiry: number, ) { + if (!trustedSignerAddress || !isAddress(trustedSignerAddress)) { + throw new Error('Must provide a valid trustedSignerAddress'); + } // encode the message const message = encodePacked( ['bytes2', 'address', 'address', 'address', 'uint64'], @@ -122,7 +126,7 @@ export async function sybilResistantUsernameSigning( const discountValidatorAddress = discountTypes[chainId][discountType]?.discountValidatorAddress; if (!discountValidatorAddress || !isAddress(discountValidatorAddress)) { - throw new Error('Must provide a valid discountValidatorAddress'); + throw new ProofsException('Must provide a valid discountValidatorAddress', 500); } const attestations = await getAttestations( @@ -138,35 +142,36 @@ export async function sybilResistantUsernameSigning( (attestation) => JSON.parse(attestation.decodedDataJson)[0] as VerifiedAccount, ); - try { - let { linkedAddresses, idemKey } = await getLinkedAddresses(address as string); + let { linkedAddresses, idemKey } = await getLinkedAddresses(address as string); - const hasPreviouslyRegistered = await hasRegisteredWithDiscount(linkedAddresses, chainId); - // if any linked address registered previously return an error - if (hasPreviouslyRegistered) { - throw new Error('You have already claimed a discounted basename (onchain).'); - } + const hasPreviouslyRegistered = await hasRegisteredWithDiscount(linkedAddresses, chainId); + // if any linked address registered previously return an error + if (hasPreviouslyRegistered) { + throw new ProofsException('You have already claimed a discounted basename (onchain).', 409); + } - const kvKey = `${previousClaimsKVPrefix}${idemKey}`; - //check kv for previous claim entries - let previousClaims = (await kv.get(kvKey)) ?? {}; - const previousClaim = previousClaims[discountType]; - if (previousClaim) { - if (previousClaim.address != address) { - throw new Error( - 'You tried claiming this with a different address, wait a couple minutes to try again.', - ); - } - // return previously signed message - return { - signedMessage: previousClaim.signedMessage, - attestations: attestationsRes, - discountValidatorAddress, - expires: EXPIRY.toString(), - }; + const kvKey = `${previousClaimsKVPrefix}${idemKey}`; + //check kv for previous claim entries + let previousClaims = (await kv.get(kvKey)) ?? {}; + const previousClaim = previousClaims[discountType]; + if (previousClaim) { + if (previousClaim.address != address) { + throw new ProofsException( + 'You tried claiming this with a different address, wait a couple minutes to try again.', + 400, + ); } + // return previously signed message + return { + signedMessage: previousClaim.signedMessage, + attestations: attestationsRes, + discountValidatorAddress, + expires: EXPIRY.toString(), + }; + } - const expirationTimeUnix = Math.floor(Date.now() / 1000) + parseInt(EXPIRY); + const expirationTimeUnix = Math.floor(Date.now() / 1000) + parseInt(EXPIRY); + try { // generate and sign the message const signedMessage = await signMessageWithTrustedSigner( address, @@ -185,6 +190,9 @@ export async function sybilResistantUsernameSigning( }; } catch (error) { console.error(error); + if (error instanceof Error) { + throw new ProofsException(error.message, 500); + } throw error; } }