From 010173c3363ab0bb2cecd70f8f4bf51e3df19bf7 Mon Sep 17 00:00:00 2001 From: zy0n Date: Fri, 16 May 2025 14:19:43 -0400 Subject: [PATCH 01/17] feat: add relay ABI and export in abi.ts --- src/server/abi/abi.ts | 3 +- src/server/abi/json/relay.json | 748 +++++++++++++++++++++++++++++++++ 2 files changed, 750 insertions(+), 1 deletion(-) create mode 100644 src/server/abi/json/relay.json diff --git a/src/server/abi/abi.ts b/src/server/abi/abi.ts index 00a91061..e5e84f52 100644 --- a/src/server/abi/abi.ts +++ b/src/server/abi/abi.ts @@ -1,4 +1,5 @@ import ABI_ERC20 from './json/erc20.json'; import ABI_PERMIT2 from './json/permit2.json'; +import ABI_RELAY_ADAPT from './json/relay.json'; -export { ABI_ERC20, ABI_PERMIT2 }; +export { ABI_ERC20, ABI_PERMIT2, ABI_RELAY_ADAPT }; diff --git a/src/server/abi/json/relay.json b/src/server/abi/json/relay.json new file mode 100644 index 00000000..ba2836d1 --- /dev/null +++ b/src/server/abi/json/relay.json @@ -0,0 +1,748 @@ +[ + { + "inputs": [ + { + "internalType": "contract RailgunSmartWallet", + "name": "_railgun", + "type": "address" + }, + { + "internalType": "contract IWBase", + "name": "_wBase", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "callIndex", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "revertReason", + "type": "bytes" + } + ], + "name": "CallFailed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "callIndex", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "revertReason", + "type": "bytes" + } + ], + "name": "CallError", + "type": "event" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct G1Point", + "name": "a", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256[2]", + "name": "x", + "type": "uint256[2]" + }, + { + "internalType": "uint256[2]", + "name": "y", + "type": "uint256[2]" + } + ], + "internalType": "struct G2Point", + "name": "b", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct G1Point", + "name": "c", + "type": "tuple" + } + ], + "internalType": "struct SnarkProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "nullifiers", + "type": "bytes32[]" + }, + { + "internalType": "bytes32[]", + "name": "commitments", + "type": "bytes32[]" + }, + { + "components": [ + { + "internalType": "uint16", + "name": "treeNumber", + "type": "uint16" + }, + { + "internalType": "uint72", + "name": "minGasPrice", + "type": "uint72" + }, + { + "internalType": "enum UnshieldType", + "name": "unshield", + "type": "uint8" + }, + { + "internalType": "uint64", + "name": "chainID", + "type": "uint64" + }, + { + "internalType": "address", + "name": "adaptContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "adaptParams", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes32[4]", + "name": "ciphertext", + "type": "bytes32[4]" + }, + { + "internalType": "bytes32", + "name": "blindedSenderViewingKey", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "blindedReceiverViewingKey", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "annotationData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "memo", + "type": "bytes" + } + ], + "internalType": "struct CommitmentCiphertext[]", + "name": "commitmentCiphertext", + "type": "tuple[]" + } + ], + "internalType": "struct BoundParams", + "name": "boundParams", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "npk", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "enum TokenType", + "name": "tokenType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenSubID", + "type": "uint256" + } + ], + "internalType": "struct TokenData", + "name": "token", + "type": "tuple" + }, + { + "internalType": "uint120", + "name": "value", + "type": "uint120" + } + ], + "internalType": "struct CommitmentPreimage", + "name": "unshieldPreimage", + "type": "tuple" + } + ], + "internalType": "struct Transaction[]", + "name": "_transactions", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "bytes31", + "name": "random", + "type": "bytes31" + }, + { + "internalType": "bool", + "name": "requireSuccess", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "minGasLimit", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct RelayAdapt.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "internalType": "struct RelayAdapt.ActionData", + "name": "_actionData", + "type": "tuple" + } + ], + "name": "getAdaptParams", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "_requireSuccess", + "type": "bool" + }, + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct RelayAdapt.Call[]", + "name": "_calls", + "type": "tuple[]" + } + ], + "name": "multicall", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "railgun", + "outputs": [ + { + "internalType": "contract RailgunSmartWallet", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct G1Point", + "name": "a", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256[2]", + "name": "x", + "type": "uint256[2]" + }, + { + "internalType": "uint256[2]", + "name": "y", + "type": "uint256[2]" + } + ], + "internalType": "struct G2Point", + "name": "b", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "x", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "y", + "type": "uint256" + } + ], + "internalType": "struct G1Point", + "name": "c", + "type": "tuple" + } + ], + "internalType": "struct SnarkProof", + "name": "proof", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "merkleRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "nullifiers", + "type": "bytes32[]" + }, + { + "internalType": "bytes32[]", + "name": "commitments", + "type": "bytes32[]" + }, + { + "components": [ + { + "internalType": "uint16", + "name": "treeNumber", + "type": "uint16" + }, + { + "internalType": "uint72", + "name": "minGasPrice", + "type": "uint72" + }, + { + "internalType": "enum UnshieldType", + "name": "unshield", + "type": "uint8" + }, + { + "internalType": "uint64", + "name": "chainID", + "type": "uint64" + }, + { + "internalType": "address", + "name": "adaptContract", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "adaptParams", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "bytes32[4]", + "name": "ciphertext", + "type": "bytes32[4]" + }, + { + "internalType": "bytes32", + "name": "blindedSenderViewingKey", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "blindedReceiverViewingKey", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "annotationData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "memo", + "type": "bytes" + } + ], + "internalType": "struct CommitmentCiphertext[]", + "name": "commitmentCiphertext", + "type": "tuple[]" + } + ], + "internalType": "struct BoundParams", + "name": "boundParams", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "npk", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "enum TokenType", + "name": "tokenType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenSubID", + "type": "uint256" + } + ], + "internalType": "struct TokenData", + "name": "token", + "type": "tuple" + }, + { + "internalType": "uint120", + "name": "value", + "type": "uint120" + } + ], + "internalType": "struct CommitmentPreimage", + "name": "unshieldPreimage", + "type": "tuple" + } + ], + "internalType": "struct Transaction[]", + "name": "_transactions", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "bytes31", + "name": "random", + "type": "bytes31" + }, + { + "internalType": "bool", + "name": "requireSuccess", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "minGasLimit", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct RelayAdapt.Call[]", + "name": "calls", + "type": "tuple[]" + } + ], + "internalType": "struct RelayAdapt.ActionData", + "name": "_actionData", + "type": "tuple" + } + ], + "name": "relay", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "npk", + "type": "bytes32" + }, + { + "components": [ + { + "internalType": "enum TokenType", + "name": "tokenType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenSubID", + "type": "uint256" + } + ], + "internalType": "struct TokenData", + "name": "token", + "type": "tuple" + }, + { + "internalType": "uint120", + "name": "value", + "type": "uint120" + } + ], + "internalType": "struct CommitmentPreimage", + "name": "preimage", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bytes32[3]", + "name": "encryptedBundle", + "type": "bytes32[3]" + }, + { + "internalType": "bytes32", + "name": "shieldKey", + "type": "bytes32" + } + ], + "internalType": "struct ShieldCiphertext", + "name": "ciphertext", + "type": "tuple" + } + ], + "internalType": "struct ShieldRequest[]", + "name": "_shieldRequests", + "type": "tuple[]" + } + ], + "name": "shield", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "components": [ + { + "internalType": "enum TokenType", + "name": "tokenType", + "type": "uint8" + }, + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenSubID", + "type": "uint256" + } + ], + "internalType": "struct TokenData", + "name": "token", + "type": "tuple" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "internalType": "struct RelayAdapt.TokenTransfer[]", + "name": "_transfers", + "type": "tuple[]" + } + ], + "name": "transfer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "unwrapBase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "wBase", + "outputs": [ + { + "internalType": "contract IWBase", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "wrapBase", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] From f7c75ff12564837c9ffca213bd751b873c52ab7e Mon Sep 17 00:00:00 2001 From: zy0n Date: Fri, 16 May 2025 14:19:59 -0400 Subject: [PATCH 02/17] feat: enhance transaction validation by including chain parameter in createValidTransaction --- .../transactions/transaction-validator.ts | 67 ++++++++++++++++++- .../methods/transact-method.ts | 4 +- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/src/server/transactions/transaction-validator.ts b/src/server/transactions/transaction-validator.ts index 07d0d31c..c549994e 100644 --- a/src/server/transactions/transaction-validator.ts +++ b/src/server/transactions/transaction-validator.ts @@ -1,7 +1,11 @@ -import { ContractTransaction, getAddress, isHexString } from 'ethers'; +import { ContractTransaction, getAddress, Interface, isHexString, type InterfaceAbi, type TransactionDescription } from 'ethers'; import { logger } from '../../util/logger'; +import { ABI_RELAY_ADAPT } from '../abi/abi'; +import type { BroadcasterChain } from '../../models/chain-models'; +import configNetworks from '../config/config-networks'; export const createValidTransaction = ( + chain: BroadcasterChain, to: string, data: string, value?: bigint, @@ -10,14 +14,75 @@ export const createValidTransaction = ( if (!isHexString(data)) { throw new Error('Invalid data field.'); } + const isProxyCall = checkIsProxyAddress(chain, to); + const isRelayCall = checkIsRelayAdaptAddress(chain, to); + const validatedTo = isProxyCall || isRelayCall; + + if(!validatedTo){ + throw new Error("Invalid to address. Must be a known contract.") + } + + if(isRelayCall){ + const decoded = decodeData(data, ABI_RELAY_ADAPT); + if(decoded){ + const needsValidation = isCallToRelay(decoded); + if(needsValidation){ + const validatedData = validateRelayCallData(decoded); + if(!validatedData){ + throw new Error("Invalid Transaction Call.") + } + } + } + } const validTransaction: ContractTransaction = { to: getAddress(to), data, value, }; + return validTransaction; } catch (err) { logger.error(err); throw new Error('Could not create valid transaction object.'); } }; + +const decodeData = (data: string, abi: InterfaceAbi) => { + const iface = new Interface(abi); + try { + const decoded = iface.parseTransaction({ data }); + return decoded; + } catch { + return null; + } +}; + +const isCallToRelay = (decoded: TransactionDescription | null) =>{ + if (!decoded) return false; + if (decoded.name !== "relay") return false; + return true +} + +const validateRelayCallData = (decoded: TransactionDescription) => { + const invalid: boolean = decoded.args[1][1]; + return !invalid; +}; + +const checkIsProxyAddress = ( + chain: BroadcasterChain, + address: string, +) =>{ + const { proxyContract } = + configNetworks[chain.type][chain.id]; + return address.toLowerCase() === proxyContract.toLowerCase() + +} + +const checkIsRelayAdaptAddress = ( + chain: BroadcasterChain, + address: string, +) =>{ + const { relayAdaptContract } = + configNetworks[chain.type][chain.id]; + return address.toLowerCase() === relayAdaptContract.toLowerCase() +} diff --git a/src/server/waku-broadcaster/methods/transact-method.ts b/src/server/waku-broadcaster/methods/transact-method.ts index 40fd7b84..06ea61d3 100644 --- a/src/server/waku-broadcaster/methods/transact-method.ts +++ b/src/server/waku-broadcaster/methods/transact-method.ts @@ -221,7 +221,7 @@ export const transactMethod = async ( ); } - const transaction = createValidTransaction(to, data, 0n); + const transaction = createValidTransaction(chain, to, data, 0n); const txResponse = await processTransaction( txidVersion, @@ -285,7 +285,7 @@ export const transactMethod = async ( dbg( `LOW FEE DETECTED: Retrying Transaction with minGasPrice: ${formattedInflatedSuggestion}`, ); - const transaction = createValidTransaction(to, data, 0n); + const transaction = createValidTransaction(chain, to, data, 0n); const txResponse = await processTransaction( txidVersion, chain, From a8f50f2369bba8a3c47f204839e8a39187fad1ec Mon Sep 17 00:00:00 2001 From: zy0n Date: Fri, 16 May 2025 14:22:12 -0400 Subject: [PATCH 03/17] test: update transaction validation test to include transaction object --- src/server/transactions/__tests__/transaction-validator.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/transactions/__tests__/transaction-validator.test.ts b/src/server/transactions/__tests__/transaction-validator.test.ts index 4824ff9a..f250a871 100644 --- a/src/server/transactions/__tests__/transaction-validator.test.ts +++ b/src/server/transactions/__tests__/transaction-validator.test.ts @@ -8,7 +8,7 @@ const { expect } = chai; describe('transaction-validator', () => { it('Should throw on bad transaction validation', () => { expect(() => - createValidTransaction('0x1234', '{{', BigInt('0x123')), + createValidTransaction({ id: 1, type: 0 },'0x1234', '{{', BigInt('0x123')), ).to.throw('Could not create valid transaction object.'); }); }); From 8c25ed7bc8448ce7dafe1b71d0415fc27967be61 Mon Sep 17 00:00:00 2001 From: zy0n Date: Fri, 16 May 2025 14:49:24 -0400 Subject: [PATCH 04/17] test: update waku-broadcaster tests to use dynamic proxy contract address --- .../waku-broadcaster/__tests__/waku-broadcaster.test.ts | 4 +++- src/test/mocks.test.ts | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/server/waku-broadcaster/__tests__/waku-broadcaster.test.ts b/src/server/waku-broadcaster/__tests__/waku-broadcaster.test.ts index 8ba54020..942059c7 100644 --- a/src/server/waku-broadcaster/__tests__/waku-broadcaster.test.ts +++ b/src/server/waku-broadcaster/__tests__/waku-broadcaster.test.ts @@ -89,6 +89,8 @@ const handleHTTPPost = async (url: string, data?: unknown) => { return { data: {}, status: 200 }; }; +const MOCK_TO_ADDRESS = configNetworks[chain.type][chain.id].proxyContract; + describe('waku-broadcaster', () => { before(async () => { configDefaults.transactionFees.feeExpirationInMS = 5 * 60 * 1000; @@ -255,7 +257,7 @@ describe('waku-broadcaster', () => { chainType: chain.type, feesID: '468abc', minGasPrice: '0x1000', - to: '0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE', + to: MOCK_TO_ADDRESS, data: '0x1234', broadcasterViewingKey: ByteUtils.hexlify(viewingPublicKey), useRelayAdapt: false, diff --git a/src/test/mocks.test.ts b/src/test/mocks.test.ts index 678b053a..aff1207c 100644 --- a/src/test/mocks.test.ts +++ b/src/test/mocks.test.ts @@ -41,8 +41,10 @@ export const getMockNetwork = (): Network => { gasEstimateLimitToActualRatio: 1.25, profit: 0.07, }, - proxyContract: '0x00', - relayAdaptContract: '0x00', + // proxyContract: '0x00', + // relayAdaptContract: '0x00', + proxyContract: NETWORK_CONFIG[NetworkName.Ethereum].proxyContract, + relayAdaptContract: NETWORK_CONFIG[NetworkName.Ethereum].relayAdaptContract, coingeckoNetworkId: CoingeckoNetworkID.Ethereum, fallbackProviderConfig: fallbackProvidersEthereum, deploymentBlock: 100, From 352259136cc55bd7e6f4953deb0eda2fcee3823c Mon Sep 17 00:00:00 2001 From: zy0n Date: Fri, 16 May 2025 16:51:23 -0400 Subject: [PATCH 05/17] fix: update 0x API endpoints and improve error handling for network URLs --- src/server/api/0x/0x-fetch.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/server/api/0x/0x-fetch.ts b/src/server/api/0x/0x-fetch.ts index 27b11228..ef130384 100644 --- a/src/server/api/0x/0x-fetch.ts +++ b/src/server/api/0x/0x-fetch.ts @@ -6,8 +6,8 @@ import { NetworkChainID } from '../../config/config-chains'; import configDefaults from '../../config/config-defaults'; export enum ZeroXApiEndpoint { - PriceLookup = 'swap/v1/price', - GetSwapQuote = 'swap/v1/quote', + PriceLookup = 'swap/permit2/price', + GetSwapQuote = 'swap/allowance-holder/quote', } export const getStablecoinReferenceSymbol = ( @@ -44,19 +44,14 @@ const zeroXApiUrl = (chain: BroadcasterChain): string => { case ChainType.EVM: { switch (chain.id) { case NetworkChainID.Ethereum: - return 'https://api.0x.org/'; - case NetworkChainID.EthereumGoerli: - return 'https://goerli.api.0x.org/'; case NetworkChainID.BNBChain: - return 'https://bsc.api.0x.org/'; case NetworkChainID.PolygonPOS: - return 'https://polygon.api.0x.org/'; case NetworkChainID.Arbitrum: - return 'https://arbitrum.api.0x.org/'; case NetworkChainID.PolygonMumbai: - return 'https://mumbai.api.0x.org/'; - case NetworkChainID.ArbitrumGoerli: case NetworkChainID.EthereumSepolia: + return 'https://api.0x.org/'; + case NetworkChainID.EthereumGoerli: + case NetworkChainID.ArbitrumGoerli: case NetworkChainID.PolygonAmoy: case NetworkChainID.Hardhat: throw new Error(`No 0x API URL for chain ${chain.type}:${chain.id}`); @@ -101,7 +96,6 @@ export const getZeroXData = async ( if (!apiKey) { throw new Error('Requires 0x API Key for prices/quotes.'); } - try { const rsp = await axios.get(url, { method: 'GET', @@ -109,6 +103,7 @@ export const getZeroXData = async ( Accept: 'application/json', 'Content-Type': 'application/json', '0x-api-key': apiKey, + '0x-version': 'v2' }, }); return rsp.data; From f74ba975a4a433fe96afb3baab508bd53fc2815b Mon Sep 17 00:00:00 2001 From: zy0n Date: Fri, 16 May 2025 16:51:33 -0400 Subject: [PATCH 06/17] feat: add tokenForSymbol function to retrieve token by symbol and update getMockTokenConfig to accept a symbol parameter --- src/server/tokens/network-tokens.ts | 15 +++++++++++++++ src/test/mocks.test.ts | 4 ++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/server/tokens/network-tokens.ts b/src/server/tokens/network-tokens.ts index 88942dfc..86c7ddb8 100644 --- a/src/server/tokens/network-tokens.ts +++ b/src/server/tokens/network-tokens.ts @@ -76,6 +76,21 @@ export const allTokenAddressesForNetwork = ( ); }; +export const tokenForSymbol = ( + chain: BroadcasterChain, + symbol: string +) =>{ + const tokens = networkTokens[chain.type][chain.id]; + for (const token of tokens) { + if (token.symbol.toLowerCase() === symbol.toLowerCase()) { + return token; + } + } + throw new Error( + `Unsupported token for chain ${chain.type}:${chain.id}: ${symbol}`, + ); +} + export const tokenForAddress = ( chain: BroadcasterChain, address: string, diff --git a/src/test/mocks.test.ts b/src/test/mocks.test.ts index aff1207c..48df5dd8 100644 --- a/src/test/mocks.test.ts +++ b/src/test/mocks.test.ts @@ -106,9 +106,9 @@ export const getMockSerializedTransaction = (): string => { return JSON.stringify(getMockContractTransaction()); }; -export const getMockTokenConfig = (): TokenConfig => { +export const getMockTokenConfig = (symbol = 'SHIB'): TokenConfig => { return { - symbol: 'SHIB', + symbol, }; }; From e673d76cd2470e797d5b191dd9ec03d4b3b269e0 Mon Sep 17 00:00:00 2001 From: zy0n Date: Fri, 16 May 2025 16:51:36 -0400 Subject: [PATCH 07/17] feat: enhance zeroX price lookup by adding chainId and integrating tokenForSymbol for improved token handling --- src/server/api/0x/0x-price.ts | 22 +++++++++++++++----- src/server/api/0x/__tests__/0x-price.test.ts | 21 +++++++++++++------ 2 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/server/api/0x/0x-price.ts b/src/server/api/0x/0x-price.ts index 79b19d09..3070983f 100644 --- a/src/server/api/0x/0x-price.ts +++ b/src/server/api/0x/0x-price.ts @@ -1,7 +1,7 @@ import { isDefined } from '@railgun-community/shared-models'; import { BroadcasterChain } from '../../../models/chain-models'; import { delay, promiseTimeout } from '../../../util/promise-utils'; -import { tokenForAddress } from '../../tokens/network-tokens'; +import { tokenForAddress, tokenForSymbol } from '../../tokens/network-tokens'; import { TokenPrice, TokenPriceUpdater } from '../../tokens/token-price-cache'; import { ZeroXApiEndpoint, @@ -20,10 +20,13 @@ let ZERO_X_PRICE_LOOKUP_DELAY = 1500; const refreshLocks: NumMapType> = {}; export type ZeroXPriceData = { + minBuyAmount: string; + sellAmount: string; price: string; }; export type ZeroXPriceParams = { + chainId: string; sellToken: string; buyToken: string; sellAmount: string; @@ -45,7 +48,6 @@ const zeroXPriceLookupByAddress = async ( ): Promise> => { try { const { decimals, symbol } = tokenForAddress(chain, tokenAddress); - // TODO: This depends on DAI being stable at $1. // As we've seen, this isn't the safest methodology. // However, if the price of DAI drops, the broadcasted fees can only increase, @@ -55,19 +57,23 @@ const zeroXPriceLookupByAddress = async ( if (symbol === stablecoinSymbol) { return { price: 1 }; } + const stablecoinToken = tokenForSymbol(chain, stablecoinSymbol); + const sellAmount = (10n ** decimals).toString(10); const params: ZeroXPriceParams = { + chainId: chain.id.toString(), sellToken: tokenAddress, - buyToken: stablecoinSymbol, + buyToken: stablecoinToken.address, sellAmount, // 1 token }; - const { price } = await getZeroXData( + const zeroXPriceData= await getZeroXData( ZeroXApiEndpoint.PriceLookup, chain, params, ); + const formattedPrice = formatPriceResponse(zeroXPriceData); return { - price: parseFloat(price), + price: parseFloat(formattedPrice), }; } catch (err) { return undefined; @@ -118,3 +124,9 @@ export const zeroXUpdatePricesByAddresses = async ( refreshLocks[chain.type][chain.id] = false; }; + + +export const formatPriceResponse = (zeroXPriceData: ZeroXPriceData)=>{ + const formattedPrice = BigInt(zeroXPriceData.minBuyAmount) / BigInt(zeroXPriceData.sellAmount) + return formattedPrice.toString(10); +} \ No newline at end of file diff --git a/src/server/api/0x/__tests__/0x-price.test.ts b/src/server/api/0x/__tests__/0x-price.test.ts index dcffc23f..8333284c 100644 --- a/src/server/api/0x/__tests__/0x-price.test.ts +++ b/src/server/api/0x/__tests__/0x-price.test.ts @@ -22,6 +22,7 @@ import configTokens from '../../../config/config-tokens'; import { initTokens } from '../../../tokens/network-tokens'; import { initNetworkProviders } from '../../../providers/active-network-providers'; import { + formatPriceResponse, overrideZeroXPriceLookupDelay_TEST_ONLY, ZeroXPriceData, ZeroXPriceParams, @@ -52,6 +53,8 @@ const TOKEN_PRICE_SOURCE = TokenPriceSource.ZeroX; const expectedZeroXPriceOutput: ZeroXPriceData = { price: '1234.56', + minBuyAmount: '1000000000000', + sellAmount: '100000000000' }; const validatePriceRefresherOutput = (chain: BroadcasterChain) => { @@ -83,7 +86,7 @@ describe('0x-price', () => { resetTokenPriceCache(); const tokenConfigs = { - [TOKEN_ADDRESS_1]: getMockTokenConfig(), + [TOKEN_ADDRESS_1]: getMockTokenConfig('DAI'), [TOKEN_ADDRESS_2]: getMockTokenConfig(), }; @@ -100,18 +103,23 @@ describe('0x-price', () => { it('Should run live 0x API fetch for RAIL token', async () => { const params: ZeroXPriceParams = { - sellToken: '0xe76c6c83af64e4c60245d8c7de953df673a7a33d', // RAIL - buyToken: 'DAI', - sellAmount: '1000000000000000000', // 1 token + chainId: '1', + sellToken: configNetworks[0][1].gasToken.wrappedAddress, // '0xe76c6c83af64e4c60245d8c7de953df673a7a33d', // RAIL + buyToken: '0x6B175474E89094C44Da98b954EedeAC495271d0F', + sellAmount: (1 * 10 ** 18).toString(), // '1000000000000000000', // 1 token } as ZeroXPriceParams; const zeroXPriceData = await getZeroXData( ZeroXApiEndpoint.PriceLookup, chainEthereum, params, ); + const formattedPrice = formatPriceResponse(zeroXPriceData); // BigInt(zeroXPriceData.minBuyAmount) / BigInt(zeroXPriceData.sellAmount) + expect(zeroXPriceData).to.be.an('object'); - expect(zeroXPriceData.price).to.be.a('string'); - expect(parseFloat(zeroXPriceData.price)).to.be.a('number'); + expect(zeroXPriceData.minBuyAmount).to.be.a('string'); + expect(zeroXPriceData.sellAmount).to.be.a('string'); + + expect(formattedPrice).to.be.a('string'); }).timeout(5000); it('Should format prices from mock ZeroX response', async () => { @@ -130,6 +138,7 @@ describe('0x-price', () => { tokenPrice, ), ); + validatePriceRefresherOutput(chainEthereum); stubGetZeroXData.restore(); From cf9357470cb21b897c72b12817fd4ff70c1eac3c Mon Sep 17 00:00:00 2001 From: zy0n Date: Fri, 16 May 2025 16:58:36 -0400 Subject: [PATCH 08/17] fix: update Polygon provider URL for improved reliability --- src/server/config/fallback-providers/137-polygon-pos.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/config/fallback-providers/137-polygon-pos.ts b/src/server/config/fallback-providers/137-polygon-pos.ts index 56dc52c8..ad84932a 100644 --- a/src/server/config/fallback-providers/137-polygon-pos.ts +++ b/src/server/config/fallback-providers/137-polygon-pos.ts @@ -4,7 +4,7 @@ const config: FallbackProviderJsonConfig = { chainId: 137, providers: [ { - provider: 'https://rpc.ankr.com/polygon', + provider: 'https://rpc-mainnet.matic.quiknode.pro', priority: 2, weight: 2, maxLogsPerBatch: 1, // Supports up to 10, but at 1 ethers handles getLogs differently, and this seems to be more stable. From 3b36b1587b0e326378ee1f1e9bc479344744cb09 Mon Sep 17 00:00:00 2001 From: zy0n Date: Thu, 5 Jun 2025 19:34:11 -0400 Subject: [PATCH 09/17] chore: update package version and dependencies for improved compatibility --- package.json | 8 ++++---- yarn.lock | 23 ++++++++++++++--------- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 154443a6..562eb19d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@railgun-community/poi-safe-broadcaster-example", - "version": "7.2.0", + "version": "7.3.0", "description": "", "main": "dist/main.js", "packageManager": "yarn@1.22.19", @@ -31,8 +31,8 @@ "dependencies": { "@0x/contract-addresses": "^8.0.0", "@noble/ed25519": "^1.7.1", - "@railgun-community/shared-models": "7.5.0", - "@railgun-community/wallet": "10.3.3", + "@railgun-community/shared-models": "^7.6.1", + "@railgun-community/wallet": "^10.4.0", "@walletconnect/jsonrpc-types": "^1.0.2", "@walletconnect/jsonrpc-utils": "^1.0.4", "axios": "1.7.2", @@ -70,4 +70,4 @@ "tsc-alias": "^1.8.2", "typescript": "^4.9.4" } -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index eb2faae2..0ccd9191 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1353,10 +1353,10 @@ resolved "https://registry.yarnpkg.com/@railgun-community/curve25519-scalarmult-wasm/-/curve25519-scalarmult-wasm-0.1.5.tgz#edb5e40a8f1fdb7f7e0de1d04e8badabe41cb2a8" integrity sha512-Cur8uM/IdNW3WzUwdPloDG1CF0rpSBDWq2yGXJMZ7IMeBGdc4Jj0h9tnNMFRZ35ZuCVVbZ3yClmqSa4PsbpdGQ== -"@railgun-community/engine@9.3.1": - version "9.3.1" - resolved "https://registry.yarnpkg.com/@railgun-community/engine/-/engine-9.3.1.tgz#cfc14b6a7dd7d4c841e0fbe91ccf417e71414424" - integrity sha512-fTN/Ct+myrcecBZOlk8+pEdNZI0gy3s9aGeu54YKAn1TAMORH9udu9dQ3UFEkXS9P+EdcABSpbxPp/KIrp+N6Q== +"@railgun-community/engine@9.4.0": + version "9.4.0" + resolved "https://registry.yarnpkg.com/@railgun-community/engine/-/engine-9.4.0.tgz#d8beb18ac83f2a560ce63f8b5e49e3f0866a2a5a" + integrity sha512-7BZcUKo5oVBWdyBrjpKft3zT0hFo1V3PzcDSuvEIDzA8mOqFXTrIr4j+0A9ONwb5bo4A/7vfO0yll6uk0Y4GSQ== dependencies: "@noble/ciphers" "^0.4.0" "@noble/ed25519" "^1.7.1" @@ -1393,10 +1393,15 @@ resolved "https://registry.yarnpkg.com/@railgun-community/shared-models/-/shared-models-7.5.0.tgz#d36d73740e32dbd5c21b2864e8c3db96e1241cb3" integrity sha512-npSFFzSq2nSCLseEBZmLwJlZ4hMJArzEeM/DpqAAyxaTfznSHvpPIKmvEWorXVGjG+6xB7AY01TPGOq+3XHdcA== -"@railgun-community/wallet@10.3.3": - version "10.3.3" - resolved "https://registry.yarnpkg.com/@railgun-community/wallet/-/wallet-10.3.3.tgz#cef885628b76b3c547a0016f298a2e5752fb7bbe" - integrity sha512-dsQV7sjso7mhE15HvJliLEMLsuvUMN5wDt6hSP7nm8S+n6hsBx6tSzc5JAI7nPsi1UVDIW/f96pqMRRPRPgYxw== +"@railgun-community/shared-models@^7.6.1": + version "7.6.1" + resolved "https://registry.yarnpkg.com/@railgun-community/shared-models/-/shared-models-7.6.1.tgz#f3cad60183dc0ad4b1e396d864349f22357e2bc3" + integrity sha512-53ZK5oibJNtJIgsDhOCw+nUGM+2WsJoE21ro1vGWTJYqN6xAFBUUC/19OvcbKWUNjWYTr7iaAeSthBrS0DoGIA== + +"@railgun-community/wallet@^10.4.0": + version "10.4.0" + resolved "https://registry.yarnpkg.com/@railgun-community/wallet/-/wallet-10.4.0.tgz#bc910981a494445634d5a04c187457934acc96db" + integrity sha512-G006G9ZAmZDEnVN8k/i6ygeZnbKjXd/MvnvgxRKi33k7uTK9mzlg9MchcEZo3wIvd39onvjUDkBCy/dLO7JbHA== dependencies: "@graphql-mesh/cache-localforage" "^0.7.20" "@graphql-mesh/cross-helpers" "^0.3.4" @@ -1409,7 +1414,7 @@ "@graphql-mesh/types" "^0.91.14" "@graphql-mesh/utils" "^0.43.22" "@noble/ed25519" "^1.7.1" - "@railgun-community/engine" "9.3.1" + "@railgun-community/engine" "9.4.0" "@railgun-community/shared-models" "7.5.0" "@whatwg-node/fetch" "^0.8.4" assert "2.0.0" From 1b86e2cca203a512f6ef01afa4ad90ed8d4f4c4b Mon Sep 17 00:00:00 2001 From: zy0n Date: Thu, 19 Jun 2025 16:33:20 -0400 Subject: [PATCH 10/17] chore: update package version to 8.0.0 for release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 562eb19d..291b7887 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@railgun-community/poi-safe-broadcaster-example", - "version": "7.3.0", + "version": "8.0.0", "description": "", "main": "dist/main.js", "packageManager": "yarn@1.22.19", From 85d2c909ea2d8140f5ce87c4913d5aa3653c88ab Mon Sep 17 00:00:00 2001 From: zy0n Date: Mon, 14 Jul 2025 22:17:21 -0400 Subject: [PATCH 11/17] fix: bug in unsubscribe --- src/server/networking/waku-rest-api-client.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/networking/waku-rest-api-client.ts b/src/server/networking/waku-rest-api-client.ts index 1afe59a9..404da8c6 100644 --- a/src/server/networking/waku-rest-api-client.ts +++ b/src/server/networking/waku-rest-api-client.ts @@ -149,7 +149,7 @@ export class WakuRestApiClient { const data = await this.request( WakuRequestMethods.DeleteSubscriptions, 'DELETE', - [topics], + topics, ); return data; } From 215ab282dfb663c65e0e92bc7ba0992f5f3fd418 Mon Sep 17 00:00:00 2001 From: zy0n Date: Wed, 23 Jul 2025 19:03:59 -0400 Subject: [PATCH 12/17] engine optimization patch --- patches/@railgun-community+engine+9.4.0.patch | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 patches/@railgun-community+engine+9.4.0.patch diff --git a/patches/@railgun-community+engine+9.4.0.patch b/patches/@railgun-community+engine+9.4.0.patch new file mode 100644 index 00000000..a3964e7a --- /dev/null +++ b/patches/@railgun-community+engine+9.4.0.patch @@ -0,0 +1,132 @@ +diff --git a/node_modules/@railgun-community/engine/dist/contracts/railgun-smart-wallet/V2/railgun-smart-wallet.js b/node_modules/@railgun-community/engine/dist/contracts/railgun-smart-wallet/V2/railgun-smart-wallet.js +index 62590aa..df099e9 100644 +--- a/node_modules/@railgun-community/engine/dist/contracts/railgun-smart-wallet/V2/railgun-smart-wallet.js ++++ b/node_modules/@railgun-community/engine/dist/contracts/railgun-smart-wallet/V2/railgun-smart-wallet.js +@@ -161,6 +161,8 @@ class RailgunSmartWalletContract extends events_1.default { + * @param eventsUnshieldListener - unshield listener callback + */ + async setTreeUpdateListeners(eventsCommitmentListener, eventsNullifierListener, eventsUnshieldListener) { ++ console.log("Disabled tree update listeners.") ++ return false; + const nullifiedTopic = this.contract.getEvent('Nullified').getFragment().topicHash; + const shieldTopic = this.contract.getEvent('Shield').getFragment().topicHash; + const transactTopic = this.contract.getEvent('Transact').getFragment().topicHash; +diff --git a/node_modules/@railgun-community/engine/dist/provider/polling-json-rpc-provider.js b/node_modules/@railgun-community/engine/dist/provider/polling-json-rpc-provider.js +index a21d16c..4d51573 100644 +--- a/node_modules/@railgun-community/engine/dist/provider/polling-json-rpc-provider.js ++++ b/node_modules/@railgun-community/engine/dist/provider/polling-json-rpc-provider.js +@@ -7,12 +7,13 @@ const ethers_1 = require("ethers"); + * rather than using sparsely-implemented eth_filter events. + */ + class PollingJsonRpcProvider extends ethers_1.JsonRpcProvider { +- constructor(url, chainId, pollingInterval = 10000, maxLogsPerBatch = 100) { ++ constructor(url, chainId, pollingInterval = 60000, maxLogsPerBatch = 2) { + const network = ethers_1.Network.from(chainId); + const options = { + polling: true, + staticNetwork: network, + batchMaxCount: maxLogsPerBatch, ++ batchStallTime: 2500, + }; + super(url, network, options); + this.pollingInterval = pollingInterval; +diff --git a/node_modules/@railgun-community/engine/dist/railgun-engine.d.ts b/node_modules/@railgun-community/engine/dist/railgun-engine.d.ts +index 70dcd36..877ecc9 100644 +--- a/node_modules/@railgun-community/engine/dist/railgun-engine.d.ts ++++ b/node_modules/@railgun-community/engine/dist/railgun-engine.d.ts +@@ -36,6 +36,7 @@ declare class RailgunEngine extends EventEmitter { + static walletSource: Optional; + private readonly skipMerkletreeScans; + private readonly hasSyncedRailgunTransactionsV2; ++ private readonly isSyncingRailgunTransactionsV2; + readonly isPOINode: boolean; + private constructor(); + /** +diff --git a/node_modules/@railgun-community/engine/dist/railgun-engine.js b/node_modules/@railgun-community/engine/dist/railgun-engine.js +index dfd6202..5da371e 100644 +--- a/node_modules/@railgun-community/engine/dist/railgun-engine.js ++++ b/node_modules/@railgun-community/engine/dist/railgun-engine.js +@@ -53,6 +53,7 @@ class RailgunEngine extends events_1.default { + static walletSource; + skipMerkletreeScans; + hasSyncedRailgunTransactionsV2 = new registry_1.Registry(); ++ isSyncingRailgunTransactionsV2 = new registry_1.Registry(); + isPOINode; + constructor(walletSource, leveldown, artifactGetter, quickSyncEvents, quickSyncRailgunTransactionsV2, validateRailgunTxidMerkleroot, getLatestValidatedRailgunTxid, engineDebugger, skipMerkletreeScans, isPOINode) { + super(); +@@ -288,7 +289,7 @@ class RailgunEngine extends events_1.default { + await this.nullifierListener(txidVersion, chain, nullifierEvents); + debugger_1.default.log(`[${txidVersion}] QuickSync commitments: ${commitmentEvents.length}`); + // Make sure commitments are scanned after Unshields and Nullifiers. +- await this.commitmentListener(txidVersion, chain, commitmentEvents, false, // shouldUpdateTrees - wait until after all commitments added ++ await this.commitmentListener(txidVersion, chain, commitmentEvents, true, // shouldUpdateTrees - wait until after all commitments added + false); + // Scan after all leaves added. + if (commitmentEvents.length) { +@@ -382,23 +383,25 @@ class RailgunEngine extends events_1.default { + await this.performQuickSync(txidVersion, chain, postQuickSyncProgress); + this.emitUTXOMerkletreeScanUpdateEvent(txidVersion, chain, postQuickSyncProgress); // 50% + // Get updated start-scanning block from new valid utxoMerkletree. +- const startScanningBlockSlowScan = await this.getNextStartingBlockSlowScan(txidVersion, chain); +- debugger_1.default.log(`[${txidVersion}] startScanningBlockSlowScan: ${startScanningBlockSlowScan} (note: continously updated during scan)`); +- const railgunSmartWalletContract = contract_store_1.ContractStore.railgunSmartWalletContracts.get(null, chain); +- if (!railgunSmartWalletContract?.contract.runner?.provider) { +- throw new Error('Requires RailgunSmartWalletContract with provider'); +- } +- const latestBlock = await railgunSmartWalletContract.contract.runner.provider.getBlockNumber(); ++ // const startScanningBlockSlowScan = await this.getNextStartingBlockSlowScan(txidVersion, chain); ++ // debugger_1.default.log(`[${txidVersion}] startScanningBlockSlowScan: ${startScanningBlockSlowScan} (note: continously updated during scan)`); ++ // const railgunSmartWalletContract = contract_store_1.ContractStore.railgunSmartWalletContracts.get(null, chain); ++ // if (!railgunSmartWalletContract?.contract.runner?.provider) { ++ // throw new Error('Requires RailgunSmartWalletContract with provider'); ++ // } ++ // SKIP SLOW SYNC ++ // const latestBlock = await railgunSmartWalletContract.contract.runner.provider.getBlockNumber(); + try { +- switch (txidVersion) { +- case poi_types_1.TXIDVersion.V2_PoseidonMerkle: +- await this.slowSyncV2(chain, utxoMerkletree, startScanningBlockSlowScan, latestBlock, postQuickSyncProgress); +- break; +- case poi_types_1.TXIDVersion.V3_PoseidonMerkle: +- await this.slowSyncV3(chain, utxoMerkletree, startScanningBlockSlowScan, latestBlock, postQuickSyncProgress); +- break; +- } ++ // switch (txidVersion) { ++ // case poi_types_1.TXIDVersion.V2_PoseidonMerkle: ++ // await this.slowSyncV2(chain, utxoMerkletree, startScanningBlockSlowScan, latestBlock, postQuickSyncProgress); ++ // break; ++ // case poi_types_1.TXIDVersion.V3_PoseidonMerkle: ++ // await this.slowSyncV3(chain, utxoMerkletree, startScanningBlockSlowScan, latestBlock, postQuickSyncProgress); ++ // break; ++ // } + // Final balance decryption after all leaves added. ++ + const decryptStartingProgress = 0.7; + await this.decryptBalancesAllWallets(txidVersion, chain, walletIdFilter, (progress) => { + const overallProgress = progress * (0.97 - decryptStartingProgress) + decryptStartingProgress; +@@ -505,11 +508,17 @@ class RailgunEngine extends events_1.default { + */ + async scanTXIDHistoryV2(chain) { + const txidVersion = poi_types_1.TXIDVersion.V2_PoseidonMerkle; ++ if (this.isSyncingRailgunTransactionsV2.get(txidVersion, chain) === true) { ++ debugger_1.default.log(`Already synced txids for chain ${chain.type}:${chain.id}. Stopping additional re-sync.`); ++ return; ++ } ++ + if (!this.hasTXIDMerkletree(txidVersion, chain)) { + debugger_1.default.log(`Cannot sync txids. Txid merkletree not yet loaded for chain ${chain.type}:${chain.id}.`); + return; + } + this.hasSyncedRailgunTransactionsV2.set(null, chain, true); ++ this.isSyncingRailgunTransactionsV2.set(txidVersion, chain, true); + await this.syncRailgunTransactionsV2(chain, 'poller'); + } + /** +@@ -537,6 +546,7 @@ class RailgunEngine extends events_1.default { + txidMerkletree.isScanning = true; + await this.performSyncRailgunTransactionsV2(chain, trigger); + txidMerkletree.isScanning = false; ++ this.isSyncingRailgunTransactionsV2.set(txidVersion, chain, false); + } + async shouldAddNewRailgunTransactions(txidVersion, chain, latestValidatedTxidIndex) { + if (!(0, is_defined_1.isDefined)(latestValidatedTxidIndex)) { From f1ee87d9b1a75a2b80f2968750e447325779ff9d Mon Sep 17 00:00:00 2001 From: zy0n Date: Wed, 23 Jul 2025 19:05:34 -0400 Subject: [PATCH 13/17] update dependencies --- package.json | 4 ++-- yarn.lock | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index 291b7887..9b389291 100644 --- a/package.json +++ b/package.json @@ -31,8 +31,8 @@ "dependencies": { "@0x/contract-addresses": "^8.0.0", "@noble/ed25519": "^1.7.1", - "@railgun-community/shared-models": "^7.6.1", - "@railgun-community/wallet": "^10.4.0", + "@railgun-community/shared-models": "^7.6.2", + "@railgun-community/wallet": "^10.4.1", "@walletconnect/jsonrpc-types": "^1.0.2", "@walletconnect/jsonrpc-utils": "^1.0.4", "axios": "1.7.2", diff --git a/yarn.lock b/yarn.lock index 0ccd9191..49250558 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1393,15 +1393,15 @@ resolved "https://registry.yarnpkg.com/@railgun-community/shared-models/-/shared-models-7.5.0.tgz#d36d73740e32dbd5c21b2864e8c3db96e1241cb3" integrity sha512-npSFFzSq2nSCLseEBZmLwJlZ4hMJArzEeM/DpqAAyxaTfznSHvpPIKmvEWorXVGjG+6xB7AY01TPGOq+3XHdcA== -"@railgun-community/shared-models@^7.6.1": - version "7.6.1" - resolved "https://registry.yarnpkg.com/@railgun-community/shared-models/-/shared-models-7.6.1.tgz#f3cad60183dc0ad4b1e396d864349f22357e2bc3" - integrity sha512-53ZK5oibJNtJIgsDhOCw+nUGM+2WsJoE21ro1vGWTJYqN6xAFBUUC/19OvcbKWUNjWYTr7iaAeSthBrS0DoGIA== - -"@railgun-community/wallet@^10.4.0": - version "10.4.0" - resolved "https://registry.yarnpkg.com/@railgun-community/wallet/-/wallet-10.4.0.tgz#bc910981a494445634d5a04c187457934acc96db" - integrity sha512-G006G9ZAmZDEnVN8k/i6ygeZnbKjXd/MvnvgxRKi33k7uTK9mzlg9MchcEZo3wIvd39onvjUDkBCy/dLO7JbHA== +"@railgun-community/shared-models@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@railgun-community/shared-models/-/shared-models-7.6.2.tgz#87d29461e3314974c9825e417313573cca8330c4" + integrity sha512-iHskJp50XqpnUB9XUaMOYcENNq5A7PI1A2ni0uLwMkvAVs6msFtuYobQLo3Ryr3UgF5FJ816cwYhkqCWwkG+Jw== + +"@railgun-community/wallet@^10.4.1": + version "10.4.1" + resolved "https://registry.yarnpkg.com/@railgun-community/wallet/-/wallet-10.4.1.tgz#2696f2c2fc3b93163982fdaaea4918342e6f44c4" + integrity sha512-vzmgCs4ZtYnLPv25B3855jemxGI0YBI7leDL9Y8LtPDRQUhwjg0l+RRkn1nDcdtgGDmKz/aBl3qvDRp3pgojwA== dependencies: "@graphql-mesh/cache-localforage" "^0.7.20" "@graphql-mesh/cross-helpers" "^0.3.4" From a1ad8af0f079a2047a20c320b2f82f3c8926e109 Mon Sep 17 00:00:00 2001 From: zy0n Date: Mon, 28 Jul 2025 19:00:29 -0400 Subject: [PATCH 14/17] fix: type assertion in tests --- src/server/waku-broadcaster/__tests__/waku-broadcaster.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/waku-broadcaster/__tests__/waku-broadcaster.test.ts b/src/server/waku-broadcaster/__tests__/waku-broadcaster.test.ts index 942059c7..8a48ee09 100644 --- a/src/server/waku-broadcaster/__tests__/waku-broadcaster.test.ts +++ b/src/server/waku-broadcaster/__tests__/waku-broadcaster.test.ts @@ -177,7 +177,7 @@ describe('waku-broadcaster', () => { 'string', 'No fee for token in broadcast data', ); - expect(BigInt(data.fees[MOCK_TOKEN_ADDRESS]).toString()).to.equal( + expect(BigInt(data.fees[MOCK_TOKEN_ADDRESS] as string).toString()).to.equal( '990424892220000000000', ); expect(data.feeExpiration).to.be.a('number'); From e11420657dd47a35688dfeae06f0c54b7fb19b39 Mon Sep 17 00:00:00 2001 From: zy0n Date: Mon, 28 Jul 2025 19:23:44 -0400 Subject: [PATCH 15/17] fix: remove broen provider --- src/server/config/fallback-providers/1-ethereum.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/config/fallback-providers/1-ethereum.ts b/src/server/config/fallback-providers/1-ethereum.ts index 908288ab..0ae84943 100644 --- a/src/server/config/fallback-providers/1-ethereum.ts +++ b/src/server/config/fallback-providers/1-ethereum.ts @@ -4,7 +4,7 @@ const config: FallbackProviderJsonConfig = { chainId: 1, providers: [ { - provider: 'https://mainnet.infura.io/v3/84842078b09946638c03157f83405213', + provider: 'https://eth.llamarpc.com', priority: 2, weight: 2, maxLogsPerBatch: 1, // Supports up to 10, but at 1 ethers handles getLogs differently, and this seems to be more stable. From adbda0f3462ffc04292055061caae42376fe9576 Mon Sep 17 00:00:00 2001 From: "zy0n.bear" Date: Wed, 10 Dec 2025 09:23:03 -0500 Subject: [PATCH 16/17] chore: update package manager and dependencies versions --- package.json | 6 ++--- yarn.lock | 65 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 45 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index 9b389291..fb0e1b98 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "8.0.0", "description": "", "main": "dist/main.js", - "packageManager": "yarn@1.22.19", + "packageManager": "yarn@1.22.22", "engines": { "node": ">=16.15.0" }, @@ -31,8 +31,8 @@ "dependencies": { "@0x/contract-addresses": "^8.0.0", "@noble/ed25519": "^1.7.1", - "@railgun-community/shared-models": "^7.6.2", - "@railgun-community/wallet": "^10.4.1", + "@railgun-community/shared-models": "^8.0.0", + "@railgun-community/wallet": "^10.8.1", "@walletconnect/jsonrpc-types": "^1.0.2", "@walletconnect/jsonrpc-utils": "^1.0.4", "axios": "1.7.2", diff --git a/yarn.lock b/yarn.lock index 49250558..2802a9c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1353,10 +1353,10 @@ resolved "https://registry.yarnpkg.com/@railgun-community/curve25519-scalarmult-wasm/-/curve25519-scalarmult-wasm-0.1.5.tgz#edb5e40a8f1fdb7f7e0de1d04e8badabe41cb2a8" integrity sha512-Cur8uM/IdNW3WzUwdPloDG1CF0rpSBDWq2yGXJMZ7IMeBGdc4Jj0h9tnNMFRZ35ZuCVVbZ3yClmqSa4PsbpdGQ== -"@railgun-community/engine@9.4.0": - version "9.4.0" - resolved "https://registry.yarnpkg.com/@railgun-community/engine/-/engine-9.4.0.tgz#d8beb18ac83f2a560ce63f8b5e49e3f0866a2a5a" - integrity sha512-7BZcUKo5oVBWdyBrjpKft3zT0hFo1V3PzcDSuvEIDzA8mOqFXTrIr4j+0A9ONwb5bo4A/7vfO0yll6uk0Y4GSQ== +"@railgun-community/engine@9.5.1": + version "9.5.1" + resolved "https://registry.yarnpkg.com/@railgun-community/engine/-/engine-9.5.1.tgz#ed761969c133ef85edc15900de7fdad96dbeeb37" + integrity sha512-tLX0WSHABzRC1VB7vhdwSBDFUYCFqRYHD2ek5/GT9+AZaKZJ6fU+UrAJYKxyEaGJ066l3M70fChc0Q6qM21scQ== dependencies: "@noble/ciphers" "^0.4.0" "@noble/ed25519" "^1.7.1" @@ -1388,20 +1388,15 @@ resolved "https://registry.yarnpkg.com/@railgun-community/poseidon-hash-wasm/-/poseidon-hash-wasm-1.0.1.tgz#bfd3b3f915391a59486d8c9d632069f029e152d6" integrity sha512-zDAbMu095ZjMqsKIoyOnuKR4Zofnqqx4eTCtnA6qYglnexX5cadxItvJa3ozhDDTmFkDGAidDssQ7Pzl3wwLDA== -"@railgun-community/shared-models@7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@railgun-community/shared-models/-/shared-models-7.5.0.tgz#d36d73740e32dbd5c21b2864e8c3db96e1241cb3" - integrity sha512-npSFFzSq2nSCLseEBZmLwJlZ4hMJArzEeM/DpqAAyxaTfznSHvpPIKmvEWorXVGjG+6xB7AY01TPGOq+3XHdcA== - -"@railgun-community/shared-models@^7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@railgun-community/shared-models/-/shared-models-7.6.2.tgz#87d29461e3314974c9825e417313573cca8330c4" - integrity sha512-iHskJp50XqpnUB9XUaMOYcENNq5A7PI1A2ni0uLwMkvAVs6msFtuYobQLo3Ryr3UgF5FJ816cwYhkqCWwkG+Jw== +"@railgun-community/shared-models@8.0.0", "@railgun-community/shared-models@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@railgun-community/shared-models/-/shared-models-8.0.0.tgz#689d4f6a3a80060e018abeb1b351cc711f97e77c" + integrity sha512-JY2HOobRlZpX9CsfiOfbjA2zmG3qLYA/QUupfz0V3ERUErQIm1ZQBSdMfVDZWhflW/4As+rbsY7vc3rXLGbpvA== -"@railgun-community/wallet@^10.4.1": - version "10.4.1" - resolved "https://registry.yarnpkg.com/@railgun-community/wallet/-/wallet-10.4.1.tgz#2696f2c2fc3b93163982fdaaea4918342e6f44c4" - integrity sha512-vzmgCs4ZtYnLPv25B3855jemxGI0YBI7leDL9Y8LtPDRQUhwjg0l+RRkn1nDcdtgGDmKz/aBl3qvDRp3pgojwA== +"@railgun-community/wallet@^10.8.1": + version "10.8.1" + resolved "https://registry.yarnpkg.com/@railgun-community/wallet/-/wallet-10.8.1.tgz#361c6a11e41b194dcc4878ef8a66848d0d8dfd24" + integrity sha512-UEVydOi6k2nWEXh54gsgTpX5/ncbiV/uqnkV0DQzinXSeGcCLKNEopcogSYT/1mcIjTwHEs+rR6iNc5IwlZdcA== dependencies: "@graphql-mesh/cache-localforage" "^0.7.20" "@graphql-mesh/cross-helpers" "^0.3.4" @@ -1414,8 +1409,8 @@ "@graphql-mesh/types" "^0.91.14" "@graphql-mesh/utils" "^0.43.22" "@noble/ed25519" "^1.7.1" - "@railgun-community/engine" "9.4.0" - "@railgun-community/shared-models" "7.5.0" + "@railgun-community/engine" "9.5.1" + "@railgun-community/shared-models" "8.0.0" "@whatwg-node/fetch" "^0.8.4" assert "2.0.0" axios "1.7.2" @@ -7294,7 +7289,16 @@ strict-uri-encode@^1.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -7346,7 +7350,7 @@ string_decoder@^1.1.1, string_decoder@^1.3.0: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -7360,6 +7364,13 @@ strip-ansi@^5.0.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -8222,8 +8233,7 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: - name wrap-ansi-cjs +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -8241,6 +8251,15 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From 51e5370bc2bb03a6218836ca1d28c1f17e28af69 Mon Sep 17 00:00:00 2001 From: "zy0n.bear" Date: Wed, 10 Dec 2025 09:42:56 -0500 Subject: [PATCH 17/17] refactor: remove outdated railgun engine patch and optimize sync logic --- patches/@railgun-community+engine+9.4.0.patch | 132 ------------------ 1 file changed, 132 deletions(-) delete mode 100644 patches/@railgun-community+engine+9.4.0.patch diff --git a/patches/@railgun-community+engine+9.4.0.patch b/patches/@railgun-community+engine+9.4.0.patch deleted file mode 100644 index a3964e7a..00000000 --- a/patches/@railgun-community+engine+9.4.0.patch +++ /dev/null @@ -1,132 +0,0 @@ -diff --git a/node_modules/@railgun-community/engine/dist/contracts/railgun-smart-wallet/V2/railgun-smart-wallet.js b/node_modules/@railgun-community/engine/dist/contracts/railgun-smart-wallet/V2/railgun-smart-wallet.js -index 62590aa..df099e9 100644 ---- a/node_modules/@railgun-community/engine/dist/contracts/railgun-smart-wallet/V2/railgun-smart-wallet.js -+++ b/node_modules/@railgun-community/engine/dist/contracts/railgun-smart-wallet/V2/railgun-smart-wallet.js -@@ -161,6 +161,8 @@ class RailgunSmartWalletContract extends events_1.default { - * @param eventsUnshieldListener - unshield listener callback - */ - async setTreeUpdateListeners(eventsCommitmentListener, eventsNullifierListener, eventsUnshieldListener) { -+ console.log("Disabled tree update listeners.") -+ return false; - const nullifiedTopic = this.contract.getEvent('Nullified').getFragment().topicHash; - const shieldTopic = this.contract.getEvent('Shield').getFragment().topicHash; - const transactTopic = this.contract.getEvent('Transact').getFragment().topicHash; -diff --git a/node_modules/@railgun-community/engine/dist/provider/polling-json-rpc-provider.js b/node_modules/@railgun-community/engine/dist/provider/polling-json-rpc-provider.js -index a21d16c..4d51573 100644 ---- a/node_modules/@railgun-community/engine/dist/provider/polling-json-rpc-provider.js -+++ b/node_modules/@railgun-community/engine/dist/provider/polling-json-rpc-provider.js -@@ -7,12 +7,13 @@ const ethers_1 = require("ethers"); - * rather than using sparsely-implemented eth_filter events. - */ - class PollingJsonRpcProvider extends ethers_1.JsonRpcProvider { -- constructor(url, chainId, pollingInterval = 10000, maxLogsPerBatch = 100) { -+ constructor(url, chainId, pollingInterval = 60000, maxLogsPerBatch = 2) { - const network = ethers_1.Network.from(chainId); - const options = { - polling: true, - staticNetwork: network, - batchMaxCount: maxLogsPerBatch, -+ batchStallTime: 2500, - }; - super(url, network, options); - this.pollingInterval = pollingInterval; -diff --git a/node_modules/@railgun-community/engine/dist/railgun-engine.d.ts b/node_modules/@railgun-community/engine/dist/railgun-engine.d.ts -index 70dcd36..877ecc9 100644 ---- a/node_modules/@railgun-community/engine/dist/railgun-engine.d.ts -+++ b/node_modules/@railgun-community/engine/dist/railgun-engine.d.ts -@@ -36,6 +36,7 @@ declare class RailgunEngine extends EventEmitter { - static walletSource: Optional; - private readonly skipMerkletreeScans; - private readonly hasSyncedRailgunTransactionsV2; -+ private readonly isSyncingRailgunTransactionsV2; - readonly isPOINode: boolean; - private constructor(); - /** -diff --git a/node_modules/@railgun-community/engine/dist/railgun-engine.js b/node_modules/@railgun-community/engine/dist/railgun-engine.js -index dfd6202..5da371e 100644 ---- a/node_modules/@railgun-community/engine/dist/railgun-engine.js -+++ b/node_modules/@railgun-community/engine/dist/railgun-engine.js -@@ -53,6 +53,7 @@ class RailgunEngine extends events_1.default { - static walletSource; - skipMerkletreeScans; - hasSyncedRailgunTransactionsV2 = new registry_1.Registry(); -+ isSyncingRailgunTransactionsV2 = new registry_1.Registry(); - isPOINode; - constructor(walletSource, leveldown, artifactGetter, quickSyncEvents, quickSyncRailgunTransactionsV2, validateRailgunTxidMerkleroot, getLatestValidatedRailgunTxid, engineDebugger, skipMerkletreeScans, isPOINode) { - super(); -@@ -288,7 +289,7 @@ class RailgunEngine extends events_1.default { - await this.nullifierListener(txidVersion, chain, nullifierEvents); - debugger_1.default.log(`[${txidVersion}] QuickSync commitments: ${commitmentEvents.length}`); - // Make sure commitments are scanned after Unshields and Nullifiers. -- await this.commitmentListener(txidVersion, chain, commitmentEvents, false, // shouldUpdateTrees - wait until after all commitments added -+ await this.commitmentListener(txidVersion, chain, commitmentEvents, true, // shouldUpdateTrees - wait until after all commitments added - false); - // Scan after all leaves added. - if (commitmentEvents.length) { -@@ -382,23 +383,25 @@ class RailgunEngine extends events_1.default { - await this.performQuickSync(txidVersion, chain, postQuickSyncProgress); - this.emitUTXOMerkletreeScanUpdateEvent(txidVersion, chain, postQuickSyncProgress); // 50% - // Get updated start-scanning block from new valid utxoMerkletree. -- const startScanningBlockSlowScan = await this.getNextStartingBlockSlowScan(txidVersion, chain); -- debugger_1.default.log(`[${txidVersion}] startScanningBlockSlowScan: ${startScanningBlockSlowScan} (note: continously updated during scan)`); -- const railgunSmartWalletContract = contract_store_1.ContractStore.railgunSmartWalletContracts.get(null, chain); -- if (!railgunSmartWalletContract?.contract.runner?.provider) { -- throw new Error('Requires RailgunSmartWalletContract with provider'); -- } -- const latestBlock = await railgunSmartWalletContract.contract.runner.provider.getBlockNumber(); -+ // const startScanningBlockSlowScan = await this.getNextStartingBlockSlowScan(txidVersion, chain); -+ // debugger_1.default.log(`[${txidVersion}] startScanningBlockSlowScan: ${startScanningBlockSlowScan} (note: continously updated during scan)`); -+ // const railgunSmartWalletContract = contract_store_1.ContractStore.railgunSmartWalletContracts.get(null, chain); -+ // if (!railgunSmartWalletContract?.contract.runner?.provider) { -+ // throw new Error('Requires RailgunSmartWalletContract with provider'); -+ // } -+ // SKIP SLOW SYNC -+ // const latestBlock = await railgunSmartWalletContract.contract.runner.provider.getBlockNumber(); - try { -- switch (txidVersion) { -- case poi_types_1.TXIDVersion.V2_PoseidonMerkle: -- await this.slowSyncV2(chain, utxoMerkletree, startScanningBlockSlowScan, latestBlock, postQuickSyncProgress); -- break; -- case poi_types_1.TXIDVersion.V3_PoseidonMerkle: -- await this.slowSyncV3(chain, utxoMerkletree, startScanningBlockSlowScan, latestBlock, postQuickSyncProgress); -- break; -- } -+ // switch (txidVersion) { -+ // case poi_types_1.TXIDVersion.V2_PoseidonMerkle: -+ // await this.slowSyncV2(chain, utxoMerkletree, startScanningBlockSlowScan, latestBlock, postQuickSyncProgress); -+ // break; -+ // case poi_types_1.TXIDVersion.V3_PoseidonMerkle: -+ // await this.slowSyncV3(chain, utxoMerkletree, startScanningBlockSlowScan, latestBlock, postQuickSyncProgress); -+ // break; -+ // } - // Final balance decryption after all leaves added. -+ - const decryptStartingProgress = 0.7; - await this.decryptBalancesAllWallets(txidVersion, chain, walletIdFilter, (progress) => { - const overallProgress = progress * (0.97 - decryptStartingProgress) + decryptStartingProgress; -@@ -505,11 +508,17 @@ class RailgunEngine extends events_1.default { - */ - async scanTXIDHistoryV2(chain) { - const txidVersion = poi_types_1.TXIDVersion.V2_PoseidonMerkle; -+ if (this.isSyncingRailgunTransactionsV2.get(txidVersion, chain) === true) { -+ debugger_1.default.log(`Already synced txids for chain ${chain.type}:${chain.id}. Stopping additional re-sync.`); -+ return; -+ } -+ - if (!this.hasTXIDMerkletree(txidVersion, chain)) { - debugger_1.default.log(`Cannot sync txids. Txid merkletree not yet loaded for chain ${chain.type}:${chain.id}.`); - return; - } - this.hasSyncedRailgunTransactionsV2.set(null, chain, true); -+ this.isSyncingRailgunTransactionsV2.set(txidVersion, chain, true); - await this.syncRailgunTransactionsV2(chain, 'poller'); - } - /** -@@ -537,6 +546,7 @@ class RailgunEngine extends events_1.default { - txidMerkletree.isScanning = true; - await this.performSyncRailgunTransactionsV2(chain, trigger); - txidMerkletree.isScanning = false; -+ this.isSyncingRailgunTransactionsV2.set(txidVersion, chain, false); - } - async shouldAddNewRailgunTransactions(txidVersion, chain, latestValidatedTxidIndex) { - if (!(0, is_defined_1.isDefined)(latestValidatedTxidIndex)) {