Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add BTC send flow #27964

Merged
merged 1 commit into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 0 additions & 1 deletion shared/lib/accounts/bitcoin-wallet-snap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion test/e2e/flask/btc/btc-account-overview.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down
9 changes: 2 additions & 7 deletions ui/components/app/wallet-overview/btc-overview.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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(<BtcOverview />, 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();
Expand Down
2 changes: 1 addition & 1 deletion ui/components/app/wallet-overview/btc-overview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down
96 changes: 79 additions & 17 deletions ui/components/app/wallet-overview/coin-buttons.tsx
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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,
danroc marked this conversation as resolved.
Show resolved Hide resolved
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)
Expand Down
20 changes: 20 additions & 0 deletions ui/store/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
},
},
});
}
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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"
Expand Down
Loading