diff --git a/biome.json b/biome.json index 9993a1f..12bca48 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.2.0/schema.json", + "$schema": "https://biomejs.dev/schemas/2.2.2/schema.json", "formatter": { "enabled": true, "formatWithErrors": false, diff --git a/packages/block-sync-monitor/package.json b/packages/block-sync-monitor/package.json index c12f7ae..e097379 100644 --- a/packages/block-sync-monitor/package.json +++ b/packages/block-sync-monitor/package.json @@ -4,7 +4,7 @@ "dependencies": { "@intmax2-function/shared": "workspace:*", "axios": "^1.11.0", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/bridge-monitor/src/constants.ts b/packages/bridge-monitor/src/constants.ts index 6d050f5..f5e0bf6 100644 --- a/packages/bridge-monitor/src/constants.ts +++ b/packages/bridge-monitor/src/constants.ts @@ -2,3 +2,6 @@ export const LAYER_ZERO_SCAN_API = { ["mainnet"]: "https://scan.layerzero-api.com/v1", ["testnet"]: "https://scan-testnet.layerzero-api.com/v1", } as const; + +export const MAX_RETRIES = 3; +export const RETRY_DELAY_MS = 10000; diff --git a/packages/bridge-monitor/src/lib/layerzero.ts b/packages/bridge-monitor/src/lib/layerzero.ts new file mode 100644 index 0000000..7ff6031 --- /dev/null +++ b/packages/bridge-monitor/src/lib/layerzero.ts @@ -0,0 +1,63 @@ +import { API_TIMEOUT, config, logger, sleep } from "@intmax2-function/shared"; +import axios, { AxiosError } from "axios"; +import { LAYER_ZERO_SCAN_API, MAX_RETRIES, RETRY_DELAY_MS } from "../constants"; +import type { BridgeGuidTransaction, BridgeGuidTransactionResponse } from "../types"; + +export const fetchBridgeGuidTransaction = async ( + guid: string, + maxRetries: number = MAX_RETRIES, + retryDelayMs: number = RETRY_DELAY_MS, +) => { + const layerZeroMessagesUrl = `${LAYER_ZERO_SCAN_API[config.LAYER_ZERO_NETWORK]}/messages/guid/${guid}`; + + let lastError: Error | null = null; + + for (let attempt = 1; attempt <= maxRetries; attempt++) { + try { + const response = await axios.get(layerZeroMessagesUrl, { + timeout: API_TIMEOUT, + headers: { + Accept: "application/json", + }, + }); + + if (response.data?.data === undefined) { + throw new Error("Data is missing in the response"); + } + + const transactions = response.data.data as BridgeGuidTransaction[]; + if (transactions.length === 0) { + throw new Error("No transactions found"); + } + + return transactions[0]; + } catch (error) { + lastError = error instanceof Error ? error : new Error(String(error)); + + logger.warn( + `Failed to fetch bridge transaction (attempt ${attempt}/${maxRetries}): ${lastError.message}`, + ); + + if (attempt === maxRetries) { + break; + } + + logger.info(`Waiting ${retryDelayMs}ms before retry...`); + await sleep(retryDelayMs); + } + } + + logger.error( + `Failed to fetch bridge transaction after ${maxRetries} attempts: ${layerZeroMessagesUrl}`, + ); + + if (lastError instanceof AxiosError) { + throw new Error( + `Failed to fetch status after ${maxRetries} attempts: ${lastError.response?.status}`, + ); + } + + throw new Error( + `Unexpected error while fetching bridge transaction status after ${maxRetries} attempts: ${lastError?.message}`, + ); +}; diff --git a/packages/bridge-monitor/src/service/job.service.ts b/packages/bridge-monitor/src/service/job.service.ts index 42ac51c..b390813 100644 --- a/packages/bridge-monitor/src/service/job.service.ts +++ b/packages/bridge-monitor/src/service/job.service.ts @@ -2,11 +2,13 @@ import { BridgeTransaction, type BridgeTransactionData, BridgeTransactionStatus, + logger, } from "@intmax2-function/shared"; +import { fetchBridgeGuidTransaction } from "../lib/layerzero"; +import type { UpdateParams } from "../types"; import { - fetchBridgeGuidTransaction, handleFailedStatus, - handleInflightOrConfirming, + handleInflightOrConfirmingStatus, handlePayloadStored, handleVerifiedStatus, } from "./process.service"; @@ -20,7 +22,7 @@ export const performJob = async () => { BridgeTransactionStatus.VERIFIED, BridgeTransactionStatus.BLOCKED, ], - alertSent: false, + // alertSent: not true(include undefined) }); const sortedTransactions = bridgeTransactions.sort((a, b) => a.nonce - b.nonce); @@ -31,30 +33,68 @@ export const performJob = async () => { }; const processBridgeTransaction = async (bridgeTransaction: BridgeTransactionData) => { - // TODO: sleep and retry - const bridgeGuidTransaction = await fetchBridgeGuidTransaction(bridgeTransaction.guid); - const statusName = bridgeGuidTransaction.status.name; - - switch (statusName) { - case BridgeTransactionStatus.FAILED: - await handleFailedStatus(bridgeGuidTransaction); - break; - - case BridgeTransactionStatus.INFLIGHT: - case BridgeTransactionStatus.CONFIRMING: - await handleInflightOrConfirming(bridgeTransaction); - break; - - case BridgeTransactionStatus.VERIFIED: - await handleVerifiedStatus(bridgeTransaction); - break; - - case BridgeTransactionStatus.PAYLOAD_STORED: - await handlePayloadStored(bridgeGuidTransaction); - break; - } + try { + const bridgeGuidTransaction = await fetchBridgeGuidTransaction(bridgeTransaction.guid); + const statusName = bridgeGuidTransaction.status.name as BridgeTransactionStatus; - await BridgeTransaction.getInstance().updateBridgeTransaction(bridgeTransaction.guid, { - status: statusName as BridgeTransactionStatus, - }); + let updateParams: UpdateParams = { + status: statusName, + }; + + switch (statusName) { + case BridgeTransactionStatus.FAILED: { + const result = await handleFailedStatus({ bridgeTransaction, bridgeGuidTransaction }); + updateParams = { ...updateParams, ...result }; + break; + } + case BridgeTransactionStatus.INFLIGHT: + case BridgeTransactionStatus.CONFIRMING: { + const result = await handleInflightOrConfirmingStatus(bridgeTransaction); + if (result) { + updateParams = { ...updateParams, ...result }; + } + break; + } + case BridgeTransactionStatus.VERIFIED: { + const result = await handleVerifiedStatus({ + bridgeTransaction, + bridgeGuidTransaction, + }); + updateParams = { ...updateParams, ...result }; + break; + } + case BridgeTransactionStatus.PAYLOAD_STORED: { + const result = await handlePayloadStored({ + bridgeTransaction, + bridgeGuidTransaction, + }); + updateParams = { ...updateParams, ...result }; + break; + } + } + + logger.info( + `Updated bridge transaction ${bridgeTransaction.guid} with status: ${updateParams.status}`, + ); + + await BridgeTransaction.getInstance().updateBridgeTransaction( + bridgeTransaction.guid, + updateParams, + ); + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + logger.error(`Failed to process bridge transaction ${bridgeTransaction.guid}: ${errorMessage}`); + + if (errorMessage.includes("404")) { + logger.warn( + `Updated bridge transaction ${bridgeTransaction.guid} with status: ${BridgeTransactionStatus.NOT_FOUND}`, + ); + await BridgeTransaction.getInstance().updateBridgeTransaction(bridgeTransaction.guid, { + status: BridgeTransactionStatus.NOT_FOUND, + }); + return; + } + + throw error; + } }; diff --git a/packages/bridge-monitor/src/service/process.service.ts b/packages/bridge-monitor/src/service/process.service.ts index 5e6cbe0..06168db 100644 --- a/packages/bridge-monitor/src/service/process.service.ts +++ b/packages/bridge-monitor/src/service/process.service.ts @@ -1,107 +1,140 @@ import { - API_TIMEOUT, - BridgeTransactionData, - config, + type BridgeTransactionData, Discord, - logger, MAINNET_BRIDGE_O_APP_CONTRACT_ADDRESS, MainnetBridgeOAppAbi, } from "@intmax2-function/shared"; -import axios, { AxiosError } from "axios"; -import type { Abi } from "viem"; -import { LAYER_ZERO_SCAN_API } from "../constants"; +import { type Abi, encodeAbiParameters } from "viem"; import { l1Client } from "../lib/blockchain"; -import type { BridgeGuidTransaction, BridgeGuidTransactionResponse } from "../types"; +import type { BridgeParams } from "../types"; import { submitTransaction } from "./submit.service"; -export const fetchBridgeGuidTransaction = async (guid: string) => { - const layerZeroMessagesUrl = `${LAYER_ZERO_SCAN_API[config.LAYER_ZERO_NETWORK]}/messages/guid/${guid}`; - try { - const response = await axios.get(layerZeroMessagesUrl, { - timeout: API_TIMEOUT, - headers: { - Accept: "application/json", - }, - }); - if (response.data?.data === undefined) { - throw new Error("Data is missing in the response"); - } - const transactions = response.data.data as BridgeGuidTransaction[]; - - if (transactions.length === 0) { - throw new Error("No transactions found"); - } - - return transactions[0]; - } catch (error) { - logger.error( - `Failed to fetch bridge transaction status url: ${layerZeroMessagesUrl} ${error instanceof Error ? error.message : error}`, - ); - // 404 +export const handleFailedStatus = async (bridgeParams: BridgeParams) => { + const { srcEid, sender, nonce, guid, message } = buildContractParams(bridgeParams); - if (error instanceof AxiosError) { - throw new Error(`Failed to fetch status: ${error.response?.status}`); - } - - throw new Error( - `Unexpected error while fetching bridge transaction status: ${ - error instanceof Error ? error.message : error - }`, - ); - } -}; + const receipt = await submitTransaction({ + operation: "clearMessage", + args: [ + { + srcEid, + sender, + nonce, + }, + guid, + message, + ], + }); -export const handleFailedStatus = async (_: BridgeGuidTransaction) => { - await submitTransaction("clear"); + return { + clearedAt: new Date(), + clearMessageTxHash: receipt.hash, + }; }; -export const handleInflightOrConfirming = async (bridgeTransaction: BridgeTransactionData) => { +export const handleInflightOrConfirmingStatus = async ( + bridgeTransaction: BridgeTransactionData, +) => { const twentyFourHoursAgo = new Date(Date.now() - 24 * 60 * 60 * 1000); - // TODO - if (bridgeTransaction.updatedAt.toDate() < twentyFourHoursAgo) { + if (bridgeTransaction.createdAt.toDate() < twentyFourHoursAgo) { + Discord.getInstance().initialize(); await Discord.getInstance().sendMessageWitForReady( "FATAL", `INFLIGHT/CONFIRMING status persists over 24 hours: ${bridgeTransaction.guid}`, ); + + return { + alertSent: true, + lastAlertAt: new Date(), + }; } + + return null; }; -export const handleVerifiedStatus = async (bridgeTransaction: BridgeTransactionData) => { +// TODO: manual retry and alertSent cannot get from db +export const handleVerifiedStatus = async (bridgeParams: BridgeParams) => { const twentyFourHoursAgo = new Date(Date.now() - 24 * 60 * 60 * 1000); - const verifiedTimestamp = bridgeTransaction.verifiedAt - ? bridgeTransaction.verifiedAt.toDate() - : bridgeTransaction.createdAt.toDate(); - // TODO: - if (verifiedTimestamp < twentyFourHoursAgo) { - await submitTransaction("manualRetry"); + if ( + bridgeParams.bridgeTransaction.verifiedAt && + bridgeParams.bridgeTransaction.verifiedAt.toDate() < twentyFourHoursAgo + ) { + const { sender, message, srcEid, nonce, guid, extraData } = buildContractParams(bridgeParams); + const receipt = await submitTransaction({ + operation: "manualRetry", + args: [ + { + srcEid, + sender, + nonce, + }, + guid, + message, + extraData, + ], + }); + + return { + alertSent: true, + lastAlertAt: new Date(), + manualRetryAt: new Date(), + manualRetryTxHash: receipt.hash, + }; } + + return { + verifiedAt: new Date(), + }; }; -export const handlePayloadStored = async (bridgeGuidTransaction: BridgeGuidTransaction) => { - const hasStored = await hasStoredPayload(); +export const handlePayloadStored = async (bridgeParams: BridgeParams) => { + const hasStored = await hasStoredPayload(bridgeParams); if (hasStored) { - await submitTransaction("manualRetry"); - } else { - await Discord.getInstance().sendMessageWitForReady( - "FATAL", - `PAYLOAD_STORED but hasStoredPayload is false: ${bridgeGuidTransaction.guid}`, - ); + const { sender, message, srcEid, nonce, guid, extraData } = buildContractParams(bridgeParams); + const receipt = await submitTransaction({ + operation: "manualRetry", + args: [ + { + srcEid, + sender, + nonce, + }, + guid, + message, + extraData, + ], + }); + + return { + manualRetryAt: new Date(), + manualRetryTxHash: receipt.hash, + }; } + + Discord.getInstance().initialize(); + await Discord.getInstance().sendMessageWitForReady( + "FATAL", + `PAYLOAD_STORED but hasStoredPayload is false: ${bridgeParams.bridgeGuidTransaction.guid}`, + ); + + return { + alertSent: true, + lastAlertAt: new Date(), + }; }; -const hasStoredPayload = async () => { - const currentBlockNumber = await l1Client.getBlockNumber(); +const hasStoredPayload = async (bridgeParams: BridgeParams) => { + const { sender, message, srcEid, nonce, guid } = buildContractParams(bridgeParams); const args = [ { - srcEid: "srcEid", - sender: "sender", - nonce: "nonce", - guid: "guid", - message: "message", + srcEid, + sender, + nonce, + guid, + message, }, ]; @@ -110,8 +143,35 @@ const hasStoredPayload = async () => { abi: MainnetBridgeOAppAbi as Abi, functionName: "hasStoredPayload", args, - blockNumber: currentBlockNumber, }); return isStored as boolean; }; + +const buildContractParams = ({ bridgeTransaction, bridgeGuidTransaction }: BridgeParams) => { + const sender = bridgeGuidTransaction.pathway.sender.address as `0x${string}`; + const recipient = bridgeGuidTransaction.pathway.receiver.address as `0x${string}`; + const amount = BigInt(bridgeTransaction.amount); + + const message = encodeAbiParameters( + [{ type: "address" }, { type: "uint256" }, { type: "address" }], + [recipient, amount, sender], + ); + + const srcEid = BigInt(bridgeGuidTransaction.pathway.srcEid); + const nonce = BigInt(bridgeGuidTransaction.pathway.nonce); + const guid = bridgeGuidTransaction.guid; + + const extraData = "0x" as `0x${string}`; + + return { + sender, + recipient, + amount, + message, + srcEid, + nonce, + guid, + extraData, + }; +}; diff --git a/packages/bridge-monitor/src/service/submit.service.ts b/packages/bridge-monitor/src/service/submit.service.ts index 64a3872..76ed94d 100644 --- a/packages/bridge-monitor/src/service/submit.service.ts +++ b/packages/bridge-monitor/src/service/submit.service.ts @@ -1,3 +1,150 @@ -export const submitTransaction = async (operation: string) => { - console.log(`Submitting transaction for operation: ${operation}`); +import { + type ContractCallOptionsEthers, + type ContractCallParameters, + calculateGasMultiplier, + calculateIncreasedGasFees, + ETHERS_CONFIRMATIONS, + ETHERS_WAIT_TRANSACTION_TIMEOUT_MESSAGE, + ethersWaitForTransactionConfirmation, + executeEthersTransaction, + getEthersMaxGasMultiplier, + getEthersTxOptions, + getNonce, + getWalletClient, + logger, + MAINNET_BRIDGE_O_APP_CONTRACT_ADDRESS, + MainnetBridgeOApp__factory, + MainnetBridgeOAppAbi, + type RetryOptions, + replacedEthersTransaction, + TRANSACTION_INCREMENT_RATE, + TRANSACTION_MAX_RETRIES, + TRANSACTION_MISSING_REVERT_DATA, + TRANSACTION_REPLACEMENT_FEE_TOO_LOW, + TRANSACTION_WAIT_TIMEOUT_ERROR_MESSAGE, + TRANSACTION_WAIT_TRANSACTION_TIMEOUT, +} from "@intmax2-function/shared"; +import { ethers } from "ethers"; +import { type Abi, toHex } from "viem"; +import { l1Client } from "../lib/blockchain"; +import type { CallParams } from "../types"; + +export const submitTransaction = async (params: CallParams) => { + const retryOptions: RetryOptions = { + maxFeePerGas: null, + maxPriorityFeePerGas: null, + }; + + for (let attempt = 0; attempt < TRANSACTION_MAX_RETRIES; attempt++) { + try { + const multiplier = calculateGasMultiplier(attempt, TRANSACTION_INCREMENT_RATE); + + const { transactionHash } = await submitWithRetry(params, multiplier, retryOptions); + + const receipt = await ethersWaitForTransactionConfirmation( + l1Client, + transactionHash, + params.operation, + { + confirms: ETHERS_CONFIRMATIONS, + timeout: TRANSACTION_WAIT_TRANSACTION_TIMEOUT, + }, + ); + + return receipt; + } catch (error) { + const message = error instanceof Error ? error.message : "Unknown error"; + logger.warn(`Error sending transaction: ${message}`); + + if (attempt === TRANSACTION_MAX_RETRIES - 1) { + throw new Error("Transaction Max retries reached"); + } + + if ( + message.includes(TRANSACTION_WAIT_TIMEOUT_ERROR_MESSAGE) || + message.includes(TRANSACTION_REPLACEMENT_FEE_TOO_LOW) || + message.includes(TRANSACTION_MISSING_REVERT_DATA) || + message.includes(ETHERS_WAIT_TRANSACTION_TIMEOUT_MESSAGE) + ) { + logger.warn(`Attempt ${attempt + 1} failed. Retrying with higher gas...`); + continue; + } + + throw error; + } + } + + throw new Error("Unexpected end of transaction"); +}; + +export const submitWithRetry = async ( + params: CallParams, + multiplier: number, + retryOptions: RetryOptions, +) => { + const walletClientData = getWalletClient("bridgeManager", "l1"); + + const contractCallParams: ContractCallParameters = { + contractAddress: MAINNET_BRIDGE_O_APP_CONTRACT_ADDRESS, + abi: MainnetBridgeOAppAbi as Abi, + functionName: params.operation, + account: walletClientData.account, + args: params.args, + }; + + const [{ pendingNonce, currentNonce }, gasPriceData] = await Promise.all([ + getNonce(l1Client, walletClientData.account.address), + getEthersMaxGasMultiplier(l1Client, multiplier), + ]); + let { maxFeePerGas, maxPriorityFeePerGas } = gasPriceData; + + if (retryOptions.maxFeePerGas && retryOptions.maxPriorityFeePerGas) { + const { newMaxFeePerGas, newMaxPriorityFeePerGas } = calculateIncreasedGasFees( + retryOptions.maxFeePerGas, + retryOptions.maxPriorityFeePerGas, + maxFeePerGas, + maxPriorityFeePerGas, + ); + + maxFeePerGas = newMaxFeePerGas; + maxPriorityFeePerGas = newMaxPriorityFeePerGas; + + logger.info( + `Increased gas fees multiplier: ${multiplier} - MaxFee: ${maxFeePerGas}, MaxPriorityFee: ${maxPriorityFeePerGas}`, + ); + } + + retryOptions.maxFeePerGas = maxFeePerGas; + retryOptions.maxPriorityFeePerGas = maxPriorityFeePerGas; + + const contractCallOptions: ContractCallOptionsEthers = { + nonce: currentNonce, + maxFeePerGas, + maxPriorityFeePerGas, + }; + + const provider = new ethers.JsonRpcProvider(l1Client.transport.url); + const signer = new ethers.Wallet( + toHex(walletClientData.account.getHdKey().privateKey!), + provider, + ); + const contract = MainnetBridgeOApp__factory.connect(contractCallParams.contractAddress, signer); + const ethersTxOptions = getEthersTxOptions(contractCallParams, contractCallOptions ?? {}); + const callArgs = [...contractCallParams.args, ethersTxOptions]; + + if (pendingNonce > currentNonce) { + return await replacedEthersTransaction({ + functionName: contractCallParams.functionName, + contract, + callArgs, + }); + } + + const transactionResult = await executeEthersTransaction({ + functionName: contractCallParams.functionName, + contract, + callArgs, + }); + + return transactionResult; }; diff --git a/packages/bridge-monitor/src/types.ts b/packages/bridge-monitor/src/types.ts index eccb88b..7c73fc6 100644 --- a/packages/bridge-monitor/src/types.ts +++ b/packages/bridge-monitor/src/types.ts @@ -1,3 +1,5 @@ +import { type BridgeTransactionData, BridgeTransactionStatus } from "@intmax2-function/shared"; + export interface BridgeGuidTransactionResponse { data: BridgeGuidTransaction[]; } @@ -144,3 +146,26 @@ export interface Status { name: string; message: string; } + +export type ArgType = string | number | bigint | boolean | ArgType[] | { [key: string]: ArgType }; + +export interface CallParams { + operation: string; + args: ArgType[]; +} + +export interface BridgeParams { + bridgeTransaction: BridgeTransactionData; + bridgeGuidTransaction: BridgeGuidTransaction; +} + +export interface UpdateParams { + status: BridgeTransactionStatus; + clearedAt?: Date; + clearMessageTxHash?: string; + alertSent?: boolean; + lastAlertAt?: Date; + manualRetryAt?: Date; + manualRetryTxHash?: string; + verifiedAt?: Date; +} diff --git a/packages/deposit-analyzer/package.json b/packages/deposit-analyzer/package.json index 219ffc1..9a69861 100644 --- a/packages/deposit-analyzer/package.json +++ b/packages/deposit-analyzer/package.json @@ -4,7 +4,7 @@ "dependencies": { "@intmax2-function/shared": "workspace:*", "ethers": "^6.15.0", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/indexer-cache-validator/package.json b/packages/indexer-cache-validator/package.json index 11a94f6..626f6f5 100644 --- a/packages/indexer-cache-validator/package.json +++ b/packages/indexer-cache-validator/package.json @@ -5,7 +5,7 @@ "@intmax2-function/shared": "workspace:*", "axios": "^1.11.0", "semver": "^7.7.2", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/indexer-event-watcher/package.json b/packages/indexer-event-watcher/package.json index 813bdf2..452a4b0 100644 --- a/packages/indexer-event-watcher/package.json +++ b/packages/indexer-event-watcher/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "dependencies": { "@intmax2-function/shared": "workspace:*", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/indexer-monitor/package.json b/packages/indexer-monitor/package.json index c717a05..de36d7b 100644 --- a/packages/indexer-monitor/package.json +++ b/packages/indexer-monitor/package.json @@ -5,7 +5,7 @@ "@intmax2-function/shared": "workspace:*", "axios": "^1.11.0", "semver": "^7.7.2", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/indexer/package.json b/packages/indexer/package.json index e2d401f..93d1e18 100644 --- a/packages/indexer/package.json +++ b/packages/indexer/package.json @@ -4,7 +4,7 @@ "dependencies": { "@hono/node-server": "^1.19.0", "@intmax2-function/shared": "workspace:*", - "hono": "^4.9.2" + "hono": "^4.9.4" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/messenger-relayer/package.json b/packages/messenger-relayer/package.json index 0dd96b2..acfd6ee 100644 --- a/packages/messenger-relayer/package.json +++ b/packages/messenger-relayer/package.json @@ -5,7 +5,7 @@ "@intmax2-function/shared": "workspace:*", "axios": "^1.11.0", "ethers": "^6.15.0", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start:withdrawal": "node dist/index.js withdrawal", diff --git a/packages/mint-executor/package.json b/packages/mint-executor/package.json index 75b8a9a..274615a 100644 --- a/packages/mint-executor/package.json +++ b/packages/mint-executor/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "dependencies": { "@intmax2-function/shared": "workspace:*", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/mock-l1-to-l2-relayer/package.json b/packages/mock-l1-to-l2-relayer/package.json index 872474b..ac763ef 100644 --- a/packages/mock-l1-to-l2-relayer/package.json +++ b/packages/mock-l1-to-l2-relayer/package.json @@ -4,7 +4,7 @@ "dependencies": { "@intmax2-function/shared": "workspace:*", "ethers": "^6.15.0", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/mock-l2-to-l1-relayer/package.json b/packages/mock-l2-to-l1-relayer/package.json index f5183d0..14d5b6c 100644 --- a/packages/mock-l2-to-l1-relayer/package.json +++ b/packages/mock-l2-to-l1-relayer/package.json @@ -4,7 +4,7 @@ "dependencies": { "@intmax2-function/shared": "workspace:*", "ethers": "^6.15.0", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/predicate/package.json b/packages/predicate/package.json index d30956e..218911c 100644 --- a/packages/predicate/package.json +++ b/packages/predicate/package.json @@ -5,7 +5,7 @@ "@hono/node-server": "^1.19.0", "@intmax2-function/shared": "workspace:*", "axios": "^1.11.0", - "hono": "^4.9.2" + "hono": "^4.9.4" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/shared/package.json b/packages/shared/package.json index 41e0271..2f37dc6 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -4,23 +4,23 @@ "main": "dist/index.js", "dependencies": { "@google-cloud/firestore": "^7.11.3", - "@google-cloud/storage": "^7.16.0", + "@google-cloud/storage": "^7.17.0", "@hono/node-server": "^1.19.0", - "abitype": "^1.0.8", + "abitype": "^1.0.9", "alchemy-sdk": "^3.6.3", "axios": "^1.11.0", - "discord.js": "^14.21.0", + "discord.js": "^14.22.1", "envalid": "^8.1.0", "ethers": "^6.15.0", - "hono": "^4.9.2", + "hono": "^4.9.4", "hono-rate-limiter": "^0.4.2", "http-status": "2.1.0", "ioredis": "^5.7.0", "node-cache": "^5.1.2", "pino": "^9.9.0", "pino-pretty": "^13.1.1", - "viem": "^2.33.3", - "zod": "4.0.17" + "viem": "^2.34.0", + "zod": "4.1.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/shared/src/blockchain/wallet.ts b/packages/shared/src/blockchain/wallet.ts index c5cb34f..f4a6c77 100644 --- a/packages/shared/src/blockchain/wallet.ts +++ b/packages/shared/src/blockchain/wallet.ts @@ -15,7 +15,8 @@ type WalletType = | "depositAnalyzer" | "withdrawal" | "blockBuilderReward" - | "tokenManager"; + | "tokenManager" + | "bridgeManager"; const walletConfigs: Record = { builder: 0, @@ -23,6 +24,7 @@ const walletConfigs: Record = { withdrawal: 2, blockBuilderReward: 3, tokenManager: 4, + bridgeManager: 5, }; export const getMockWalletClient = ( diff --git a/packages/shared/src/config/index.ts b/packages/shared/src/config/index.ts index 125614e..295c91b 100644 --- a/packages/shared/src/config/index.ts +++ b/packages/shared/src/config/index.ts @@ -99,6 +99,7 @@ export const config = cleanEnv(process.env, { // discord DISCORD_BOT_TOKEN: str({ default: "dummy" }), DISCORD_BOT_INFO_CHANNEL_ID: str({ default: "dummy" }), + DISCORD_BOT_WARN_CHANNEL_ID: str({ default: "dummy" }), DISCORD_BOT_ERROR_CHANNEL_ID: str({ default: "dummy" }), // scroll SCROLL_GAS_MULTIPLIER: num({ default: 2 }), diff --git a/packages/shared/src/lib/discord.ts b/packages/shared/src/lib/discord.ts index 40ff532..b7e080a 100644 --- a/packages/shared/src/lib/discord.ts +++ b/packages/shared/src/lib/discord.ts @@ -1,5 +1,6 @@ import { Client, GatewayIntentBits, type TextChannel } from "discord.js"; import { config } from "../config"; +import { DiscordMessageType } from "../types"; import { logger } from "./logger"; export class Discord { @@ -55,9 +56,16 @@ export class Discord { await this.sendMessage(messageType, message); } - private getChannelIDByMessageType(type: "INFO" | "WARN" | "FATAL") { - return type === "FATAL" - ? config.DISCORD_BOT_ERROR_CHANNEL_ID - : config.DISCORD_BOT_INFO_CHANNEL_ID; + private getChannelIDByMessageType(type: DiscordMessageType) { + switch (type) { + case "INFO": + return config.DISCORD_BOT_INFO_CHANNEL_ID; + case "WARN": + return config.DISCORD_BOT_WARN_CHANNEL_ID; + case "FATAL": + return config.DISCORD_BOT_ERROR_CHANNEL_ID; + default: + throw new Error(`Unknown message type: ${type}`); + } } } diff --git a/packages/shared/src/typechainTypes/factories/contracts/index.ts b/packages/shared/src/typechainTypes/factories/contracts/index.ts index fbe6c1c..1f61d5d 100644 --- a/packages/shared/src/typechainTypes/factories/contracts/index.ts +++ b/packages/shared/src/typechainTypes/factories/contracts/index.ts @@ -4,4 +4,5 @@ export * as liquidity from "./liquidity"; export * as test from "./test"; export * as minter from "./minter"; +export * as mainnetBridgeOApp from "./mainnetBridgeOApp"; diff --git a/packages/shared/src/typechainTypes/factories/contracts/mainnetBridgeOApp/MainnetBridgeOApp.ts b/packages/shared/src/typechainTypes/factories/contracts/mainnetBridgeOApp/MainnetBridgeOApp.ts new file mode 100644 index 0000000..71f0b7d --- /dev/null +++ b/packages/shared/src/typechainTypes/factories/contracts/mainnetBridgeOApp/MainnetBridgeOApp.ts @@ -0,0 +1,552 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +import type { + BaseContract, + BigNumberish, + BytesLike, + FunctionFragment, + Result, + Interface, + EventFragment, + AddressLike, + ContractRunner, + ContractMethod, + Listener, +} from "ethers"; +import type { + TypedContractEvent, + TypedDeferredTopicFilter, + TypedEventLog, + TypedLogDescription, + TypedListener, + TypedContractMethod, +} from "../../../common"; + +export type OriginStruct = { + srcEid: BigNumberish; + sender: BytesLike; + nonce: BigNumberish; +}; + +export type OriginStructOutput = [ + srcEid: bigint, + sender: string, + nonce: bigint +] & { srcEid: bigint; sender: string; nonce: bigint }; + +export interface MainnetBridgeOAppInterface extends Interface { + getFunction( + nameOrSignature: + | "allowInitializePath" + | "clearMessage" + | "endpoint" + | "hasStoredPayload" + | "isComposeMsgSender" + | "lzReceive" + | "manualRetry" + | "nextNonce" + | "oAppVersion" + | "owner" + | "peers" + | "renounceOwnership" + | "setDelegate" + | "setPeer" + | "transferOwnership" + | "withdrawTokens" + ): FunctionFragment; + + getEvent( + nameOrSignatureOrTopic: + | "BridgeFulfilled" + | "OwnershipTransferred" + | "PeerSet" + | "TokensWithdrawn" + ): EventFragment; + + encodeFunctionData( + functionFragment: "allowInitializePath", + values: [OriginStruct] + ): string; + encodeFunctionData( + functionFragment: "clearMessage", + values: [OriginStruct, BytesLike, BytesLike] + ): string; + encodeFunctionData(functionFragment: "endpoint", values?: undefined): string; + encodeFunctionData( + functionFragment: "hasStoredPayload", + values: [BigNumberish, BytesLike, BigNumberish, BytesLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "isComposeMsgSender", + values: [OriginStruct, BytesLike, AddressLike] + ): string; + encodeFunctionData( + functionFragment: "lzReceive", + values: [OriginStruct, BytesLike, BytesLike, AddressLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "manualRetry", + values: [OriginStruct, BytesLike, BytesLike, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "nextNonce", + values: [BigNumberish, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "oAppVersion", + values?: undefined + ): string; + encodeFunctionData(functionFragment: "owner", values?: undefined): string; + encodeFunctionData(functionFragment: "peers", values: [BigNumberish]): string; + encodeFunctionData( + functionFragment: "renounceOwnership", + values?: undefined + ): string; + encodeFunctionData( + functionFragment: "setDelegate", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "setPeer", + values: [BigNumberish, BytesLike] + ): string; + encodeFunctionData( + functionFragment: "transferOwnership", + values: [AddressLike] + ): string; + encodeFunctionData( + functionFragment: "withdrawTokens", + values: [AddressLike, BigNumberish] + ): string; + + decodeFunctionResult( + functionFragment: "allowInitializePath", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "clearMessage", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "endpoint", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "hasStoredPayload", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "isComposeMsgSender", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "lzReceive", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "manualRetry", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "nextNonce", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "oAppVersion", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "owner", data: BytesLike): Result; + decodeFunctionResult(functionFragment: "peers", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "renounceOwnership", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "setDelegate", + data: BytesLike + ): Result; + decodeFunctionResult(functionFragment: "setPeer", data: BytesLike): Result; + decodeFunctionResult( + functionFragment: "transferOwnership", + data: BytesLike + ): Result; + decodeFunctionResult( + functionFragment: "withdrawTokens", + data: BytesLike + ): Result; +} + +export namespace BridgeFulfilledEvent { + export type InputTuple = [ + srcUser: AddressLike, + recipient: AddressLike, + amount: BigNumberish + ]; + export type OutputTuple = [ + srcUser: string, + recipient: string, + amount: bigint + ]; + export interface OutputObject { + srcUser: string; + recipient: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace OwnershipTransferredEvent { + export type InputTuple = [previousOwner: AddressLike, newOwner: AddressLike]; + export type OutputTuple = [previousOwner: string, newOwner: string]; + export interface OutputObject { + previousOwner: string; + newOwner: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace PeerSetEvent { + export type InputTuple = [eid: BigNumberish, peer: BytesLike]; + export type OutputTuple = [eid: bigint, peer: string]; + export interface OutputObject { + eid: bigint; + peer: string; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export namespace TokensWithdrawnEvent { + export type InputTuple = [to: AddressLike, amount: BigNumberish]; + export type OutputTuple = [to: string, amount: bigint]; + export interface OutputObject { + to: string; + amount: bigint; + } + export type Event = TypedContractEvent; + export type Filter = TypedDeferredTopicFilter; + export type Log = TypedEventLog; + export type LogDescription = TypedLogDescription; +} + +export interface MainnetBridgeOApp extends BaseContract { + connect(runner?: ContractRunner | null): MainnetBridgeOApp; + waitForDeployment(): Promise; + + interface: MainnetBridgeOAppInterface; + + queryFilter( + event: TCEvent, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + queryFilter( + filter: TypedDeferredTopicFilter, + fromBlockOrBlockhash?: string | number | undefined, + toBlock?: string | number | undefined + ): Promise>>; + + on( + event: TCEvent, + listener: TypedListener + ): Promise; + on( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + once( + event: TCEvent, + listener: TypedListener + ): Promise; + once( + filter: TypedDeferredTopicFilter, + listener: TypedListener + ): Promise; + + listeners( + event: TCEvent + ): Promise>>; + listeners(eventName?: string): Promise>; + removeAllListeners( + event?: TCEvent + ): Promise; + + allowInitializePath: TypedContractMethod< + [origin: OriginStruct], + [boolean], + "view" + >; + + clearMessage: TypedContractMethod< + [_origin: OriginStruct, _guid: BytesLike, _message: BytesLike], + [void], + "nonpayable" + >; + + endpoint: TypedContractMethod<[], [string], "view">; + + hasStoredPayload: TypedContractMethod< + [ + srcEid: BigNumberish, + sender: BytesLike, + nonce: BigNumberish, + guid: BytesLike, + message: BytesLike + ], + [boolean], + "view" + >; + + isComposeMsgSender: TypedContractMethod< + [arg0: OriginStruct, arg1: BytesLike, _sender: AddressLike], + [boolean], + "view" + >; + + lzReceive: TypedContractMethod< + [ + _origin: OriginStruct, + _guid: BytesLike, + _message: BytesLike, + _executor: AddressLike, + _extraData: BytesLike + ], + [void], + "payable" + >; + + manualRetry: TypedContractMethod< + [ + _origin: OriginStruct, + _guid: BytesLike, + _message: BytesLike, + _extraData: BytesLike + ], + [void], + "nonpayable" + >; + + nextNonce: TypedContractMethod< + [arg0: BigNumberish, arg1: BytesLike], + [bigint], + "view" + >; + + oAppVersion: TypedContractMethod< + [], + [[bigint, bigint] & { senderVersion: bigint; receiverVersion: bigint }], + "view" + >; + + owner: TypedContractMethod<[], [string], "view">; + + peers: TypedContractMethod<[eid: BigNumberish], [string], "view">; + + renounceOwnership: TypedContractMethod<[], [void], "nonpayable">; + + setDelegate: TypedContractMethod< + [_delegate: AddressLike], + [void], + "nonpayable" + >; + + setPeer: TypedContractMethod< + [_eid: BigNumberish, _peer: BytesLike], + [void], + "nonpayable" + >; + + transferOwnership: TypedContractMethod< + [newOwner: AddressLike], + [void], + "nonpayable" + >; + + withdrawTokens: TypedContractMethod< + [to: AddressLike, amount: BigNumberish], + [void], + "nonpayable" + >; + + getFunction( + key: string | FunctionFragment + ): T; + + getFunction( + nameOrSignature: "allowInitializePath" + ): TypedContractMethod<[origin: OriginStruct], [boolean], "view">; + getFunction( + nameOrSignature: "clearMessage" + ): TypedContractMethod< + [_origin: OriginStruct, _guid: BytesLike, _message: BytesLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "endpoint" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "hasStoredPayload" + ): TypedContractMethod< + [ + srcEid: BigNumberish, + sender: BytesLike, + nonce: BigNumberish, + guid: BytesLike, + message: BytesLike + ], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "isComposeMsgSender" + ): TypedContractMethod< + [arg0: OriginStruct, arg1: BytesLike, _sender: AddressLike], + [boolean], + "view" + >; + getFunction( + nameOrSignature: "lzReceive" + ): TypedContractMethod< + [ + _origin: OriginStruct, + _guid: BytesLike, + _message: BytesLike, + _executor: AddressLike, + _extraData: BytesLike + ], + [void], + "payable" + >; + getFunction( + nameOrSignature: "manualRetry" + ): TypedContractMethod< + [ + _origin: OriginStruct, + _guid: BytesLike, + _message: BytesLike, + _extraData: BytesLike + ], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "nextNonce" + ): TypedContractMethod< + [arg0: BigNumberish, arg1: BytesLike], + [bigint], + "view" + >; + getFunction( + nameOrSignature: "oAppVersion" + ): TypedContractMethod< + [], + [[bigint, bigint] & { senderVersion: bigint; receiverVersion: bigint }], + "view" + >; + getFunction( + nameOrSignature: "owner" + ): TypedContractMethod<[], [string], "view">; + getFunction( + nameOrSignature: "peers" + ): TypedContractMethod<[eid: BigNumberish], [string], "view">; + getFunction( + nameOrSignature: "renounceOwnership" + ): TypedContractMethod<[], [void], "nonpayable">; + getFunction( + nameOrSignature: "setDelegate" + ): TypedContractMethod<[_delegate: AddressLike], [void], "nonpayable">; + getFunction( + nameOrSignature: "setPeer" + ): TypedContractMethod< + [_eid: BigNumberish, _peer: BytesLike], + [void], + "nonpayable" + >; + getFunction( + nameOrSignature: "transferOwnership" + ): TypedContractMethod<[newOwner: AddressLike], [void], "nonpayable">; + getFunction( + nameOrSignature: "withdrawTokens" + ): TypedContractMethod< + [to: AddressLike, amount: BigNumberish], + [void], + "nonpayable" + >; + + getEvent( + key: "BridgeFulfilled" + ): TypedContractEvent< + BridgeFulfilledEvent.InputTuple, + BridgeFulfilledEvent.OutputTuple, + BridgeFulfilledEvent.OutputObject + >; + getEvent( + key: "OwnershipTransferred" + ): TypedContractEvent< + OwnershipTransferredEvent.InputTuple, + OwnershipTransferredEvent.OutputTuple, + OwnershipTransferredEvent.OutputObject + >; + getEvent( + key: "PeerSet" + ): TypedContractEvent< + PeerSetEvent.InputTuple, + PeerSetEvent.OutputTuple, + PeerSetEvent.OutputObject + >; + getEvent( + key: "TokensWithdrawn" + ): TypedContractEvent< + TokensWithdrawnEvent.InputTuple, + TokensWithdrawnEvent.OutputTuple, + TokensWithdrawnEvent.OutputObject + >; + + filters: { + "BridgeFulfilled(address,address,uint256)": TypedContractEvent< + BridgeFulfilledEvent.InputTuple, + BridgeFulfilledEvent.OutputTuple, + BridgeFulfilledEvent.OutputObject + >; + BridgeFulfilled: TypedContractEvent< + BridgeFulfilledEvent.InputTuple, + BridgeFulfilledEvent.OutputTuple, + BridgeFulfilledEvent.OutputObject + >; + + "OwnershipTransferred(address,address)": TypedContractEvent< + OwnershipTransferredEvent.InputTuple, + OwnershipTransferredEvent.OutputTuple, + OwnershipTransferredEvent.OutputObject + >; + OwnershipTransferred: TypedContractEvent< + OwnershipTransferredEvent.InputTuple, + OwnershipTransferredEvent.OutputTuple, + OwnershipTransferredEvent.OutputObject + >; + + "PeerSet(uint32,bytes32)": TypedContractEvent< + PeerSetEvent.InputTuple, + PeerSetEvent.OutputTuple, + PeerSetEvent.OutputObject + >; + PeerSet: TypedContractEvent< + PeerSetEvent.InputTuple, + PeerSetEvent.OutputTuple, + PeerSetEvent.OutputObject + >; + + "TokensWithdrawn(address,uint256)": TypedContractEvent< + TokensWithdrawnEvent.InputTuple, + TokensWithdrawnEvent.OutputTuple, + TokensWithdrawnEvent.OutputObject + >; + TokensWithdrawn: TypedContractEvent< + TokensWithdrawnEvent.InputTuple, + TokensWithdrawnEvent.OutputTuple, + TokensWithdrawnEvent.OutputObject + >; + }; +} diff --git a/packages/shared/src/typechainTypes/factories/contracts/mainnetBridgeOApp/MainnetBridgeOApp__factory.ts b/packages/shared/src/typechainTypes/factories/contracts/mainnetBridgeOApp/MainnetBridgeOApp__factory.ts new file mode 100644 index 0000000..b388722 --- /dev/null +++ b/packages/shared/src/typechainTypes/factories/contracts/mainnetBridgeOApp/MainnetBridgeOApp__factory.ts @@ -0,0 +1,661 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ + +import { Contract, Interface, type ContractRunner } from "ethers"; +import type { + MainnetBridgeOApp, + MainnetBridgeOAppInterface, +} from "./MainnetBridgeOApp"; + +const _abi = [ + { + type: "constructor", + inputs: [ + { + name: "_endpoint", + type: "address", + internalType: "address", + }, + { + name: "_delegate", + type: "address", + internalType: "address", + }, + { + name: "_owner", + type: "address", + internalType: "address", + }, + { + name: "_token", + type: "address", + internalType: "address", + }, + { + name: "_srcEid", + type: "uint32", + internalType: "uint32", + }, + { + name: "_srcSender", + type: "bytes32", + internalType: "bytes32", + }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "allowInitializePath", + inputs: [ + { + name: "origin", + type: "tuple", + internalType: "struct Origin", + components: [ + { + name: "srcEid", + type: "uint32", + internalType: "uint32", + }, + { + name: "sender", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "nonce", + type: "uint64", + internalType: "uint64", + }, + ], + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "clearMessage", + inputs: [ + { + name: "_origin", + type: "tuple", + internalType: "struct Origin", + components: [ + { + name: "srcEid", + type: "uint32", + internalType: "uint32", + }, + { + name: "sender", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "nonce", + type: "uint64", + internalType: "uint64", + }, + ], + }, + { + name: "_guid", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "_message", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "endpoint", + inputs: [], + outputs: [ + { + name: "", + type: "address", + internalType: "contract ILayerZeroEndpointV2", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "hasStoredPayload", + inputs: [ + { + name: "srcEid", + type: "uint32", + internalType: "uint32", + }, + { + name: "sender", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "nonce", + type: "uint64", + internalType: "uint64", + }, + { + name: "guid", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "message", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "isComposeMsgSender", + inputs: [ + { + name: "", + type: "tuple", + internalType: "struct Origin", + components: [ + { + name: "srcEid", + type: "uint32", + internalType: "uint32", + }, + { + name: "sender", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "nonce", + type: "uint64", + internalType: "uint64", + }, + ], + }, + { + name: "", + type: "bytes", + internalType: "bytes", + }, + { + name: "_sender", + type: "address", + internalType: "address", + }, + ], + outputs: [ + { + name: "", + type: "bool", + internalType: "bool", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "lzReceive", + inputs: [ + { + name: "_origin", + type: "tuple", + internalType: "struct Origin", + components: [ + { + name: "srcEid", + type: "uint32", + internalType: "uint32", + }, + { + name: "sender", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "nonce", + type: "uint64", + internalType: "uint64", + }, + ], + }, + { + name: "_guid", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "_message", + type: "bytes", + internalType: "bytes", + }, + { + name: "_executor", + type: "address", + internalType: "address", + }, + { + name: "_extraData", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [], + stateMutability: "payable", + }, + { + type: "function", + name: "manualRetry", + inputs: [ + { + name: "_origin", + type: "tuple", + internalType: "struct Origin", + components: [ + { + name: "srcEid", + type: "uint32", + internalType: "uint32", + }, + { + name: "sender", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "nonce", + type: "uint64", + internalType: "uint64", + }, + ], + }, + { + name: "_guid", + type: "bytes32", + internalType: "bytes32", + }, + { + name: "_message", + type: "bytes", + internalType: "bytes", + }, + { + name: "_extraData", + type: "bytes", + internalType: "bytes", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "nextNonce", + inputs: [ + { + name: "", + type: "uint32", + internalType: "uint32", + }, + { + name: "", + type: "bytes32", + internalType: "bytes32", + }, + ], + outputs: [ + { + name: "nonce", + type: "uint64", + internalType: "uint64", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "oAppVersion", + inputs: [], + outputs: [ + { + name: "senderVersion", + type: "uint64", + internalType: "uint64", + }, + { + name: "receiverVersion", + type: "uint64", + internalType: "uint64", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "owner", + inputs: [], + outputs: [ + { + name: "", + type: "address", + internalType: "address", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "peers", + inputs: [ + { + name: "eid", + type: "uint32", + internalType: "uint32", + }, + ], + outputs: [ + { + name: "peer", + type: "bytes32", + internalType: "bytes32", + }, + ], + stateMutability: "view", + }, + { + type: "function", + name: "renounceOwnership", + inputs: [], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setDelegate", + inputs: [ + { + name: "_delegate", + type: "address", + internalType: "address", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "setPeer", + inputs: [ + { + name: "_eid", + type: "uint32", + internalType: "uint32", + }, + { + name: "_peer", + type: "bytes32", + internalType: "bytes32", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "transferOwnership", + inputs: [ + { + name: "newOwner", + type: "address", + internalType: "address", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "withdrawTokens", + inputs: [ + { + name: "to", + type: "address", + internalType: "address", + }, + { + name: "amount", + type: "uint256", + internalType: "uint256", + }, + ], + outputs: [], + stateMutability: "nonpayable", + }, + { + type: "event", + name: "BridgeFulfilled", + inputs: [ + { + name: "srcUser", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "recipient", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "amount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "OwnershipTransferred", + inputs: [ + { + name: "previousOwner", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "newOwner", + type: "address", + indexed: true, + internalType: "address", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "PeerSet", + inputs: [ + { + name: "eid", + type: "uint32", + indexed: false, + internalType: "uint32", + }, + { + name: "peer", + type: "bytes32", + indexed: false, + internalType: "bytes32", + }, + ], + anonymous: false, + }, + { + type: "event", + name: "TokensWithdrawn", + inputs: [ + { + name: "to", + type: "address", + indexed: true, + internalType: "address", + }, + { + name: "amount", + type: "uint256", + indexed: false, + internalType: "uint256", + }, + ], + anonymous: false, + }, + { + type: "error", + name: "BadSender", + inputs: [], + }, + { + type: "error", + name: "BadSrcEid", + inputs: [], + }, + { + type: "error", + name: "InvalidAddress", + inputs: [], + }, + { + type: "error", + name: "InvalidAmount", + inputs: [], + }, + { + type: "error", + name: "InvalidDelegate", + inputs: [], + }, + { + type: "error", + name: "InvalidEndpointCall", + inputs: [], + }, + { + type: "error", + name: "NoPeer", + inputs: [ + { + name: "eid", + type: "uint32", + internalType: "uint32", + }, + ], + }, + { + type: "error", + name: "OnlyEndpoint", + inputs: [ + { + name: "addr", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "OnlyPeer", + inputs: [ + { + name: "eid", + type: "uint32", + internalType: "uint32", + }, + { + name: "sender", + type: "bytes32", + internalType: "bytes32", + }, + ], + }, + { + type: "error", + name: "OwnableInvalidOwner", + inputs: [ + { + name: "owner", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "OwnableUnauthorizedAccount", + inputs: [ + { + name: "account", + type: "address", + internalType: "address", + }, + ], + }, + { + type: "error", + name: "RecipientZero", + inputs: [], + }, + { + type: "error", + name: "SafeERC20FailedOperation", + inputs: [ + { + name: "token", + type: "address", + internalType: "address", + }, + ], + }, +] as const; + +export class MainnetBridgeOApp__factory { + static readonly abi = _abi; + static createInterface(): MainnetBridgeOAppInterface { + return new Interface(_abi) as MainnetBridgeOAppInterface; + } + static connect( + address: string, + runner?: ContractRunner | null + ): MainnetBridgeOApp { + return new Contract(address, _abi, runner) as unknown as MainnetBridgeOApp; + } +} diff --git a/packages/shared/src/typechainTypes/factories/contracts/mainnetBridgeOApp/index.ts b/packages/shared/src/typechainTypes/factories/contracts/mainnetBridgeOApp/index.ts new file mode 100644 index 0000000..12d518c --- /dev/null +++ b/packages/shared/src/typechainTypes/factories/contracts/mainnetBridgeOApp/index.ts @@ -0,0 +1,4 @@ +/* Autogenerated file. Do not edit manually. */ +/* tslint:disable */ +/* eslint-disable */ +export { MainnetBridgeOApp__factory } from "./MainnetBridgeOApp__factory"; diff --git a/packages/shared/src/typechainTypes/factories/index.ts b/packages/shared/src/typechainTypes/factories/index.ts index 145680e..7e527f1 100644 --- a/packages/shared/src/typechainTypes/factories/index.ts +++ b/packages/shared/src/typechainTypes/factories/index.ts @@ -2,5 +2,4 @@ /* tslint:disable */ /* eslint-disable */ export * as scrollTech from "./@scroll-tech"; -export * as contracts from "./contracts"; - +export * as contracts from "./contracts"; \ No newline at end of file diff --git a/packages/shared/src/typechainTypes/index.ts b/packages/shared/src/typechainTypes/index.ts index a9810da..d99737a 100644 --- a/packages/shared/src/typechainTypes/index.ts +++ b/packages/shared/src/typechainTypes/index.ts @@ -13,4 +13,4 @@ export { MockL1ScrollMessenger__factory } from "./factories/contracts/test/MockL export { MockL2ScrollMessenger__factory } from "./factories/contracts/test/MockL2ScrollMessanger.sol/MockL2ScrollMessenger__factory"; export { Minter__factory } from "./factories/contracts/minter/Minter__factory"; export type { contracts }; - +export { MainnetBridgeOApp__factory } from './factories/contracts/mainnetBridgeOApp/MainnetBridgeOApp__factory'; diff --git a/packages/shared/src/types/bridgeTransaction.ts b/packages/shared/src/types/bridgeTransaction.ts index 4fa8068..fb6a6aa 100644 --- a/packages/shared/src/types/bridgeTransaction.ts +++ b/packages/shared/src/types/bridgeTransaction.ts @@ -2,6 +2,7 @@ export interface BridgeTransactionData { guid: string; status: BridgeTransactionStatus; nonce: number; + amount: string; verifiedAt?: FirebaseFirestore.Timestamp; alertSent?: boolean; lastAlertAt?: FirebaseFirestore.Timestamp; @@ -18,8 +19,13 @@ export interface BridgeTransactionInput { export interface BridgeTransactionUpdateInput { status: BridgeTransactionStatus; + clearedAt?: Date; + clearMessageTxHash?: string; alertSent?: boolean; - lastAlertAt?: FirebaseFirestore.Timestamp; + lastAlertAt?: Date; + manualRetryAt?: Date; + manualRetryTxHash?: string; + verifiedAt?: Date; } export interface BridgeTransactionFilter { @@ -28,7 +34,9 @@ export interface BridgeTransactionFilter { } export enum BridgeTransactionStatus { + // original QUEUED = "QUEUED", + // definition INFLIGHT = "INFLIGHT", CONFIRMING = "CONFIRMING", VERIFIED = "VERIFIED", @@ -36,4 +44,6 @@ export enum BridgeTransactionStatus { FAILED = "FAILED", PAYLOAD_STORED = "PAYLOAD_STORED", BLOCKED = "BLOCKED", + // original + NOT_FOUND = "NOT_FOUND", } diff --git a/packages/shared/src/types/utils.ts b/packages/shared/src/types/utils.ts index 3ed9c3a..d180364 100644 --- a/packages/shared/src/types/utils.ts +++ b/packages/shared/src/types/utils.ts @@ -18,3 +18,5 @@ export const FIRESTORE_DOCUMENT_TYPES = { export type FirestoreDocumentKey = (typeof FIRESTORE_DOCUMENT_TYPES)[keyof typeof FIRESTORE_DOCUMENT_TYPES]; + +export type DiscordMessageType = "INFO" | "WARN" | "FATAL"; diff --git a/packages/token-map-register/package.json b/packages/token-map-register/package.json index a957994..d2ff37a 100644 --- a/packages/token-map-register/package.json +++ b/packages/token-map-register/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "dependencies": { "@intmax2-function/shared": "workspace:*", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/token-metadata-sync/package.json b/packages/token-metadata-sync/package.json index 70b88a9..048dbdb 100644 --- a/packages/token-metadata-sync/package.json +++ b/packages/token-metadata-sync/package.json @@ -5,7 +5,7 @@ "@intmax2-function/shared": "workspace:*", "axios": "^1.11.0", "coingecko-api-v3": "^0.0.31", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/token/package.json b/packages/token/package.json index 1ae4d56..851a5b2 100644 --- a/packages/token/package.json +++ b/packages/token/package.json @@ -4,7 +4,7 @@ "dependencies": { "@hono/node-server": "^1.19.0", "@intmax2-function/shared": "workspace:*", - "hono": "^4.9.2" + "hono": "^4.9.4" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/tx-map/package.json b/packages/tx-map/package.json index 2156b29..cc24cf8 100644 --- a/packages/tx-map/package.json +++ b/packages/tx-map/package.json @@ -4,7 +4,7 @@ "dependencies": { "@hono/node-server": "^1.19.0", "@intmax2-function/shared": "workspace:*", - "hono": "^4.9.2" + "hono": "^4.9.4" }, "scripts": { "start": "node dist/index.js", diff --git a/packages/wallet-observer/package.json b/packages/wallet-observer/package.json index 50eaf62..97eeebd 100644 --- a/packages/wallet-observer/package.json +++ b/packages/wallet-observer/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "dependencies": { "@intmax2-function/shared": "workspace:*", - "viem": "^2.33.3" + "viem": "^2.34.0" }, "scripts": { "start": "node dist/index.js", diff --git a/yarn.lock b/yarn.lock index 3ac0e50..cc3a117 100644 --- a/yarn.lock +++ b/yarn.lock @@ -224,6 +224,23 @@ __metadata: languageName: node linkType: hard +"@discordjs/rest@npm:^2.6.0": + version: 2.6.0 + resolution: "@discordjs/rest@npm:2.6.0" + dependencies: + "@discordjs/collection": "npm:^2.1.1" + "@discordjs/util": "npm:^1.1.1" + "@sapphire/async-queue": "npm:^1.5.3" + "@sapphire/snowflake": "npm:^3.5.3" + "@vladfrangu/async_event_emitter": "npm:^2.4.6" + discord-api-types: "npm:^0.38.16" + magic-bytes.js: "npm:^1.10.0" + tslib: "npm:^2.6.3" + undici: "npm:6.21.3" + checksum: 10c0/67e12f54b8aa11208441d07dd2a30d3b125142a5bc76f34f5b7de3e676334f36b6cce63a0afd78d380eea25d8c56ade8ae3fd8770c88ec31c318a20d412ff31f + languageName: node + linkType: hard + "@discordjs/util@npm:^1.1.0, @discordjs/util@npm:^1.1.1": version: 1.1.1 resolution: "@discordjs/util@npm:1.1.1" @@ -848,9 +865,9 @@ __metadata: languageName: node linkType: hard -"@google-cloud/storage@npm:^7.16.0": - version: 7.16.0 - resolution: "@google-cloud/storage@npm:7.16.0" +"@google-cloud/storage@npm:^7.17.0": + version: 7.17.0 + resolution: "@google-cloud/storage@npm:7.17.0" dependencies: "@google-cloud/paginator": "npm:^5.0.0" "@google-cloud/projectify": "npm:^4.0.0" @@ -867,7 +884,7 @@ __metadata: retry-request: "npm:^7.0.0" teeny-request: "npm:^9.0.0" uuid: "npm:^8.0.0" - checksum: 10c0/a2a3f341232415d702c8fb054ec2eecbb6908a613848d7279f0b36db9b556ad93444a77a2f2a4c4c6b3f8901b3e7b2350120408c89b17c0ee17b31867a261462 + checksum: 10c0/6246c278bddfb4b20532cadd100cbeb85ee076b3c89c6cd347ca21f4b82c8985b9221e5e2bacdccb80b7726236027a437da7e553ea4b2c171371f8be50aa4f09 languageName: node linkType: hard @@ -909,15 +926,15 @@ __metadata: resolution: "@intmax2-function/shared@workspace:packages/shared" dependencies: "@google-cloud/firestore": "npm:^7.11.3" - "@google-cloud/storage": "npm:^7.16.0" + "@google-cloud/storage": "npm:^7.17.0" "@hono/node-server": "npm:^1.19.0" - abitype: "npm:^1.0.8" + abitype: "npm:^1.0.9" alchemy-sdk: "npm:^3.6.3" axios: "npm:^1.11.0" - discord.js: "npm:^14.21.0" + discord.js: "npm:^14.22.1" envalid: "npm:^8.1.0" ethers: "npm:^6.15.0" - hono: "npm:^4.9.2" + hono: "npm:^4.9.4" hono-rate-limiter: "npm:^0.4.2" http-status: "npm:2.1.0" ioredis: "npm:^5.7.0" @@ -926,8 +943,8 @@ __metadata: pino-pretty: "npm:^13.1.1" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" - zod: "npm:4.0.17" + viem: "npm:^2.34.0" + zod: "npm:4.1.0" languageName: unknown linkType: soft @@ -1033,15 +1050,6 @@ __metadata: languageName: node linkType: hard -"@noble/curves@npm:1.9.2, @noble/curves@npm:^1.9.1": - version: 1.9.2 - resolution: "@noble/curves@npm:1.9.2" - dependencies: - "@noble/hashes": "npm:1.8.0" - checksum: 10c0/21d049ae4558beedbf5da0004407b72db84360fa29d64822d82dc9e80251e1ecb46023590cc4b20e70eed697d1b87279b4911dc39f8694c51c874289cfc8e9a7 - languageName: node - linkType: hard - "@noble/curves@npm:1.9.6": version: 1.9.6 resolution: "@noble/curves@npm:1.9.6" @@ -1060,6 +1068,15 @@ __metadata: languageName: node linkType: hard +"@noble/curves@npm:^1.9.1": + version: 1.9.2 + resolution: "@noble/curves@npm:1.9.2" + dependencies: + "@noble/hashes": "npm:1.8.0" + checksum: 10c0/21d049ae4558beedbf5da0004407b72db84360fa29d64822d82dc9e80251e1ecb46023590cc4b20e70eed697d1b87279b4911dc39f8694c51c874289cfc8e9a7 + languageName: node + linkType: hard + "@noble/hashes@npm:1.3.2": version: 1.3.2 resolution: "@noble/hashes@npm:1.3.2" @@ -1728,6 +1745,21 @@ __metadata: languageName: node linkType: hard +"abitype@npm:^1.0.9": + version: 1.0.9 + resolution: "abitype@npm:1.0.9" + peerDependencies: + typescript: ">=5.0.4" + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + checksum: 10c0/8707fcc80d3edaea14717b0c9ebe15cef1f11825a9c5ffcdbd3ac8e53ae34aaa4c5eb9fb4c352d598d0013fcf71370eeda8eac2fc575f04fa0699a43477ae52b + languageName: node + linkType: hard + "abort-controller@npm:^3.0.0": version: 3.0.0 resolution: "abort-controller@npm:3.0.0" @@ -1944,7 +1976,7 @@ __metadata: axios: "npm:^1.11.0" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" vitest: "npm:^3.2.4" languageName: unknown linkType: soft @@ -2305,7 +2337,7 @@ __metadata: ethers: "npm:^6.15.0" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" vitest: "npm:^3.2.4" languageName: unknown linkType: soft @@ -2317,24 +2349,31 @@ __metadata: languageName: node linkType: hard -"discord.js@npm:^14.21.0": - version: 14.21.0 - resolution: "discord.js@npm:14.21.0" +"discord-api-types@npm:^0.38.16": + version: 0.38.21 + resolution: "discord-api-types@npm:0.38.21" + checksum: 10c0/e20e5a4ad6db6dc9b436d32af25ef85f7562348ce695a5c8f1097dd29850b5918fe42a6754c97b53a532c5225ea51a8f396cf17aded86babce02977a68380fbe + languageName: node + linkType: hard + +"discord.js@npm:^14.22.1": + version: 14.22.1 + resolution: "discord.js@npm:14.22.1" dependencies: "@discordjs/builders": "npm:^1.11.2" "@discordjs/collection": "npm:1.5.3" "@discordjs/formatters": "npm:^0.6.1" - "@discordjs/rest": "npm:^2.5.1" + "@discordjs/rest": "npm:^2.6.0" "@discordjs/util": "npm:^1.1.1" "@discordjs/ws": "npm:^1.2.3" "@sapphire/snowflake": "npm:3.5.3" - discord-api-types: "npm:^0.38.1" + discord-api-types: "npm:^0.38.16" fast-deep-equal: "npm:3.1.3" lodash.snakecase: "npm:4.1.1" magic-bytes.js: "npm:^1.10.0" tslib: "npm:^2.6.3" undici: "npm:6.21.3" - checksum: 10c0/35d89b66ec427ecc972f9141540774af6c6a5bf177bdbb5c948efbf838ec074204fb4610227f0f8405336d66706ba17f7280aedf00cccd858ef5c1048d861b34 + checksum: 10c0/d67dc90537270b4941aee896f70aafdba440dcd0f5d1d1f2762888b2edb804c1a384ccff48b6159211225091c3b5d8669799846d46147b907569a3591d8064b9 languageName: node linkType: hard @@ -3117,10 +3156,10 @@ __metadata: languageName: node linkType: hard -"hono@npm:^4.9.2": - version: 4.9.2 - resolution: "hono@npm:4.9.2" - checksum: 10c0/0f1a25ea729e90ce9ace8f8dc4e05a180a1a41e3fdd68e5564a4348c260b784b7dccfc4e4c9e004eb0f42acbd9360bda0856639088ba11639c6851929c1d77f7 +"hono@npm:^4.9.4": + version: 4.9.4 + resolution: "hono@npm:4.9.4" + checksum: 10c0/2ecea6846d6fb2f9135e1287af849c5fbafac0394b2e38b1d00d4afe00b791c20e39b6a6d8dcd6c444b97aafcf7043509f53d00960da636ce395fe91e089ede5 languageName: node linkType: hard @@ -3242,7 +3281,7 @@ __metadata: semver: "npm:^7.7.2" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" languageName: unknown linkType: soft @@ -3253,7 +3292,7 @@ __metadata: "@intmax2-function/shared": "workspace:*" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" languageName: unknown linkType: soft @@ -3267,7 +3306,7 @@ __metadata: semver: "npm:^7.7.2" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" languageName: unknown linkType: soft @@ -3277,7 +3316,7 @@ __metadata: dependencies: "@hono/node-server": "npm:^1.19.0" "@intmax2-function/shared": "workspace:*" - hono: "npm:^4.9.2" + hono: "npm:^4.9.4" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" languageName: unknown @@ -3654,7 +3693,7 @@ __metadata: ethers: "npm:^6.15.0" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" languageName: unknown linkType: soft @@ -3796,7 +3835,7 @@ __metadata: "@intmax2-function/shared": "workspace:*" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" languageName: unknown linkType: soft @@ -3817,7 +3856,7 @@ __metadata: ethers: "npm:^6.15.0" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" vitest: "npm:^3.2.4" languageName: unknown linkType: soft @@ -3830,7 +3869,7 @@ __metadata: ethers: "npm:^6.15.0" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" languageName: unknown linkType: soft @@ -3959,27 +3998,6 @@ __metadata: languageName: node linkType: hard -"ox@npm:0.8.6": - version: 0.8.6 - resolution: "ox@npm:0.8.6" - dependencies: - "@adraffy/ens-normalize": "npm:^1.11.0" - "@noble/ciphers": "npm:^1.3.0" - "@noble/curves": "npm:^1.9.1" - "@noble/hashes": "npm:^1.8.0" - "@scure/bip32": "npm:^1.7.0" - "@scure/bip39": "npm:^1.6.0" - abitype: "npm:^1.0.8" - eventemitter3: "npm:5.0.1" - peerDependencies: - typescript: ">=5.4.0" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/025c638966c6e569bb38a78a6f9f84bbeb9f5b0a594ef011ab3f81414edcaf5b20d9ea7d8f90471ddafdcb3f21c61f7a2255d35d2032e8daafbc8b20d98d27cf - languageName: node - linkType: hard - "ox@npm:0.8.7": version: 0.8.7 resolution: "ox@npm:0.8.7" @@ -4147,7 +4165,7 @@ __metadata: "@hono/node-server": "npm:^1.19.0" "@intmax2-function/shared": "workspace:*" axios: "npm:^1.11.0" - hono: "npm:^4.9.2" + hono: "npm:^4.9.4" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" languageName: unknown @@ -4821,7 +4839,7 @@ __metadata: "@intmax2-function/shared": "workspace:*" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" languageName: unknown linkType: soft @@ -4834,7 +4852,7 @@ __metadata: coingecko-api-v3: "npm:^0.0.31" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" languageName: unknown linkType: soft @@ -4844,7 +4862,7 @@ __metadata: dependencies: "@hono/node-server": "npm:^1.19.0" "@intmax2-function/shared": "workspace:*" - hono: "npm:^4.9.2" + hono: "npm:^4.9.4" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" languageName: unknown @@ -4910,7 +4928,7 @@ __metadata: dependencies: "@hono/node-server": "npm:^1.19.0" "@intmax2-function/shared": "workspace:*" - hono: "npm:^4.9.2" + hono: "npm:^4.9.4" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" languageName: unknown @@ -5026,27 +5044,6 @@ __metadata: languageName: node linkType: hard -"viem@npm:^2.33.3": - version: 2.33.3 - resolution: "viem@npm:2.33.3" - dependencies: - "@noble/curves": "npm:1.9.2" - "@noble/hashes": "npm:1.8.0" - "@scure/bip32": "npm:1.7.0" - "@scure/bip39": "npm:1.6.0" - abitype: "npm:1.0.8" - isows: "npm:1.0.7" - ox: "npm:0.8.6" - ws: "npm:8.18.2" - peerDependencies: - typescript: ">=5.0.4" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10c0/3e1e1849f88529d37e5a52336003209d2b054364738bdd2b89ef3e684cdefe7894a541886bfbfe35ef6c5441849cd7fa6f393ecfa1008c09a5cacc2c978fd42d - languageName: node - linkType: hard - "viem@npm:^2.34.0": version: 2.34.0 resolution: "viem@npm:2.34.0" @@ -5201,7 +5198,7 @@ __metadata: "@intmax2-function/shared": "workspace:*" tsx: "npm:^4.20.4" typescript: "npm:^5.9.2" - viem: "npm:^2.33.3" + viem: "npm:^2.34.0" languageName: unknown linkType: soft @@ -5329,21 +5326,6 @@ __metadata: languageName: node linkType: hard -"ws@npm:8.18.2, ws@npm:^8.5.0": - version: 8.18.2 - resolution: "ws@npm:8.18.2" - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - checksum: 10c0/4b50f67931b8c6943c893f59c524f0e4905bbd183016cfb0f2b8653aa7f28dad4e456b9d99d285bbb67cca4fedd9ce90dfdfaa82b898a11414ebd66ee99141e4 - languageName: node - linkType: hard - "ws@npm:8.18.3": version: 8.18.3 resolution: "ws@npm:8.18.3" @@ -5389,6 +5371,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.5.0": + version: 8.18.2 + resolution: "ws@npm:8.18.2" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 10c0/4b50f67931b8c6943c893f59c524f0e4905bbd183016cfb0f2b8653aa7f28dad4e456b9d99d285bbb67cca4fedd9ce90dfdfaa82b898a11414ebd66ee99141e4 + languageName: node + linkType: hard + "y18n@npm:^5.0.5": version: 5.0.8 resolution: "y18n@npm:5.0.8" @@ -5446,9 +5443,9 @@ __metadata: languageName: node linkType: hard -"zod@npm:4.0.17": - version: 4.0.17 - resolution: "zod@npm:4.0.17" - checksum: 10c0/c56ef4cc02f8f52be8724c5a8b338266202d68477c7606bee9b7299818b75c9adc27f16f4b6704a372f3e7578bd016f389de19bfec766564b7c39d0d327c540a +"zod@npm:4.1.0": + version: 4.1.0 + resolution: "zod@npm:4.1.0" + checksum: 10c0/b39bce830cf9864e33b00da2e3fee008e1abb96fff169936ba779648276b6a031d35ed5438d7659ac5d5e09b932d40dce6c255344184794d56f8bd22e501561b languageName: node linkType: hard