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