diff --git a/package.json b/package.json index 6c52604d6b84..d01735a7e755 100644 --- a/package.json +++ b/package.json @@ -302,7 +302,7 @@ "@metamask/approval-controller": "^7.0.0", "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A38.3.0#~/.yarn/patches/@metamask-assets-controllers-npm-38.3.0-57b3d695bb.patch", "@metamask/base-controller": "^7.0.0", - "@metamask/bitcoin-wallet-snap": "^0.7.0", + "@metamask/bitcoin-wallet-snap": "^0.8.1", "@metamask/browser-passworder": "^4.3.0", "@metamask/contract-metadata": "^2.5.0", "@metamask/controller-utils": "^11.2.0", diff --git a/shared/lib/accounts/bitcoin-wallet-snap.ts b/shared/lib/accounts/bitcoin-wallet-snap.ts index 58f367b173e1..c068e4e8e35c 100644 --- a/shared/lib/accounts/bitcoin-wallet-snap.ts +++ b/shared/lib/accounts/bitcoin-wallet-snap.ts @@ -3,7 +3,6 @@ import { SnapId } from '@metamask/snaps-sdk'; // the Snap is being pre-installed only for Flask build (for the moment). import BitcoinWalletSnap from '@metamask/bitcoin-wallet-snap/dist/preinstalled-snap.json'; -// export const BITCOIN_WALLET_SNAP_ID: SnapId = 'local:http://localhost:8080'; export const BITCOIN_WALLET_SNAP_ID: SnapId = BitcoinWalletSnap.snapId as SnapId; diff --git a/test/e2e/flask/btc/btc-account-overview.spec.ts b/test/e2e/flask/btc/btc-account-overview.spec.ts index 24eedb60b6a2..f32a48d9c4a8 100644 --- a/test/e2e/flask/btc/btc-account-overview.spec.ts +++ b/test/e2e/flask/btc/btc-account-overview.spec.ts @@ -16,7 +16,7 @@ describe('BTC Account - Overview', function (this: Suite) { await driver.waitForSelector({ text: 'Send', tag: 'button', - css: '[disabled]', + css: '[data-testid="coin-overview-send"]', }); await driver.waitForSelector({ diff --git a/ui/components/app/wallet-overview/btc-overview.test.tsx b/ui/components/app/wallet-overview/btc-overview.test.tsx index c7bb501ee98f..abff2cb2b239 100644 --- a/ui/components/app/wallet-overview/btc-overview.test.tsx +++ b/ui/components/app/wallet-overview/btc-overview.test.tsx @@ -19,7 +19,6 @@ const BTC_OVERVIEW_BUY = 'coin-overview-buy'; const BTC_OVERVIEW_BRIDGE = 'coin-overview-bridge'; const BTC_OVERVIEW_RECEIVE = 'coin-overview-receive'; const BTC_OVERVIEW_SWAP = 'token-overview-button-swap'; -const BTC_OVERVIEW_SEND = 'coin-overview-send'; const BTC_OVERVIEW_PRIMARY_CURRENCY = 'coin-overview__primary-currency'; const mockMetaMetricsId = 'deadbeef'; @@ -158,14 +157,10 @@ describe('BtcOverview', () => { expect(spinner).toBeInTheDocument(); }); - it('buttons Send/Swap/Bridge are disabled', () => { + it('buttons Swap/Bridge are disabled', () => { const { queryByTestId } = renderWithProvider(, getStore()); - for (const buttonTestId of [ - BTC_OVERVIEW_SEND, - BTC_OVERVIEW_SWAP, - BTC_OVERVIEW_BRIDGE, - ]) { + for (const buttonTestId of [BTC_OVERVIEW_SWAP, BTC_OVERVIEW_BRIDGE]) { const button = queryByTestId(buttonTestId); expect(button).toBeInTheDocument(); expect(button).toBeDisabled(); diff --git a/ui/components/app/wallet-overview/btc-overview.tsx b/ui/components/app/wallet-overview/btc-overview.tsx index e5d0b0103805..dc47df7567b5 100644 --- a/ui/components/app/wallet-overview/btc-overview.tsx +++ b/ui/components/app/wallet-overview/btc-overview.tsx @@ -27,7 +27,7 @@ const BtcOverview = ({ className }: BtcOverviewProps) => { balanceIsCached={false} className={className} chainId={chainId} - isSigningEnabled={false} + isSigningEnabled={true} isSwapsChain={false} ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) isBridgeChain={false} diff --git a/ui/components/app/wallet-overview/coin-buttons.tsx b/ui/components/app/wallet-overview/coin-buttons.tsx index 63bcdd2f58e6..bac7872c79e3 100644 --- a/ui/components/app/wallet-overview/coin-buttons.tsx +++ b/ui/components/app/wallet-overview/coin-buttons.tsx @@ -1,4 +1,11 @@ -import React, { useCallback, useContext, useState } from 'react'; +import React, { + useCallback, + useContext, + useState, + ///: BEGIN:ONLY_INCLUDE_IF(build-flask) + useEffect, + ///: END:ONLY_INCLUDE_IF +} from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { useHistory, @@ -16,6 +23,9 @@ import { CaipChainId, } from '@metamask/utils'; +///: BEGIN:ONLY_INCLUDE_IF(build-flask) +import { BtcAccountType } from '@metamask/keyring-api'; +///: END:ONLY_INCLUDE_IF ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) import { ChainId } from '../../../../shared/constants/network'; ///: END:ONLY_INCLUDE_IF @@ -27,6 +37,9 @@ import { ///: END:ONLY_INCLUDE_IF import { I18nContext } from '../../../contexts/i18n'; import { + ///: BEGIN:ONLY_INCLUDE_IF(build-flask) + CONFIRMATION_V_NEXT_ROUTE, + ///: END:ONLY_INCLUDE_IF ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) PREPARE_SWAP_ROUTE, ///: END:ONLY_INCLUDE_IF @@ -39,6 +52,9 @@ import { ///: END:ONLY_INCLUDE_IF getUseExternalServices, getSelectedAccount, + ///: BEGIN:ONLY_INCLUDE_IF(build-flask) + getMemoizedUnapprovedTemplatedConfirmations, + ///: END:ONLY_INCLUDE_IF } from '../../../selectors'; import Tooltip from '../../ui/tooltip'; ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) @@ -67,6 +83,13 @@ import useRamps from '../../../hooks/ramps/useRamps/useRamps'; import useBridging from '../../../hooks/bridge/useBridging'; ///: END:ONLY_INCLUDE_IF import { ReceiveModal } from '../../multichain/receive-modal'; +///: BEGIN:ONLY_INCLUDE_IF(build-flask) +import { + sendMultichainTransaction, + setDefaultHomeActiveTabName, +} from '../../../store/actions'; +import { BITCOIN_WALLET_SNAP_ID } from '../../../../shared/lib/accounts/bitcoin-wallet-snap'; +///: END:ONLY_INCLUDE_IF const CoinButtons = ({ chainId, @@ -99,7 +122,8 @@ const CoinButtons = ({ const trackEvent = useContext(MetaMetricsContext); const [showReceiveModal, setShowReceiveModal] = useState(false); - const { address: selectedAddress } = useSelector(getSelectedAccount); + const account = useSelector(getSelectedAccount); + const { address: selectedAddress } = account; const history = useHistory(); ///: BEGIN:ONLY_INCLUDE_IF(build-main,build-beta,build-flask) const location = useLocation(); @@ -230,23 +254,61 @@ const CoinButtons = ({ const { openBridgeExperience } = useBridging(); ///: END:ONLY_INCLUDE_IF - const handleSendOnClick = useCallback(async () => { - trackEvent( - { - event: MetaMetricsEventName.NavSendButtonClicked, - category: MetaMetricsEventCategory.Navigation, - properties: { - token_symbol: 'ETH', - location: 'Home', - text: 'Send', - chain_id: chainId, - }, + ///: BEGIN:ONLY_INCLUDE_IF(build-flask) + const unapprovedTemplatedConfirmations = useSelector( + getMemoizedUnapprovedTemplatedConfirmations, + ); + + useEffect(() => { + const templatedSnapApproval = unapprovedTemplatedConfirmations.find( + (approval) => { + return ( + approval.type === 'snap_dialog' && + approval.origin === BITCOIN_WALLET_SNAP_ID + ); }, - { excludeMetaMetricsId: false }, ); - await dispatch(startNewDraftTransaction({ type: AssetType.native })); - history.push(SEND_ROUTE); - }, [chainId]); + + if (templatedSnapApproval) { + history.push(`${CONFIRMATION_V_NEXT_ROUTE}/${templatedSnapApproval.id}`); + } + }, [unapprovedTemplatedConfirmations, history]); + ///: END:ONLY_INCLUDE_IF + + const handleSendOnClick = useCallback(async () => { + switch (account.type) { + ///: BEGIN:ONLY_INCLUDE_IF(build-flask) + case BtcAccountType.P2wpkh: { + await sendMultichainTransaction( + BITCOIN_WALLET_SNAP_ID, + account.id, + chainId as CaipChainId, + ); + + // We automatically switch to the activity tab once the transaction has been sent. + dispatch(setDefaultHomeActiveTabName('activity')); + break; + } + ///: END:ONLY_INCLUDE_IF + default: { + trackEvent( + { + event: MetaMetricsEventName.NavSendButtonClicked, + category: MetaMetricsEventCategory.Navigation, + properties: { + token_symbol: 'ETH', + location: 'Home', + text: 'Send', + chain_id: chainId, + }, + }, + { excludeMetaMetricsId: false }, + ); + await dispatch(startNewDraftTransaction({ type: AssetType.native })); + history.push(SEND_ROUTE); + } + } + }, [chainId, account]); const handleSwapOnClick = useCallback(async () => { ///: BEGIN:ONLY_INCLUDE_IF(build-mmi) diff --git a/ui/store/actions.ts b/ui/store/actions.ts index a81dabb5e5c6..f7d839946635 100644 --- a/ui/store/actions.ts +++ b/ui/store/actions.ts @@ -43,6 +43,7 @@ import { InterfaceState } from '@metamask/snaps-sdk'; import { KeyringTypes } from '@metamask/keyring-controller'; import type { NotificationServicesController } from '@metamask/notification-services-controller'; import { Patch } from 'immer'; +import { HandlerType } from '@metamask/snaps-utils'; import switchDirection from '../../shared/lib/switch-direction'; import { ENVIRONMENT_TYPE_NOTIFICATION, @@ -5841,3 +5842,22 @@ function applyPatches( return newState; } + +export async function sendMultichainTransaction( + snapId: string, + account: string, + scope: string, +) { + await handleSnapRequest({ + snapId, + origin: 'metamask', + handler: HandlerType.OnRpcRequest, + request: { + method: 'startSendTransactionFlow', + params: { + account, + scope, + }, + }, + }); +} diff --git a/yarn.lock b/yarn.lock index 52894233bfab..af059f8960e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4982,10 +4982,10 @@ __metadata: languageName: node linkType: hard -"@metamask/bitcoin-wallet-snap@npm:^0.7.0": - version: 0.7.0 - resolution: "@metamask/bitcoin-wallet-snap@npm:0.7.0" - checksum: 10/be4eceef1715c5e6d33d095d5b4aaa974656d945ff0ed0304fdc1244eb8940eb8978f304378367642aa8fd60d6b375eecc2a4653c38ba62ec306c03955c96682 +"@metamask/bitcoin-wallet-snap@npm:^0.8.1": + version: 0.8.1 + resolution: "@metamask/bitcoin-wallet-snap@npm:0.8.1" + checksum: 10/0fff706a98c6f798ae0ae78bf9a8913c0b056b18aff64f994e521c5005ab7e326fafe1d383b2b7c248456948eaa263df3b31a081d620d82ed7c266857c94a955 languageName: node linkType: hard @@ -26098,7 +26098,7 @@ __metadata: "@metamask/assets-controllers": "patch:@metamask/assets-controllers@npm%3A38.3.0#~/.yarn/patches/@metamask-assets-controllers-npm-38.3.0-57b3d695bb.patch" "@metamask/auto-changelog": "npm:^2.1.0" "@metamask/base-controller": "npm:^7.0.0" - "@metamask/bitcoin-wallet-snap": "npm:^0.7.0" + "@metamask/bitcoin-wallet-snap": "npm:^0.8.1" "@metamask/browser-passworder": "npm:^4.3.0" "@metamask/build-utils": "npm:^3.0.0" "@metamask/contract-metadata": "npm:^2.5.0"