diff --git a/package.json b/package.json index 932d5bbbf02..1251e281c13 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "yarn": ">=999.0.0", "npm": ">=999.0.0" }, - "version": "2.24.3", + "version": "2.24.4", "private": true, "license": "AGPL-3.0-or-later", "scripts": { diff --git a/packages/web3-providers/src/Chainbase/apis/RedPacketAPI.ts b/packages/web3-providers/src/Chainbase/apis/RedPacketAPI.ts index 384dff2311e..876d1f47ad2 100644 --- a/packages/web3-providers/src/Chainbase/apis/RedPacketAPI.ts +++ b/packages/web3-providers/src/Chainbase/apis/RedPacketAPI.ts @@ -7,58 +7,70 @@ import { createPageable, pageableToIterator, } from '@masknet/shared-base' -import type { ChainId, SchemaType } from '@masknet/web3-shared-evm' +import { ChainId, type SchemaType } from '@masknet/web3-shared-evm' import { TRANSACTIONS_BY_CONTRACT_METHOD_ENDPOINT, MAX_SIZE_PER_PAGE } from '../constants.js' import type { Tx } from '../types.js' import { fetchJSON } from '../../helpers/fetchJSON.js' import type { RedPacketBaseAPI } from '../../entry-types.js' -class ChainbaseRedPacketAPI implements RedPacketBaseAPI.Provider { - async getHistoryTransactions( +export class ChainbaseRedPacketAPI implements RedPacketBaseAPI.Provider { + /** + * @see https://docs.chainbase.com/reference/supported-chains + */ + static isSupportedChain(chainId: ChainId) { + const supported = [ + ChainId.Mainnet, + ChainId.Matic, + ChainId.BSC, + ChainId.Avalanche, + ChainId.Arbitrum, + ChainId.Base, + /** zkSync */ 324, + ].includes(chainId) + console.error('Unsupported chain by ChainBase, see https://docs.chainbase.com/reference/supported-chains') + return supported + } + static async getHistoryTransactions( chainId: ChainId, senderAddress: string, contractAddress: string, methodId: string, ): Promise> | undefined> { - try { - const txes = await asyncIteratorToArray( - pageableToIterator(async (indicator) => { - const { records } = await fetchJSON<{ records: { data: { result: Tx[] } } }>( - urlcat(TRANSACTIONS_BY_CONTRACT_METHOD_ENDPOINT, { - senderAddress, - contractAddress, - chainId, - methodId: `${methodId}%`, // '%' for sql string match. - size: MAX_SIZE_PER_PAGE, - offset: Number(indicator?.id ?? 0) * MAX_SIZE_PER_PAGE, - }), - ) + const txes = await asyncIteratorToArray( + pageableToIterator(async (indicator) => { + const { records } = await fetchJSON<{ records: { data: { result: Tx[] } } }>( + urlcat(TRANSACTIONS_BY_CONTRACT_METHOD_ENDPOINT, { + senderAddress, + contractAddress, + chainId, + methodId: `${methodId}%`, // '%' for sql string match. + size: MAX_SIZE_PER_PAGE, + offset: Number(indicator?.id ?? 0) * MAX_SIZE_PER_PAGE, + }), + ) - return createPageable( - records.data.result, - createIndicator(indicator), - records.data.result.length === 0 ? undefined : createNextIndicator(indicator), - ) - }), - ) + return createPageable( + records.data.result, + createIndicator(indicator), + records.data.result.length === 0 ? undefined : createNextIndicator(indicator), + ) + }), + ) - if (!txes?.length) return + if (!txes?.length) return - return txes - .sort((a, b) => new Date(b.block_timestamp).getTime() - new Date(a.block_timestamp).getTime()) - .map((x) => { - return { - input: x.input, - to: x.to_address, - from: x.from_address, - hash: x.transaction_hash, - chainId, - blockNumber: Number(x.block_number), - } as Transaction - }) - } catch { - return - } + return txes + .sort((a, b) => new Date(b.block_timestamp).getTime() - new Date(a.block_timestamp).getTime()) + .map((x) => { + return { + input: x.input, + to: x.to_address, + from: x.from_address, + hash: x.transaction_hash, + chainId, + blockNumber: Number(x.block_number), + } as Transaction + }) } } export const ChainbaseRedPacket = new ChainbaseRedPacketAPI() diff --git a/packages/web3-providers/src/Etherscan/apis/RedPacketAPI.ts b/packages/web3-providers/src/Etherscan/apis/RedPacketAPI.ts index 8640f1a5dc0..e7fc5056a96 100644 --- a/packages/web3-providers/src/Etherscan/apis/RedPacketAPI.ts +++ b/packages/web3-providers/src/Etherscan/apis/RedPacketAPI.ts @@ -16,28 +16,28 @@ class EtherscanRedPacketAPI implements RedPacketBaseAPI.Provider> | undefined> { if (!senderAddress || !contractAddress || !startBlock || !endBlock || !methodId) return - try { - const { result } = await fetchJSON<{ result: Array> }>( - urlcat(EtherscanURL.from(chainId), { - action: 'txlist', - module: 'account', - sort: 'desc', - startBlock, - endBlock, - address: contractAddress, - chain_id: chainId, - }), - ) + const { result } = await fetchJSON<{ result: Array> }>( + urlcat(EtherscanURL.from(chainId), { + action: 'txlist', + module: 'account', + sort: 'desc', + startBlock, + endBlock, + address: contractAddress, + chain_id: chainId, + }), + ) - if (!result) return + if (!result) return - methodId = methodId.toLowerCase() - return result - .filter((x) => x.methodId?.toLowerCase() === methodId && isSameAddress(x.from, senderAddress)) - .map((x) => ({ ...x, chainId })) - } catch { - return - } + methodId = methodId.toLowerCase() + const methodIdLength = methodId.length + return result + .filter((x) => { + const txMethodId = x.methodId || x.input?.slice(0, methodIdLength) + return txMethodId?.toLowerCase() === methodId && isSameAddress(x.from, senderAddress) + }) + .map((x) => ({ ...x, chainId })) } } export const EtherscanRedPacket = new EtherscanRedPacketAPI() diff --git a/packages/web3-providers/src/RedPacket/index.ts b/packages/web3-providers/src/RedPacket/index.ts index 3222b6434e5..db181a061fd 100644 --- a/packages/web3-providers/src/RedPacket/index.ts +++ b/packages/web3-providers/src/RedPacket/index.ts @@ -8,7 +8,7 @@ import REDPACKET_ABI from '@masknet/web3-contracts/abis/HappyRedPacketV4.json' import NFT_REDPACKET_ABI from '@masknet/web3-contracts/abis/NftRedPacket.json' import { DSEARCH_BASE_URL } from '../DSearch/constants.js' import { fetchFromDSearch } from '../DSearch/helpers.js' -import { ChainbaseRedPacket } from '../Chainbase/index.js' +import { ChainbaseRedPacketAPI } from '../Chainbase/index.js' import { EtherscanRedPacket } from '../Etherscan/index.js' import { ContractRedPacket } from './api.js' import { @@ -89,24 +89,24 @@ class RedPacketAPI implements RedPacketBaseAPI.Provider { fromBlock: number, endBlock: number, ) { - return attemptUntil( - [ - () => { - return ChainbaseRedPacket.getHistoryTransactions(chainId, senderAddress, contractAddress, methodId) - }, - () => { - return EtherscanRedPacket.getHistoryTransactions( - chainId, - senderAddress, - contractAddress, - methodId, - fromBlock, - endBlock, - ) - }, - ], - [], - ) + const attempts = [ + () => { + return EtherscanRedPacket.getHistoryTransactions( + chainId, + senderAddress, + contractAddress, + methodId, + fromBlock, + endBlock, + ) + }, + ] + if (ChainbaseRedPacketAPI.isSupportedChain(chainId)) { + attempts.unshift(() => { + return ChainbaseRedPacketAPI.getHistoryTransactions(chainId, senderAddress, contractAddress, methodId) + }) + } + return attemptUntil(attempts, []) } async getCollectionsByOwner(