From d8bf88724538b6fb2af7b04ba778563d3950b911 Mon Sep 17 00:00:00 2001 From: Matthew Russell Date: Tue, 17 May 2022 09:04:41 -0400 Subject: [PATCH] chore(#315): Convert token to use wallet lib * delete token version of vega wallet serivce * update use-user-vote to use new wallet service * remove typo * add further types for transaction submissions, add assets to withdraw page query * update api client package to get generated types, adjust render logic of withdrawals page * fix withdrawals list rendering * update determine id function to not use nodejs buffer * update service api client so it accepts new tx types * remove stray logs and formatting * make filtering erc20 assets the responsibility of the withdraw/deposit lib and not the app * remove sha3 dep and use js-sha3 and ethers to determine ids * use hook for fetching withdrawals form lib, add type policy to ensure withdrawal state is updated correctly * fix: markets page feature --- apps/token/src/components/nav/nav.tsx | 1 + .../transaction-complete.tsx | 1 - apps/token/src/hooks/use-create-withdrawal.ts | 143 --------- .../src/hooks/use-erc-poll20-approval.ts | 66 ---- apps/token/src/i18n/translations/dev.json | 3 +- apps/token/src/lib/apollo-client.ts | 7 + apps/token/src/lib/sig-to-id.test.ts | 9 - apps/token/src/lib/sig-to-id.ts | 18 -- .../lib/vega-wallet/vega-wallet-service.ts | 303 ------------------ .../src/lib/vega-wallet/vega-wallet-types.ts | 3 - .../components/vote-details/use-user-vote.tsx | 14 +- .../staking/associate/associate-page.tsx | 2 + .../src/routes/staking/pending-stake.tsx | 34 +- .../token/src/routes/staking/staking-form.tsx | 24 +- .../withdraw/__generated__/WithdrawPage.ts | 42 +++ apps/token/src/routes/withdraw/index.tsx | 56 ++-- .../src/routes/withdraw/withdraw-form.tsx | 153 --------- .../__generated__/WithdrawalsPage.ts | 105 ------ apps/token/src/routes/withdrawals/index.tsx | 194 ++++------- .../src/integration/markets-page.feature | 2 + .../src/support/pages/markets-page.ts | 3 + .../step_definitions/markets-page.step.ts | 8 +- apps/trading/lib/assets.ts | 18 -- .../portfolio/deposit/deposit-container.tsx | 3 +- .../withdraw/withdraw-page-container.tsx | 3 +- libs/deposits/src/lib/deposit-form.tsx | 16 +- libs/deposits/src/lib/deposit-manager.tsx | 19 +- .../src/lib/use-get-deposit-limits.ts | 2 +- libs/react-helpers/src/lib/determine-id.ts | 17 +- libs/wallet/src/connectors/index.ts | 5 +- libs/wallet/src/connectors/rest-connector.ts | 9 +- libs/wallet/src/provider.tsx | 20 +- libs/wallet/src/types.ts | 8 +- libs/withdraws/src/index.ts | 1 + libs/withdraws/src/lib/test-helpers.ts | 1 + libs/withdraws/src/lib/types.ts | 15 +- libs/withdraws/src/lib/withdraw-form.tsx | 12 +- package.json | 4 +- yarn.lock | 27 +- 39 files changed, 265 insertions(+), 1106 deletions(-) delete mode 100644 apps/token/src/hooks/use-create-withdrawal.ts delete mode 100644 apps/token/src/hooks/use-erc-poll20-approval.ts delete mode 100644 apps/token/src/lib/sig-to-id.test.ts delete mode 100644 apps/token/src/lib/sig-to-id.ts delete mode 100644 apps/token/src/lib/vega-wallet/vega-wallet-service.ts delete mode 100644 apps/token/src/lib/vega-wallet/vega-wallet-types.ts delete mode 100644 apps/token/src/routes/withdraw/withdraw-form.tsx delete mode 100644 apps/token/src/routes/withdrawals/__generated__/WithdrawalsPage.ts delete mode 100644 apps/trading/lib/assets.ts diff --git a/apps/token/src/components/nav/nav.tsx b/apps/token/src/components/nav/nav.tsx index 5b6a1dfe6..816e074d8 100644 --- a/apps/token/src/components/nav/nav.tsx +++ b/apps/token/src/components/nav/nav.tsx @@ -147,6 +147,7 @@ const IconLine = ({ inverted }: { inverted: boolean }) => ( const NavDrawer = ({ inverted }: { inverted: boolean }) => { const { appState, appDispatch } = useAppState(); + return ( <> + + ); + } } - }, [state, refetchWithdrawals, refetchBalances]); + + return status; + }; return (
@@ -201,10 +145,6 @@ export const Withdrawal = ({ {withdrawal.asset.symbol} - - {t('from')} - {truncateMiddle(withdrawal.party.id)} - {t('toEthereum')} @@ -226,27 +166,23 @@ export const Withdrawal = ({ - {t('Signature')} - - {!erc20Approval?.signatures - ? t('Loading') - : truncateMiddle(erc20Approval.signatures)} + {t('withdrawalTransaction', { foreignChain: 'Ethereum' })} + + {withdrawal.txHash ? ( + + ) : ( + '-' + )} + + {t('status')} + {renderStatus(withdrawal)} + -
); }; diff --git a/apps/trading-e2e/src/integration/markets-page.feature b/apps/trading-e2e/src/integration/markets-page.feature index 81698cba6..e9fb1886a 100644 --- a/apps/trading-e2e/src/integration/markets-page.feature +++ b/apps/trading-e2e/src/integration/markets-page.feature @@ -8,10 +8,12 @@ Feature: Markets page Scenario: Select active market Given I am on the markets page + And I can view markets When I click on "Active" mocked market Then trading page for "active" market is displayed Scenario: Select suspended market Given I am on the markets page + And I can view markets When I click on "Suspended" mocked market Then trading page for "suspended" market is displayed diff --git a/apps/trading-e2e/src/support/pages/markets-page.ts b/apps/trading-e2e/src/support/pages/markets-page.ts index 28cd5c782..7d16abd0f 100644 --- a/apps/trading-e2e/src/support/pages/markets-page.ts +++ b/apps/trading-e2e/src/support/pages/markets-page.ts @@ -10,6 +10,9 @@ export default class MarketPage extends BasePage { marketStateColId = 'data'; validateMarketsAreDisplayed() { + // We need this to ensure that ag-grid is fully rendered before asserting + // eslint-disable-next-line cypress/no-unnecessary-waiting + cy.wait(1000); cy.get('.ag-root-wrapper').should('be.visible'); } diff --git a/apps/trading-e2e/src/support/step_definitions/markets-page.step.ts b/apps/trading-e2e/src/support/step_definitions/markets-page.step.ts index 4a70f607f..d46982c5c 100644 --- a/apps/trading-e2e/src/support/step_definitions/markets-page.step.ts +++ b/apps/trading-e2e/src/support/step_definitions/markets-page.step.ts @@ -15,21 +15,19 @@ const mockMarkets = () => { }); }; -beforeEach(() => { - mockMarkets(); -}); - Then('I navigate to markets page', () => { + mockMarkets(); marketsPage.navigateToMarkets(); + cy.wait('@Markets'); }); Given('I am on the markets page', () => { + mockMarkets(); cy.visit('/markets'); cy.wait('@Markets'); }); Then('I can view markets', () => { - cy.wait('@Markets'); marketsPage.validateMarketsAreDisplayed(); }); diff --git a/apps/trading/lib/assets.ts b/apps/trading/lib/assets.ts deleted file mode 100644 index e3d629176..000000000 --- a/apps/trading/lib/assets.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { AssetFields } from './__generated__/AssetFields'; - -export interface ERC20Asset extends AssetFields { - source: { - __typename: 'ERC20'; - contractAddress: string; - }; -} - -type UnknownAsset = Pick; - -// Type guard to ensure an asset is an ERC20 token -export const isERC20Asset = (asset: UnknownAsset): asset is ERC20Asset => { - if (asset.source.__typename === 'ERC20') { - return true; - } - return false; -}; diff --git a/apps/trading/pages/portfolio/deposit/deposit-container.tsx b/apps/trading/pages/portfolio/deposit/deposit-container.tsx index 3526644e9..feea5b361 100644 --- a/apps/trading/pages/portfolio/deposit/deposit-container.tsx +++ b/apps/trading/pages/portfolio/deposit/deposit-container.tsx @@ -6,7 +6,6 @@ import { DepositManager } from '@vegaprotocol/deposits'; import { t } from '@vegaprotocol/react-helpers'; import { Splash } from '@vegaprotocol/ui-toolkit'; import { ASSET_FRAGMENT } from '../../../lib/query-fragments'; -import { isERC20Asset } from '../../../lib/assets'; const DEPOSIT_PAGE_QUERY = gql` ${ASSET_FRAGMENT} @@ -45,7 +44,7 @@ export const DepositContainer = ({ ); diff --git a/apps/trading/pages/portfolio/withdraw/withdraw-page-container.tsx b/apps/trading/pages/portfolio/withdraw/withdraw-page-container.tsx index cb7901c27..aaf61156a 100644 --- a/apps/trading/pages/portfolio/withdraw/withdraw-page-container.tsx +++ b/apps/trading/pages/portfolio/withdraw/withdraw-page-container.tsx @@ -6,7 +6,6 @@ import { WithdrawManager } from '@vegaprotocol/withdraws'; import { ASSET_FRAGMENT } from '../../../lib/query-fragments'; import Link from 'next/link'; import { PageQueryContainer } from '../../../components/page-query-container'; -import { isERC20Asset } from '../../../lib/assets'; import type { WithdrawPageQuery, WithdrawPageQueryVariables, @@ -85,7 +84,7 @@ export const WithdrawPageContainer = ({

) : null} diff --git a/libs/deposits/src/lib/deposit-form.tsx b/libs/deposits/src/lib/deposit-form.tsx index 9624b7ab9..1b888cd4f 100644 --- a/libs/deposits/src/lib/deposit-form.tsx +++ b/libs/deposits/src/lib/deposit-form.tsx @@ -82,8 +82,8 @@ export const DepositForm = ({ }); const onDeposit = async (fields: FormFields) => { - if (!selectedAsset) { - throw new Error('Asset not selected'); + if (!selectedAsset || selectedAsset.source.__typename !== 'ERC20') { + throw new Error('Invalid asset'); } submitDeposit({ @@ -153,11 +153,13 @@ export const DepositForm = ({ {errors.asset?.message && ( diff --git a/libs/deposits/src/lib/deposit-manager.tsx b/libs/deposits/src/lib/deposit-manager.tsx index 462466fff..36858ccfb 100644 --- a/libs/deposits/src/lib/deposit-manager.tsx +++ b/libs/deposits/src/lib/deposit-manager.tsx @@ -10,16 +10,23 @@ import { useSubmitFaucet } from './use-submit-faucet'; import { EthTxStatus, TransactionDialog } from '@vegaprotocol/web3'; import { useTokenContract, useBridgeContract } from '@vegaprotocol/web3'; +interface ERC20AssetSource { + __typename: 'ERC20'; + contractAddress: string; +} + +interface BuiltinAssetSource { + __typename: 'BuiltinAsset'; +} + +type AssetSource = ERC20AssetSource | BuiltinAssetSource; export interface Asset { __typename: 'Asset'; id: string; symbol: string; name: string; decimals: number; - source: { - __typename: 'ERC20'; - contractAddress: string; - }; + source: AssetSource; } interface DepositManagerProps { @@ -44,7 +51,9 @@ export const DepositManager = ({ }, [assets, assetId]); const tokenContract = useTokenContract( - asset?.source.contractAddress, + asset?.source.__typename === 'ERC20' + ? asset.source.contractAddress + : undefined, process.env['NX_VEGA_ENV'] !== 'MAINNET' ); const bridgeContract = useBridgeContract(); diff --git a/libs/deposits/src/lib/use-get-deposit-limits.ts b/libs/deposits/src/lib/use-get-deposit-limits.ts index d36943876..eb743896f 100644 --- a/libs/deposits/src/lib/use-get-deposit-limits.ts +++ b/libs/deposits/src/lib/use-get-deposit-limits.ts @@ -14,7 +14,7 @@ export const useGetDepositLimits = ( asset?: Asset ): Limits | null => { const getLimits = useCallback(async () => { - if (!contract || !asset) { + if (!contract || !asset || asset.source.__typename !== 'ERC20') { return; } diff --git a/libs/react-helpers/src/lib/determine-id.ts b/libs/react-helpers/src/lib/determine-id.ts index ba2861fe6..23e4e2d60 100644 --- a/libs/react-helpers/src/lib/determine-id.ts +++ b/libs/react-helpers/src/lib/determine-id.ts @@ -1,23 +1,10 @@ import { ethers } from 'ethers'; -import { SHA3 } from 'sha3'; -import { remove0x } from './remove-0x'; +import { sha3_256 } from 'js-sha3'; /** * This function creates an ID in the same way that core does on the backend. This way we * Can match up the newly created order with incoming orders via a subscription */ export const determineId = (sig: string) => { - // Prepend 0x - if (sig.slice(0, 2) !== '0x') { - sig = '0x' + sig; - } - - // Create the ID - const hash = new SHA3(256); - const bytes = ethers.utils.arrayify(sig); - hash.update(Buffer.from(bytes)); - const id = ethers.utils.hexlify(hash.digest()); - - // Remove 0x as core doesn't keep them in the API - return remove0x(id); + return sha3_256(ethers.utils.arrayify('0x' + sig)); }; diff --git a/libs/wallet/src/connectors/index.ts b/libs/wallet/src/connectors/index.ts index dcc534768..c23e90638 100644 --- a/libs/wallet/src/connectors/index.ts +++ b/libs/wallet/src/connectors/index.ts @@ -1,9 +1,8 @@ import type { VegaKey, TransactionResponse, - OrderSubmissionBody, - WithdrawSubmissionBody, } from '@vegaprotocol/vegawallet-service-api-client'; +import type { TransactionSubmission } from '../types'; export { RestConnector } from './rest-connector'; type ErrorResponse = @@ -26,6 +25,6 @@ export interface VegaConnector { /** Send a TX to the network. Only support order submission for now */ sendTx: ( - body: OrderSubmissionBody | WithdrawSubmissionBody + body: TransactionSubmission ) => Promise; } diff --git a/libs/wallet/src/connectors/rest-connector.ts b/libs/wallet/src/connectors/rest-connector.ts index 75d19591a..2dfe240f3 100644 --- a/libs/wallet/src/connectors/rest-connector.ts +++ b/libs/wallet/src/connectors/rest-connector.ts @@ -1,8 +1,4 @@ -import type { - Configuration, - OrderSubmissionBody, - WithdrawSubmissionBody, -} from '@vegaprotocol/vegawallet-service-api-client'; +import type { Configuration } from '@vegaprotocol/vegawallet-service-api-client'; import { createConfiguration, DefaultApi, @@ -10,6 +6,7 @@ import { import { LocalStorage } from '@vegaprotocol/react-helpers'; import { WALLET_CONFIG } from '../storage-keys'; import type { VegaConnector } from '.'; +import type { TransactionSubmission } from '../types'; // Perhaps there should be a default ConnectorConfig that others can extend off. Do all connectors // need to use local storage, I don't think so... @@ -88,7 +85,7 @@ export class RestConnector implements VegaConnector { } } - async sendTx(body: OrderSubmissionBody | WithdrawSubmissionBody) { + async sendTx(body: TransactionSubmission) { try { return await this.service.commandSyncPost(body); } catch (err) { diff --git a/libs/wallet/src/provider.tsx b/libs/wallet/src/provider.tsx index d45b0e0b4..7428cbe63 100644 --- a/libs/wallet/src/provider.tsx +++ b/libs/wallet/src/provider.tsx @@ -5,10 +5,7 @@ import type { VegaKeyExtended, VegaWalletContextShape } from '.'; import type { VegaConnector } from './connectors'; import { VegaWalletContext } from './context'; import { WALLET_KEY } from './storage-keys'; -import type { - OrderSubmissionBody, - WithdrawSubmissionBody, -} from '@vegaprotocol/vegawallet-service-api-client'; +import type { TransactionSubmission } from './types'; interface VegaWalletProviderProps { children: ReactNode; @@ -72,16 +69,13 @@ export const VegaWalletProvider = ({ children }: VegaWalletProviderProps) => { } }, []); - const sendTx = useCallback( - (body: OrderSubmissionBody | WithdrawSubmissionBody) => { - if (!connector.current) { - return null; - } + const sendTx = useCallback((body: TransactionSubmission) => { + if (!connector.current) { + return null; + } - return connector.current.sendTx(body); - }, - [] - ); + return connector.current.sendTx(body); + }, []); // Current selected keypair derived from publicKey state const keypair = useMemo(() => { diff --git a/libs/wallet/src/types.ts b/libs/wallet/src/types.ts index 5430c6632..c4e85c95d 100644 --- a/libs/wallet/src/types.ts +++ b/libs/wallet/src/types.ts @@ -1,5 +1,8 @@ import type { + DelegateSubmissionBody, OrderSubmissionBody, + UndelegateSubmissionBody, + VoteSubmissionBody, WithdrawSubmissionBody, } from '@vegaprotocol/vegawallet-service-api-client'; @@ -25,4 +28,7 @@ export enum OrderTimeInForce { // Will make Transaction a union type as other transactions are added export type TransactionSubmission = | OrderSubmissionBody - | WithdrawSubmissionBody; + | WithdrawSubmissionBody + | VoteSubmissionBody + | DelegateSubmissionBody + | UndelegateSubmissionBody; diff --git a/libs/withdraws/src/index.ts b/libs/withdraws/src/index.ts index 0f76390cd..41cbea1fe 100644 --- a/libs/withdraws/src/index.ts +++ b/libs/withdraws/src/index.ts @@ -4,3 +4,4 @@ export * from './lib/withdrawals-table'; export * from './lib/use-complete-withdraw'; export * from './lib/use-withdraw'; export * from './lib/use-withdrawals'; +export * from './lib/__generated__/Withdrawals'; diff --git a/libs/withdraws/src/lib/test-helpers.ts b/libs/withdraws/src/lib/test-helpers.ts index 320f4ab1e..afd650b86 100644 --- a/libs/withdraws/src/lib/test-helpers.ts +++ b/libs/withdraws/src/lib/test-helpers.ts @@ -11,6 +11,7 @@ export const generateAsset = (override?: PartialDeep) => { name: 'asset-name', decimals: 5, source: { + __typename: 'ERC20', contractAddress: 'contract-address', }, }; diff --git a/libs/withdraws/src/lib/types.ts b/libs/withdraws/src/lib/types.ts index b3a14d3e6..27a95ab91 100644 --- a/libs/withdraws/src/lib/types.ts +++ b/libs/withdraws/src/lib/types.ts @@ -1,13 +1,22 @@ import type { AccountType } from '@vegaprotocol/types'; +interface ERC20AssetSource { + __typename: 'ERC20'; + contractAddress: string; +} + +interface BuiltinAssetSource { + __typename: 'BuiltinAsset'; +} + +type AssetSource = ERC20AssetSource | BuiltinAssetSource; + export interface Asset { id: string; symbol: string; name: string; decimals: number; - source: { - contractAddress: string; - }; + source: AssetSource; } export interface Account { diff --git a/libs/withdraws/src/lib/withdraw-form.tsx b/libs/withdraws/src/lib/withdraw-form.tsx index adad298f2..8bea38b0a 100644 --- a/libs/withdraws/src/lib/withdraw-form.tsx +++ b/libs/withdraws/src/lib/withdraw-form.tsx @@ -90,11 +90,13 @@ export const WithdrawForm = ({ id="asset" > - {assets.map((a) => ( - - ))} + {assets + .filter((a) => a.source.__typename === 'ERC20') + .map((a) => ( + + ))} )} /> diff --git a/package.json b/package.json index d2b383912..0062653b3 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@sentry/react": "^6.19.2", "@sentry/tracing": "^6.19.2", "@vegaprotocol/smart-contracts-sdk": "^1.6.0", - "@vegaprotocol/vegawallet-service-api-client": "^0.4.9", + "@vegaprotocol/vegawallet-service-api-client": "^0.4.11", "@walletconnect/ethereum-provider": "^1.7.5", "@web3-react/core": "8.0.20-beta.0", "@web3-react/metamask": "8.0.16-beta.0", @@ -52,6 +52,7 @@ "i18next": "^20.3.5", "i18next-browser-languagedetector": "^6.1.2", "immer": "^9.0.12", + "js-sha3": "^0.8.0", "lodash": "^4.17.21", "next": "^12.0.7", "pennant": "0.4.8", @@ -69,7 +70,6 @@ "react-window-infinite-loader": "^1.0.7", "recharts": "^2.1.2", "regenerator-runtime": "0.13.7", - "sha3": "^2.1.4", "tailwindcss": "^3.0.23", "tslib": "^2.0.0", "uuid": "^8.3.2", diff --git a/yarn.lock b/yarn.lock index ef251676b..1bc5077b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6205,10 +6205,10 @@ ethers "^5.5.2" lodash "^4.17.21" -"@vegaprotocol/vegawallet-service-api-client@^0.4.9": - version "0.4.9" - resolved "https://registry.yarnpkg.com/@vegaprotocol/vegawallet-service-api-client/-/vegawallet-service-api-client-0.4.9.tgz#9c2566407e9c86248f2c170b1f495afdcb347d87" - integrity sha512-zqppuVu3VrsHpdcNBvu6G+qMMt0CBXi5wHBb/0ryiXdXD9dmQci5Qz8zoGx5syOupFMdUDNstmGOaFWbBOuvbg== +"@vegaprotocol/vegawallet-service-api-client@^0.4.11": + version "0.4.11" + resolved "https://registry.yarnpkg.com/@vegaprotocol/vegawallet-service-api-client/-/vegawallet-service-api-client-0.4.11.tgz#41a623afc9957dcf8b5425f74280ba7861e92b74" + integrity sha512-yiodc3YFWG+RGG+wjpTjYmNAECP/Nv244mVu8IGVtj8LZo02KC/LpNCgmMhGaK4ZcqVtxHv9t7OUCSEWZhSgOg== dependencies: es6-promise "^4.2.4" url-parse "^1.4.3" @@ -8438,14 +8438,6 @@ buffer@5.6.0: base64-js "^1.0.2" ieee754 "^1.1.4" -buffer@6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - buffer@^4.3.0: version "4.9.2" resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" @@ -13304,7 +13296,7 @@ identity-obj-proxy@3.0.0: dependencies: harmony-reflect "^1.4.6" -ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: +ieee754@^1.1.13, ieee754@^1.1.4: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -14693,7 +14685,7 @@ jest@27.2.3: import-local "^3.0.2" jest-cli "^27.2.3" -js-sha3@0.8.0: +js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== @@ -19310,13 +19302,6 @@ sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8, sha.js@~2.4.4: inherits "^2.0.1" safe-buffer "^5.0.1" -sha3@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/sha3/-/sha3-2.1.4.tgz#000fac0fe7c2feac1f48a25e7a31b52a6492cc8f" - integrity sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg== - dependencies: - buffer "6.0.3" - shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"