diff --git a/packages/currency/src/chains/evm/data/boba.ts b/packages/currency/src/chains/evm/data/boba.ts new file mode 100644 index 0000000000..d46b3ee30a --- /dev/null +++ b/packages/currency/src/chains/evm/data/boba.ts @@ -0,0 +1 @@ +export const chainId = 288; diff --git a/packages/currency/src/chains/evm/index.ts b/packages/currency/src/chains/evm/index.ts index 881b284d92..09d3669276 100644 --- a/packages/currency/src/chains/evm/index.ts +++ b/packages/currency/src/chains/evm/index.ts @@ -4,6 +4,7 @@ import * as AlfajoresDefinition from './data/alfajores'; import * as ArbitrumOneDefinition from './data/arbitrum-one'; import * as ArbitrumRinkebyDefinition from './data/arbitrum-rinkeby'; import * as AvalancheDefinition from './data/avalanche'; +import * as BobaDefinition from './data/boba'; import * as BscDefinition from './data/bsc'; import * as BscTestDefinition from './data/bsctest'; import * as CeloDefinition from './data/celo'; @@ -64,6 +65,7 @@ export const chains: Record = { zksynceratestnet: ZkSyncEraTestnetDefinition, zksyncera: ZkSyncEraDefinition, base: BaseDefinition, + boba: BobaDefinition, 'base-sepolia': BaseSepoliaDefinition, sonic: SonicDefinition, }; diff --git a/packages/currency/src/native.ts b/packages/currency/src/native.ts index db1f3608b9..366bec2ed5 100644 --- a/packages/currency/src/native.ts +++ b/packages/currency/src/native.ts @@ -190,6 +190,12 @@ export const nativeCurrencies: Record = { zksyncera: { chainId: 324, name: 'zksyncera' }, 'base-sepolia': { chainId: 84532, name: 'base-sepolia' }, sonic: { chainId: 146, name: 'sonic' }, + boba: { chainId: 288, name: 'boba' }, }; /** @@ -81,6 +82,8 @@ export class MultichainExplorerApiProvider extends ethers.providers.EtherscanPro return 'https://api-sepolia.basescan.org/api'; case 'sonic': return 'https://api.sonicscan.org/api'; + case 'boba': + return 'https://api.routescan.io/v2/network/mainnet/evm/288/etherscan/api'; default: return super.getBaseUrl(); } diff --git a/packages/payment-detection/src/thegraph/queries/superfluid/graphql.config.yml b/packages/payment-detection/src/thegraph/queries/superfluid/graphql.config.yml index 37f2dbe0a3..9290d44c17 100644 --- a/packages/payment-detection/src/thegraph/queries/superfluid/graphql.config.yml +++ b/packages/payment-detection/src/thegraph/queries/superfluid/graphql.config.yml @@ -1 +1 @@ -schema: https://subgraph-endpoints.superfluid.dev/eth-sepolia/protocol-v1 +schema: https://subgraph-endpoints.superfluid.dev/eth-mainnet/protocol-v1 diff --git a/packages/request-client.js/test/index.test.ts b/packages/request-client.js/test/index.test.ts index c6eef993ef..0feb47df23 100644 --- a/packages/request-client.js/test/index.test.ts +++ b/packages/request-client.js/test/index.test.ts @@ -164,6 +164,16 @@ const waitForConfirmation = async ( }); }; +/** + * Avoid live `eth_getLogs` RPC in CI. With subgraph disabled, ETH/ERC20 proxy + * fallbacks use `getDefaultProvider().getLogs` over large block ranges, which + * is slow and can time out. Tests that use mocked Etherscan (or only assert + * currency) do not need those logs. Do not use for local `private` chain + * transfer integration tests. + */ +const mockEvmGetLogsEmpty = (): jest.SpyInstance => + jest.spyOn(ethers.providers.BaseProvider.prototype, 'getLogs').mockResolvedValue([] as any); + // Integration tests /* eslint-disable @typescript-eslint/no-unused-expressions */ describe('request-client.js', () => { @@ -1164,6 +1174,7 @@ describe('request-client.js', () => { jest.useRealTimers(); jest.clearAllMocks(); jest.restoreAllMocks(); + mockEvmGetLogsEmpty(); }); it('can create ETH requests with given salt', async () => { @@ -1987,6 +1998,7 @@ describe('request-client.js', () => { }; it('supports a default list when nothing is provided', async () => { + mockEvmGetLogsEmpty(); const requestNetwork = new RequestNetwork({ signatureProvider: TestData.fakeSignatureProvider, useMockStorage: true, @@ -2062,6 +2074,7 @@ describe('request-client.js', () => { }); it('overrides the default token list', async () => { + mockEvmGetLogsEmpty(); const daiRequest = await requestNetwork.createRequest({ requestInfo: daiData, paymentNetwork, diff --git a/packages/smart-contracts/hardhat.config.ts b/packages/smart-contracts/hardhat.config.ts index 96e0951cea..73517ff40f 100644 --- a/packages/smart-contracts/hardhat.config.ts +++ b/packages/smart-contracts/hardhat.config.ts @@ -222,6 +222,11 @@ export default { chainId: 146, accounts, }, + boba: { + url: url('boba'), + chainId: 288, + accounts, + }, }, zksolc: { version: '1.3.16', @@ -285,6 +290,14 @@ export default { browserURL: 'https://sepolia.basescan.org/', }, }, + { + network: 'boba', + chainId: 288, + urls: { + apiURL: 'https://api.routescan.io/v2/network/mainnet/evm/288/etherscan/api', + browserURL: 'https://bobascan.com/', + }, + }, ], }, tenderly: { @@ -318,6 +331,7 @@ export default { 'optimism', 'moonbeam', 'sonic', + 'boba', ], gasLimit: undefined, deployerAddress: requestDeployer, diff --git a/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts b/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts index 48f25c6f56..a4d7373b13 100644 --- a/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts +++ b/packages/smart-contracts/scripts-create2/contract-setup/setupBatchConversionPayments.ts @@ -72,14 +72,26 @@ export const setupBatchConversionPayments = async ({ 'chainlinkConversionPath', ]; for (const proxy of proxies) { - await updateBatchConversionProxy( - batchConversionPaymentConnected, - network, - txOverrides, - proxy, - signer, - signWithEoa, - ); + try { + await updateBatchConversionProxy( + batchConversionPaymentConnected, + network, + txOverrides, + proxy, + signer, + signWithEoa, + ); + } catch (err) { + if (err.message.includes('No deployment for network')) { + console.warn(`No deployment for proxy ${proxy} on ${network}`); + console.warn(`Skipping Batch contract setup for ${proxy} on ${network}`); + console.warn( + `If ${proxy} was deployed on ${network} update the artifacts and run the contract setup script`, + ); + } else { + throw err; + } + } } await updateNativeAndUSDAddress( batchConversionPaymentConnected, diff --git a/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/index.ts b/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/index.ts index 0b9ca11d38..98ebd5b6a9 100644 --- a/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/index.ts +++ b/packages/smart-contracts/src/lib/artifacts/BatchConversionPayments/index.ts @@ -90,6 +90,11 @@ export const batchConversionPaymentsArtifact = new ContractArtifact( address: '0x399F5EE127ce7432E4921a61b8CF52b0af52cbfE', creationBlockNumber: 3974138, }, + boba: { + address: '0x8881F1623D0015FAA93139fB88558be7dB0aBeE7', + creationBlockNumber: 32880250, + }, }, }, near: { diff --git a/packages/smart-contracts/src/lib/artifacts/ERC20Proxy/index.ts b/packages/smart-contracts/src/lib/artifacts/ERC20Proxy/index.ts index 8937cb5f84..35c7ec6d59 100644 --- a/packages/smart-contracts/src/lib/artifacts/ERC20Proxy/index.ts +++ b/packages/smart-contracts/src/lib/artifacts/ERC20Proxy/index.ts @@ -45,6 +45,10 @@ export const erc20ProxyArtifact = new ContractArtifact( address: '0xC8D3FE2A27bB69a85F6973081FdC41103E107595', creationBlockNumber: 3974125, }, + boba: { + address: '0x5079FE74b3888dE1B2b2deeCF1751E3759e4bd72', + creationBlockNumber: 32880247, + }, }, }, }, diff --git a/packages/smart-contracts/src/lib/artifacts/EthereumFeeProxy/index.ts b/packages/smart-contracts/src/lib/artifacts/EthereumFeeProxy/index.ts index 9f1e2d2753..e73aa22cd7 100644 --- a/packages/smart-contracts/src/lib/artifacts/EthereumFeeProxy/index.ts +++ b/packages/smart-contracts/src/lib/artifacts/EthereumFeeProxy/index.ts @@ -154,6 +154,10 @@ export const ethereumFeeProxyArtifact = new ContractArtifact( address: '0x4989F941D62bEEb3548Bf55d0D5291Ec335429f0', creationBlockNumber: 3974098, }, + boba: { + address: '0xe4569336bcaeaBFa5bDE1713288E54cD2073a6eF', + creationBlockNumber: 32880246, + }, }, }, }, diff --git a/packages/smart-contracts/src/lib/artifacts/EthereumProxy/index.ts b/packages/smart-contracts/src/lib/artifacts/EthereumProxy/index.ts index f922414088..a655f05cfb 100644 --- a/packages/smart-contracts/src/lib/artifacts/EthereumProxy/index.ts +++ b/packages/smart-contracts/src/lib/artifacts/EthereumProxy/index.ts @@ -208,6 +208,10 @@ export const ethereumProxyArtifact = new ContractArtifact( address: '0x171Ee0881407d4c0C11eA1a2FB7D5b4cdED71e6e', creationBlockNumber: 3974083, }, + boba: { + address: '0xba25dA333691A23DC527b4BBa35cda68abd8dfBA', + creationBlockNumber: 32880244, + }, }, }, }, diff --git a/packages/smart-contracts/src/lib/artifacts/RequestDeployer/index.ts b/packages/smart-contracts/src/lib/artifacts/RequestDeployer/index.ts index a01deaa270..9b4dc3c214 100644 --- a/packages/smart-contracts/src/lib/artifacts/RequestDeployer/index.ts +++ b/packages/smart-contracts/src/lib/artifacts/RequestDeployer/index.ts @@ -93,6 +93,10 @@ export const requestDeployer = new ContractArtifact( address: '0xE99Ab70a5FAE59551544FA326fA048f7B95A24B2', creationBlockNumber: 3970964, }, + boba: { + address: '0xE99Ab70a5FAE59551544FA326fA048f7B95A24B2', + creationBlockNumber: 32878129, + }, }, }, }, diff --git a/packages/types/src/currency-types.ts b/packages/types/src/currency-types.ts index 5fd4f1e36f..4fa480bc4b 100644 --- a/packages/types/src/currency-types.ts +++ b/packages/types/src/currency-types.ts @@ -8,6 +8,7 @@ export type EvmChainName = | 'arbitrum-one' | 'arbitrum-rinkeby' | 'avalanche' + | 'boba' | 'base' | 'base-sepolia' | 'bsc' diff --git a/packages/utils/src/providers.ts b/packages/utils/src/providers.ts index 671b7d4653..584ce2a7e6 100644 --- a/packages/utils/src/providers.ts +++ b/packages/utils/src/providers.ts @@ -54,6 +54,7 @@ const networkRpcs: Record = { sepolia: 'https://rpc.sepolia.org/', base: 'https://mainnet.base.org/', sonic: 'https://rpc.soniclabs.com', + boba: 'https://mainnet.boba.network', }; /**