diff --git a/apps/copilot-api/config/publicClient.ts b/apps/copilot-api/config/publicClient.ts new file mode 100644 index 00000000..2087d309 --- /dev/null +++ b/apps/copilot-api/config/publicClient.ts @@ -0,0 +1,7 @@ +import { createPublicClient, http } from 'viem'; +import { mainnet } from 'viem/chains'; + +export const publicClient = createPublicClient({ + chain: mainnet, + transport: http('https://rpc.payload.de'), +}); diff --git a/apps/copilot-api/routes/auth.ts b/apps/copilot-api/routes/auth.ts index 7e75070f..7f37b958 100644 --- a/apps/copilot-api/routes/auth.ts +++ b/apps/copilot-api/routes/auth.ts @@ -3,11 +3,12 @@ import type { Request, Response } from 'express'; import dotenv from 'dotenv'; import jwt from 'jsonwebtoken'; import { throwInternalError } from '../middleware/error.middleware'; -import { isAddress, verifyMessage } from 'viem'; +import { isAddress } from 'viem'; import { dataSource } from '../db'; import { AddressesEntity } from '../entities/addreesses.entity'; import { UsersEntity } from '../entities/users.entity'; -import { v4 as uuidv4 } from 'uuid'; +import { createSiweMessage, generateSiweNonce } from 'viem/siwe'; +import { publicClient } from '../config/publicClient'; import { join } from 'path'; dotenv.config({ path: join(__dirname, `../.env.${process.env.NODE_ENV}`) }); @@ -18,7 +19,7 @@ const addressesRepo = dataSource.getRepository(AddressesEntity); const usersRepo = dataSource.getRepository(UsersEntity); router.post('/login', async (req: Request, res: Response) => { - const { signature, walletAddress, challengeMessage } = req.body; + const { signature, walletAddress, message } = req.body; if (!isAddress(walletAddress)) { res.status(403).json({ error: 'Invalid wallet address' }); @@ -26,13 +27,13 @@ router.post('/login', async (req: Request, res: Response) => { } try { - const valid_address = await verifyMessage({ - signature, + const valid = await publicClient.verifySiweMessage({ address: walletAddress, - message: challengeMessage, + message, + signature, }); - if (!valid_address) { + if (!valid) { res.status(403).json({ error: 'Invalid signature' }); return; } @@ -77,20 +78,23 @@ router.post('/login', async (req: Request, res: Response) => { router.post('/wallet-address', async (req, res) => { try { - const { walletAddress } = req.body; - const nonce = uuidv4(); - const timestamp = new Date().toISOString(); - const challengeMessage = ` - Challenge: ${process.env.CHALLENGE_SECRET}, - Wallet Address: ${walletAddress}, - Nonce: ${nonce}, - Timestamp: ${timestamp} - ` - .replace(/\\s+/g, ' ') - .trim(); - res.status(200).json({ nonce, challengeMessage }); + const { walletAddress, chainId, domain } = req.body; + const nonce = generateSiweNonce(); + const timestamp = new Date(); + + const message = createSiweMessage({ + address: walletAddress, + chainId, + domain, + nonce, + uri: `https://${domain}`, // TODO: Change for production + version: '1', + issuedAt: timestamp, + }); + + res.status(200).json({ nonce, message }); } catch (err) { - throwInternalError(res, 'Error generating challenge message: ', err); + throwInternalError(res, 'Error generating login message: ', err); } }); diff --git a/apps/extension/src/application/trading-copilot/commands/constants.ts b/apps/extension/src/application/trading-copilot/commands/constants.ts index a51ecdec..8c16e5e5 100644 --- a/apps/extension/src/application/trading-copilot/commands/constants.ts +++ b/apps/extension/src/application/trading-copilot/commands/constants.ts @@ -1,2 +1,3 @@ export const COPILOT_API_URL = 'https://copilot-production-e887.up.railway.app'; export const QUOTE_API_URL = 'https://idriss-lifi.vercel.app/api/get-quote'; +export const AUTH_API_URL = 'http://localhost:8080/auth'; diff --git a/apps/extension/src/application/trading-copilot/commands/get-siwe-message.ts b/apps/extension/src/application/trading-copilot/commands/get-siwe-message.ts new file mode 100644 index 00000000..ed55465c --- /dev/null +++ b/apps/extension/src/application/trading-copilot/commands/get-siwe-message.ts @@ -0,0 +1,54 @@ +import { + Command, + FailureResult, + HandlerError, + HandlerResponseError, + OkResult, +} from 'shared/messaging'; + +import { + SiweMessageRequest as Payload, + SiweMessageResponse as Response, +} from '../types'; + +import { AUTH_API_URL } from './constants'; + +export class GetSiweMessageCommand extends Command { + public readonly name = 'GetSiweMessageCommand' as const; + + constructor(public payload: Payload) { + super(); + } + + async handle() { + try { + const response = await fetch(`${AUTH_API_URL}/wallet-address`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(this.payload), + }); + + if (!response.ok) { + const responseText = await response.text(); + throw new HandlerResponseError( + this.name, + responseText, + response.status, + ); + } + + const json = (await response.json()) as Response; + + return new OkResult(json); + } catch (error) { + this.captureException(error); + if (error instanceof HandlerError) { + return new FailureResult(error.message); + } + + return new FailureResult(); + } + } +} diff --git a/apps/extension/src/application/trading-copilot/commands/index.ts b/apps/extension/src/application/trading-copilot/commands/index.ts index 76624589..78223b09 100644 --- a/apps/extension/src/application/trading-copilot/commands/index.ts +++ b/apps/extension/src/application/trading-copilot/commands/index.ts @@ -8,6 +8,8 @@ import { GetFarcasterAddressCommand } from './get-farcaster-address'; import { GetFarcasterUserCommand } from './get-farcaster-user'; import { GetQuoteCommand } from './get-quote'; import { GetEnsBalanceCommand } from './get-ens-balance'; +import { GetSiweMessageCommand } from './get-siwe-message'; +import { VerifySiweSignatureCommand } from './verify-siwe-signature'; export const COMMAND_MAP = { [AddTradingCopilotSubscriptionCommand.name]: @@ -23,6 +25,8 @@ export const COMMAND_MAP = { [GetEnsAddressCommand.name]: GetEnsAddressCommand, [GetQuoteCommand.name]: GetQuoteCommand, [GetEnsBalanceCommand.name]: GetEnsBalanceCommand, + [GetSiweMessageCommand.name]: GetSiweMessageCommand, + [VerifySiweSignatureCommand.name]: VerifySiweSignatureCommand, }; export { AddTradingCopilotSubscriptionCommand } from './add-trading-copilot-subscription'; @@ -33,5 +37,7 @@ export { GetEnsNameCommand } from './get-ens-name'; export { GetEnsAddressCommand } from './get-ens-address'; export { GetFarcasterAddressCommand } from './get-farcaster-address'; export { GetFarcasterUserCommand } from './get-farcaster-user'; +export { GetSiweMessageCommand } from './get-siwe-message'; +export { VerifySiweSignatureCommand } from './verify-siwe-signature'; export { GetEnsBalanceCommand } from './get-ens-balance'; export { GetQuoteCommand } from './get-quote'; diff --git a/apps/extension/src/application/trading-copilot/commands/verify-siwe-signature.ts b/apps/extension/src/application/trading-copilot/commands/verify-siwe-signature.ts new file mode 100644 index 00000000..bfe6f43e --- /dev/null +++ b/apps/extension/src/application/trading-copilot/commands/verify-siwe-signature.ts @@ -0,0 +1,54 @@ +import { + Command, + FailureResult, + HandlerError, + HandlerResponseError, + OkResult, +} from 'shared/messaging'; + +import { + VerifySiweSignatureRequest as Payload, + VerifySiweSignatureResponse as Response, +} from '../types'; + +import { AUTH_API_URL } from './constants'; + +export class VerifySiweSignatureCommand extends Command { + public readonly name = 'VerifySiweSignatureCommand' as const; + + constructor(public payload: Payload) { + super(); + } + + async handle() { + try { + const response = await fetch(`${AUTH_API_URL}/login`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(this.payload), + }); + + if (!response.ok) { + const responseText = await response.text(); + throw new HandlerResponseError( + this.name, + responseText, + response.status, + ); + } + + const json = (await response.json()) as Response; + + return new OkResult(json); + } catch (error) { + this.captureException(error); + if (error instanceof HandlerError) { + return new FailureResult(error.message); + } + + return new FailureResult(); + } + } +} diff --git a/apps/extension/src/application/trading-copilot/hooks/index.ts b/apps/extension/src/application/trading-copilot/hooks/index.ts index 976a462f..4d2277c3 100644 --- a/apps/extension/src/application/trading-copilot/hooks/index.ts +++ b/apps/extension/src/application/trading-copilot/hooks/index.ts @@ -1 +1,2 @@ +export { useLoginViaSiwe } from './use-login-via-siwe'; export { useExchanger } from './use-exchanger'; diff --git a/apps/extension/src/application/trading-copilot/hooks/use-login-via-siwe.ts b/apps/extension/src/application/trading-copilot/hooks/use-login-via-siwe.ts new file mode 100644 index 00000000..c8f8842c --- /dev/null +++ b/apps/extension/src/application/trading-copilot/hooks/use-login-via-siwe.ts @@ -0,0 +1,84 @@ +import { useCallback } from 'react'; + +import { + GetSiweMessageCommand, + VerifySiweSignatureCommand, + VerifySiweSignatureRequest, +} from 'application/trading-copilot'; +import { useCommandMutation } from 'shared/messaging'; +import { SiweMessageRequest } from 'application/trading-copilot/types'; +import { createWalletClient, Wallet } from 'shared/web3'; + +export const useLoginViaSiwe = () => { + const getSiweMessage = useCommandMutation(GetSiweMessageCommand); + const verifySiweSignature = useCommandMutation(VerifySiweSignatureCommand); + + const login = useCallback( + async (wallet: Wallet) => { + if (!wallet) { + return; + } + + const handleGetSiweMessage = async (payload: SiweMessageRequest) => { + return await getSiweMessage.mutateAsync(payload); + }; + + const handleVerifySiweSignature = async ( + payload: VerifySiweSignatureRequest, + ) => { + return await verifySiweSignature.mutateAsync(payload); + }; + + const walletClient = createWalletClient(wallet); + + const siweMessage = await handleGetSiweMessage({ + walletAddress: wallet.account, + chainId: wallet.chainId, + domain: window.location.hostname, + }); + + const siweSignature = await walletClient.signMessage({ + account: wallet.account, + message: siweMessage.message, + }); + + const verifiedSiweSignature = await handleVerifySiweSignature({ + walletAddress: wallet.account, + message: siweMessage.message, + signature: siweSignature, + }); + + localStorage.setItem('authToken', verifiedSiweSignature.token); + }, + [getSiweMessage, verifySiweSignature], + ); + + const loggedIn = useCallback(() => { + const authToken = localStorage.getItem('authToken'); + + return !!authToken; + }, []); + + const isSending = getSiweMessage.isPending || verifySiweSignature.isPending; + + const isError = getSiweMessage.isError || verifySiweSignature.isError; + + const isSuccess = getSiweMessage.isSuccess && verifySiweSignature.isSuccess; + + const isIdle = !isSending && !isError && !isSuccess; + + const reset = useCallback(() => { + getSiweMessage.reset(); + verifySiweSignature.reset(); + }, [getSiweMessage, verifySiweSignature]); + + return { + login, + loggedIn, + isSending, + isError, + isSuccess, + isIdle, + reset, + }; +}; diff --git a/apps/extension/src/application/trading-copilot/index.ts b/apps/extension/src/application/trading-copilot/index.ts index 8fd0443f..70efa740 100644 --- a/apps/extension/src/application/trading-copilot/index.ts +++ b/apps/extension/src/application/trading-copilot/index.ts @@ -2,12 +2,19 @@ export { COMMAND_MAP as TRADING_COPILOT_COMMAND_MAP, GetEnsInfoCommand, GetEnsNameCommand, - GetEnsBalanceCommand, GetQuoteCommand, + GetEnsBalanceCommand, + GetSiweMessageCommand, + VerifySiweSignatureCommand, AddTradingCopilotSubscriptionCommand, GetTradingCopilotSubscriptionsCommand, RemoveTradingCopilotSubscriptionCommand, } from './commands'; -export type { SwapData, FormValues, SubscriptionRequest } from './types'; +export type { + SwapData, + FormValues, + SubscriptionRequest, + VerifySiweSignatureRequest, +} from './types'; export { SubscriptionsManagement } from './subscriptions-management'; -export { useExchanger } from './hooks'; +export { useExchanger, useLoginViaSiwe } from './hooks'; diff --git a/apps/extension/src/application/trading-copilot/subscriptions-management/components/subscription-form.tsx b/apps/extension/src/application/trading-copilot/subscriptions-management/components/subscription-form.tsx index 113c3c68..5dd0f589 100644 --- a/apps/extension/src/application/trading-copilot/subscriptions-management/components/subscription-form.tsx +++ b/apps/extension/src/application/trading-copilot/subscriptions-management/components/subscription-form.tsx @@ -1,7 +1,9 @@ import { useCallback } from 'react'; import { Controller, SubmitHandler, useForm } from 'react-hook-form'; +import { useWallet } from '@idriss-xyz/wallet-connect'; import { useCommandMutation } from 'shared/messaging'; +import { useLoginViaSiwe } from 'application/trading-copilot'; import { ErrorMessage } from 'shared/ui'; import { LsFarcasterUsersDetails } from 'application/trading-copilot/types'; @@ -21,6 +23,9 @@ export const SubscriptionForm = ({ onSubmit, subscriptionsAmount, }: Properties) => { + const { wallet } = useWallet(); + const siwe = useLoginViaSiwe(); + const form = useForm({ defaultValues: EMPTY_FORM, }); @@ -41,6 +46,15 @@ export const SubscriptionForm = ({ const farcasterPattern = /^[^.]+$/; const isWalletAddress = hexPattern.test(data.subscriptionDetails); const isFarcasterName = farcasterPattern.test(data.subscriptionDetails); + const siweLoggedIn = siwe.loggedIn(); + + if (!wallet) { + return; + } + + if (!siweLoggedIn) { + await siwe.login(wallet); + } if (isWalletAddress) { onSubmit(data.subscriptionDetails); @@ -104,6 +118,8 @@ export const SubscriptionForm = ({ getFarcasterAddressMutation, getFarcasterUserMutation, onSubmit, + siwe, + wallet, ], ); diff --git a/apps/extension/src/application/trading-copilot/subscriptions-management/components/subscriptions-list/subscription-item.tsx b/apps/extension/src/application/trading-copilot/subscriptions-management/components/subscriptions-list/subscription-item.tsx index 5a41e3dd..3d30eeda 100644 --- a/apps/extension/src/application/trading-copilot/subscriptions-management/components/subscriptions-list/subscription-item.tsx +++ b/apps/extension/src/application/trading-copilot/subscriptions-management/components/subscriptions-list/subscription-item.tsx @@ -2,11 +2,13 @@ import { useCallback } from 'react'; import { ExternalLink } from '@idriss-xyz/ui/external-link'; import { Icon as IdrissIcon } from '@idriss-xyz/ui/icon'; import { IconButton } from '@idriss-xyz/ui/icon-button'; +import { useWallet } from '@idriss-xyz/wallet-connect'; import { useCommandQuery } from 'shared/messaging'; import { Icon, LazyImage, getGithubUserLink } from 'shared/ui'; import { getTwitterUserLink } from 'host/twitter'; import { GetEnsNameCommand } from 'application/trading-copilot/commands/get-ens-name'; +import { useLoginViaSiwe } from 'application/trading-copilot'; import { LsFarcasterUsersDetails } from 'application/trading-copilot/types'; import { GetEnsInfoCommand } from '../../../commands'; @@ -62,9 +64,22 @@ const SubscriptionItemContent = ({ isFarcasterSubscription, farcasterSubscriptionDetails, }: ItemContentProperties) => { - const remove = useCallback(() => { + const { wallet } = useWallet(); + const siwe = useLoginViaSiwe(); + + const remove = useCallback(async () => { + const siweLoggedIn = siwe.loggedIn(); + + if (!wallet) { + return; + } + + if (!siweLoggedIn) { + await siwe.login(wallet); + } + onRemove(subscription); - }, [onRemove, subscription]); + }, [onRemove, siwe, subscription, wallet]); const emailQuery = useCommandQuery({ command: new GetEnsInfoCommand({ diff --git a/apps/extension/src/application/trading-copilot/types.ts b/apps/extension/src/application/trading-copilot/types.ts index 29dafea6..eaa91cff 100644 --- a/apps/extension/src/application/trading-copilot/types.ts +++ b/apps/extension/src/application/trading-copilot/types.ts @@ -203,3 +203,24 @@ type Options = { export interface FormValues { amount: string; } + +export type SiweMessageRequest = { + walletAddress: Hex; + chainId: number; + domain: string; +}; + +export type SiweMessageResponse = { + nonce: string; + message: string; +}; + +export type VerifySiweSignatureRequest = { + walletAddress: Hex; + message: string; + signature: Hex; +}; + +export type VerifySiweSignatureResponse = { + token: string; +}; diff --git a/apps/extension/src/final/notifications-popup/components/trading-copilot-dialog/trading-copilot-dialog.tsx b/apps/extension/src/final/notifications-popup/components/trading-copilot-dialog/trading-copilot-dialog.tsx index d5f2d700..4166036d 100644 --- a/apps/extension/src/final/notifications-popup/components/trading-copilot-dialog/trading-copilot-dialog.tsx +++ b/apps/extension/src/final/notifications-popup/components/trading-copilot-dialog/trading-copilot-dialog.tsx @@ -16,6 +16,7 @@ import { GetEnsNameCommand, GetQuoteCommand, useExchanger, + useLoginViaSiwe, } from 'application/trading-copilot'; import { TimeDifferenceCounter } from 'shared/utils'; import { CHAIN, roundToSignificantFigures } from 'shared/web3'; @@ -69,6 +70,7 @@ const TradingCopilotDialogContent = ({ }: ContentProperties) => { const { wallet, isConnectionModalOpened, openConnectionModal } = useWallet(); const exchanger = useExchanger({ wallet }); + const siwe = useLoginViaSiwe(); const avatarQuery = useCommandQuery({ command: new GetEnsInfoCommand({ @@ -92,12 +94,22 @@ const TradingCopilotDialogContent = ({ const onSubmit = useCallback( async (formValues: FormValues) => { + const siweLoggedIn = siwe.loggedIn(); + + if (!wallet) { + return; + } + + if (!siweLoggedIn) { + await siwe.login(wallet); + } + await exchanger.exchange({ formValues: formValues, dialog: dialog, }); }, - [dialog, exchanger], + [dialog, exchanger, siwe, wallet], ); if (exchanger.isSending && exchanger.quoteData?.includedSteps[0]) { @@ -219,12 +231,15 @@ const TradingCopilotDialogContent = ({ size="medium" className="w-full" type="submit" - loading={exchanger.isSending} - disabled={Number(watch('amount')) < Number(balanceQuery.data)} + loading={siwe.isSending || exchanger.isSending} + disabled={ + Number(watch('amount')) < Number(balanceQuery.data) || + Number(watch('amount')) <= 0 + } > BUY {dialog.tokenIn.symbol} - {exchanger.isError ? ( + {siwe.isError || exchanger.isError ? ( Something went wrong. diff --git a/apps/extension/src/final/notifications-popup/components/trading-copilot-toast/trading-copilot-toast.tsx b/apps/extension/src/final/notifications-popup/components/trading-copilot-toast/trading-copilot-toast.tsx index 5cc99a2f..b956c00e 100644 --- a/apps/extension/src/final/notifications-popup/components/trading-copilot-toast/trading-copilot-toast.tsx +++ b/apps/extension/src/final/notifications-popup/components/trading-copilot-toast/trading-copilot-toast.tsx @@ -45,8 +45,6 @@ const TradingCopilotToastContent = ({ staleTime: Number.POSITIVE_INFINITY, }); - console.log(toast); - return (
=21.1.0} peerDependencies: '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 @@ -3670,8 +3670,8 @@ packages: typescript: optional: true - '@typescript-eslint/parser@8.19.0': - resolution: {integrity: sha512-6M8taKyOETY1TKHp0x8ndycipTVgmp4xtg5QpEZzXxDhNvvHOJi5rLRkLr8SK3jTgD5l4fTlvBiRdfsuWydxBw==} + '@typescript-eslint/parser@8.19.1': + resolution: {integrity: sha512-67gbfv8rAwawjYx3fYArwldTQKoYfezNUT4D5ioWetr/xCrxXxvleo3uuiFuKfejipvq+og7mjz3b0G2bVyUCw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3685,8 +3685,8 @@ packages: resolution: {integrity: sha512-Uholz7tWhXmA4r6epo+vaeV7yjdKy5QFCERMjs1kMVsLRKIrSdM6o21W2He9ftp5PP6aWOVpD5zvrvuHZC0bMQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.19.0': - resolution: {integrity: sha512-hkoJiKQS3GQ13TSMEiuNmSCvhz7ujyqD1x3ShbaETATHrck+9RaDdUbt+osXaUuns9OFwrDTTrjtwsU8gJyyRA==} + '@typescript-eslint/scope-manager@8.19.1': + resolution: {integrity: sha512-60L9KIuN/xgmsINzonOcMDSB8p82h95hoBfSBtXuO4jlR1R9L1xSkmVZKgCPVfavDlXihh4ARNjXhh1gGnLC7Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/type-utils@8.11.0': @@ -3698,8 +3698,8 @@ packages: typescript: optional: true - '@typescript-eslint/type-utils@8.19.0': - resolution: {integrity: sha512-TZs0I0OSbd5Aza4qAMpp1cdCYVnER94IziudE3JU328YUHgWu9gwiwhag+fuLeJ2LkWLXI+F/182TbG+JaBdTg==} + '@typescript-eslint/type-utils@8.19.1': + resolution: {integrity: sha512-Rp7k9lhDKBMRJB/nM9Ksp1zs4796wVNyihG9/TU9R6KCJDNkQbc2EOKjrBtLYh3396ZdpXLtr/MkaSEmNMtykw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3713,8 +3713,8 @@ packages: resolution: {integrity: sha512-tn6sNMHf6EBAYMvmPUaKaVeYvhUsrE6x+bXQTxjQRp360h1giATU0WvgeEys1spbvb5R+VpNOZ+XJmjD8wOUHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.19.0': - resolution: {integrity: sha512-8XQ4Ss7G9WX8oaYvD4OOLCjIQYgRQxO+qCiR2V2s2GxI9AUpo7riNwo6jDhKtTcaJjT8PY54j2Yb33kWtSJsmA==} + '@typescript-eslint/types@8.19.1': + resolution: {integrity: sha512-JBVHMLj7B1K1v1051ZaMMgLW4Q/jre5qGK0Ew6UgXz1Rqh+/xPzV1aW581OM00X6iOfyr1be+QyW8LOUf19BbA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@5.62.0': @@ -3735,8 +3735,8 @@ packages: typescript: optional: true - '@typescript-eslint/typescript-estree@8.19.0': - resolution: {integrity: sha512-WW9PpDaLIFW9LCbucMSdYUuGeFUz1OkWYS/5fwZwTA+l2RwlWFdJvReQqMUMBw4yJWJOfqd7An9uwut2Oj8sLw==} + '@typescript-eslint/typescript-estree@8.19.1': + resolution: {integrity: sha512-jk/TZwSMJlxlNnqhy0Eod1PNEvCkpY6MXOXE/WLlblZ6ibb32i2We4uByoKPv1d0OD2xebDv4hbs3fm11SMw8Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.8.0' @@ -3753,8 +3753,8 @@ packages: peerDependencies: eslint: ^8.57.0 || ^9.0.0 - '@typescript-eslint/utils@8.19.0': - resolution: {integrity: sha512-PTBG+0oEMPH9jCZlfg07LCB2nYI0I317yyvXGfxnvGvw4SHIOuRnQ3kadyyXY6tGdChusIHIbM5zfIbp4M6tCg==} + '@typescript-eslint/utils@8.19.1': + resolution: {integrity: sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3768,8 +3768,8 @@ packages: resolution: {integrity: sha512-EaewX6lxSjRJnc+99+dqzTeoDZUfyrA52d2/HRrkI830kgovWsmIiTfmr0NZorzqic7ga+1bS60lRBUgR3n/Bw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.19.0': - resolution: {integrity: sha512-mCFtBbFBJDCNCWUl5y6sZSCHXw1DEFEk3c/M3nRK2a4XUB8StGFtmcEMizdjKuBzB6e/smJAAWYug3VrdLMr1w==} + '@typescript-eslint/visitor-keys@8.19.1': + resolution: {integrity: sha512-fzmjU8CHK853V/avYZAvuVut3ZTfwN5YtMaoi+X9Y9MA9keaWNHC3zEQ9zvyX/7Hj+5JkNyK1l7TOR2hevHB6Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.2.0': @@ -5990,10 +5990,6 @@ packages: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} - globals@15.11.0: - resolution: {integrity: sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==} - engines: {node: '>=18'} - globals@15.14.0: resolution: {integrity: sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==} engines: {node: '>=18'} @@ -6737,14 +6733,14 @@ packages: jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - jsonwebtoken@9.0.2: - resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} - engines: {node: '>=12', npm: '>=6'} - jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} + jsonwebtoken@9.0.2: + resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} + engines: {node: '>=12', npm: '>=6'} + jsprim@1.4.2: resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} engines: {node: '>=0.6.0'} @@ -9115,6 +9111,12 @@ packages: peerDependencies: typescript: '>=4.2.0' + ts-api-utils@2.0.0: + resolution: {integrity: sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + ts-custom-error@3.3.1: resolution: {integrity: sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==} engines: {node: '>=14.0.0'} @@ -9337,8 +9339,8 @@ packages: typeorm-aurora-data-api-driver: optional: true - typescript-eslint@8.19.0: - resolution: {integrity: sha512-Ni8sUkVWYK4KAcTtPjQ/UTiRk6jcsuDhPpxULapUDi8A/l8TSBk+t1GtJA1RsCzIJg0q6+J7bf35AwQigENWRQ==} + typescript-eslint@8.19.1: + resolution: {integrity: sha512-LKPUQpdEMVOeKluHi8md7rwLcoXHhwvWp3x+sJkMuq3gGm9yaYJtPo8sRZSblMFJ5pcOGCAak/scKf1mvZDlQw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -13025,8 +13027,6 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} - '@sqltools/formatter@1.2.5': {} - '@solana/buffer-layout@4.0.1': dependencies: buffer: 6.0.3 @@ -13066,6 +13066,8 @@ snapshots: - encoding - utf-8-validate + '@sqltools/formatter@1.2.5': {} + '@stablelib/aead@1.0.1': {} '@stablelib/binary@1.0.1': @@ -13852,19 +13854,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/eslint-plugin@8.19.0(@typescript-eslint/parser@8.19.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/eslint-plugin@8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3)': dependencies: '@eslint-community/regexpp': 4.11.1 - '@typescript-eslint/parser': 8.19.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/scope-manager': 8.19.0 - '@typescript-eslint/type-utils': 8.19.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/utils': 8.19.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.19.0 + '@typescript-eslint/parser': 8.19.1(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.19.1 + '@typescript-eslint/type-utils': 8.19.1(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/utils': 8.19.1(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.19.1 eslint: 8.57.1 graphemer: 1.4.0 ignore: 5.3.2 natural-compare: 1.4.0 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 2.0.0(typescript@5.6.3) typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -13882,12 +13884,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.19.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.6.3)': dependencies: - '@typescript-eslint/scope-manager': 8.19.0 - '@typescript-eslint/types': 8.19.0 - '@typescript-eslint/typescript-estree': 8.19.0(typescript@5.6.3) - '@typescript-eslint/visitor-keys': 8.19.0 + '@typescript-eslint/scope-manager': 8.19.1 + '@typescript-eslint/types': 8.19.1 + '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.19.1 debug: 4.3.7 eslint: 8.57.1 typescript: 5.6.3 @@ -13904,10 +13906,10 @@ snapshots: '@typescript-eslint/types': 8.11.0 '@typescript-eslint/visitor-keys': 8.11.0 - '@typescript-eslint/scope-manager@8.19.0': + '@typescript-eslint/scope-manager@8.19.1': dependencies: - '@typescript-eslint/types': 8.19.0 - '@typescript-eslint/visitor-keys': 8.19.0 + '@typescript-eslint/types': 8.19.1 + '@typescript-eslint/visitor-keys': 8.19.1 '@typescript-eslint/type-utils@8.11.0(eslint@8.57.1)(typescript@5.6.3)': dependencies: @@ -13921,13 +13923,13 @@ snapshots: - eslint - supports-color - '@typescript-eslint/type-utils@8.19.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/type-utils@8.19.1(eslint@8.57.1)(typescript@5.6.3)': dependencies: - '@typescript-eslint/typescript-estree': 8.19.0(typescript@5.6.3) - '@typescript-eslint/utils': 8.19.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.6.3) + '@typescript-eslint/utils': 8.19.1(eslint@8.57.1)(typescript@5.6.3) debug: 4.3.7 eslint: 8.57.1 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 2.0.0(typescript@5.6.3) typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -13936,7 +13938,7 @@ snapshots: '@typescript-eslint/types@8.11.0': {} - '@typescript-eslint/types@8.19.0': {} + '@typescript-eslint/types@8.19.1': {} '@typescript-eslint/typescript-estree@5.62.0(typescript@5.6.3)': dependencies: @@ -13967,16 +13969,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/typescript-estree@8.19.0(typescript@5.6.3)': + '@typescript-eslint/typescript-estree@8.19.1(typescript@5.6.3)': dependencies: - '@typescript-eslint/types': 8.19.0 - '@typescript-eslint/visitor-keys': 8.19.0 + '@typescript-eslint/types': 8.19.1 + '@typescript-eslint/visitor-keys': 8.19.1 debug: 4.3.7 fast-glob: 3.3.2 is-glob: 4.0.3 minimatch: 9.0.5 semver: 7.6.3 - ts-api-utils: 1.3.0(typescript@5.6.3) + ts-api-utils: 2.0.0(typescript@5.6.3) typescript: 5.6.3 transitivePeerDependencies: - supports-color @@ -14007,12 +14009,12 @@ snapshots: - supports-color - typescript - '@typescript-eslint/utils@8.19.0(eslint@8.57.1)(typescript@5.6.3)': + '@typescript-eslint/utils@8.19.1(eslint@8.57.1)(typescript@5.6.3)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) - '@typescript-eslint/scope-manager': 8.19.0 - '@typescript-eslint/types': 8.19.0 - '@typescript-eslint/typescript-estree': 8.19.0(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.19.1 + '@typescript-eslint/types': 8.19.1 + '@typescript-eslint/typescript-estree': 8.19.1(typescript@5.6.3) eslint: 8.57.1 typescript: 5.6.3 transitivePeerDependencies: @@ -14028,9 +14030,9 @@ snapshots: '@typescript-eslint/types': 8.11.0 eslint-visitor-keys: 3.4.3 - '@typescript-eslint/visitor-keys@8.19.0': + '@typescript-eslint/visitor-keys@8.19.1': dependencies: - '@typescript-eslint/types': 8.19.0 + '@typescript-eslint/types': 8.19.1 eslint-visitor-keys: 4.2.0 '@ungap/structured-clone@1.2.0': {} @@ -16236,7 +16238,7 @@ snapshots: is-bun-module: 1.2.1 is-glob: 4.0.3 optionalDependencies: - eslint-plugin-import: 2.31.0(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(eslint-import-resolver-typescript@3.6.3(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - '@typescript-eslint/parser' - eslint-import-resolver-node @@ -16315,7 +16317,7 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-plugin-import@2.31.0(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1): + eslint-plugin-import@2.31.0(eslint-import-resolver-typescript@3.6.3(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.8 @@ -16432,7 +16434,7 @@ snapshots: core-js-compat: 3.38.1 eslint: 8.57.1 esquery: 1.6.0 - globals: 15.11.0 + globals: 15.14.0 indent-string: 4.0.0 is-builtin-module: 3.2.1 jsesc: 3.0.2 @@ -17089,8 +17091,6 @@ snapshots: dependencies: type-fest: 0.20.2 - globals@15.11.0: {} - globals@15.14.0: {} globalthis@1.0.4: @@ -17408,7 +17408,7 @@ snapshots: eslint: 8.57.1 eslint-config-prettier: 9.1.0(eslint@8.57.1) eslint-import-resolver-typescript: 3.6.3(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1) - eslint-plugin-import: 2.31.0(eslint-import-resolver-typescript@3.6.3)(eslint@8.57.1) + eslint-plugin-import: 2.31.0(eslint-import-resolver-typescript@3.6.3(eslint-plugin-import@2.31.0(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-prettier: 5.2.1(eslint-config-prettier@9.1.0(eslint@8.57.1))(eslint@8.57.1)(prettier@3.3.3) ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) node-fetch: 2.7.0 @@ -17899,6 +17899,8 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonparse@1.3.1: {} + jsonwebtoken@9.0.2: dependencies: jws: 3.2.2 @@ -17912,8 +17914,6 @@ snapshots: ms: 2.1.3 semver: 7.6.3 - jsonparse@1.3.1: {} - jsprim@1.4.2: dependencies: assert-plus: 1.0.0 @@ -20550,6 +20550,10 @@ snapshots: dependencies: typescript: 5.6.3 + ts-api-utils@2.0.0(typescript@5.6.3): + dependencies: + typescript: 5.6.3 + ts-custom-error@3.3.1: {} ts-dedent@2.2.0: {} @@ -20733,11 +20737,11 @@ snapshots: transitivePeerDependencies: - supports-color - typescript-eslint@8.19.0(eslint@8.57.1)(typescript@5.6.3): + typescript-eslint@8.19.1(eslint@8.57.1)(typescript@5.6.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.19.0(@typescript-eslint/parser@8.19.0(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/parser': 8.19.0(eslint@8.57.1)(typescript@5.6.3) - '@typescript-eslint/utils': 8.19.0(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/eslint-plugin': 8.19.1(@typescript-eslint/parser@8.19.1(eslint@8.57.1)(typescript@5.6.3))(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/parser': 8.19.1(eslint@8.57.1)(typescript@5.6.3) + '@typescript-eslint/utils': 8.19.1(eslint@8.57.1)(typescript@5.6.3) eslint: 8.57.1 typescript: 5.6.3 transitivePeerDependencies: @@ -20913,12 +20917,12 @@ snapshots: uuid@9.0.1: {} + v8-compile-cache-lib@3.0.1: {} + valibot@0.38.0(typescript@5.6.3): optionalDependencies: typescript: 5.6.3 - v8-compile-cache-lib@3.0.1: {} - validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0