on master help sign in
bridge/src/lib/metamask.ts
79 lines 2.6 kB history raw
1import { FeeMarketEIP1559Transaction as EIP1559Transaction } from '@ethereumjs/tx';
2import Web3 from 'web3';
3import { FakeSignableTx, FakeSignResult } from './txn';
5export class MetamaskWallet {
6 address: string;
8 constructor(address: string) {
9 this.address = address;
10 }
13// Cheat a bit and pretend to sign transaction
14// Sign it actually when sending
15export const metamaskSignTransaction = async (txn: EIP1559Transaction) => {
16 return FakeSignResult(txn, metamaskSendTransaction);
17};
19const metamaskSendTransaction = async (txn: FakeSignableTx, web3: Web3) => {
20 /**
21 * Depending which version of Metamask is installed, there are different
22 * approaches to get the `from` address.
23 */
24 let from = null;
25 if (window.ethereum) {
26 from = window.ethereum.selectedAddress;
27 if (!from) {
28 const accounts = await window.ethereum.request({
29 method: 'eth_requestAccounts',
30 });
31 from = accounts[0] ?? null;
32 }
33 } else if (window.web3) {
34 from = window.web3?.eth?.defaultAccount ?? null;
35 } else {
36 const accounts = await web3.eth.getAccounts();
37 from = accounts[0] ?? null;
38 }
40 if (!from) {
41 throw new Error('No accounts connected');
42 }
44 const { data, to, value, maxPriorityFeePerGas, maxFeePerGas } = txn.toJSON();
45 if (!(data && to && value && maxPriorityFeePerGas && maxFeePerGas && from)) {
46 throw new Error('Unable to send Metamask TX, something is missing');
47 }
49 // https://docs.metamask.io/guide/sending-transactions.html#transaction-parameters
50 // https://github.com/brave/brave-wallet-docs/blob/b19d8884035b00fb21b7ea7628199fea17d5c6ee/docs/ethereum/use-cases/sending-transactions.md
51 const metamaskFormattedTxn = {
52 from,
53 to,
54 value,
55 data,
56 maxPriorityFeePerGas,
57 maxFeePerGas,
58 };
60 let txHash;
61 if (window.ethereum) {
62 //NOTE see also #596, #630, #646
63 // no idea what's going on, we should figure it out,
64 // but we apply this bandaid to hopefully stop the bleeding.
65 // at least it also helps with the NOTE of the other branch.
66 txHash = await window.ethereum.request({
67 method: 'eth_sendTransaction',
68 params: [metamaskFormattedTxn],
69 });
70 } else {
71 //NOTE since this gives us a receipt instead of just the hash of the
72 // signed tx, it makes us wait for confirmation outside of our own
73 // waitForTransactionConfirm. because of this the progress bar loses
74 // its progressiveness for metamask users.
75 let receipt = await web3.eth.sendTransaction(metamaskFormattedTxn);
76 txHash = receipt.transactionHash;
77 }
78 return txHash;
79};