From 93f98863546d60486a6791930716994d3eba9c54 Mon Sep 17 00:00:00 2001 From: dwasse Date: Mon, 14 Oct 2024 10:18:13 -0500 Subject: [PATCH 01/15] feat(rfq-relayer): add MaxRelayAmount (#3259) * Feat: add quoteParams helper for test * Feat: add MaxQuoteAmount to relconfig * Feat: use MaxQuoteAmount * Feat: handle MaxQuoteAmount in quoter test * Replace: MaxQuoteAmount -> MaxRelayAmount * Feat: shouldProcess() returns false if max relay amount exceeded * Feat: add test for MaxRelayAmount --- services/rfq/relayer/quoter/quoter.go | 21 +++++- services/rfq/relayer/quoter/quoter_test.go | 82 +++++++++++++++++++--- services/rfq/relayer/relconfig/config.go | 2 + services/rfq/relayer/relconfig/getters.go | 35 +++++++++ 4 files changed, 128 insertions(+), 12 deletions(-) diff --git a/services/rfq/relayer/quoter/quoter.go b/services/rfq/relayer/quoter/quoter.go index 3b5ecc8352..2cd3dfcf94 100644 --- a/services/rfq/relayer/quoter/quoter.go +++ b/services/rfq/relayer/quoter/quoter.go @@ -207,6 +207,15 @@ func (m *Manager) ShouldProcess(parentCtx context.Context, quote reldb.QuoteRequ return false, nil } + // check relay amount + maxRelayAmount := m.config.GetMaxRelayAmount(int(quote.Transaction.OriginChainId), quote.Transaction.OriginToken) + if maxRelayAmount != nil { + if quote.Transaction.OriginAmount.Cmp(maxRelayAmount) > 0 { + span.AddEvent("origin amount is greater than max relay amount") + return false, nil + } + } + // all checks have passed return true, nil } @@ -713,7 +722,7 @@ func (m *Manager) getOriginAmount(parentCtx context.Context, input QuoteInput) ( } } - // Finally, clip the quoteAmount by the dest balance + // Clip the quoteAmount by the dest balance if quoteAmount.Cmp(input.DestBalance) > 0 { span.AddEvent("quote amount greater than destination balance", trace.WithAttributes( attribute.String("quote_amount", quoteAmount.String()), @@ -722,6 +731,16 @@ func (m *Manager) getOriginAmount(parentCtx context.Context, input QuoteInput) ( quoteAmount = input.DestBalance } + // Clip the quoteAmount by the maxQuoteAmount + maxQuoteAmount := m.config.GetMaxRelayAmount(input.DestChainID, input.DestTokenAddr) + if maxQuoteAmount != nil && quoteAmount.Cmp(maxQuoteAmount) > 0 { + span.AddEvent("quote amount greater than max quote amount", trace.WithAttributes( + attribute.String("quote_amount", quoteAmount.String()), + attribute.String("max_quote_amount", maxQuoteAmount.String()), + )) + quoteAmount = maxQuoteAmount + } + // Deduct gas cost from the quote amount, if necessary quoteAmount, err = m.deductGasCost(ctx, quoteAmount, input.DestTokenAddr, input.DestChainID) if err != nil { diff --git a/services/rfq/relayer/quoter/quoter_test.go b/services/rfq/relayer/quoter/quoter_test.go index 1d6a52c7de..321d55b189 100644 --- a/services/rfq/relayer/quoter/quoter_test.go +++ b/services/rfq/relayer/quoter/quoter_test.go @@ -136,6 +136,13 @@ func (s *QuoterSuite) TestShouldProcess() { s.False(s.manager.ShouldProcess(s.GetTestContext(), quote)) s.manager.SetRelayPaused(false) s.True(s.manager.ShouldProcess(s.GetTestContext(), quote)) + + // Set max relay amount + originTokenCfg := s.config.Chains[int(s.origin)].Tokens["USDC"] + originTokenCfg.MaxRelayAmount = "900" // less than balance + s.config.Chains[int(s.origin)].Tokens["USDC"] = originTokenCfg + s.manager.SetConfig(s.config) + s.False(s.manager.ShouldProcess(s.GetTestContext(), quote)) } func (s *QuoterSuite) TestIsProfitable() { @@ -173,13 +180,23 @@ func (s *QuoterSuite) TestGetOriginAmount() { originAddr := common.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48") balance := big.NewInt(1000_000_000) // 1000 USDC - setQuoteParams := func(quotePct, quoteOffset float64, minQuoteAmount, maxBalance string) { - s.config.BaseChainConfig.QuotePct = "ePct + type quoteParams struct { + quotePct float64 + quoteOffset float64 + minQuoteAmount string + maxBalance string + maxQuoteAmount string + } + + setQuoteParams := func(params quoteParams) { + s.config.BaseChainConfig.QuotePct = ¶ms.quotePct destTokenCfg := s.config.Chains[dest].Tokens["USDC"] - destTokenCfg.MinQuoteAmount = minQuoteAmount + destTokenCfg.MinQuoteAmount = params.minQuoteAmount + destTokenCfg.MaxRelayAmount = params.maxQuoteAmount originTokenCfg := s.config.Chains[origin].Tokens["USDC"] - originTokenCfg.QuoteOffsetBps = quoteOffset - originTokenCfg.MaxBalance = &maxBalance + originTokenCfg.QuoteOffsetBps = params.quoteOffset + originTokenCfg.MaxBalance = ¶ms.maxBalance + originTokenCfg.MaxRelayAmount = params.maxQuoteAmount s.config.Chains[dest].Tokens["USDC"] = destTokenCfg s.config.Chains[origin].Tokens["USDC"] = originTokenCfg s.manager.SetConfig(s.config) @@ -201,42 +218,85 @@ func (s *QuoterSuite) TestGetOriginAmount() { s.Equal(expectedAmount, quoteAmount) // Set QuotePct to 50 with MinQuoteAmount of 0; should be 50% of balance. - setQuoteParams(50, 0, "0", "0") + setQuoteParams(quoteParams{ + quotePct: 50, + quoteOffset: 0, + minQuoteAmount: "0", + maxBalance: "0", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(500_000_000) s.Equal(expectedAmount, quoteAmount) // Set QuotePct to 50 with QuoteOffset of -1%. Should be 1% less than 50% of balance. - setQuoteParams(50, -100, "0", "0") + setQuoteParams(quoteParams{ + quotePct: 50, + quoteOffset: -100, + minQuoteAmount: "0", + maxBalance: "0", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(495_000_000) s.Equal(expectedAmount, quoteAmount) // Set QuotePct to 25 with MinQuoteAmount of 500; should be 50% of balance. - setQuoteParams(25, 0, "500", "0") + setQuoteParams(quoteParams{ + quotePct: 25, + quoteOffset: 0, + minQuoteAmount: "500", + maxBalance: "0", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(500_000_000) s.Equal(expectedAmount, quoteAmount) // Set QuotePct to 25 with MinQuoteAmount of 500; should be 50% of balance. - setQuoteParams(25, 0, "500", "0") + setQuoteParams(quoteParams{ + quotePct: 25, + quoteOffset: 0, + minQuoteAmount: "500", + maxBalance: "0", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(500_000_000) s.Equal(expectedAmount, quoteAmount) // Set QuotePct to 25 with MinQuoteAmount of 1500; should be total balance. - setQuoteParams(25, 0, "1500", "0") + setQuoteParams(quoteParams{ + quotePct: 25, + quoteOffset: 0, + minQuoteAmount: "1500", + maxBalance: "0", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(1000_000_000) s.Equal(expectedAmount, quoteAmount) + // Set QuotePct to 100 with MinQuoteAmount of 0 and MaxRelayAmount of 500; should be 500. + setQuoteParams(quoteParams{ + quotePct: 100, + quoteOffset: 0, + minQuoteAmount: "0", + maxBalance: "0", + maxQuoteAmount: "500", + }) + quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) + s.NoError(err) + expectedAmount = big.NewInt(500_000_000) + s.Equal(expectedAmount, quoteAmount) + // Set QuotePct to 25 with MinQuoteAmount of 1500 and MaxBalance of 1200; should be 200. - setQuoteParams(25, 0, "1500", "1200") + setQuoteParams(quoteParams{ + quotePct: 25, + quoteOffset: 0, + minQuoteAmount: "1500", + maxBalance: "1200", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(200_000_000) diff --git a/services/rfq/relayer/relconfig/config.go b/services/rfq/relayer/relconfig/config.go index a4449bf8db..220627e13a 100644 --- a/services/rfq/relayer/relconfig/config.go +++ b/services/rfq/relayer/relconfig/config.go @@ -124,6 +124,8 @@ type TokenConfig struct { PriceUSD float64 `yaml:"price_usd"` // MinQuoteAmount is the minimum amount to quote for this token in human-readable units. MinQuoteAmount string `yaml:"min_quote_amount"` + // MaxRelayAmount is the maximum amount to quote and relay for this token in human-readable units. + MaxRelayAmount string `yaml:"max_relay_amount"` // RebalanceMethods are the supported methods for rebalancing. RebalanceMethods []string `yaml:"rebalance_methods"` // MaintenanceBalancePct is the percentage of the total balance under which a rebalance will be triggered. diff --git a/services/rfq/relayer/relconfig/getters.go b/services/rfq/relayer/relconfig/getters.go index 2cb4880712..a3fbb25cc7 100644 --- a/services/rfq/relayer/relconfig/getters.go +++ b/services/rfq/relayer/relconfig/getters.go @@ -746,6 +746,41 @@ func (c Config) GetMinQuoteAmount(chainID int, addr common.Address) *big.Int { return quoteAmountScaled } +var defaultMaxRelayAmount *big.Int // nil + +// GetMaxRelayAmount returns the quote amount for the given chain and address. +// Note that this getter returns the value in native token decimals. +func (c Config) GetMaxRelayAmount(chainID int, addr common.Address) *big.Int { + chainCfg, ok := c.Chains[chainID] + if !ok { + return defaultMaxRelayAmount + } + + var tokenCfg *TokenConfig + for _, cfg := range chainCfg.Tokens { + if common.HexToAddress(cfg.Address).Hex() == addr.Hex() { + cfgCopy := cfg + tokenCfg = &cfgCopy + break + } + } + if tokenCfg == nil { + return defaultMaxRelayAmount + } + quoteAmountFlt, ok := new(big.Float).SetString(tokenCfg.MaxRelayAmount) + if !ok { + return defaultMaxRelayAmount + } + if quoteAmountFlt.Cmp(big.NewFloat(0)) <= 0 { + return defaultMaxRelayAmount + } + + // Scale the minQuoteAmount by the token decimals. + denomDecimalsFactor := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(tokenCfg.Decimals)), nil) + quoteAmountScaled, _ := new(big.Float).Mul(quoteAmountFlt, new(big.Float).SetInt(denomDecimalsFactor)).Int(nil) + return quoteAmountScaled +} + var defaultMinRebalanceAmount = big.NewInt(1000) // GetMinRebalanceAmount returns the min rebalance amount for the given chain and address. From e9f7adf9ffb867ee7e13cfc89a08d08b67705e02 Mon Sep 17 00:00:00 2001 From: aureliusbtc <82057759+aureliusbtc@users.noreply.github.com> Date: Mon, 14 Oct 2024 18:05:42 -0400 Subject: [PATCH 02/15] update bl --- packages/synapse-interface/public/blacklist.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/synapse-interface/public/blacklist.json b/packages/synapse-interface/public/blacklist.json index f018d998e9..baf4815770 100644 --- a/packages/synapse-interface/public/blacklist.json +++ b/packages/synapse-interface/public/blacklist.json @@ -557,5 +557,6 @@ "0x6fdb264a876c811c7e101ee7a4f4fe7704ecbb72", "0xb584050909a300fa0306b29f72e63dc4615b6f53", "0xA963df55B326609a0cd205e85ca92d2a3c94DaB5", - "0x0605eDeE6a8b8b553caE09Abe83b2ebeb75516eC" + "0x0605eDeE6a8b8b553caE09Abe83b2ebeb75516eC", + "0x4c968f6beecf1906710b08e8b472b8ba6e75f957" ] From 99cf53e44297af1781af6da1cb204e44c73b569f Mon Sep 17 00:00:00 2001 From: aureliusbtc <82057759+aureliusbtc@users.noreply.github.com> Date: Mon, 14 Oct 2024 18:08:10 -0400 Subject: [PATCH 03/15] update bl --- packages/synapse-interface/public/blacklist.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/synapse-interface/public/blacklist.json b/packages/synapse-interface/public/blacklist.json index baf4815770..21ddc573ba 100644 --- a/packages/synapse-interface/public/blacklist.json +++ b/packages/synapse-interface/public/blacklist.json @@ -558,5 +558,6 @@ "0xb584050909a300fa0306b29f72e63dc4615b6f53", "0xA963df55B326609a0cd205e85ca92d2a3c94DaB5", "0x0605eDeE6a8b8b553caE09Abe83b2ebeb75516eC", - "0x4c968f6beecf1906710b08e8b472b8ba6e75f957" + "0x4c968f6beecf1906710b08e8b472b8ba6e75f957", + "0xff3a8d02109393726a90c04d7afd76e2d571890e" ] From cfed271a10edae07fc7c5d1fb7856dbca6d06203 Mon Sep 17 00:00:00 2001 From: abtestingalpha <104046418+abtestingalpha@users.noreply.github.com> Date: Mon, 14 Oct 2024 21:06:06 -0400 Subject: [PATCH 04/15] Fixes typos (#3290) --- docs/bridge/docs/02-Bridge/01-SDK.md | 112 ++++++++++++++------------- 1 file changed, 57 insertions(+), 55 deletions(-) diff --git a/docs/bridge/docs/02-Bridge/01-SDK.md b/docs/bridge/docs/02-Bridge/01-SDK.md index c58d7e3f51..29687f414c 100644 --- a/docs/bridge/docs/02-Bridge/01-SDK.md +++ b/docs/bridge/docs/02-Bridge/01-SDK.md @@ -10,25 +10,25 @@ The Synapse Bridge SDK is built on top of the [Synapse Router](/docs/Routers/Syn ### Use cases -* Integrate your front-end application with the Synapse Bridge. -* Provide bridge liquidity. -* Perform cross-chain arbitrage. -* Integrate the Synapse Javascript SDK with your non-Javascript application. +- Integrate your front-end application with the Synapse Bridge. +- Provide bridge liquidity. +- Perform cross-chain arbitrage. +- Integrate the Synapse Javascript SDK with your non-Javascript application. ## Install :::note requires Node v16+ -The SDK has only been fully tested on Node 16+ or greater. Earlier versions are not guaranteed to work. +The SDK has only been fully tested on Node 16+ or greater. Earlier versions are not guaranteed to work. ::: -Requires either the `npx` or `yarn` package manager. +Requires either the `npm` or `yarn` package manager. | Options |- -| `npx install @synapsecns/sdk-router` -| `yarn install @synapsecns/sdk-router` +| `npm install @synapsecns/sdk-router` +| `yarn add @synapsecns/sdk-router` ## Configure Ethers @@ -60,8 +60,9 @@ const Synapse = new SynapseSDK(chainIds, providers) :::tip Ethers v6 Use of Ethers v6 requires the `@ethersproject/providers` dependency to be installed via `npm` or `yarn`: -* `npm install @ethersproject/providers@^5.7.2` -* `yarn add @ethersproject/providers@^5.7.2` + +- `npm install @ethersproject/providers@^5.7.2` +- `yarn add @ethersproject/providers@^5.7.2` ::: @@ -90,11 +91,11 @@ const Synapse = new SynapseSDK(chainIds, providers) `originQuery` and `destQuery`, returned by `bridgeQuote()` and required for `bridge()`, are [`Query`](https://synapserouter.gitbook.io/untitled/) objects, which contain: -* `swapAdapter`: (string): 0x address of the swap adapter. -* `tokenOut`: (string): 0x address of the outputted token on that chain. -* `minAmountOut`: (Ethers BigNumber): The min amount of value exiting the transaction. -* `deadline`: (Ethers BigNumber): The deadline for the potential transaction. -* `rawParams`: (string): 0x params for the potential transaction. +- `swapAdapter`: (string): 0x address of the swap adapter. +- `tokenOut`: (string): 0x address of the outputted token on that chain. +- `minAmountOut`: (Ethers BigNumber): The min amount of value exiting the transaction. +- `deadline`: (Ethers BigNumber): The deadline for the potential transaction. +- `rawParams`: (string): 0x params for the potential transaction. ::: @@ -106,25 +107,25 @@ Get all relevant information regarding a possible transaction. `bridgeQuote()` requires the following arguments: -* `fromChain` (number): Origin chain id. -* `toChain` (number): Destination chain id. -* `fromToken` (string): 0x token address on the origin chain. -* `toToken` (string): 0x token address on the destination chain. -* `amount` (Ethers BigNumber): The amount (with the correct amount of decimals specified by the token on the origin chain) -* `object` (three seperate args): -* `deadline` (Ethers BigNumber): Deadline for the transaction to be initiated on the origin chain, in seconds (optional) -* `originUserAddress` (string): Address of the user on the origin chain, optional, mandatory if a smart contract is going to initiate the bridge operation -* `excludedModules` (array): (optional) List of bridge modules to exclude from the result +- `fromChain` (number): Origin chain id. +- `toChain` (number): Destination chain id. +- `fromToken` (string): 0x token address on the origin chain. +- `toToken` (string): 0x token address on the destination chain. +- `amount` (Ethers BigNumber): The amount (with the correct amount of decimals specified by the token on the origin chain) +- An `object` with three separate args: + - `deadline` (Ethers BigNumber): Deadline for the transaction to be initiated on the origin chain, in seconds (optional) + - `originUserAddress` (string): Address of the user on the origin chain, optional, mandatory if a smart contract is going to initiate the bridge operation + - `excludedModules` (array): (optional) List of bridge modules to exclude from the result #### Return value `bridgeQuote` returns the following information -* `feeAmount` (Ethers BigNumber): The calculated amount of fee to be taken. -* `bridgeFee` (number): The percentage of fee to be taken. -* `maxAmountOut` (Ethers BigNumber): The maximum output amount resulting from the bridge transaction. -* `originQuery` (`Query`): The query to be executed on the origin chain. -* `destQuery` (`Query`): The query to be executed on the destination chain. +- `feeAmount` (Ethers BigNumber): The calculated amount of fee to be taken. +- `bridgeFee` (number): The percentage of fee to be taken. +- `maxAmountOut` (Ethers BigNumber): The maximum output amount resulting from the bridge transaction. +- `originQuery` (`Query`): The query to be executed on the origin chain. +- `destQuery` (`Query`): The query to be executed on the destination chain. ### `bridge()` @@ -132,19 +133,19 @@ Use `bridgeQuote` to request a Bridge transaction #### Parameters -* `toAddress` (number): The 0x wallet address on the destination chain. -* `routerAddress` (string): The 0x contract address on the origin chain of the bridge router contract. -* `fromChain` (number): The origin chain id. -* `toChain` (number): The destination chain id. -* `fromToken` (string): The 0x token address on the origin chain. -* `amount` (Ethers BigNumber): The amount (with the correct amount of decimals specified by the token on the origin chain) -* `originQuery` (`Query`): The query to be executed on the origin chain. -* `destQuery` (`Query`): The query to be executed on the destination chain. +- `toAddress` (number): The 0x wallet address on the destination chain. +- `routerAddress` (string): The 0x contract address on the origin chain of the bridge router contract. +- `fromChain` (number): The origin chain id. +- `toChain` (number): The destination chain id. +- `fromToken` (string): The 0x token address on the origin chain. +- `amount` (Ethers BigNumber): The amount (with the correct amount of decimals specified by the token on the origin chain) +- `originQuery` (`Query`): The query to be executed on the origin chain. +- `destQuery` (`Query`): The query to be executed on the destination chain. #### Return value -* `to` (string): 0x wallet address on the destination chain. -* `data` (string): Output data in 0x hex format +- `to` (string): 0x wallet address on the destination chain. +- `data` (string): Output data in 0x hex format ### `allBridgeQuotes()` @@ -165,7 +166,7 @@ const quotes = await Synapse.bridgeQuote( 43114, // Destination Chain '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', // Origin Token Address '0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664', // Destination Token Address - BigNumber.from('20000000') // Amount in + BigNumber.from('20000000') // Amount in { // Deadline for the transaction to be initiated on the origin chain, in seconds (optional) deadline: 1234567890, @@ -183,14 +184,14 @@ const quotes = await Synapse.bridgeQuote( ```js await Synapse.bridge( - '0x0AF91FA049A7e1894F480bFE5bBa20142C6c29a9', // To Address - bridgeQuote.routerAddress, // address of the contract to route the txn - 42161, // Origin Chain - 43114, // Destination Chain - '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', // Origin Token Address - BigNumber.from('20000000'), // Amount - quote.originQuery, // Origin query from bridgeQuote() - quote.destQuery // Destination query from bridgeQuote() + '0x0AF91FA049A7e1894F480bFE5bBa20142C6c29a9', // To Address + bridgeQuote.routerAddress, // address of the contract to route the txn + 42161, // Origin Chain + 43114, // Destination Chain + '0xff970a61a04b1ca14834a43f5de4533ebddb5cc8', // Origin Token Address + BigNumber.from('20000000'), // Amount + quote.originQuery, // Origin query from bridgeQuote() + quote.destQuery // Destination query from bridgeQuote() ) ``` @@ -198,22 +199,23 @@ await Synapse.bridge( ### Options object -* `deadline`, `excludeCCTP` (now `excludedModules`), and `originUserAddress` parameters are now found in an (optional) options object at the end of the arguments list for `bridgeQuote()`, and `allBridgeQuotes()`. -* `excludedModules` excludes one or more modules with an array of the module names. Supported names are `SynapseBridge`, `SynapseCCTP`, and `SynapseRFQ`. -* `originUserAddress` is required as part of the options object to initiate a bridge transaction on behalf of a user. +- `deadline`, `excludeCCTP` (now `excludedModules`), and `originUserAddress` parameters are now found in an (optional) options object at the end of the arguments list for `bridgeQuote()`, and `allBridgeQuotes()`. +- `excludedModules` excludes one or more modules with an array of the module names. Supported names are `SynapseBridge`, `SynapseCCTP`, and `SynapseRFQ`. +- `originUserAddress` is required as part of the options object to initiate a bridge transaction on behalf of a user. ### Examples + ```js bridgeQuote(...arguments, { deadline: 1234567890, - excludedModules: ["SynapseCCTP"], - originUserAddress: "0x1234...", + excludedModules: ['SynapseCCTP'], + originUserAddress: '0x1234...', }) allBridgeQuotes({ deadline: 1234567890, - excludedModules: ["SynapseCCTP"], - originUserAddress: "0x1234...", + excludedModules: ['SynapseCCTP'], + originUserAddress: '0x1234...', }) ``` From e0ce7e71db0b100d5345a4b76446d42f5433220f Mon Sep 17 00:00:00 2001 From: abtestingalpha Date: Tue, 15 Oct 2024 01:10:16 +0000 Subject: [PATCH 05/15] Publish - @synapsecns/bridge-docs@0.4.3 - @synapsecns/synapse-interface@0.40.9 --- docs/bridge/CHANGELOG.md | 8 ++++++++ docs/bridge/package.json | 2 +- packages/synapse-interface/CHANGELOG.md | 8 ++++++++ packages/synapse-interface/package.json | 2 +- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/docs/bridge/CHANGELOG.md b/docs/bridge/CHANGELOG.md index d7f5871ab9..6aae6f9de8 100644 --- a/docs/bridge/CHANGELOG.md +++ b/docs/bridge/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.4.3](https://github.com/synapsecns/sanguine/compare/@synapsecns/bridge-docs@0.4.2...@synapsecns/bridge-docs@0.4.3) (2024-10-15) + +**Note:** Version bump only for package @synapsecns/bridge-docs + + + + + ## [0.4.2](https://github.com/synapsecns/sanguine/compare/@synapsecns/bridge-docs@0.4.1...@synapsecns/bridge-docs@0.4.2) (2024-10-12) diff --git a/docs/bridge/package.json b/docs/bridge/package.json index 2e2d1bb267..f3bb4e55a7 100644 --- a/docs/bridge/package.json +++ b/docs/bridge/package.json @@ -1,6 +1,6 @@ { "name": "@synapsecns/bridge-docs", - "version": "0.4.2", + "version": "0.4.3", "private": true, "scripts": { "docusaurus": "docusaurus", diff --git a/packages/synapse-interface/CHANGELOG.md b/packages/synapse-interface/CHANGELOG.md index 0895428ebb..e6a6670415 100644 --- a/packages/synapse-interface/CHANGELOG.md +++ b/packages/synapse-interface/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.40.9](https://github.com/synapsecns/sanguine/compare/@synapsecns/synapse-interface@0.40.8...@synapsecns/synapse-interface@0.40.9) (2024-10-15) + +**Note:** Version bump only for package @synapsecns/synapse-interface + + + + + ## [0.40.8](https://github.com/synapsecns/sanguine/compare/@synapsecns/synapse-interface@0.40.7...@synapsecns/synapse-interface@0.40.8) (2024-10-11) **Note:** Version bump only for package @synapsecns/synapse-interface diff --git a/packages/synapse-interface/package.json b/packages/synapse-interface/package.json index 0efdd27a49..7acf6c7973 100644 --- a/packages/synapse-interface/package.json +++ b/packages/synapse-interface/package.json @@ -1,6 +1,6 @@ { "name": "@synapsecns/synapse-interface", - "version": "0.40.8", + "version": "0.40.9", "private": true, "engines": { "node": ">=18.18.0" From ea0154c23055972583af3ba1a31cbb6d86cfdbd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CF=87=C2=B2?= <88190723+ChiTimesChi@users.noreply.github.com> Date: Tue, 15 Oct 2024 14:32:44 +0100 Subject: [PATCH 06/15] test(contracts-rfq): remove test contracts from coverage report (#3291) * test: remove old test contracts from coverage * test: remove new test contracts from coverage --- packages/contracts-rfq/script/FastBridge.s.sol | 3 +++ packages/contracts-rfq/test/FastBridgeMock.sol | 3 +++ packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol | 5 ++++- .../test/FastBridgeV2.GasBench.Dst.ArbitraryCall.t.sol | 5 ++++- .../contracts-rfq/test/FastBridgeV2.GasBench.Dst.Excl.t.sol | 5 ++++- .../test/FastBridgeV2.GasBench.Src.ArbitraryCall.t.sol | 5 ++++- .../test/FastBridgeV2.GasBench.Src.PFees.t.sol | 5 ++++- .../contracts-rfq/test/FastBridgeV2.Src.ProtocolFees.t.sol | 5 ++++- packages/contracts-rfq/test/FastBridgeV2.t.sol | 3 +++ packages/contracts-rfq/test/MockERC20.sol | 4 ++++ packages/contracts-rfq/test/UniversalTokenLibHarness.sol | 5 ++++- .../contracts-rfq/test/harnesses/MulticallTargetHarness.sol | 4 ++++ .../test/mocks/ExcessiveReturnValueRecipient.sol | 4 ++++ .../test/mocks/IncorrectReturnValueRecipient.sol | 4 ++++ .../contracts-rfq/test/mocks/NoReturnValueRecipient.sol | 6 ++++-- packages/contracts-rfq/test/mocks/NonPayableRecipient.sol | 4 ++++ packages/contracts-rfq/test/mocks/RecipientMock.sol | 4 ++++ 17 files changed, 65 insertions(+), 9 deletions(-) diff --git a/packages/contracts-rfq/script/FastBridge.s.sol b/packages/contracts-rfq/script/FastBridge.s.sol index 84d048575d..de3208889f 100644 --- a/packages/contracts-rfq/script/FastBridge.s.sol +++ b/packages/contracts-rfq/script/FastBridge.s.sol @@ -7,6 +7,9 @@ import {Script} from "forge-std/Script.sol"; contract DeployFastBridge is Script { FastBridge public bridge; + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testDeployFastBridge() external {} + /// e.g. forge script contracts/script/FastBridge.s.sol --sig "run(address, address[])" 0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 "[0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f]" function run(address owner, address[] memory relayers) external { vm.startBroadcast(); diff --git a/packages/contracts-rfq/test/FastBridgeMock.sol b/packages/contracts-rfq/test/FastBridgeMock.sol index 0f035c3430..a84ce7db72 100644 --- a/packages/contracts-rfq/test/FastBridgeMock.sol +++ b/packages/contracts-rfq/test/FastBridgeMock.sol @@ -16,6 +16,9 @@ contract FastBridgeMock is IFastBridge, Admin { /// @dev to prevent replays uint256 public nonce; + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeMock() external {} + function getBridgeTransaction(bytes memory request) public pure returns (BridgeTransaction memory) { return abi.decode(request, (BridgeTransaction)); } diff --git a/packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol b/packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol index 9e79e48489..f499136cfe 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.Dst.Base.t.sol @@ -3,10 +3,13 @@ pragma solidity ^0.8.20; import {FastBridgeV2, FastBridgeV2Test, IFastBridgeV2} from "./FastBridgeV2.t.sol"; -// solhint-disable func-name-mixedcase, ordering +// solhint-disable func-name-mixedcase, no-empty-blocks contract FastBridgeV2DstBaseTest is FastBridgeV2Test { uint256 public constant LEFTOVER_BALANCE = 1 ether; + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeV2DstBaseTest() external {} + function setUp() public virtual override { vm.chainId(DST_CHAIN_ID); super.setUp(); diff --git a/packages/contracts-rfq/test/FastBridgeV2.GasBench.Dst.ArbitraryCall.t.sol b/packages/contracts-rfq/test/FastBridgeV2.GasBench.Dst.ArbitraryCall.t.sol index 1fe2da38ab..55958e937f 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.GasBench.Dst.ArbitraryCall.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.GasBench.Dst.ArbitraryCall.t.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.20; import {FastBridgeV2GasBenchmarkDstTest} from "./FastBridgeV2.GasBench.Dst.t.sol"; import {RecipientMock} from "./mocks/RecipientMock.sol"; -// solhint-disable func-name-mixedcase, ordering +// solhint-disable func-name-mixedcase, no-empty-blocks contract FastBridgeV2GasBenchmarkDstArbitraryCallTest is FastBridgeV2GasBenchmarkDstTest { // To get an idea about how much overhead the arbitrary call adds to the relaying process, we use a mock // recipient that has the hook function implemented as a no-op. @@ -12,6 +12,9 @@ contract FastBridgeV2GasBenchmarkDstArbitraryCallTest is FastBridgeV2GasBenchmar // - user address // - some kind of ID to decide what to do with the tokens next + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeV2GasBenchmarkDstArbitraryCallTest() external {} + function setUp() public virtual override { // In the inherited tests userB is always used as the recipient of the tokens. userB = address(new RecipientMock()); diff --git a/packages/contracts-rfq/test/FastBridgeV2.GasBench.Dst.Excl.t.sol b/packages/contracts-rfq/test/FastBridgeV2.GasBench.Dst.Excl.t.sol index 685dab76a4..970f51465b 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.GasBench.Dst.Excl.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.GasBench.Dst.Excl.t.sol @@ -3,10 +3,13 @@ pragma solidity ^0.8.20; import {FastBridgeV2GasBenchmarkDstTest} from "./FastBridgeV2.GasBench.Dst.t.sol"; -// solhint-disable func-name-mixedcase, ordering +// solhint-disable func-name-mixedcase, no-empty-blocks contract FastBridgeV2GasBenchmarkDstExclusivityTest is FastBridgeV2GasBenchmarkDstTest { uint256 public constant EXCLUSIVITY_PERIOD = 60 seconds; + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeV2GasBenchmarkDstExclusivityTest() external {} + function setUp() public virtual override { super.setUp(); skip({time: EXCLUSIVITY_PERIOD / 2}); diff --git a/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.ArbitraryCall.t.sol b/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.ArbitraryCall.t.sol index e806f27544..d9291b8208 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.ArbitraryCall.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.ArbitraryCall.t.sol @@ -3,8 +3,11 @@ pragma solidity ^0.8.20; import {FastBridgeV2GasBenchmarkSrcTest} from "./FastBridgeV2.GasBench.Src.t.sol"; -// solhint-disable func-name-mixedcase, ordering +// solhint-disable func-name-mixedcase, no-empty-blocks contract FastBridgeV2GasBenchmarkSrcArbitraryCallTest is FastBridgeV2GasBenchmarkSrcTest { + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeV2GasBenchmarkSrcArbitraryCallTest() external {} + function createFixturesV2() public virtual override { super.createFixturesV2(); bytes memory mockCallParams = abi.encode(userA, keccak256("Random ID")); diff --git a/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.PFees.t.sol b/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.PFees.t.sol index 51f17b5a96..790db012f6 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.PFees.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.GasBench.Src.PFees.t.sol @@ -3,8 +3,11 @@ pragma solidity ^0.8.20; import {FastBridgeV2GasBenchmarkSrcTest} from "./FastBridgeV2.GasBench.Src.t.sol"; -// solhint-disable func-name-mixedcase, ordering +// solhint-disable func-name-mixedcase, no-empty-blocks contract FastBridgeV2GasBenchmarkSrcProtocolFeesTest is FastBridgeV2GasBenchmarkSrcTest { + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeV2GasBenchmarkSrcProtocolFeesTest() external {} + function configureFastBridge() public virtual override { super.configureFastBridge(); fastBridge.grantRole(fastBridge.GOVERNOR_ROLE(), address(this)); diff --git a/packages/contracts-rfq/test/FastBridgeV2.Src.ProtocolFees.t.sol b/packages/contracts-rfq/test/FastBridgeV2.Src.ProtocolFees.t.sol index d9a5324ed1..775ff257e5 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.Src.ProtocolFees.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.Src.ProtocolFees.t.sol @@ -3,8 +3,11 @@ pragma solidity ^0.8.20; import {FastBridgeV2SrcTest} from "./FastBridgeV2.Src.t.sol"; -// solhint-disable func-name-mixedcase, ordering +// solhint-disable func-name-mixedcase, no-empty-blocks contract FastBridgeV2SrcProtocolFeesTest is FastBridgeV2SrcTest { + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeV2SrcProtocolFeesTest() external {} + function configureFastBridge() public virtual override { super.configureFastBridge(); fastBridge.grantRole(fastBridge.GOVERNOR_ROLE(), address(this)); diff --git a/packages/contracts-rfq/test/FastBridgeV2.t.sol b/packages/contracts-rfq/test/FastBridgeV2.t.sol index fca2bad7c3..1a0c3645a3 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.t.sol @@ -44,6 +44,9 @@ abstract contract FastBridgeV2Test is Test, IFastBridgeV2Errors { IFastBridgeV2.BridgeParamsV2 internal tokenParamsV2; IFastBridgeV2.BridgeParamsV2 internal ethParamsV2; + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testFastBridgeV2Test() external {} + function setUp() public virtual { srcToken = new MockERC20("SrcToken", 6); dstToken = new MockERC20("DstToken", 6); diff --git a/packages/contracts-rfq/test/MockERC20.sol b/packages/contracts-rfq/test/MockERC20.sol index f4c07d49aa..b0e2f67d99 100644 --- a/packages/contracts-rfq/test/MockERC20.sol +++ b/packages/contracts-rfq/test/MockERC20.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.17; import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +// solhint-disable no-empty-blocks contract MockERC20 is ERC20 { uint8 private _decimals; @@ -10,6 +11,9 @@ contract MockERC20 is ERC20 { _decimals = decimals_; } + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testMockERC20() external {} + function burn(address account, uint256 amount) external { _burn(account, amount); } diff --git a/packages/contracts-rfq/test/UniversalTokenLibHarness.sol b/packages/contracts-rfq/test/UniversalTokenLibHarness.sol index 7f8d2d6753..5e628b5fa2 100644 --- a/packages/contracts-rfq/test/UniversalTokenLibHarness.sol +++ b/packages/contracts-rfq/test/UniversalTokenLibHarness.sol @@ -3,8 +3,11 @@ pragma solidity ^0.8.17; import {UniversalTokenLib} from "../contracts/libs/UniversalToken.sol"; -// solhint-disable ordering +// solhint-disable no-empty-blocks, ordering contract UniversalTokenLibHarness { + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testUniversalTokenLibHarness() external {} + function universalTransfer(address token, address to, uint256 value) public { UniversalTokenLib.universalTransfer(token, to, value); } diff --git a/packages/contracts-rfq/test/harnesses/MulticallTargetHarness.sol b/packages/contracts-rfq/test/harnesses/MulticallTargetHarness.sol index 5819dbf3fc..4a2e527f22 100644 --- a/packages/contracts-rfq/test/harnesses/MulticallTargetHarness.sol +++ b/packages/contracts-rfq/test/harnesses/MulticallTargetHarness.sol @@ -3,6 +3,7 @@ pragma solidity ^0.8.0; import {MulticallTarget} from "../../contracts/utils/MulticallTarget.sol"; +// solhint-disable no-empty-blocks contract MulticallTargetHarness is MulticallTarget { address public addressField; uint256 public uintField; @@ -11,6 +12,9 @@ contract MulticallTargetHarness is MulticallTarget { error CustomError(); + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testMulticallTargetHarness() external {} + function setMsgSenderAsAddressField() external returns (address) { addressField = msg.sender; return addressField; diff --git a/packages/contracts-rfq/test/mocks/ExcessiveReturnValueRecipient.sol b/packages/contracts-rfq/test/mocks/ExcessiveReturnValueRecipient.sol index 9c3be02502..21f3484dd7 100644 --- a/packages/contracts-rfq/test/mocks/ExcessiveReturnValueRecipient.sol +++ b/packages/contracts-rfq/test/mocks/ExcessiveReturnValueRecipient.sol @@ -3,11 +3,15 @@ pragma solidity ^0.8.0; import {IFastBridgeRecipient} from "../../contracts/interfaces/IFastBridgeRecipient.sol"; +// solhint-disable no-empty-blocks /// @notice Incorrectly implemented recipient mock for testing purposes. DO NOT USE IN PRODUCTION. contract ExcessiveReturnValueRecipient { /// @notice Mock needs to accept ETH receive() external payable {} + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testExcessiveReturnValueRecipient() external {} + /// @notice Incorrectly implemented - method returns excessive bytes. function fastBridgeTransferReceived(address, uint256, bytes memory) external payable returns (bytes4, uint256) { return (IFastBridgeRecipient.fastBridgeTransferReceived.selector, 1337); diff --git a/packages/contracts-rfq/test/mocks/IncorrectReturnValueRecipient.sol b/packages/contracts-rfq/test/mocks/IncorrectReturnValueRecipient.sol index 2bf955da7f..0570f49cd0 100644 --- a/packages/contracts-rfq/test/mocks/IncorrectReturnValueRecipient.sol +++ b/packages/contracts-rfq/test/mocks/IncorrectReturnValueRecipient.sol @@ -3,11 +3,15 @@ pragma solidity ^0.8.0; import {IFastBridgeRecipient} from "../../contracts/interfaces/IFastBridgeRecipient.sol"; +// solhint-disable no-empty-blocks /// @notice Incorrectly implemented recipient mock for testing purposes. DO NOT USE IN PRODUCTION. contract IncorrectReturnValueRecipient is IFastBridgeRecipient { /// @notice Mock needs to accept ETH receive() external payable {} + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testIncorrectReturnValueRecipient() external {} + /// @notice Incorrectly implemented - method returns incorrect value. function fastBridgeTransferReceived(address, uint256, bytes memory) external payable returns (bytes4) { // Flip the last bit diff --git a/packages/contracts-rfq/test/mocks/NoReturnValueRecipient.sol b/packages/contracts-rfq/test/mocks/NoReturnValueRecipient.sol index e10c8b6ded..1ba76e7402 100644 --- a/packages/contracts-rfq/test/mocks/NoReturnValueRecipient.sol +++ b/packages/contracts-rfq/test/mocks/NoReturnValueRecipient.sol @@ -1,13 +1,15 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -// solhint-disable - +// solhint-disable no-empty-blocks /// @notice Incorrectly implemented recipient mock for testing purposes. DO NOT USE IN PRODUCTION. contract NoReturnValueRecipient { /// @notice Mock needs to accept ETH receive() external payable {} + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testNoReturnValueRecipient() external {} + /// @notice Incorrectly implemented - method does not return anything. function fastBridgeTransferReceived(address, uint256, bytes memory) external payable {} } diff --git a/packages/contracts-rfq/test/mocks/NonPayableRecipient.sol b/packages/contracts-rfq/test/mocks/NonPayableRecipient.sol index 1f53dabfd1..2c80581943 100644 --- a/packages/contracts-rfq/test/mocks/NonPayableRecipient.sol +++ b/packages/contracts-rfq/test/mocks/NonPayableRecipient.sol @@ -1,8 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; +// solhint-disable no-empty-blocks /// @notice Incorrectly implemented recipient mock for testing purposes. DO NOT USE IN PRODUCTION. contract NonPayableRecipient { + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testNonPayableRecipient() external {} + /// @notice Incorrectly implemented - method is not payable. function fastBridgeTransferReceived(address, uint256, bytes memory) external pure returns (bytes4) { return NonPayableRecipient.fastBridgeTransferReceived.selector; diff --git a/packages/contracts-rfq/test/mocks/RecipientMock.sol b/packages/contracts-rfq/test/mocks/RecipientMock.sol index a35d4ac5ec..f95422b322 100644 --- a/packages/contracts-rfq/test/mocks/RecipientMock.sol +++ b/packages/contracts-rfq/test/mocks/RecipientMock.sol @@ -3,11 +3,15 @@ pragma solidity ^0.8.0; import {IFastBridgeRecipient} from "../../contracts/interfaces/IFastBridgeRecipient.sol"; +// solhint-disable no-empty-blocks /// @notice Recipient mock for testing purposes. DO NOT USE IN PRODUCTION. contract RecipientMock is IFastBridgeRecipient { /// @notice Mock needs to accept ETH receive() external payable {} + /// @notice We include an empty "test" function so that this contract does not appear in the coverage report. + function testRecipientMock() external {} + /// @notice Minimal viable implementation of the fastBridgeTransferReceived hook. function fastBridgeTransferReceived(address, uint256, bytes memory) external payable returns (bytes4) { return IFastBridgeRecipient.fastBridgeTransferReceived.selector; From b09b41c2a55efbca44e6daef27e723284e8137ea Mon Sep 17 00:00:00 2001 From: ChiTimesChi Date: Tue, 15 Oct 2024 13:37:06 +0000 Subject: [PATCH 07/15] Publish - @synapsecns/contracts-rfq@0.8.2 --- packages/contracts-rfq/CHANGELOG.md | 8 ++++++++ packages/contracts-rfq/package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/contracts-rfq/CHANGELOG.md b/packages/contracts-rfq/CHANGELOG.md index 2cdda57ace..3c3f40bb2d 100644 --- a/packages/contracts-rfq/CHANGELOG.md +++ b/packages/contracts-rfq/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.8.2](https://github.com/synapsecns/sanguine/compare/@synapsecns/contracts-rfq@0.8.1...@synapsecns/contracts-rfq@0.8.2) (2024-10-15) + +**Note:** Version bump only for package @synapsecns/contracts-rfq + + + + + ## [0.8.1](https://github.com/synapsecns/sanguine/compare/@synapsecns/contracts-rfq@0.8.0...@synapsecns/contracts-rfq@0.8.1) (2024-10-14) **Note:** Version bump only for package @synapsecns/contracts-rfq diff --git a/packages/contracts-rfq/package.json b/packages/contracts-rfq/package.json index 45f09710e3..701ea12ed0 100644 --- a/packages/contracts-rfq/package.json +++ b/packages/contracts-rfq/package.json @@ -1,7 +1,7 @@ { "name": "@synapsecns/contracts-rfq", "license": "MIT", - "version": "0.8.1", + "version": "0.8.2", "description": "FastBridge contracts.", "private": true, "files": [ From cd85cadc6c7d490d3d71812339ebea473ce1091e Mon Sep 17 00:00:00 2001 From: parodime Date: Tue, 15 Oct 2024 12:29:50 -0400 Subject: [PATCH 08/15] +rfq-loadtest [SLT-349] (#3281) * +rfq-loadtest * lint * lint * lint * fix retry loop * yarn fix * scope package & set private * impv docs --------- Co-authored-by: Trajan0x --- docs/bridge/docs/04-Routers/RFQ/index.md | 4 + packages/rfq-loadtest/.gitignore | 11 + packages/rfq-loadtest/.vscode/launch.json | 26 + packages/rfq-loadtest/README.md | 61 ++ packages/rfq-loadtest/config-template.yaml | 70 ++ packages/rfq-loadtest/package.json | 34 + packages/rfq-loadtest/sql/ponderSummary.sql | 43 + packages/rfq-loadtest/src/abi.ts | 952 ++++++++++++++++++++ packages/rfq-loadtest/src/index.ts | 496 ++++++++++ packages/rfq-loadtest/src/pyRepeater.py | 11 + packages/rfq-loadtest/src/utils.ts | 34 + packages/rfq-loadtest/tsconfig.json | 16 + yarn.lock | 74 +- 13 files changed, 1822 insertions(+), 10 deletions(-) create mode 100644 packages/rfq-loadtest/.gitignore create mode 100644 packages/rfq-loadtest/.vscode/launch.json create mode 100644 packages/rfq-loadtest/README.md create mode 100644 packages/rfq-loadtest/config-template.yaml create mode 100644 packages/rfq-loadtest/package.json create mode 100644 packages/rfq-loadtest/sql/ponderSummary.sql create mode 100644 packages/rfq-loadtest/src/abi.ts create mode 100644 packages/rfq-loadtest/src/index.ts create mode 100644 packages/rfq-loadtest/src/pyRepeater.py create mode 100644 packages/rfq-loadtest/src/utils.ts create mode 100644 packages/rfq-loadtest/tsconfig.json diff --git a/docs/bridge/docs/04-Routers/RFQ/index.md b/docs/bridge/docs/04-Routers/RFQ/index.md index b44418cde1..b2a498f803 100644 --- a/docs/bridge/docs/04-Routers/RFQ/index.md +++ b/docs/bridge/docs/04-Routers/RFQ/index.md @@ -75,3 +75,7 @@ In a successful dispute, the relayer loses their claimable funds. This design is ## Unfulfilled requests If a request is not fulfilled, users can reclaim their funds by using the [`claim`](https://vercel-rfq-docs.vercel.app/contracts/FastBridge.sol/contract.FastBridge.html#claim) function once the optimistic window has passed. + +## Load Tester + +The [`rfq-loadtest`](https://github.com/synapsecns/sanguine/tree/master/packages/rfq-loadtest) tool can be used to rapidly send ETH bridges for the purpose of load testing. \ No newline at end of file diff --git a/packages/rfq-loadtest/.gitignore b/packages/rfq-loadtest/.gitignore new file mode 100644 index 0000000000..2d6baefbab --- /dev/null +++ b/packages/rfq-loadtest/.gitignore @@ -0,0 +1,11 @@ + +node_modules/ + +*.tsbuildinfo + +dist/ + +.env + +config*.yaml +!config-template.yaml diff --git a/packages/rfq-loadtest/.vscode/launch.json b/packages/rfq-loadtest/.vscode/launch.json new file mode 100644 index 0000000000..d15373c646 --- /dev/null +++ b/packages/rfq-loadtest/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "debugRun", + "skipFiles": [ + "/**" + ], + "program": "${workspaceFolder}/src/index.ts", + "preLaunchTask": "npm: build", + "sourceMaps": true, + "smartStep": true, + "console": "internalConsole", + "internalConsoleOptions": "openOnSessionStart", + "args": ["--configFile", "config-dev.yaml", "--pKeyIndex", "5"], + "outFiles": [ + "${workspaceFolder}/dist/**/*.js" + ] + } + ] +} \ No newline at end of file diff --git a/packages/rfq-loadtest/README.md b/packages/rfq-loadtest/README.md new file mode 100644 index 0000000000..4af4152226 --- /dev/null +++ b/packages/rfq-loadtest/README.md @@ -0,0 +1,61 @@ +> :warning: **Warning**: This tool is not intended to be used for anything other than testing with inconsequentially small amounts of ETH on EOAs that were created for the sole & explicit purpose of testing. + +# RFQ Load Test Configuration Guide + +This guide outlines the steps and requirements for setting up the RFQ load testing tool. The tool is designed to send many ETH bridges in rapid succession. + +## Wallet Configuration + +- **Create and Fund Wallets:** You are required to create and fund as many wallets as you wish to test with. This tool only supports native ETH bridges on chains that use ETH as the gas currency. + +- **Auto-Rebalance:** If you only initially fund ETH on one of the test chains, the tool will automatically rebalance the funds to the other chains before beginning the tests. It will also rebalance as needed while the tests are operating until none of the test chains have enough ETH to effectively rebalance to the others - at which point it will cease the process. The RFQ system is also used for these rebalance actions. + + +# Script Configuration + +Follow these steps to configure your load testing environment for blockchain transactions. + +## Step 1: Prepare Configuration File + +1. Start by copying the `config-template.yaml` file from the `packages/rfq-loadtest` directory. This will serve as the basis for your test configuration. + ```bash + cp packages/rfq-loadtest/config-template.yaml packages/rfq-loadtest/config-run.yaml + ``` + +## Step 2: Configure Private Keys + +2. Open the `config-run.yaml` file and locate the `PRIVATE_KEY_X` entries. Replace the placeholder values with your actual private keys. These keys will be used to execute transactions during the tests. + ```yaml + PRIVATE_KEY_1: 'your_private_key_here' + PRIVATE_KEY_2: 'your_private_key_here' + PRIVATE_KEY_3: 'your_private_key_here' + PRIVATE_KEY_4: 'your_private_key_here' + PRIVATE_KEY_5: 'your_private_key_here' + ``` + +## Step 3: Set Transaction Pace + +3. Adjust the settings under `##### TEST PACE` to control the pace of transactions. You can modify the `VOLLEY_MILLISECONDS_BETWEEN`, `VOLLEY_MIN_COUNT`, and `VOLLEY_MAX_COUNT` to fit your testing requirements. + +## Step 4: Specify Test Bridge Amount + +4. Define the amount of ETH to be sent in each test transaction under `TEST_BRIDGE_AMOUNT_UNITS`. The default is set to `0.00007`. + +## Step 5: Configure Gas and Rebalance Settings + +5. Set the `MINIMUM_GAS_UNITS` to the desired threshold for triggering a rebalance of funds across chains. Specify the `REBALANCE_TO_UNITS` to determine the target amount for each chain after rebalancing. + +## Step 6: Define Chain Settings + +6. In the `CHAINS` section, configure the `FastRouterAddr` and `rpcUrl` settings for each chain involved in your tests. These settings include URLs for reading, simulation, and submitting transactions. + +## Step 7: Configure Test Routes + +7. Under `TEST_ROUTES`, define the routes for your test transactions, including `fromChainId`, `toChainId`, and `testDistributionPercentage` to control the flow and distribution of transactions between chains. + +## Step 8: Save and Run + +8. Save your changes to `config-run.yaml`. To start the load test, use the provided startup example, adjusting the path to your configuration file as necessary. + ```bash + python3 pyRepeater.py 'node index.js --configFile ../config-run.yaml --pKeyIndex 1' + ``` diff --git a/packages/rfq-loadtest/config-template.yaml b/packages/rfq-loadtest/config-template.yaml new file mode 100644 index 0000000000..0727058300 --- /dev/null +++ b/packages/rfq-loadtest/config-template.yaml @@ -0,0 +1,70 @@ + +# create & fund however many wallets you want to test with. +# only supports native ETH bridges on chains that use ETH as gas. +# if you only fund ETH on one of the test chains it will auto-rebalance the funds to the others before beginning tests. + +# Startup example w/ pyRepeater to auto-restart the process if anything kills it +# python3 pyRepeater.py 'node index.js --configFile ../config-prod.yaml --pKeyIndex 1' + +PRIVATE_KEY_1: '0xabcdef123456abcdef123456abcdef123456abcdef123456abcdef123456abcd' +PRIVATE_KEY_2: '0xabcdef123456abcdef123456abcdef123456abcdef123456abcdef123456abcd' +PRIVATE_KEY_3: '0xabcdef123456abcdef123456abcdef123456abcdef123456abcdef123456abcd' +PRIVATE_KEY_4: '0xabcdef123456abcdef123456abcdef123456abcdef123456abcdef123456abcd' +PRIVATE_KEY_5: '0xabcdef123456abcdef123456abcdef123456abcdef123456abcdef123456abcd' + +##### TEST PACE +# these settings are a pace of about 100K deposits per day +# +# how long to wait in btwn each volley? +VOLLEY_MILLISECONDS_BETWEEN: 5500 +# each volley sends a batch of between {min} and {max} transactions +VOLLEY_MIN_COUNT: 1 +VOLLEY_MAX_COUNT: 5 + +# these settings are a pace of about 150K deposits per day +#VOLLEY_MILLISECONDS_BETWEEN: 5500 +#VOLLEY_MIN_COUNT: 1 +#VOLLEY_MAX_COUNT: 5 + +# approx how much ETH to send on each test bridge? 0.00007 +TEST_BRIDGE_AMOUNT_UNITS: 0.00007 + +# trigger a rebalance when gas reaches this value or lower +MINIMUM_GAS_UNITS: 0.003 + +# when a rebalance is triggered, resupply the deficit chain to this amount +REBALANCE_TO_UNITS: 0.01 + +CHAINS: + 10: + FastRouterAddr: '0x00cd000000003f7f682be4813200893d4e690000' + # urls used for Reading / Tx Simulation / Tx Submit -- respectively. Change to others as needed. + rpcUrl_Read: 'https://mainnet.optimism.io' + rpcUrl_Sim: 'https://mainnet.optimism.io' + rpcUrl_Write: 'https://mainnet.optimism.io' + 8453: + FastRouterAddr: '0x00cd000000003f7f682be4813200893d4e690000' + # urls used for Reading / Tx Simulation / Tx Submit -- respectively. Change to others as needed. + rpcUrl_Read: 'https://mainnet.base.org' + rpcUrl_Sim: 'https://mainnet.base.org' + rpcUrl_Write: 'https://mainnet.base.org' + 480: + FastRouterAddr: '0x00cd000000003f7f682be4813200893d4e690000' + # urls used for Reading / Tx Simulation / Tx Submit -- respectively. Change to others as needed. + rpcUrl_Read: 'https://worldchain-mainnet.g.alchemy.com/public' + rpcUrl_Sim: 'https://worldchain-mainnet.g.alchemy.com/public' + rpcUrl_Write: 'https://worldchain-mainnet.g.alchemy.com/public' + +TEST_ROUTES: + 480>10: + fromChainId: 480 + toChainId: 10 + testDistributionPercentage: 70 + 10>480: + fromChainId: 10 + toChainId: 480 + testDistributionPercentage: 15 + 8453>480: + fromChainId: 8453 + toChainId: 480 + testDistributionPercentage: 15 diff --git a/packages/rfq-loadtest/package.json b/packages/rfq-loadtest/package.json new file mode 100644 index 0000000000..c5640dc64c --- /dev/null +++ b/packages/rfq-loadtest/package.json @@ -0,0 +1,34 @@ +{ + "name": "@synapsecns/rfq-loadtest", + "version": "1.0.0", + "main": "index.js", + "type": "module", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "cp src/pyRepeater.py dist/ && tsc", + "lint": "eslint .", + "ci:lint": "eslint .", + "typecheck": "tsc", + "test:coverage": "echo 'No tests defined.'", + "build:go": " ", + "build:slither": " " + }, + "keywords": [], + "author": "", + "license": "ISC", + "private": "true", + "description": "", + "devDependencies": { + "@types/js-yaml": "^4.0.9", + "@types/node": "^22.7.5", + "@types/yargs": "^17.0.33", + "ts-node": "^10.9.2", + "typescript": "^5.6.3" + }, + "dependencies": { + "axios": "^1.7.7", + "js-yaml": "^4.1.0", + "viem": "^2.21.19", + "yargs": "^17.7.2" + } +} diff --git a/packages/rfq-loadtest/sql/ponderSummary.sql b/packages/rfq-loadtest/sql/ponderSummary.sql new file mode 100644 index 0000000000..0ce67b33ce --- /dev/null +++ b/packages/rfq-loadtest/sql/ponderSummary.sql @@ -0,0 +1,43 @@ + +-- run this on ponder index to get a summary of a test run. use WHERE params to point it at a particular test period. + +select to_timestamp(min(depositTs)) period_start, + to_timestamp(max(depositTs)) period_end, + max(depositTs) - min(depositTs) period_seconds, + round(count(1) * 1.00 / (max(depositTs) - min(depositTs)), 2) deposits_per_second, + round(count(1) * 1.00 / (max(depositTs) - min(depositTs)) * 86400, 0) deposits_per_day, + count(1) count_deposits, + count(case when proofSeconds is not null then 1 else null end) count_proofs, + count(case when claimSeconds is not null then 1 else null end) count_claims, + count(case when disputeId is not null then 1 else null end) count_disputes, + round(avg(relaySeconds), 2) relaySeconds_AVG, + max(relaySeconds) relaySeconds_MAX, + round(avg(proofSeconds), 2) proofSeconds_AVG, + max(proofSeconds) proofSeconds_MAX, + round(avg(claimSeconds), 2) claimSeconds_AVG, + max(claimSeconds) claimSeconds_MAX +from ( +-- this subquery can be executed by itself for detail data + select xdeposit."blockTimestamp" depositTs, + xdeposit."transactionId", + xrelay."blockTimestamp" - xdeposit."blockTimestamp" relaySeconds, + xproof."blockTimestamp" - xrelay."blockTimestamp" proofSeconds, + xclaim."blockTimestamp" - xproof."blockTimestamp" - 1800 claimSeconds, + xdispute.id disputeId, + xrelay.relayer + from "BridgeRequestEvents" xdeposit + left join "BridgeRelayedEvents" xrelay on + xdeposit."transactionId" = xrelay."transactionId" + left join "BridgeProofProvidedEvents" xproof on + xdeposit."transactionId" = xproof."transactionId" + left join "BridgeDepositClaimedEvents" xclaim on + xdeposit."transactionId" = xclaim."transactionId" + left join "BridgeProofDisputedEvents" xdispute on + xdeposit."transactionId" = xdispute."transactionId" + where xdeposit."originChainId" = 480 + and xdeposit."originAmount" <= 71000000000000 + + -- change these to point at a particular test period + and xdeposit."blockTimestamp" between 1728666774 and 1728667721 + ) sqData; + diff --git a/packages/rfq-loadtest/src/abi.ts b/packages/rfq-loadtest/src/abi.ts new file mode 100644 index 0000000000..d5345e3dc8 --- /dev/null +++ b/packages/rfq-loadtest/src/abi.ts @@ -0,0 +1,952 @@ +export const ABI = { + fastBridgeV1: [ + { + inputs: [{ internalType: 'address', name: '_owner', type: 'address' }], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'AccessControlBadConfirmation', type: 'error' }, + { + inputs: [ + { internalType: 'address', name: 'account', type: 'address' }, + { internalType: 'bytes32', name: 'neededRole', type: 'bytes32' }, + ], + name: 'AccessControlUnauthorizedAccount', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'target', type: 'address' }], + name: 'AddressEmptyCode', + type: 'error', + }, + { + inputs: [{ internalType: 'address', name: 'account', type: 'address' }], + name: 'AddressInsufficientBalance', + type: 'error', + }, + { inputs: [], name: 'AmountIncorrect', type: 'error' }, + { inputs: [], name: 'ChainIncorrect', type: 'error' }, + { inputs: [], name: 'DeadlineExceeded', type: 'error' }, + { inputs: [], name: 'DeadlineNotExceeded', type: 'error' }, + { inputs: [], name: 'DeadlineTooShort', type: 'error' }, + { inputs: [], name: 'DisputePeriodNotPassed', type: 'error' }, + { inputs: [], name: 'DisputePeriodPassed', type: 'error' }, + { inputs: [], name: 'FailedInnerCall', type: 'error' }, + { inputs: [], name: 'MsgValueIncorrect', type: 'error' }, + { + inputs: [{ internalType: 'address', name: 'token', type: 'address' }], + name: 'SafeERC20FailedOperation', + type: 'error', + }, + { inputs: [], name: 'SenderIncorrect', type: 'error' }, + { inputs: [], name: 'StatusIncorrect', type: 'error' }, + { inputs: [], name: 'TokenNotContract', type: 'error' }, + { inputs: [], name: 'TransactionRelayed', type: 'error' }, + { inputs: [], name: 'ZeroAddress', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'transactionId', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'relayer', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'BridgeDepositClaimed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'transactionId', + type: 'bytes32', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'BridgeDepositRefunded', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'transactionId', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'relayer', + type: 'address', + }, + ], + name: 'BridgeProofDisputed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'transactionId', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'relayer', + type: 'address', + }, + { + indexed: false, + internalType: 'bytes32', + name: 'transactionHash', + type: 'bytes32', + }, + ], + name: 'BridgeProofProvided', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'transactionId', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'relayer', + type: 'address', + }, + { indexed: true, internalType: 'address', name: 'to', type: 'address' }, + { + indexed: false, + internalType: 'uint32', + name: 'originChainId', + type: 'uint32', + }, + { + indexed: false, + internalType: 'address', + name: 'originToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'destToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'originAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'destAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'chainGasAmount', + type: 'uint256', + }, + ], + name: 'BridgeRelayed', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'transactionId', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + { + indexed: false, + internalType: 'bytes', + name: 'request', + type: 'bytes', + }, + { + indexed: false, + internalType: 'uint32', + name: 'destChainId', + type: 'uint32', + }, + { + indexed: false, + internalType: 'address', + name: 'originToken', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'destToken', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'originAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'destAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'bool', + name: 'sendChainGas', + type: 'bool', + }, + ], + name: 'BridgeRequested', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldChainGasAmount', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newChainGasAmount', + type: 'uint256', + }, + ], + name: 'ChainGasAmountUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'uint256', + name: 'oldFeeRate', + type: 'uint256', + }, + { + indexed: false, + internalType: 'uint256', + name: 'newFeeRate', + type: 'uint256', + }, + ], + name: 'FeeRateUpdated', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'token', + type: 'address', + }, + { + indexed: false, + internalType: 'address', + name: 'recipient', + type: 'address', + }, + { + indexed: false, + internalType: 'uint256', + name: 'amount', + type: 'uint256', + }, + ], + name: 'FeesSwept', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'previousAdminRole', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'bytes32', + name: 'newAdminRole', + type: 'bytes32', + }, + ], + name: 'RoleAdminChanged', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'RoleGranted', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'bytes32', + name: 'role', + type: 'bytes32', + }, + { + indexed: true, + internalType: 'address', + name: 'account', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'sender', + type: 'address', + }, + ], + name: 'RoleRevoked', + type: 'event', + }, + { + inputs: [], + name: 'DEFAULT_ADMIN_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'DISPUTE_PERIOD', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'FEE_BPS', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'FEE_RATE_MAX', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'GOVERNOR_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'GUARD_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'MIN_DEADLINE_PERIOD', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'REFUNDER_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'REFUND_DELAY', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'RELAYER_ROLE', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { + components: [ + { internalType: 'uint32', name: 'dstChainId', type: 'uint32' }, + { internalType: 'address', name: 'sender', type: 'address' }, + { internalType: 'address', name: 'to', type: 'address' }, + { internalType: 'address', name: 'originToken', type: 'address' }, + { internalType: 'address', name: 'destToken', type: 'address' }, + { internalType: 'uint256', name: 'originAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'destAmount', type: 'uint256' }, + { internalType: 'bool', name: 'sendChainGas', type: 'bool' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + ], + internalType: 'struct IFastBridge.BridgeParams', + name: 'params', + type: 'tuple', + }, + ], + name: 'bridge', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + name: 'bridgeProofs', + outputs: [ + { internalType: 'uint96', name: 'timestamp', type: 'uint96' }, + { internalType: 'address', name: 'relayer', type: 'address' }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + name: 'bridgeRelays', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + name: 'bridgeStatuses', + outputs: [ + { + internalType: 'enum FastBridge.BridgeStatus', + name: '', + type: 'uint8', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'transactionId', type: 'bytes32' }, + { internalType: 'address', name: 'relayer', type: 'address' }, + ], + name: 'canClaim', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'chainGasAmount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes', name: 'request', type: 'bytes' }, + { internalType: 'address', name: 'to', type: 'address' }, + ], + name: 'claim', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'deployBlock', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'transactionId', type: 'bytes32' }, + ], + name: 'dispute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes', name: 'request', type: 'bytes' }], + name: 'getBridgeTransaction', + outputs: [ + { + components: [ + { internalType: 'uint32', name: 'originChainId', type: 'uint32' }, + { internalType: 'uint32', name: 'destChainId', type: 'uint32' }, + { internalType: 'address', name: 'originSender', type: 'address' }, + { internalType: 'address', name: 'destRecipient', type: 'address' }, + { internalType: 'address', name: 'originToken', type: 'address' }, + { internalType: 'address', name: 'destToken', type: 'address' }, + { internalType: 'uint256', name: 'originAmount', type: 'uint256' }, + { internalType: 'uint256', name: 'destAmount', type: 'uint256' }, + { + internalType: 'uint256', + name: 'originFeeAmount', + type: 'uint256', + }, + { internalType: 'bool', name: 'sendChainGas', type: 'bool' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'uint256', name: 'nonce', type: 'uint256' }, + ], + internalType: 'struct IFastBridge.BridgeTransaction', + name: '', + type: 'tuple', + }, + ], + stateMutability: 'pure', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'role', type: 'bytes32' }], + name: 'getRoleAdmin', + outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'uint256', name: 'index', type: 'uint256' }, + ], + name: 'getRoleMember', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes32', name: 'role', type: 'bytes32' }], + name: 'getRoleMemberCount', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'grantRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'hasRole', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'nonce', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'protocolFeeRate', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: '', type: 'address' }], + name: 'protocolFees', + outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes', name: 'request', type: 'bytes' }, + { internalType: 'bytes32', name: 'destTxHash', type: 'bytes32' }, + ], + name: 'prove', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes', name: 'request', type: 'bytes' }], + name: 'refund', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes', name: 'request', type: 'bytes' }], + name: 'relay', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { + internalType: 'address', + name: 'callerConfirmation', + type: 'address', + }, + ], + name: 'renounceRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'bytes32', name: 'role', type: 'bytes32' }, + { internalType: 'address', name: 'account', type: 'address' }, + ], + name: 'revokeRole', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'newChainGasAmount', type: 'uint256' }, + ], + name: 'setChainGasAmount', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'uint256', name: 'newFeeRate', type: 'uint256' }, + ], + name: 'setProtocolFeeRate', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [{ internalType: 'bytes4', name: 'interfaceId', type: 'bytes4' }], + name: 'supportsInterface', + outputs: [{ internalType: 'bool', name: '', type: 'bool' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'address', name: 'recipient', type: 'address' }, + ], + name: 'sweepProtocolFees', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + ], + + fastRouterV2: [ + { + inputs: [{ internalType: 'address', name: 'owner_', type: 'address' }], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { inputs: [], name: 'DeadlineExceeded', type: 'error' }, + { + inputs: [], + name: 'FastBridgeRouterV2__OriginSenderNotSpecified', + type: 'error', + }, + { inputs: [], name: 'InsufficientOutputAmount', type: 'error' }, + { inputs: [], name: 'MsgValueIncorrect', type: 'error' }, + { inputs: [], name: 'PoolNotFound', type: 'error' }, + { inputs: [], name: 'TokenAddressMismatch', type: 'error' }, + { inputs: [], name: 'TokenNotContract', type: 'error' }, + { inputs: [], name: 'TokenNotETH', type: 'error' }, + { inputs: [], name: 'TokensIdentical', type: 'error' }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newFastBridge', + type: 'address', + }, + ], + name: 'FastBridgeSet', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: 'address', + name: 'previousOwner', + type: 'address', + }, + { + indexed: true, + internalType: 'address', + name: 'newOwner', + type: 'address', + }, + ], + name: 'OwnershipTransferred', + type: 'event', + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: 'address', + name: 'newSwapQuoter', + type: 'address', + }, + ], + name: 'SwapQuoterSet', + type: 'event', + }, + { + inputs: [], + name: 'GAS_REBATE_FLAG', + outputs: [{ internalType: 'bytes1', name: '', type: 'bytes1' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'address', name: 'tokenIn', type: 'address' }, + { internalType: 'uint256', name: 'amountIn', type: 'uint256' }, + { internalType: 'address', name: 'tokenOut', type: 'address' }, + { internalType: 'bytes', name: 'rawParams', type: 'bytes' }, + ], + name: 'adapterSwap', + outputs: [ + { internalType: 'uint256', name: 'amountOut', type: 'uint256' }, + ], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'recipient', type: 'address' }, + { internalType: 'uint256', name: 'chainId', type: 'uint256' }, + { internalType: 'address', name: 'token', type: 'address' }, + { internalType: 'uint256', name: 'amount', type: 'uint256' }, + { + components: [ + { internalType: 'address', name: 'routerAdapter', type: 'address' }, + { internalType: 'address', name: 'tokenOut', type: 'address' }, + { internalType: 'uint256', name: 'minAmountOut', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'bytes', name: 'rawParams', type: 'bytes' }, + ], + internalType: 'struct SwapQuery', + name: 'originQuery', + type: 'tuple', + }, + { + components: [ + { internalType: 'address', name: 'routerAdapter', type: 'address' }, + { internalType: 'address', name: 'tokenOut', type: 'address' }, + { internalType: 'uint256', name: 'minAmountOut', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'bytes', name: 'rawParams', type: 'bytes' }, + ], + internalType: 'struct SwapQuery', + name: 'destQuery', + type: 'tuple', + }, + ], + name: 'bridge', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, + { + inputs: [], + name: 'fastBridge', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'tokenIn', type: 'address' }, + { internalType: 'address[]', name: 'rfqTokens', type: 'address[]' }, + { internalType: 'uint256', name: 'amountIn', type: 'uint256' }, + ], + name: 'getOriginAmountOut', + outputs: [ + { + components: [ + { internalType: 'address', name: 'routerAdapter', type: 'address' }, + { internalType: 'address', name: 'tokenOut', type: 'address' }, + { internalType: 'uint256', name: 'minAmountOut', type: 'uint256' }, + { internalType: 'uint256', name: 'deadline', type: 'uint256' }, + { internalType: 'bytes', name: 'rawParams', type: 'bytes' }, + ], + internalType: 'struct SwapQuery[]', + name: 'originQueries', + type: 'tuple[]', + }, + ], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [], + name: 'renounceOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'fastBridge_', type: 'address' }, + ], + name: 'setFastBridge', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'swapQuoter_', type: 'address' }, + ], + name: 'setSwapQuoter', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [], + name: 'swapQuoter', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, + { + inputs: [{ internalType: 'address', name: 'newOwner', type: 'address' }], + name: 'transferOwnership', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { stateMutability: 'payable', type: 'receive' }, + ], +} diff --git a/packages/rfq-loadtest/src/index.ts b/packages/rfq-loadtest/src/index.ts new file mode 100644 index 0000000000..c064a36022 --- /dev/null +++ b/packages/rfq-loadtest/src/index.ts @@ -0,0 +1,496 @@ +import fs from 'fs/promises' + +import * as viemChains from 'viem/chains' +import { privateKeyToAccount } from 'viem/accounts' +import { + createPublicClient, + createWalletClient, + formatUnits, + http, + parseUnits, + publicActions, + PublicClient, + WalletClient, +} from 'viem' +import yaml from 'js-yaml' +import yargs from 'yargs' +import { hideBin } from 'yargs/helpers' +import axios from 'axios' +import { createNonceManager, jsonRpc } from 'viem/nonce' + +import { ABI } from './abi.js' +import { delay, print, getRandomInt } from './utils.js' + +const argv = await yargs(hideBin(process.argv)) + .option('configFile', { + alias: 'c', + type: 'string', + description: 'Path to the config file', + demandOption: true, + }) + .option('pKeyIndex', { + alias: 'p', + type: 'number', + description: 'Index of the private key', + demandOption: true, + }) + .help().argv + +const configFilePath = argv.configFile +const configFileContent = await fs.readFile(configFilePath, 'utf-8') + +let config: any +try { + config = yaml.load(configFileContent) as object + + if (typeof config !== 'object' || config === null) { + throw new Error() + } + + if ( + typeof config.VOLLEY_MILLISECONDS_BETWEEN !== 'number' || + typeof config.VOLLEY_MIN_COUNT !== 'number' || + typeof config.VOLLEY_MAX_COUNT !== 'number' + ) { + throw new Error('Invalid configuration values for volley settings') + } + + if (typeof config.CHAINS !== 'object' || config.CHAINS === null) { + throw new Error('Invalid configuration for CHAINS') + } + + if (typeof config.TEST_ROUTES !== 'object' || config.TEST_ROUTES === null) { + throw new Error('Invalid configuration for TEST_ROUTES') + } + + if (typeof config.TEST_BRIDGE_AMOUNT_UNITS !== 'number') { + throw new Error('Invalid configuration for TEST_BRIDGE_AMOUNT_UNITS') + } + if (typeof config.MINIMUM_GAS_UNITS !== 'number') { + throw new Error('Invalid configuration for MINIMUM_GAS_UNITS') + } + if (typeof config.REBALANCE_TO_UNITS !== 'number') { + throw new Error('Invalid configuration for REBALANCE_TO_UNITS') + } + + Object.entries(config.TEST_ROUTES).forEach( + ([route, details]: [string, any]) => { + if (typeof details !== 'object' || details === null) { + throw new Error(`Invalid configuration for route: ${route}`) + } + if ( + typeof details.fromChainId !== 'number' || + typeof details.toChainId !== 'number' || + typeof details.testDistributionPercentage !== 'number' + ) { + throw new Error(`Invalid configuration values for route: ${route}`) + } + } + ) +} catch (error: any) { + throw new Error( + `Failed to parse ${configFilePath}. Check your syntax, structure, data, and for duplicates. \n${error.message}` + ) +} + +const privateKeyIndex = argv.pKeyIndex +if (typeof privateKeyIndex !== 'number' || privateKeyIndex < 1) { + throw new Error('pKeyIndex must be a positive integer') +} + +const privateKeyName = `PRIVATE_KEY_${privateKeyIndex}` +const privateKey: `0x${string}` = config[privateKeyName] as `0x${string}` + +if (!privateKey) { + throw new Error(`${privateKeyName} is not defined in the config file`) +} + +// construct enriched versions of viem chain objects ("vChains") based on what was supplied in config file +const vChains: any = {} +Object.entries(config.CHAINS).forEach( + ([chainId, chainConfig]: [string, any]) => { + const viemChain = Object.values(viemChains).find( + (chain) => chain.id === parseInt(chainId, 10) + ) + if (!viemChain) { + throw new Error( + `No viem chain config found for chain ID ${chainId}. Bump viem version or add manually` + ) + } + + vChains[chainId] = { + ...viemChain, + ...chainConfig, + vCliRead: {} as PublicClient, + vCliSim: {} as WalletClient, + vCliWrite: {} as WalletClient, + } + } +) + +const nonceManager = createNonceManager({ + source: jsonRpc(), +}) + +const walletAccount = privateKeyToAccount(privateKey, { nonceManager }) + +print(`Using ${privateKeyName}: ${walletAccount.address}`) + +Object.keys(vChains).forEach((chainId: string) => { + const chain = vChains[chainId] + + chain.vCliRead = createPublicClient({ + chain, + transport: http(chain.rpcUrl_Read), + }) as PublicClient + + chain.vCliSim = createWalletClient({ + chain, + transport: http(chain.rpcUrl_Sim), + }).extend(publicActions) + + chain.vCliWrite = createWalletClient({ + chain, + transport: http(chain.rpcUrl_Write), + }).extend(publicActions) + + Promise.all([ + chain.vCliRead.readContract({ + address: chain.FastRouterAddr, + abi: ABI.fastRouterV2, + functionName: 'fastBridge', + }), + // not just used to report block height. also serves as connectivity test for all three clients. + chain.vCliRead.getBlockNumber(), + chain.vCliSim.getBlockNumber(), + chain.vCliWrite.getBlockNumber(), + ]).then( + // eslint-disable-next-line @typescript-eslint/no-unused-vars + ([fastBridgeAddr, blockNumber_Read, blockNumber_Sim, blockNumber_Write]: [ + string, + bigint, + bigint, + bigint + ]) => { + print( + `Connected to chain ID ${chainId + .toString() + .padStart(7)}. FastBridge at: ${fastBridgeAddr.slice( + 0, + 6 + )}... Current block height: ${blockNumber_Read}` + ) + } + ) +}) + +let cachedResponseRFQ: any + +let sendCounter = 0 + +let lastAction: string = 'none' + +const testBridgeAmountUnits = config.TEST_BRIDGE_AMOUNT_UNITS + +mainFlow() + +async function mainFlow() { + await delay(1500) + + while (!walletAccount.address) { + print(`%ts Awaiting Initialization...`) + await delay(5000) + } + + checkBals() + + looper_getRequestParams() + + await delay(2500) + + while (!cachedResponseRFQ) { + print(`%ts Awaiting cached RFQ API response to populate...`) + await delay(5000) + } + + bridgeLooper() +} + +async function checkBals() { + for (;;) { + await Promise.all( + Object.keys(vChains).map(async (chainId: string) => { + const chain = vChains[chainId] + try { + const balance = await chain.vCliRead.getBalance({ + address: walletAccount.address, + }) + chain.balanceRaw = balance + chain.balanceUnits = formatUnits(balance, 18) + } catch (error: any) { + print( + `Error fetching balance for chain ID ${chainId}: ${error.message}` + ) + } + }) + ) + + await delay(15_000) + } +} + +const minGasUnits = config.MINIMUM_GAS_UNITS +const rebalToUnits = config.REBALANCE_TO_UNITS +async function bridgeLooper() { + + let retryCount = 0 + + for (;;) { + // Find the chain with the lowest balance below our minimum gas -- if any + const rebalToChain: any = Object.values(vChains).find( + (chain: any) => chain.balanceUnits < minGasUnits + ) + + if (rebalToChain) { + const rebalFromChain: any = Object.values(vChains).reduce( + (prev: any, current: any) => { + return prev.balanceUnits > current.balanceUnits ? prev : current + } + ) + + const rebalLabel = `%ts Rebal: ${rebalFromChain.id} > ${rebalToChain.id}` + + print(rebalLabel) + + // avoid repeating rebal actions. just loop until it lands on-chain. + if (lastAction === `rebal${rebalFromChain.id}>${rebalToChain.id}`) { + print( + `${rebalLabel} Last action was identical (${lastAction}). Not repeating. Re-evaluating momentarily...` + ) + + if (retryCount > 5) { + // abort after X attempts - if running in repeater mode this will effectively re-send the rebal tx if it is still needed + print(`${rebalLabel} Max retries. Exiting process...`) + await delay(1500) + process.exit() + } + + await delay(7500) + retryCount++ + continue + } + + retryCount=0 + + // leave rebalFrom chain with X units + const rebalAmount = rebalToUnits - rebalToChain.balanceUnits + + if (rebalFromChain.balanceUnits < rebalToUnits * 1.1) { + // if we hit this point, it indicates the wallet has no funds left to keep playing. hang process. + print( + `${rebalLabel} - Insuff Funds on From Chain ${rebalFromChain.balanceUnits}. Ending tests.` + ) + await delay(60_000) + return + } + + await sendBridge( + rebalFromChain, + rebalToChain, + Number(rebalAmount.toFixed(18)), + false, + rebalLabel + ) + + lastAction = `rebal${rebalFromChain.id}>${rebalToChain.id}` + + await delay(config.VOLLEY_MILLISECONDS_BETWEEN) + continue + } + + let fromChain: any + let toChain: any + + const totalPercentage: number = Object.values(config.TEST_ROUTES).reduce( + (acc: number, route: any) => acc + route.testDistributionPercentage, + 0 + ) + const randomizer: number = getRandomInt(1, totalPercentage) + let cumulative = 0 + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + for (const [route, details] of Object.entries(config.TEST_ROUTES) as [ + string, + any + ][]) { + cumulative += details.testDistributionPercentage + if (randomizer <= cumulative) { + fromChain = vChains[`${details.fromChainId}`] + toChain = vChains[`${details.toChainId}`] + break + } + } + + const countToSend = getRandomInt( + config.VOLLEY_MIN_COUNT, + config.VOLLEY_MAX_COUNT + ) + const printLabel = `%ts Batch${(sendCounter + countToSend) + .toString() + .padStart(5, '0')} of ${countToSend} : ${fromChain.id + .toString() + .padStart(7)} >> ${toChain.id.toString().padEnd(7)}` + + for (let i = 0; i < countToSend; i++) { + // sendCounter is applied as a tag on the amount just for sloppy tracking purposes. not actually important. + sendBridge( + fromChain, + toChain, + Number( + (testBridgeAmountUnits + sendCounter / 100000000000).toFixed(18) + ), + true, + printLabel + ) + sendCounter++ + await delay(50) + } + + lastAction = 'testVolley' + await delay(config.VOLLEY_MILLISECONDS_BETWEEN) + } +} + +async function getRequestParams( + fromChain: any, + toChain: any, + sendAmountUnits: number +) { + // 480 is not supported currently on the API - using Opti/Base as proxies. Can be improved later as needed. + if (toChain.id === 480) { + toChain = fromChain.id === 8453 ? vChains['10'] : vChains['8453'] + } + if (fromChain.id === 480) { + fromChain = toChain.id === 8453 ? vChains['10'] : vChains['8453'] + } + + const requestURL = `https://api.synapseprotocol.com/bridge?fromChain=${ + fromChain.id + }&toChain=${ + toChain.id + }&fromToken=${'0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'}&toToken=${'0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'}&amount=${sendAmountUnits}&destAddress=${ + walletAccount.address + }` + + let responseRFQ: any + let response: any + try { + response = await axios.request({ + url: requestURL, + }) + + if ((response.data?.length ?? 0) === 0) { + throw new Error(`No data returned from api`) + } + + responseRFQ = Array.isArray(response.data) + ? response.data.find( + (item: any) => item.bridgeModuleName === 'SynapseRFQ' + ) + : null + if (!responseRFQ) { + throw new Error(`No RFQ response returned from api`) + } + } catch (error: any) { + throw new Error( + `RFQ Api Fail: ${error.message.substr(0, 50)} -- ${requestURL}` + ) + } + + return responseRFQ +} + +async function looper_getRequestParams() { + for (;;) { + // in future iteration, this could be improved to dynamically pull a response for each route that is involved w/ testing. + // for now, all tests just use a cached route btwn two OP stacks as proxies for Worldchain tests -- because this is close enough. + cachedResponseRFQ = await getRequestParams( + vChains['8453'], + vChains['10'], + testBridgeAmountUnits + ) + + await delay(10_000) + } +} + +async function sendBridge( + fromChain: any, + toChain: any, + sendAmountUnits: number, + useCachedRequest: boolean, + printLabel: string +) { + const sendAmountRaw = parseUnits(sendAmountUnits.toString(), 18) + + printLabel = printLabel + ` ${sendAmountUnits} ETH` + + const _responseRFQ = useCachedRequest + ? cachedResponseRFQ + : await getRequestParams(fromChain, toChain, sendAmountUnits) + + const contractCall: any = { + address: fromChain.FastRouterAddr as `0x${string}`, + abi: ABI.fastRouterV2, + functionName: 'bridge', + account: walletAccount, + chain: fromChain, + args: [ + walletAccount.address, //recipient + toChain.id, // chainId + '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // token + sendAmountRaw, // amount + [ + //originQuery + '0x0000000000000000000000000000000000000000', //routerAdapter + _responseRFQ.originQuery.tokenOut, //tokenOut + sendAmountRaw, //minAmountOut + BigInt(_responseRFQ.originQuery.deadline.hex), //deadline + _responseRFQ.originQuery.rawParams, //rawParms + ], + [ + //destQuery + '0x0000000000000000000000000000000000000000', //routerAdapter + _responseRFQ.destQuery.tokenOut, //tokenOut + BigInt(_responseRFQ.destQuery.minAmountOut.hex), //minAmountOut + BigInt(_responseRFQ.destQuery.deadline.hex), //deadline + _responseRFQ.destQuery.rawParams, //rawParms + ], + ], + value: sendAmountRaw, + } + + let estGasUnits + + try { + //@ts-ignore + estGasUnits = await fromChain.vCliSim.estimateContractGas(contractCall) + } catch (error: any) { + throw new Error(`${printLabel} Bridge Sim error: ${error.message}`) + } + + if (estGasUnits <= 50000n) { + throw new Error(`${printLabel} estimated gas units too low. possible error`) + } + + contractCall.gas = Math.floor(Number(estGasUnits) * 1.3) + + let txHash + try { + txHash = await fromChain.vCliWrite.writeContract(contractCall) + } catch (error: any) { + throw new Error(`${printLabel} Send failed: ${error.message}`) + } + + print(`${printLabel} Submitted ${txHash}`) +} diff --git a/packages/rfq-loadtest/src/pyRepeater.py b/packages/rfq-loadtest/src/pyRepeater.py new file mode 100644 index 0000000000..1094c43cd0 --- /dev/null +++ b/packages/rfq-loadtest/src/pyRepeater.py @@ -0,0 +1,11 @@ +import time +import subprocess +import sys +from datetime import datetime + +callStatement = sys.argv[1] + +while 1==1: + subprocess.call(f"{callStatement}", shell=True) + print (f"{datetime.now()} - Restarting...") + time.sleep(1) \ No newline at end of file diff --git a/packages/rfq-loadtest/src/utils.ts b/packages/rfq-loadtest/src/utils.ts new file mode 100644 index 0000000000..0785c8dcdd --- /dev/null +++ b/packages/rfq-loadtest/src/utils.ts @@ -0,0 +1,34 @@ +export function delay(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)) +} + +export function tStamp(startTimeStamp = 0) { + const timeCur = new Date().toISOString().replace('T', ' ').replace('Z', '') + + const timeDiff = + startTimeStamp > 0 + ? ` +${(Date.now() - startTimeStamp).toString().padStart(5)}ms` + : '' + + return `${timeCur}${timeDiff} - ` +} + +export function print(...outputs: any[]) { + outputs = outputs.map((output: any) => { + if (typeof output == 'string') { + // Replace %ts with formatted timestamp + output = output.replaceAll('%ts', tStamp()) + } + return output + }) + + console.log(...outputs) +} + +export function getRandomInt(min: number, max: number) { + if (min > max) { + // fix mistake inputs + ;[min, max] = [max, min] + } + return Math.floor(Math.random() * (max - min + 1)) + min +} diff --git a/packages/rfq-loadtest/tsconfig.json b/packages/rfq-loadtest/tsconfig.json new file mode 100644 index 0000000000..bf8c0320ea --- /dev/null +++ b/packages/rfq-loadtest/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "esnext", + "moduleResolution": "node", + "sourceMap": true, + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src"], + "exclude": ["node_modules", "dist"] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 61c7578a54..bbf0529519 100644 --- a/yarn.lock +++ b/yarn.lock @@ -55,7 +55,7 @@ resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz#63430d04bd8c5e74f8d7d049338f1cd9d4f02069" integrity sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw== -"@adraffy/ens-normalize@^1.8.8": +"@adraffy/ens-normalize@1.11.0", "@adraffy/ens-normalize@^1.8.8": version "1.11.0" resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.11.0.tgz#42cc67c5baa407ac25059fcd7d405cc5ecdb0c33" integrity sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg== @@ -6007,7 +6007,7 @@ dependencies: "@noble/hashes" "1.4.0" -"@noble/curves@^1.4.0": +"@noble/curves@1.6.0", "@noble/curves@^1.4.0", "@noble/curves@~1.6.0": version "1.6.0" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.6.0.tgz#be5296ebcd5a1730fccea4786d420f87abfeb40b" integrity sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ== @@ -7122,7 +7122,7 @@ resolved "https://registry.yarnpkg.com/@safe-global/safe-gateway-typescript-sdk/-/safe-gateway-typescript-sdk-3.22.2.tgz#d4ff9972e58f9344fc95f8d41b2ec6517baa8e79" integrity sha512-Y0yAxRaB98LFp2Dm+ACZqBSdAmI3FlpH/LjxOZ94g/ouuDJecSq0iR26XZ5QDuEL8Rf+L4jBJaoDC08CD0KkJw== -"@scure/base@^1.1.3", "@scure/base@~1.1.0", "@scure/base@~1.1.2", "@scure/base@~1.1.6", "@scure/base@~1.1.8": +"@scure/base@^1.1.3", "@scure/base@~1.1.0", "@scure/base@~1.1.2", "@scure/base@~1.1.6", "@scure/base@~1.1.7", "@scure/base@~1.1.8": version "1.1.9" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg== @@ -7154,6 +7154,15 @@ "@noble/hashes" "~1.4.0" "@scure/base" "~1.1.6" +"@scure/bip32@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.5.0.tgz#dd4a2e1b8a9da60e012e776d954c4186db6328e6" + integrity sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw== + dependencies: + "@noble/curves" "~1.6.0" + "@noble/hashes" "~1.5.0" + "@scure/base" "~1.1.7" + "@scure/bip39@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" @@ -9324,7 +9333,7 @@ jest-diff "^25.2.1" pretty-format "^25.2.1" -"@types/js-yaml@^4.0.0": +"@types/js-yaml@^4.0.0", "@types/js-yaml@^4.0.9": version "4.0.9" resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2" integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg== @@ -9469,6 +9478,13 @@ dependencies: undici-types "~6.19.2" +"@types/node@^22.7.5": + version "22.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" + integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== + dependencies: + undici-types "~6.19.2" + "@types/normalize-package-data@^2.4.0": version "2.4.4" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" @@ -9859,7 +9875,7 @@ dependencies: "@types/yargs-parser" "*" -"@types/yargs@^17.0.8": +"@types/yargs@^17.0.33", "@types/yargs@^17.0.8": version "17.0.33" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d" integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA== @@ -11090,6 +11106,11 @@ abitype@1.0.5: resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.5.tgz#29d0daa3eea867ca90f7e4123144c1d1270774b6" integrity sha512-YzDhti7cjlfaBhHutMaboYB21Ha3rXR9QTkNJFzYC4kC8YclaiwPBBBJY8ejFdu2wnJeZCVZSMlQJ7fi8S6hsw== +abitype@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.6.tgz#76410903e1d88e34f1362746e2d407513c38565b" + integrity sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A== + abitype@^0.10.2: version "0.10.3" resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.10.3.tgz#27ce7a7cdb9a80ccd732a3f3cf1ce6ff05266fce" @@ -21583,6 +21604,11 @@ isows@1.0.4: resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.4.tgz#810cd0d90cc4995c26395d2aa4cfa4037ebdf061" integrity sha512-hEzjY+x9u9hPmBom9IIAqdJCwNLax+xrPb51vEPpERoFlIxgmZcHzsT5jKG06nvInKOBGvReAVz80Umed5CczQ== +isows@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.6.tgz#0da29d706fa51551c663c627ace42769850f86e7" + integrity sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw== + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -33985,6 +34011,11 @@ typescript@^5.0.4, typescript@^5.2.2, typescript@^5.3.2, typescript@^5.3.3, type resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.2.tgz#d1de67b6bef77c41823f822df8f0b3bcff60a5a0" integrity sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw== +typescript@^5.6.3: + version "5.6.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.3.tgz#5f3449e31c9d94febb17de03cc081dd56d81db5b" + integrity sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw== + typescript@~5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" @@ -35024,6 +35055,21 @@ viem@^2.1.1, viem@^2.13.6, viem@^2.21.6: webauthn-p256 "0.0.5" ws "8.17.1" +viem@^2.21.19: + version "2.21.25" + resolved "https://registry.yarnpkg.com/viem/-/viem-2.21.25.tgz#5e4a7c6a8543396f67ef221ea5d2226321f000b8" + integrity sha512-fQbFLVW5RjC1MwjelmzzDygmc2qMfY17NruAIIdYeiB8diQfhqsczU5zdGw/jTbmNXbKoYnSdgqMb8MFZcbZ1w== + dependencies: + "@adraffy/ens-normalize" "1.11.0" + "@noble/curves" "1.6.0" + "@noble/hashes" "1.5.0" + "@scure/bip32" "1.5.0" + "@scure/bip39" "1.4.0" + abitype "1.0.6" + isows "1.0.6" + webauthn-p256 "0.0.10" + ws "8.18.0" + vite-node@^1.0.2: version "1.6.0" resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-1.6.0.tgz#2c7e61129bfecc759478fa592754fd9704aaba7f" @@ -35891,6 +35937,14 @@ web3@1.7.4: web3-shh "1.7.4" web3-utils "1.7.4" +webauthn-p256@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/webauthn-p256/-/webauthn-p256-0.0.10.tgz#877e75abe8348d3e14485932968edf3325fd2fdd" + integrity sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA== + dependencies: + "@noble/curves" "^1.4.0" + "@noble/hashes" "^1.4.0" + webauthn-p256@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/webauthn-p256/-/webauthn-p256-0.0.5.tgz#0baebd2ba8a414b21cc09c0d40f9dd0be96a06bd" @@ -36544,6 +36598,11 @@ ws@8.17.1, ws@~8.17.1: resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b" integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ== +ws@8.18.0, ws@^8.12.0, ws@^8.13.0, ws@^8.17.1, ws@^8.2.3: + version "8.18.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + ws@^3.0.0: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" @@ -36558,11 +36617,6 @@ ws@^7.0.0, ws@^7.3.1, ws@^7.4.6, ws@^7.5.1: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== -ws@^8.12.0, ws@^8.13.0, ws@^8.17.1, ws@^8.2.3: - version "8.18.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc" - integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== - x-default-browser@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/x-default-browser/-/x-default-browser-0.4.0.tgz#70cf0da85da7c0ab5cb0f15a897f2322a6bdd481" From ed60f1793860842542806a6a260a13f8d4712fd9 Mon Sep 17 00:00:00 2001 From: parodime Date: Tue, 15 Oct 2024 16:34:14 +0000 Subject: [PATCH 09/15] Publish - @synapsecns/bridge-docs@0.4.4 - @synapsecns/rfq-loadtest@1.0.1 --- docs/bridge/CHANGELOG.md | 8 ++++++++ docs/bridge/package.json | 2 +- packages/rfq-loadtest/CHANGELOG.md | 8 ++++++++ packages/rfq-loadtest/package.json | 2 +- 4 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 packages/rfq-loadtest/CHANGELOG.md diff --git a/docs/bridge/CHANGELOG.md b/docs/bridge/CHANGELOG.md index 6aae6f9de8..c692d12f9d 100644 --- a/docs/bridge/CHANGELOG.md +++ b/docs/bridge/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.4.4](https://github.com/synapsecns/sanguine/compare/@synapsecns/bridge-docs@0.4.3...@synapsecns/bridge-docs@0.4.4) (2024-10-15) + +**Note:** Version bump only for package @synapsecns/bridge-docs + + + + + ## [0.4.3](https://github.com/synapsecns/sanguine/compare/@synapsecns/bridge-docs@0.4.2...@synapsecns/bridge-docs@0.4.3) (2024-10-15) **Note:** Version bump only for package @synapsecns/bridge-docs diff --git a/docs/bridge/package.json b/docs/bridge/package.json index f3bb4e55a7..7b01af0b92 100644 --- a/docs/bridge/package.json +++ b/docs/bridge/package.json @@ -1,6 +1,6 @@ { "name": "@synapsecns/bridge-docs", - "version": "0.4.3", + "version": "0.4.4", "private": true, "scripts": { "docusaurus": "docusaurus", diff --git a/packages/rfq-loadtest/CHANGELOG.md b/packages/rfq-loadtest/CHANGELOG.md new file mode 100644 index 0000000000..23b23875d4 --- /dev/null +++ b/packages/rfq-loadtest/CHANGELOG.md @@ -0,0 +1,8 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## 1.0.1 (2024-10-15) + +**Note:** Version bump only for package @synapsecns/rfq-loadtest diff --git a/packages/rfq-loadtest/package.json b/packages/rfq-loadtest/package.json index c5640dc64c..763a876e7a 100644 --- a/packages/rfq-loadtest/package.json +++ b/packages/rfq-loadtest/package.json @@ -1,6 +1,6 @@ { "name": "@synapsecns/rfq-loadtest", - "version": "1.0.0", + "version": "1.0.1", "main": "index.js", "type": "module", "scripts": { From 31a3ce9f1a90d47425dae6ef969b28de3895a6aa Mon Sep 17 00:00:00 2001 From: abtestingalpha <104046418+abtestingalpha@users.noreply.github.com> Date: Tue, 15 Oct 2024 13:48:22 -0400 Subject: [PATCH 10/15] feat(rest-api): Primary RPCs get omnirpc (#3294) * Primary RPCs get omnirpc --- packages/rest-api/.env.example | 1 + packages/rest-api/package.json | 1 + packages/rest-api/src/constants/chains.ts | 89 +-- .../rest-api/src/services/synapseService.ts | 3 +- packages/rest-api/src/utils/getOmniRpcUrl.ts | 10 + yarn.lock | 643 +++++++++++++++++- 6 files changed, 689 insertions(+), 58 deletions(-) create mode 100644 packages/rest-api/.env.example create mode 100644 packages/rest-api/src/utils/getOmniRpcUrl.ts diff --git a/packages/rest-api/.env.example b/packages/rest-api/.env.example new file mode 100644 index 0000000000..8bb7766569 --- /dev/null +++ b/packages/rest-api/.env.example @@ -0,0 +1 @@ +OMNIRPC_BASE_URL= \ No newline at end of file diff --git a/packages/rest-api/package.json b/packages/rest-api/package.json index 38b029d3d3..cc3dc43fa6 100644 --- a/packages/rest-api/package.json +++ b/packages/rest-api/package.json @@ -24,6 +24,7 @@ "@ethersproject/units": "5.7.0", "@synapsecns/sdk-router": "^0.11.4", "bignumber": "^1.1.0", + "dotenv": "^16.4.5", "ethers": "5.7.2", "express": "^4.18.2", "express-validator": "^7.2.0", diff --git a/packages/rest-api/src/constants/chains.ts b/packages/rest-api/src/constants/chains.ts index dcc4c2502b..521698e789 100644 --- a/packages/rest-api/src/constants/chains.ts +++ b/packages/rest-api/src/constants/chains.ts @@ -1,13 +1,14 @@ import _ from 'lodash' import { Chain } from '../types' +import { getOmniRpcUrl } from '../utils/getOmniRpcUrl' export const ETHEREUM: Chain = { id: 1, name: 'Ethereum', rpcUrls: { - primary: 'https://ethereum.blockpi.network/v1/rpc/public', - fallback: 'https://rpc.ankr.com/eth', + primary: getOmniRpcUrl(1), + fallback: 'https://ethereum.blockpi.network/v1/rpc/public', }, explorerUrl: 'https://etherscan.com', explorerName: 'Etherscan', @@ -27,8 +28,8 @@ export const ARBITRUM: Chain = { id: 42161, name: 'Arbitrum', rpcUrls: { - primary: 'https://arbitrum.blockpi.network/v1/rpc/public', - fallback: 'https://arb1.arbitrum.io/rpc', + primary: getOmniRpcUrl(42161), + fallback: 'https://arbitrum.blockpi.network/v1/rpc/public', }, explorerUrl: 'https://arbiscan.io', explorerName: 'Arbiscan', @@ -48,8 +49,8 @@ export const BNBCHAIN: Chain = { id: 56, name: 'BNB Chain', rpcUrls: { - primary: 'https://bsc-dataseed1.ninicoin.io/', - fallback: 'https://bsc-dataseed2.ninicoin.io', + primary: getOmniRpcUrl(56), + fallback: 'https://bsc-dataseed1.ninicoin.io/', }, explorerUrl: 'https://bscscan.com', explorerName: 'BscScan', @@ -69,8 +70,8 @@ export const AVALANCHE: Chain = { id: 43114, name: 'Avalanche', rpcUrls: { - primary: 'https://api.avax.network/ext/bc/C/rpc', - fallback: 'https://1rpc.io/avax/c', + primary: getOmniRpcUrl(43114), + fallback: 'https://api.avax.network/ext/bc/C/rpc', }, explorerUrl: 'https://snowtrace.io/', explorerName: 'Snowtrace', @@ -90,8 +91,8 @@ export const CANTO: Chain = { id: 7700, name: 'Canto', rpcUrls: { - primary: 'https://mainnode.plexnode.org:8545', - fallback: 'https://canto.slingshot.finance', + primary: getOmniRpcUrl(7700), + fallback: 'https://mainnode.plexnode.org:8545', }, explorerUrl: 'https://tuber.build/', explorerName: 'Canto Explorer', @@ -111,8 +112,8 @@ export const OPTIMISM: Chain = { id: 10, name: 'Optimism', rpcUrls: { - primary: 'https://mainnet.optimism.io', - fallback: 'https://1rpc.io/op', + primary: getOmniRpcUrl(10), + fallback: 'https://mainnet.optimism.io', }, explorerUrl: 'https://optimistic.etherscan.io', explorerName: 'Optimism Explorer', @@ -132,8 +133,8 @@ export const POLYGON: Chain = { id: 137, name: 'Polygon', rpcUrls: { - primary: 'https://polygon-bor.publicnode.com', - fallback: 'https://polygon.llamarpc.com', + primary: getOmniRpcUrl(137), + fallback: 'https://polygon-bor.publicnode.com', }, explorerUrl: 'https://polygonscan.com', explorerName: 'PolygonScan', @@ -153,8 +154,8 @@ export const DFK: Chain = { id: 53935, name: 'DFK Chain', rpcUrls: { - primary: 'https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc', - fallback: 'https://dfkchain.api.onfinality.io/public', + primary: getOmniRpcUrl(53935), + fallback: 'https://subnets.avax.network/defi-kingdoms/dfk-chain/rpc', }, explorerUrl: 'https://subnets.avax.network/defi-kingdoms', explorerName: 'DFK Subnet Explorer', @@ -174,8 +175,8 @@ export const KLAYTN: Chain = { id: 8217, name: 'Klaytn', rpcUrls: { - primary: 'https://klaytn.blockpi.network/v1/rpc/public', - fallback: 'https://klaytn.api.onfinality.io/public', + primary: getOmniRpcUrl(8217), + fallback: 'https://klaytn.blockpi.network/v1/rpc/public', }, explorerUrl: 'https://scope.klaytn.com', explorerName: 'Klaytn Explorer', @@ -195,8 +196,8 @@ export const FANTOM: Chain = { id: 250, name: 'Fantom', rpcUrls: { - primary: 'https://rpc.ftm.tools', - fallback: 'https://fantom-rpc.gateway.pokt.network/', + primary: getOmniRpcUrl(250), + fallback: 'https://rpc.ftm.tools', }, explorerUrl: 'https://ftmscan.com', explorerName: 'FTMScan', @@ -216,8 +217,8 @@ export const CRONOS: Chain = { id: 25, name: 'Cronos', rpcUrls: { - primary: 'https://evm-cronos.crypto.org', - fallback: 'https://cronos.blockpi.network/v1/rpc/public', + primary: getOmniRpcUrl(25), + fallback: 'https://evm-cronos.crypto.org', }, explorerUrl: 'https://cronoscan.com', explorerName: 'CronoScan', @@ -237,8 +238,8 @@ export const BOBA: Chain = { id: 288, name: 'Boba Chain', rpcUrls: { - primary: 'https://mainnet.boba.network', - fallback: 'https://replica.boba.network', + primary: getOmniRpcUrl(288), + fallback: 'https://mainnet.boba.network', }, explorerUrl: 'https://bobascan.com', explorerName: 'Boba Explorer', @@ -258,8 +259,8 @@ export const METIS: Chain = { id: 1088, name: 'Metis', rpcUrls: { - primary: 'https://andromeda.metis.io/?owner=1088', - fallback: 'https://metis-mainnet.public.blastapi.io', + primary: getOmniRpcUrl(1088), + fallback: 'https://andromeda.metis.io/?owner=1088', }, explorerUrl: 'https://andromeda-explorer.metis.io', explorerName: 'Metis Explorer', @@ -279,8 +280,8 @@ export const AURORA: Chain = { id: 1313161554, name: 'Aurora', rpcUrls: { - primary: 'https://mainnet.aurora.dev', - fallback: 'https://1rpc.io/aurora', + primary: getOmniRpcUrl(1313161554), + fallback: 'https://mainnet.aurora.dev', }, explorerUrl: 'https://explorer.mainnet.aurora.dev', explorerName: 'Aurora Explorer', @@ -300,8 +301,8 @@ export const HARMONY: Chain = { id: 1666600000, name: 'Harmony', rpcUrls: { - primary: 'https://api.harmony.one', - fallback: 'https://api.s0.t.hmny.io', + primary: getOmniRpcUrl(1666600000), + fallback: 'https://api.harmony.one', }, explorerUrl: 'https://explorer.harmony.one', explorerName: 'Harmony Explorer', @@ -321,8 +322,8 @@ export const MOONBEAM: Chain = { id: 1284, name: 'Moonbeam', rpcUrls: { - primary: 'https://rpc.api.moonbeam.network', - fallback: 'https://moonbeam.public.blastapi.io', + primary: getOmniRpcUrl(1284), + fallback: 'https://rpc.api.moonbeam.network', }, explorerUrl: 'https://moonbeam.moonscan.io', explorerName: 'Moonbeam Explorer', @@ -342,8 +343,8 @@ export const MOONRIVER: Chain = { id: 1285, name: 'Moonriver', rpcUrls: { - primary: 'https://rpc.api.moonriver.moonbeam.network', - fallback: 'https://moonriver.public.blastapi.io', + primary: getOmniRpcUrl(1285), + fallback: 'https://rpc.api.moonriver.moonbeam.network', }, explorerUrl: 'https://moonriver.moonscan.io', explorerName: 'Moonriver Explorer', @@ -363,8 +364,8 @@ export const DOGE: Chain = { id: 2000, name: 'Dogechain', rpcUrls: { - primary: 'https://rpc.dogechain.dog', - fallback: 'https://rpc01-sg.dogechain.dog', + primary: getOmniRpcUrl(2000), + fallback: 'https://rpc.dogechain.dog', }, explorerUrl: 'https://explorer.dogechain.dog', explorerName: 'Dogechain Explorer', @@ -384,8 +385,8 @@ export const BASE: Chain = { id: 8453, name: 'Base', rpcUrls: { - primary: 'https://base.blockpi.network/v1/rpc/public', - fallback: 'https://developer-access-mainnet.base.org', + primary: getOmniRpcUrl(8453), + fallback: 'https://base.blockpi.network/v1/rpc/public', }, explorerUrl: 'https://basescan.org', explorerName: 'BaseScan', @@ -405,9 +406,9 @@ export const BLAST: Chain = { id: 81457, name: 'Blast', rpcUrls: { - primary: + primary: getOmniRpcUrl(81457), + fallback: 'https://lingering-indulgent-replica.blast-mainnet.quiknode.pro/6667a8f4be701cb6549b415d567bc706fb2f13a8/', - fallback: 'https://blast.blockpi.network/v1/rpc/publicChain', }, explorerUrl: 'https://blastscan.io', explorerName: 'Blastscan', @@ -427,8 +428,8 @@ export const SCROLL: Chain = { id: 534352, name: 'Scroll', rpcUrls: { - primary: 'https://rpc.scroll.io/', - fallback: 'https://scroll.blockpi.network/v1/rpc/public', + primary: getOmniRpcUrl(534352), + fallback: 'https://rpc.scroll.io/', }, explorerUrl: 'https://scrollscan.com', explorerName: 'Scrollscan', @@ -448,8 +449,8 @@ export const LINEA: Chain = { id: 59144, name: 'Linea', rpcUrls: { - primary: 'https://rpc.linea.build', - fallback: 'https://linea.blockpi.network/v1/rpc/public', + primary: getOmniRpcUrl(59144), + fallback: 'https://rpc.linea.build', }, explorerUrl: 'https://lineascan.build', explorerName: 'LineaScan', diff --git a/packages/rest-api/src/services/synapseService.ts b/packages/rest-api/src/services/synapseService.ts index a76b9b729c..c9306a0c82 100644 --- a/packages/rest-api/src/services/synapseService.ts +++ b/packages/rest-api/src/services/synapseService.ts @@ -4,7 +4,8 @@ import { SynapseSDK } from '@synapsecns/sdk-router' import { CHAINS_ARRAY } from '../constants/chains' const providers = CHAINS_ARRAY.map( - (chain) => new JsonRpcProvider(chain.rpcUrls.primary) + (chain) => + new JsonRpcProvider(chain.rpcUrls.primary || chain.rpcUrls.fallback) ) const chainIds = CHAINS_ARRAY.map((chain) => chain.id) diff --git a/packages/rest-api/src/utils/getOmniRpcUrl.ts b/packages/rest-api/src/utils/getOmniRpcUrl.ts new file mode 100644 index 0000000000..c635d86c1a --- /dev/null +++ b/packages/rest-api/src/utils/getOmniRpcUrl.ts @@ -0,0 +1,10 @@ +import * as dotenv from 'dotenv' + +dotenv.config() + +export const getOmniRpcUrl = (chainId: number) => { + if (!process.env.OMNIRPC_BASE_URL) { + return null + } + return `${process.env.OMNIRPC_BASE_URL}/${chainId}` +} diff --git a/yarn.lock b/yarn.lock index bbf0529519..a02e4af4de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1556,7 +1556,7 @@ "@babel/parser" "^7.25.7" "@babel/types" "^7.25.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.11.5", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.22.8", "@babel/traverse@^7.23.2", "@babel/traverse@^7.25.7", "@babel/traverse@^7.7.0": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.11.5", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.22.8", "@babel/traverse@^7.23.2", "@babel/traverse@^7.25.7", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8" integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg== @@ -4229,6 +4229,18 @@ jest-util "^25.5.0" slash "^3.0.0" +"@jest/console@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" + integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + slash "^3.0.0" + "@jest/console@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" @@ -4275,6 +4287,41 @@ slash "^3.0.0" strip-ansi "^6.0.0" +"@jest/core@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" + integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== + dependencies: + "@jest/console" "^28.1.3" + "@jest/reporters" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^28.1.3" + jest-config "^28.1.3" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-resolve-dependencies "^28.1.3" + jest-runner "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + jest-watcher "^28.1.3" + micromatch "^4.0.4" + pretty-format "^28.1.3" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + "@jest/core@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" @@ -4318,6 +4365,16 @@ "@jest/types" "^25.5.0" jest-mock "^25.5.0" +"@jest/environment@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" + integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== + dependencies: + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-mock "^28.1.3" + "@jest/environment@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" @@ -4328,6 +4385,13 @@ "@types/node" "*" jest-mock "^29.7.0" +"@jest/expect-utils@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" + integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== + dependencies: + jest-get-type "^28.0.2" + "@jest/expect-utils@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" @@ -4335,6 +4399,14 @@ dependencies: jest-get-type "^29.6.3" +"@jest/expect@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" + integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== + dependencies: + expect "^28.1.3" + jest-snapshot "^28.1.3" + "@jest/expect@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" @@ -4354,6 +4426,18 @@ jest-util "^25.5.0" lolex "^5.0.0" +"@jest/fake-timers@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" + integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== + dependencies: + "@jest/types" "^28.1.3" + "@sinonjs/fake-timers" "^9.1.2" + "@types/node" "*" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-util "^28.1.3" + "@jest/fake-timers@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" @@ -4375,6 +4459,15 @@ "@jest/types" "^25.5.0" expect "^25.5.0" +"@jest/globals@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" + integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/types" "^28.1.3" + "@jest/globals@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" @@ -4417,6 +4510,37 @@ optionalDependencies: node-notifier "^6.0.0" +"@jest/reporters@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" + integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + jest-worker "^28.1.3" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + terminal-link "^2.0.0" + v8-to-istanbul "^9.0.1" + "@jest/reporters@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" @@ -4447,6 +4571,13 @@ strip-ansi "^6.0.0" v8-to-istanbul "^9.0.1" +"@jest/schemas@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" + integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== + dependencies: + "@sinclair/typebox" "^0.24.1" + "@jest/schemas@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" @@ -4463,6 +4594,15 @@ graceful-fs "^4.2.4" source-map "^0.6.0" +"@jest/source-map@^28.1.2": + version "28.1.2" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" + integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== + dependencies: + "@jridgewell/trace-mapping" "^0.3.13" + callsites "^3.0.0" + graceful-fs "^4.2.9" + "@jest/source-map@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" @@ -4482,6 +4622,16 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" +"@jest/test-result@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" + integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== + dependencies: + "@jest/console" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + "@jest/test-result@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" @@ -4503,6 +4653,16 @@ jest-runner "^25.5.4" jest-runtime "^25.5.4" +"@jest/test-sequencer@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" + integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== + dependencies: + "@jest/test-result" "^28.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + slash "^3.0.0" + "@jest/test-sequencer@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" @@ -4556,6 +4716,27 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" +"@jest/transform@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" + integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^28.1.3" + "@jridgewell/trace-mapping" "^0.3.13" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.1" + "@jest/transform@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" @@ -4618,6 +4799,18 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" +"@jest/types@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" + integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== + dependencies: + "@jest/schemas" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + "@jest/types@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" @@ -4670,7 +4863,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -7347,6 +7540,11 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== +"@sinclair/typebox@^0.24.1": + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== + "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" @@ -7388,6 +7586,13 @@ dependencies: "@sinonjs/commons" "^3.0.0" +"@sinonjs/fake-timers@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" + integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@slorber/remark-comment@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@slorber/remark-comment/-/remark-comment-1.0.0.tgz#2a020b3f4579c89dec0361673206c28d67e08f5a" @@ -8612,14 +8817,6 @@ "@swc/counter" "^0.1.3" tslib "^2.4.0" -"@synapsecns/coverage-aggregator@file:./packages/coverage-aggregator": - version "1.0.6" - dependencies: - glob "^8.0.3" - path "^0.12.7" - ts-jest "^29.0.5" - yargs "^17.6.2" - "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -9533,7 +9730,7 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ== -"@types/prettier@^2.1.1": +"@types/prettier@^2.1.1", "@types/prettier@^2.1.5": version "2.7.3" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== @@ -12091,6 +12288,19 @@ babel-jest@^25.2.6, babel-jest@^25.5.1: graceful-fs "^4.2.4" slash "^3.0.0" +babel-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" + integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== + dependencies: + "@jest/transform" "^28.1.3" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^28.1.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -12195,6 +12405,16 @@ babel-plugin-jest-hoist@^25.5.0: "@babel/types" "^7.3.3" "@types/babel__traverse" "^7.0.6" +babel-plugin-jest-hoist@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" + integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + babel-plugin-jest-hoist@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" @@ -12390,6 +12610,14 @@ babel-preset-jest@^25.5.0: babel-plugin-jest-hoist "^25.5.0" babel-preset-current-node-syntax "^0.1.2" +babel-preset-jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" + integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== + dependencies: + babel-plugin-jest-hoist "^28.1.3" + babel-preset-current-node-syntax "^1.0.0" + babel-preset-jest@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" @@ -15693,6 +15921,11 @@ diff-sequences@^25.2.6: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== +diff-sequences@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" + integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== + diff-sequences@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" @@ -16122,6 +16355,11 @@ elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4, elliptic@^6. minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" +emittery@^0.10.2: + version "0.10.2" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== + emittery@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" @@ -17922,6 +18160,17 @@ expect@^25.5.0: jest-message-util "^25.5.0" jest-regex-util "^25.2.6" +expect@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" + integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== + dependencies: + "@jest/expect-utils" "^28.1.3" + jest-get-type "^28.0.2" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + expect@^29.0.0, expect@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" @@ -21636,7 +21885,7 @@ istanbul-lib-instrument@^4.0.0: istanbul-lib-coverage "^3.0.0" semver "^6.3.0" -istanbul-lib-instrument@^5.0.4: +istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== @@ -21748,6 +21997,14 @@ jest-changed-files@^25.5.0: execa "^3.2.0" throat "^5.0.0" +jest-changed-files@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" + integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== + dependencies: + execa "^5.0.0" + p-limit "^3.1.0" + jest-changed-files@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" @@ -21757,6 +22014,31 @@ jest-changed-files@^29.7.0: jest-util "^29.7.0" p-limit "^3.1.0" +jest-circus@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" + integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/expect" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + is-generator-fn "^2.0.0" + jest-each "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-runtime "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + p-limit "^3.1.0" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-circus@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" @@ -21803,6 +22085,24 @@ jest-cli@^25.5.4: realpath-native "^2.0.0" yargs "^15.3.1" +jest-cli@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" + integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== + dependencies: + "@jest/core" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + prompts "^2.0.1" + yargs "^17.3.1" + jest-cli@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" @@ -21845,6 +22145,34 @@ jest-config@^25.5.4: pretty-format "^25.5.0" realpath-native "^2.0.0" +jest-config@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" + integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^28.1.3" + "@jest/types" "^28.1.3" + babel-jest "^28.1.3" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^28.1.3" + jest-environment-node "^28.1.3" + jest-get-type "^28.0.2" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-runner "^28.1.3" + jest-util "^28.1.3" + jest-validate "^28.1.3" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^28.1.3" + slash "^3.0.0" + strip-json-comments "^3.1.1" + jest-config@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" @@ -21893,6 +22221,16 @@ jest-diff@^25.2.1, jest-diff@^25.5.0: jest-get-type "^25.2.6" pretty-format "^25.5.0" +jest-diff@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" + integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== + dependencies: + chalk "^4.0.0" + diff-sequences "^28.1.1" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + jest-diff@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" @@ -21910,6 +22248,13 @@ jest-docblock@^25.3.0: dependencies: detect-newline "^3.0.0" +jest-docblock@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8" + integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== + dependencies: + detect-newline "^3.0.0" + jest-docblock@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" @@ -21928,6 +22273,17 @@ jest-each@^25.5.0: jest-util "^25.5.0" pretty-format "^25.5.0" +jest-each@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" + integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== + dependencies: + "@jest/types" "^28.1.3" + chalk "^4.0.0" + jest-get-type "^28.0.2" + jest-util "^28.1.3" + pretty-format "^28.1.3" + jest-each@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" @@ -21963,6 +22319,18 @@ jest-environment-node@^25.5.0: jest-util "^25.5.0" semver "^6.3.0" +jest-environment-node@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" + integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-mock "^28.1.3" + jest-util "^28.1.3" + jest-environment-node@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" @@ -21993,6 +22361,11 @@ jest-get-type@^25.2.6: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== +jest-get-type@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" + integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== + jest-get-type@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" @@ -22039,6 +22412,25 @@ jest-haste-map@^26.6.2: optionalDependencies: fsevents "^2.1.2" +jest-haste-map@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" + integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== + dependencies: + "@jest/types" "^28.1.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^28.0.2" + jest-util "^28.1.3" + jest-worker "^28.1.3" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + jest-haste-map@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" @@ -22089,6 +22481,14 @@ jest-leak-detector@^25.5.0: jest-get-type "^25.2.6" pretty-format "^25.5.0" +jest-leak-detector@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" + integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== + dependencies: + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + jest-leak-detector@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" @@ -22107,6 +22507,16 @@ jest-matcher-utils@^25.5.0: jest-get-type "^25.2.6" pretty-format "^25.5.0" +jest-matcher-utils@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" + integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== + dependencies: + chalk "^4.0.0" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + jest-matcher-utils@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" @@ -22131,6 +22541,21 @@ jest-message-util@^25.5.0: slash "^3.0.0" stack-utils "^1.0.1" +jest-message-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" + integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^28.1.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-message-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" @@ -22168,6 +22593,14 @@ jest-mock@^27.0.6: "@jest/types" "^27.5.1" "@types/node" "*" +jest-mock@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" + integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + jest-mock@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" @@ -22192,6 +22625,11 @@ jest-regex-util@^26.0.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== +jest-regex-util@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" + integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== + jest-regex-util@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" @@ -22206,6 +22644,14 @@ jest-resolve-dependencies@^25.5.4: jest-regex-util "^25.2.6" jest-snapshot "^25.5.1" +jest-resolve-dependencies@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" + integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== + dependencies: + jest-regex-util "^28.0.2" + jest-snapshot "^28.1.3" + jest-resolve-dependencies@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" @@ -22229,6 +22675,21 @@ jest-resolve@^25.5.1: resolve "^1.17.0" slash "^3.0.0" +jest-resolve@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" + integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-pnp-resolver "^1.2.2" + jest-util "^28.1.3" + jest-validate "^28.1.3" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + jest-resolve@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" @@ -22269,6 +22730,33 @@ jest-runner@^25.5.4: source-map-support "^0.5.6" throat "^5.0.0" +jest-runner@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" + integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== + dependencies: + "@jest/console" "^28.1.3" + "@jest/environment" "^28.1.3" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.10.2" + graceful-fs "^4.2.9" + jest-docblock "^28.1.1" + jest-environment-node "^28.1.3" + jest-haste-map "^28.1.3" + jest-leak-detector "^28.1.3" + jest-message-util "^28.1.3" + jest-resolve "^28.1.3" + jest-runtime "^28.1.3" + jest-util "^28.1.3" + jest-watcher "^28.1.3" + jest-worker "^28.1.3" + p-limit "^3.1.0" + source-map-support "0.5.13" + jest-runner@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" @@ -22328,6 +22816,34 @@ jest-runtime@^25.5.4: strip-bom "^4.0.0" yargs "^15.3.1" +jest-runtime@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" + integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== + dependencies: + "@jest/environment" "^28.1.3" + "@jest/fake-timers" "^28.1.3" + "@jest/globals" "^28.1.3" + "@jest/source-map" "^28.1.2" + "@jest/test-result" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^28.1.3" + jest-message-util "^28.1.3" + jest-mock "^28.1.3" + jest-regex-util "^28.0.2" + jest-resolve "^28.1.3" + jest-snapshot "^28.1.3" + jest-util "^28.1.3" + slash "^3.0.0" + strip-bom "^4.0.0" + jest-runtime@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" @@ -22392,6 +22908,35 @@ jest-snapshot@^25.5.1: pretty-format "^25.5.0" semver "^6.3.0" +jest-snapshot@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" + integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^28.1.3" + "@jest/transform" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/babel__traverse" "^7.0.6" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^28.1.3" + graceful-fs "^4.2.9" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + jest-haste-map "^28.1.3" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + natural-compare "^1.4.0" + pretty-format "^28.1.3" + semver "^7.3.5" + jest-snapshot@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" @@ -22441,6 +22986,18 @@ jest-util@^26.6.2: is-ci "^2.0.0" micromatch "^4.0.2" +jest-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" + integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-util@^29.0.0, jest-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" @@ -22465,6 +23022,18 @@ jest-validate@^25.5.0: leven "^3.1.0" pretty-format "^25.5.0" +jest-validate@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" + integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== + dependencies: + "@jest/types" "^28.1.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^28.0.2" + leven "^3.1.0" + pretty-format "^28.1.3" + jest-validate@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" @@ -22502,6 +23071,20 @@ jest-watcher@^25.2.4, jest-watcher@^25.5.0: jest-util "^25.5.0" string-length "^3.1.0" +jest-watcher@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" + integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== + dependencies: + "@jest/test-result" "^28.1.3" + "@jest/types" "^28.1.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.10.2" + jest-util "^28.1.3" + string-length "^4.0.1" + jest-watcher@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" @@ -22550,6 +23133,15 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" +jest-worker@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jest-worker@^29.4.3, jest-worker@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" @@ -22569,6 +23161,16 @@ jest@^25.3.0: import-local "^3.0.2" jest-cli "^25.5.4" +jest@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.3.tgz#e9c6a7eecdebe3548ca2b18894a50f45b36dfc6b" + integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA== + dependencies: + "@jest/core" "^28.1.3" + "@jest/types" "^28.1.3" + import-local "^3.0.2" + jest-cli "^28.1.3" + jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" @@ -28602,6 +29204,16 @@ pretty-format@^27.0.2: ansi-styles "^5.0.0" react-is "^17.0.1" +pretty-format@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" + integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== + dependencies: + "@jest/schemas" "^28.1.3" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + pretty-format@^29.0.0, pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" @@ -30376,6 +30988,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== +resolve.exports@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" + integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== + resolve.exports@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" @@ -36535,7 +37152,7 @@ write-file-atomic@^3.0.0, write-file-atomic@^3.0.3: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -write-file-atomic@^4.0.2: +write-file-atomic@^4.0.1, write-file-atomic@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== From 47ceb855c1fb44136bcba4a496a68247386a3895 Mon Sep 17 00:00:00 2001 From: abtestingalpha Date: Tue, 15 Oct 2024 17:52:38 +0000 Subject: [PATCH 11/15] Publish - @synapsecns/rest-api@1.5.0 --- packages/rest-api/CHANGELOG.md | 11 +++++++++++ packages/rest-api/package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/rest-api/CHANGELOG.md b/packages/rest-api/CHANGELOG.md index 6c309e2a1b..4ecd8ebcae 100644 --- a/packages/rest-api/CHANGELOG.md +++ b/packages/rest-api/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +# [1.5.0](https://github.com/synapsecns/sanguine/compare/@synapsecns/rest-api@1.4.9...@synapsecns/rest-api@1.5.0) (2024-10-15) + + +### Features + +* **rest-api:** Primary RPCs get omnirpc ([#3294](https://github.com/synapsecns/sanguine/issues/3294)) ([31a3ce9](https://github.com/synapsecns/sanguine/commit/31a3ce9f1a90d47425dae6ef969b28de3895a6aa)) + + + + + ## [1.4.9](https://github.com/synapsecns/sanguine/compare/@synapsecns/rest-api@1.4.8...@synapsecns/rest-api@1.4.9) (2024-10-11) **Note:** Version bump only for package @synapsecns/rest-api diff --git a/packages/rest-api/package.json b/packages/rest-api/package.json index cc3dc43fa6..8b4a6a13ec 100644 --- a/packages/rest-api/package.json +++ b/packages/rest-api/package.json @@ -1,6 +1,6 @@ { "name": "@synapsecns/rest-api", - "version": "1.4.9", + "version": "1.5.0", "private": "true", "engines": { "node": ">=18.17.0" From fd75dbbbb6fec8ad2c35d5a16efb3a6a4812231a Mon Sep 17 00:00:00 2001 From: bigboydiamonds <57741810+bigboydiamonds@users.noreply.github.com> Date: Tue, 15 Oct 2024 14:26:34 -0700 Subject: [PATCH 12/15] fix(synapse-interface): translation period (#3297) * fix period --- .../components/Activity/Activity.tsx | 2 +- .../layouts/StandardPageContainer.tsx | 2 +- yarn.lock | 643 +----------------- 3 files changed, 15 insertions(+), 632 deletions(-) diff --git a/packages/synapse-interface/components/Activity/Activity.tsx b/packages/synapse-interface/components/Activity/Activity.tsx index 5fe5012493..96a262e1d9 100644 --- a/packages/synapse-interface/components/Activity/Activity.tsx +++ b/packages/synapse-interface/components/Activity/Activity.tsx @@ -71,7 +71,7 @@ export const Activity = ({ visibility }: { visibility: boolean }) => { {viewingAddress && !isLoading && !hasHistoricalTransactions && (
- {t('No transactions in last 30 days.')} + {t('No transactions in last 30 days')}
)} diff --git a/packages/synapse-interface/components/layouts/StandardPageContainer.tsx b/packages/synapse-interface/components/layouts/StandardPageContainer.tsx index 8c408194f5..e1c5f16868 100644 --- a/packages/synapse-interface/components/layouts/StandardPageContainer.tsx +++ b/packages/synapse-interface/components/layouts/StandardPageContainer.tsx @@ -31,7 +31,7 @@ const StandardPageContainer = ({ if (unsupported) { unsupportedToaster = toast.error( - t('Connected to an unsupported network; Please switch networks.'), + t('Connected to an unsupported network; Please switch networks'), { id: 'unsupported-popup', duration: 5000 } ) } else { diff --git a/yarn.lock b/yarn.lock index a02e4af4de..bbf0529519 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1556,7 +1556,7 @@ "@babel/parser" "^7.25.7" "@babel/types" "^7.25.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.11.5", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.22.8", "@babel/traverse@^7.23.2", "@babel/traverse@^7.25.7", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.11.5", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.22.8", "@babel/traverse@^7.23.2", "@babel/traverse@^7.25.7", "@babel/traverse@^7.7.0": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8" integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg== @@ -4229,18 +4229,6 @@ jest-util "^25.5.0" slash "^3.0.0" -"@jest/console@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" - integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== - dependencies: - "@jest/types" "^28.1.3" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - slash "^3.0.0" - "@jest/console@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" @@ -4287,41 +4275,6 @@ slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/core@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" - integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== - dependencies: - "@jest/console" "^28.1.3" - "@jest/reporters" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - ci-info "^3.2.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^28.1.3" - jest-config "^28.1.3" - jest-haste-map "^28.1.3" - jest-message-util "^28.1.3" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-resolve-dependencies "^28.1.3" - jest-runner "^28.1.3" - jest-runtime "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" - jest-watcher "^28.1.3" - micromatch "^4.0.4" - pretty-format "^28.1.3" - rimraf "^3.0.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - "@jest/core@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" @@ -4365,16 +4318,6 @@ "@jest/types" "^25.5.0" jest-mock "^25.5.0" -"@jest/environment@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" - integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== - dependencies: - "@jest/fake-timers" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - jest-mock "^28.1.3" - "@jest/environment@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" @@ -4385,13 +4328,6 @@ "@types/node" "*" jest-mock "^29.7.0" -"@jest/expect-utils@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" - integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== - dependencies: - jest-get-type "^28.0.2" - "@jest/expect-utils@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" @@ -4399,14 +4335,6 @@ dependencies: jest-get-type "^29.6.3" -"@jest/expect@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" - integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== - dependencies: - expect "^28.1.3" - jest-snapshot "^28.1.3" - "@jest/expect@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" @@ -4426,18 +4354,6 @@ jest-util "^25.5.0" lolex "^5.0.0" -"@jest/fake-timers@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" - integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== - dependencies: - "@jest/types" "^28.1.3" - "@sinonjs/fake-timers" "^9.1.2" - "@types/node" "*" - jest-message-util "^28.1.3" - jest-mock "^28.1.3" - jest-util "^28.1.3" - "@jest/fake-timers@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" @@ -4459,15 +4375,6 @@ "@jest/types" "^25.5.0" expect "^25.5.0" -"@jest/globals@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" - integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== - dependencies: - "@jest/environment" "^28.1.3" - "@jest/expect" "^28.1.3" - "@jest/types" "^28.1.3" - "@jest/globals@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" @@ -4510,37 +4417,6 @@ optionalDependencies: node-notifier "^6.0.0" -"@jest/reporters@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" - integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - "@jridgewell/trace-mapping" "^0.3.13" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - jest-worker "^28.1.3" - slash "^3.0.0" - string-length "^4.0.1" - strip-ansi "^6.0.0" - terminal-link "^2.0.0" - v8-to-istanbul "^9.0.1" - "@jest/reporters@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" @@ -4571,13 +4447,6 @@ strip-ansi "^6.0.0" v8-to-istanbul "^9.0.1" -"@jest/schemas@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" - integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== - dependencies: - "@sinclair/typebox" "^0.24.1" - "@jest/schemas@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" @@ -4594,15 +4463,6 @@ graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/source-map@^28.1.2": - version "28.1.2" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" - integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== - dependencies: - "@jridgewell/trace-mapping" "^0.3.13" - callsites "^3.0.0" - graceful-fs "^4.2.9" - "@jest/source-map@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" @@ -4622,16 +4482,6 @@ "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-result@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" - integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== - dependencies: - "@jest/console" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - "@jest/test-result@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" @@ -4653,16 +4503,6 @@ jest-runner "^25.5.4" jest-runtime "^25.5.4" -"@jest/test-sequencer@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" - integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== - dependencies: - "@jest/test-result" "^28.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - slash "^3.0.0" - "@jest/test-sequencer@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" @@ -4716,27 +4556,6 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" -"@jest/transform@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" - integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== - dependencies: - "@babel/core" "^7.11.6" - "@jest/types" "^28.1.3" - "@jridgewell/trace-mapping" "^0.3.13" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - jest-regex-util "^28.0.2" - jest-util "^28.1.3" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - write-file-atomic "^4.0.1" - "@jest/transform@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" @@ -4799,18 +4618,6 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@jest/types@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" - integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== - dependencies: - "@jest/schemas" "^28.1.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - "@jest/types@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" @@ -4863,7 +4670,7 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -7540,11 +7347,6 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== -"@sinclair/typebox@^0.24.1": - version "0.24.51" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" - integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== - "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" @@ -7586,13 +7388,6 @@ dependencies: "@sinonjs/commons" "^3.0.0" -"@sinonjs/fake-timers@^9.1.2": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" - integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== - dependencies: - "@sinonjs/commons" "^1.7.0" - "@slorber/remark-comment@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@slorber/remark-comment/-/remark-comment-1.0.0.tgz#2a020b3f4579c89dec0361673206c28d67e08f5a" @@ -8817,6 +8612,14 @@ "@swc/counter" "^0.1.3" tslib "^2.4.0" +"@synapsecns/coverage-aggregator@file:./packages/coverage-aggregator": + version "1.0.6" + dependencies: + glob "^8.0.3" + path "^0.12.7" + ts-jest "^29.0.5" + yargs "^17.6.2" + "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -9730,7 +9533,7 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ== -"@types/prettier@^2.1.1", "@types/prettier@^2.1.5": +"@types/prettier@^2.1.1": version "2.7.3" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== @@ -12288,19 +12091,6 @@ babel-jest@^25.2.6, babel-jest@^25.5.1: graceful-fs "^4.2.4" slash "^3.0.0" -babel-jest@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" - integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== - dependencies: - "@jest/transform" "^28.1.3" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^28.1.3" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" @@ -12405,16 +12195,6 @@ babel-plugin-jest-hoist@^25.5.0: "@babel/types" "^7.3.3" "@types/babel__traverse" "^7.0.6" -babel-plugin-jest-hoist@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" - integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.1.14" - "@types/babel__traverse" "^7.0.6" - babel-plugin-jest-hoist@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" @@ -12610,14 +12390,6 @@ babel-preset-jest@^25.5.0: babel-plugin-jest-hoist "^25.5.0" babel-preset-current-node-syntax "^0.1.2" -babel-preset-jest@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" - integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== - dependencies: - babel-plugin-jest-hoist "^28.1.3" - babel-preset-current-node-syntax "^1.0.0" - babel-preset-jest@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" @@ -15921,11 +15693,6 @@ diff-sequences@^25.2.6: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== -diff-sequences@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" - integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== - diff-sequences@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" @@ -16355,11 +16122,6 @@ elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4, elliptic@^6. minimalistic-assert "^1.0.1" minimalistic-crypto-utils "^1.0.1" -emittery@^0.10.2: - version "0.10.2" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" - integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== - emittery@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" @@ -18160,17 +17922,6 @@ expect@^25.5.0: jest-message-util "^25.5.0" jest-regex-util "^25.2.6" -expect@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" - integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== - dependencies: - "@jest/expect-utils" "^28.1.3" - jest-get-type "^28.0.2" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - expect@^29.0.0, expect@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" @@ -21885,7 +21636,7 @@ istanbul-lib-instrument@^4.0.0: istanbul-lib-coverage "^3.0.0" semver "^6.3.0" -istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: +istanbul-lib-instrument@^5.0.4: version "5.2.1" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== @@ -21997,14 +21748,6 @@ jest-changed-files@^25.5.0: execa "^3.2.0" throat "^5.0.0" -jest-changed-files@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" - integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== - dependencies: - execa "^5.0.0" - p-limit "^3.1.0" - jest-changed-files@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" @@ -22014,31 +21757,6 @@ jest-changed-files@^29.7.0: jest-util "^29.7.0" p-limit "^3.1.0" -jest-circus@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" - integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== - dependencies: - "@jest/environment" "^28.1.3" - "@jest/expect" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - is-generator-fn "^2.0.0" - jest-each "^28.1.3" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-runtime "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" - p-limit "^3.1.0" - pretty-format "^28.1.3" - slash "^3.0.0" - stack-utils "^2.0.3" - jest-circus@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" @@ -22085,24 +21803,6 @@ jest-cli@^25.5.4: realpath-native "^2.0.0" yargs "^15.3.1" -jest-cli@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" - integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== - dependencies: - "@jest/core" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - import-local "^3.0.2" - jest-config "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" - prompts "^2.0.1" - yargs "^17.3.1" - jest-cli@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" @@ -22145,34 +21845,6 @@ jest-config@^25.5.4: pretty-format "^25.5.0" realpath-native "^2.0.0" -jest-config@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" - integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== - dependencies: - "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^28.1.3" - "@jest/types" "^28.1.3" - babel-jest "^28.1.3" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-circus "^28.1.3" - jest-environment-node "^28.1.3" - jest-get-type "^28.0.2" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-runner "^28.1.3" - jest-util "^28.1.3" - jest-validate "^28.1.3" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^28.1.3" - slash "^3.0.0" - strip-json-comments "^3.1.1" - jest-config@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" @@ -22221,16 +21893,6 @@ jest-diff@^25.2.1, jest-diff@^25.5.0: jest-get-type "^25.2.6" pretty-format "^25.5.0" -jest-diff@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" - integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== - dependencies: - chalk "^4.0.0" - diff-sequences "^28.1.1" - jest-get-type "^28.0.2" - pretty-format "^28.1.3" - jest-diff@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" @@ -22248,13 +21910,6 @@ jest-docblock@^25.3.0: dependencies: detect-newline "^3.0.0" -jest-docblock@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8" - integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== - dependencies: - detect-newline "^3.0.0" - jest-docblock@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" @@ -22273,17 +21928,6 @@ jest-each@^25.5.0: jest-util "^25.5.0" pretty-format "^25.5.0" -jest-each@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" - integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== - dependencies: - "@jest/types" "^28.1.3" - chalk "^4.0.0" - jest-get-type "^28.0.2" - jest-util "^28.1.3" - pretty-format "^28.1.3" - jest-each@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" @@ -22319,18 +21963,6 @@ jest-environment-node@^25.5.0: jest-util "^25.5.0" semver "^6.3.0" -jest-environment-node@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" - integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== - dependencies: - "@jest/environment" "^28.1.3" - "@jest/fake-timers" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - jest-mock "^28.1.3" - jest-util "^28.1.3" - jest-environment-node@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" @@ -22361,11 +21993,6 @@ jest-get-type@^25.2.6: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== -jest-get-type@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" - integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== - jest-get-type@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" @@ -22412,25 +22039,6 @@ jest-haste-map@^26.6.2: optionalDependencies: fsevents "^2.1.2" -jest-haste-map@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" - integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== - dependencies: - "@jest/types" "^28.1.3" - "@types/graceful-fs" "^4.1.3" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^28.0.2" - jest-util "^28.1.3" - jest-worker "^28.1.3" - micromatch "^4.0.4" - walker "^1.0.8" - optionalDependencies: - fsevents "^2.3.2" - jest-haste-map@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" @@ -22481,14 +22089,6 @@ jest-leak-detector@^25.5.0: jest-get-type "^25.2.6" pretty-format "^25.5.0" -jest-leak-detector@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" - integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== - dependencies: - jest-get-type "^28.0.2" - pretty-format "^28.1.3" - jest-leak-detector@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" @@ -22507,16 +22107,6 @@ jest-matcher-utils@^25.5.0: jest-get-type "^25.2.6" pretty-format "^25.5.0" -jest-matcher-utils@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" - integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== - dependencies: - chalk "^4.0.0" - jest-diff "^28.1.3" - jest-get-type "^28.0.2" - pretty-format "^28.1.3" - jest-matcher-utils@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" @@ -22541,21 +22131,6 @@ jest-message-util@^25.5.0: slash "^3.0.0" stack-utils "^1.0.1" -jest-message-util@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" - integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^28.1.3" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^28.1.3" - slash "^3.0.0" - stack-utils "^2.0.3" - jest-message-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" @@ -22593,14 +22168,6 @@ jest-mock@^27.0.6: "@jest/types" "^27.5.1" "@types/node" "*" -jest-mock@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" - integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== - dependencies: - "@jest/types" "^28.1.3" - "@types/node" "*" - jest-mock@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" @@ -22625,11 +22192,6 @@ jest-regex-util@^26.0.0: resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== -jest-regex-util@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" - integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== - jest-regex-util@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" @@ -22644,14 +22206,6 @@ jest-resolve-dependencies@^25.5.4: jest-regex-util "^25.2.6" jest-snapshot "^25.5.1" -jest-resolve-dependencies@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" - integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== - dependencies: - jest-regex-util "^28.0.2" - jest-snapshot "^28.1.3" - jest-resolve-dependencies@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" @@ -22675,21 +22229,6 @@ jest-resolve@^25.5.1: resolve "^1.17.0" slash "^3.0.0" -jest-resolve@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" - integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== - dependencies: - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - jest-pnp-resolver "^1.2.2" - jest-util "^28.1.3" - jest-validate "^28.1.3" - resolve "^1.20.0" - resolve.exports "^1.1.0" - slash "^3.0.0" - jest-resolve@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" @@ -22730,33 +22269,6 @@ jest-runner@^25.5.4: source-map-support "^0.5.6" throat "^5.0.0" -jest-runner@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" - integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== - dependencies: - "@jest/console" "^28.1.3" - "@jest/environment" "^28.1.3" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.10.2" - graceful-fs "^4.2.9" - jest-docblock "^28.1.1" - jest-environment-node "^28.1.3" - jest-haste-map "^28.1.3" - jest-leak-detector "^28.1.3" - jest-message-util "^28.1.3" - jest-resolve "^28.1.3" - jest-runtime "^28.1.3" - jest-util "^28.1.3" - jest-watcher "^28.1.3" - jest-worker "^28.1.3" - p-limit "^3.1.0" - source-map-support "0.5.13" - jest-runner@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" @@ -22816,34 +22328,6 @@ jest-runtime@^25.5.4: strip-bom "^4.0.0" yargs "^15.3.1" -jest-runtime@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" - integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== - dependencies: - "@jest/environment" "^28.1.3" - "@jest/fake-timers" "^28.1.3" - "@jest/globals" "^28.1.3" - "@jest/source-map" "^28.1.2" - "@jest/test-result" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - execa "^5.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^28.1.3" - jest-message-util "^28.1.3" - jest-mock "^28.1.3" - jest-regex-util "^28.0.2" - jest-resolve "^28.1.3" - jest-snapshot "^28.1.3" - jest-util "^28.1.3" - slash "^3.0.0" - strip-bom "^4.0.0" - jest-runtime@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" @@ -22908,35 +22392,6 @@ jest-snapshot@^25.5.1: pretty-format "^25.5.0" semver "^6.3.0" -jest-snapshot@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" - integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== - dependencies: - "@babel/core" "^7.11.6" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.3.3" - "@jest/expect-utils" "^28.1.3" - "@jest/transform" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/babel__traverse" "^7.0.6" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^28.1.3" - graceful-fs "^4.2.9" - jest-diff "^28.1.3" - jest-get-type "^28.0.2" - jest-haste-map "^28.1.3" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - natural-compare "^1.4.0" - pretty-format "^28.1.3" - semver "^7.3.5" - jest-snapshot@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" @@ -22986,18 +22441,6 @@ jest-util@^26.6.2: is-ci "^2.0.0" micromatch "^4.0.2" -jest-util@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" - integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== - dependencies: - "@jest/types" "^28.1.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - jest-util@^29.0.0, jest-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" @@ -23022,18 +22465,6 @@ jest-validate@^25.5.0: leven "^3.1.0" pretty-format "^25.5.0" -jest-validate@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" - integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== - dependencies: - "@jest/types" "^28.1.3" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^28.0.2" - leven "^3.1.0" - pretty-format "^28.1.3" - jest-validate@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" @@ -23071,20 +22502,6 @@ jest-watcher@^25.2.4, jest-watcher@^25.5.0: jest-util "^25.5.0" string-length "^3.1.0" -jest-watcher@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" - integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== - dependencies: - "@jest/test-result" "^28.1.3" - "@jest/types" "^28.1.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.10.2" - jest-util "^28.1.3" - string-length "^4.0.1" - jest-watcher@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" @@ -23133,15 +22550,6 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" -jest-worker@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" - integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - jest-worker@^29.4.3, jest-worker@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" @@ -23161,16 +22569,6 @@ jest@^25.3.0: import-local "^3.0.2" jest-cli "^25.5.4" -jest@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.3.tgz#e9c6a7eecdebe3548ca2b18894a50f45b36dfc6b" - integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA== - dependencies: - "@jest/core" "^28.1.3" - "@jest/types" "^28.1.3" - import-local "^3.0.2" - jest-cli "^28.1.3" - jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" @@ -29204,16 +28602,6 @@ pretty-format@^27.0.2: ansi-styles "^5.0.0" react-is "^17.0.1" -pretty-format@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" - integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== - dependencies: - "@jest/schemas" "^28.1.3" - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^18.0.0" - pretty-format@^29.0.0, pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" @@ -30988,11 +30376,6 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== -resolve.exports@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" - integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== - resolve.exports@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" @@ -37152,7 +36535,7 @@ write-file-atomic@^3.0.0, write-file-atomic@^3.0.3: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -write-file-atomic@^4.0.1, write-file-atomic@^4.0.2: +write-file-atomic@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== From 3cc5077d535cd45d56f3dacdbf80e0d24478e326 Mon Sep 17 00:00:00 2001 From: abtestingalpha Date: Tue, 15 Oct 2024 21:31:01 +0000 Subject: [PATCH 13/15] Publish - @synapsecns/synapse-interface@0.40.10 --- packages/synapse-interface/CHANGELOG.md | 11 +++++++++++ packages/synapse-interface/package.json | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/synapse-interface/CHANGELOG.md b/packages/synapse-interface/CHANGELOG.md index e6a6670415..735878108a 100644 --- a/packages/synapse-interface/CHANGELOG.md +++ b/packages/synapse-interface/CHANGELOG.md @@ -3,6 +3,17 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.40.10](https://github.com/synapsecns/sanguine/compare/@synapsecns/synapse-interface@0.40.9...@synapsecns/synapse-interface@0.40.10) (2024-10-15) + + +### Bug Fixes + +* **synapse-interface:** translation period ([#3297](https://github.com/synapsecns/sanguine/issues/3297)) ([fd75dbb](https://github.com/synapsecns/sanguine/commit/fd75dbbbb6fec8ad2c35d5a16efb3a6a4812231a)) + + + + + ## [0.40.9](https://github.com/synapsecns/sanguine/compare/@synapsecns/synapse-interface@0.40.8...@synapsecns/synapse-interface@0.40.9) (2024-10-15) **Note:** Version bump only for package @synapsecns/synapse-interface diff --git a/packages/synapse-interface/package.json b/packages/synapse-interface/package.json index 7acf6c7973..152e129c94 100644 --- a/packages/synapse-interface/package.json +++ b/packages/synapse-interface/package.json @@ -1,6 +1,6 @@ { "name": "@synapsecns/synapse-interface", - "version": "0.40.9", + "version": "0.40.10", "private": true, "engines": { "node": ">=18.18.0" From 457aa959af98d372c50cb769036b07513a6566e4 Mon Sep 17 00:00:00 2001 From: parodime Date: Wed, 16 Oct 2024 05:18:03 -0400 Subject: [PATCH 14/15] fix dispute emit & revamp deposit xfer [SLT-295] [SLT-326] (#3293) * dispute emit relayer not guard. new Claim/Refund transfer & tests [SLT-295] * var & comment tweaks --- .../contracts-rfq/contracts/FastBridgeV2.sol | 38 ++++++++++++++----- .../contracts-rfq/test/FastBridgeV2.Src.t.sol | 17 ++++----- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/packages/contracts-rfq/contracts/FastBridgeV2.sol b/packages/contracts-rfq/contracts/FastBridgeV2.sol index b77e68a0c9..270f962cf9 100644 --- a/packages/contracts-rfq/contracts/FastBridgeV2.sol +++ b/packages/contracts-rfq/contracts/FastBridgeV2.sol @@ -82,13 +82,15 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors { revert DisputePeriodPassed(); } + address disputedRelayer = bridgeTxDetails[transactionId].proofRelayer; + // @dev relayer gets slashed effectively if dest relay has gone thru bridgeTxDetails[transactionId].status = BridgeStatus.REQUESTED; bridgeTxDetails[transactionId].proofRelayer = address(0); bridgeTxDetails[transactionId].proofBlockTimestamp = 0; bridgeTxDetails[transactionId].proofBlockNumber = 0; - emit BridgeProofDisputed(transactionId, msg.sender); + emit BridgeProofDisputed(transactionId, disputedRelayer); } /// @inheritdoc IFastBridge @@ -111,12 +113,17 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors { bridgeTxDetails[transactionId].status = BridgeStatus.REFUNDED; // transfer origin collateral back to original sender + uint256 amount = transaction.originAmount + transaction.originFeeAmount; address to = transaction.originSender; address token = transaction.originToken; - uint256 amount = transaction.originAmount + transaction.originFeeAmount; - token.universalTransfer(to, amount); - emit BridgeDepositRefunded(transactionId, to, token, amount); + if (token == UniversalTokenLib.ETH_ADDRESS) { + Address.sendValue(payable(to), amount); + } else { + IERC20(token).safeTransfer(to, amount); + } + + emit BridgeDepositRefunded(transactionId, transaction.originSender, transaction.originToken, amount); } /// @inheritdoc IFastBridge @@ -166,8 +173,10 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors { // track amount of origin token owed to protocol uint256 originFeeAmount; - if (protocolFeeRate > 0) originFeeAmount = (originAmount * protocolFeeRate) / FEE_BPS; - originAmount -= originFeeAmount; // remove from amount used in request as not relevant for relayers + if (protocolFeeRate > 0) { + originFeeAmount = (originAmount * protocolFeeRate) / FEE_BPS; + originAmount -= originFeeAmount; // remove from amount used in request as not relevant for relayers + } // set status to requested bytes memory request = abi.encode( @@ -298,12 +307,23 @@ contract FastBridgeV2 is Admin, IFastBridgeV2, IFastBridgeV2Errors { // update protocol fees if origin fee amount exists if (transaction.originFeeAmount > 0) protocolFees[transaction.originToken] += transaction.originFeeAmount; - // transfer origin collateral less fee to specified address address token = transaction.originToken; uint256 amount = transaction.originAmount; - token.universalTransfer(to, amount); - emit BridgeDepositClaimed(transactionId, bridgeTxDetails[transactionId].proofRelayer, to, token, amount); + // transfer origin collateral to specified address (protocol fee was pre-deducted at deposit) + if (token == UniversalTokenLib.ETH_ADDRESS) { + Address.sendValue(payable(to), amount); + } else { + IERC20(token).safeTransfer(to, amount); + } + + emit BridgeDepositClaimed( + transactionId, + bridgeTxDetails[transactionId].proofRelayer, + to, + transaction.originToken, + transaction.originAmount + ); } function bridgeStatuses(bytes32 transactionId) public view returns (BridgeStatus status) { diff --git a/packages/contracts-rfq/test/FastBridgeV2.Src.t.sol b/packages/contracts-rfq/test/FastBridgeV2.Src.t.sol index 5baa42bda0..52315635dd 100644 --- a/packages/contracts-rfq/test/FastBridgeV2.Src.t.sol +++ b/packages/contracts-rfq/test/FastBridgeV2.Src.t.sol @@ -74,10 +74,9 @@ contract FastBridgeV2SrcTest is FastBridgeV2SrcBaseTest { }); } - function expectBridgeProofDisputed(bytes32 txId, address guard) public { + function expectBridgeProofDisputed(bytes32 txId, address relayer) public { vm.expectEmit(address(fastBridge)); - // Note: BridgeProofDisputed event has a mislabeled address parameter, this is actually the guard - emit BridgeProofDisputed({transactionId: txId, relayer: guard}); + emit BridgeProofDisputed({transactionId: txId, relayer: relayer}); } function expectBridgeDepositRefunded(IFastBridge.BridgeParams memory bridgeParams, bytes32 txId) public { @@ -384,11 +383,11 @@ contract FastBridgeV2SrcTest is FastBridgeV2SrcBaseTest { bridge({caller: userA, msgValue: ethParams.originAmount, params: ethParams}); expectBridgeProofProvided({txId: txId, relayer: relayerA, destTxHash: hex"01"}); prove({caller: relayerB, transactionId: txId, destTxHash: hex"01", relayer: relayerA}); - expectBridgeProofDisputed(txId, guard); + expectBridgeProofDisputed(txId, relayerA); dispute(guard, txId); expectBridgeProofProvided({txId: txId, relayer: relayerA, destTxHash: hex"02"}); prove({caller: relayerB, transactionId: txId, destTxHash: hex"02", relayer: relayerA}); - expectBridgeProofDisputed(txId, guard); + expectBridgeProofDisputed(txId, relayerA); dispute(guard, txId); expectBridgeProofProvided({txId: txId, relayer: relayerA, destTxHash: hex"03"}); prove({caller: relayerB, transactionId: txId, destTxHash: hex"03", relayer: relayerA}); @@ -660,7 +659,7 @@ contract FastBridgeV2SrcTest is FastBridgeV2SrcBaseTest { bytes32 txId = getTxId(tokenTx); bridge({caller: userA, msgValue: 0, params: tokenParams}); prove({caller: relayerA, bridgeTx: tokenTx, destTxHash: hex"01"}); - expectBridgeProofDisputed({txId: txId, guard: guard}); + expectBridgeProofDisputed({txId: txId, relayer: relayerA}); dispute({caller: guard, txId: txId}); assertEq(fastBridge.bridgeStatuses(txId), IFastBridgeV2.BridgeStatus.REQUESTED); assertEq(fastBridge.protocolFees(address(srcToken)), INITIAL_PROTOCOL_FEES_TOKEN); @@ -672,7 +671,7 @@ contract FastBridgeV2SrcTest is FastBridgeV2SrcBaseTest { bridge({caller: userA, msgValue: 0, params: tokenParams}); prove({caller: relayerA, bridgeTx: tokenTx, destTxHash: hex"01"}); skip(CLAIM_DELAY); - expectBridgeProofDisputed({txId: txId, guard: guard}); + expectBridgeProofDisputed({txId: txId, relayer: relayerA}); dispute({caller: guard, txId: txId}); assertEq(fastBridge.bridgeStatuses(txId), IFastBridgeV2.BridgeStatus.REQUESTED); assertEq(fastBridge.protocolFees(address(srcToken)), INITIAL_PROTOCOL_FEES_TOKEN); @@ -684,7 +683,7 @@ contract FastBridgeV2SrcTest is FastBridgeV2SrcBaseTest { bytes32 txId = getTxId(ethTx); bridge({caller: userA, msgValue: ethParams.originAmount, params: ethParams}); prove({caller: relayerA, bridgeTx: ethTx, destTxHash: hex"01"}); - expectBridgeProofDisputed({txId: txId, guard: guard}); + expectBridgeProofDisputed({txId: txId, relayer: relayerA}); dispute({caller: guard, txId: txId}); assertEq(fastBridge.bridgeStatuses(txId), IFastBridgeV2.BridgeStatus.REQUESTED); assertEq(fastBridge.protocolFees(ETH_ADDRESS), INITIAL_PROTOCOL_FEES_ETH); @@ -697,7 +696,7 @@ contract FastBridgeV2SrcTest is FastBridgeV2SrcBaseTest { bridge({caller: userA, msgValue: ethParams.originAmount, params: ethParams}); prove({caller: relayerA, bridgeTx: ethTx, destTxHash: hex"01"}); skip(CLAIM_DELAY); - expectBridgeProofDisputed({txId: txId, guard: guard}); + expectBridgeProofDisputed({txId: txId, relayer: relayerA}); dispute({caller: guard, txId: txId}); assertEq(fastBridge.bridgeStatuses(txId), IFastBridgeV2.BridgeStatus.REQUESTED); assertEq(fastBridge.protocolFees(ETH_ADDRESS), INITIAL_PROTOCOL_FEES_ETH); From 47dc48e8183ddec6b795fdbc62917fa8d29711d8 Mon Sep 17 00:00:00 2001 From: parodime Date: Wed, 16 Oct 2024 09:22:12 +0000 Subject: [PATCH 15/15] Publish - @synapsecns/contracts-rfq@0.8.3 --- packages/contracts-rfq/CHANGELOG.md | 8 ++++++++ packages/contracts-rfq/package.json | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/contracts-rfq/CHANGELOG.md b/packages/contracts-rfq/CHANGELOG.md index 3c3f40bb2d..10a7314cd3 100644 --- a/packages/contracts-rfq/CHANGELOG.md +++ b/packages/contracts-rfq/CHANGELOG.md @@ -3,6 +3,14 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [0.8.3](https://github.com/synapsecns/sanguine/compare/@synapsecns/contracts-rfq@0.8.2...@synapsecns/contracts-rfq@0.8.3) (2024-10-16) + +**Note:** Version bump only for package @synapsecns/contracts-rfq + + + + + ## [0.8.2](https://github.com/synapsecns/sanguine/compare/@synapsecns/contracts-rfq@0.8.1...@synapsecns/contracts-rfq@0.8.2) (2024-10-15) **Note:** Version bump only for package @synapsecns/contracts-rfq diff --git a/packages/contracts-rfq/package.json b/packages/contracts-rfq/package.json index 701ea12ed0..5ce11f669b 100644 --- a/packages/contracts-rfq/package.json +++ b/packages/contracts-rfq/package.json @@ -1,7 +1,7 @@ { "name": "@synapsecns/contracts-rfq", "license": "MIT", - "version": "0.8.2", + "version": "0.8.3", "description": "FastBridge contracts.", "private": true, "files": [