on 2268655 help sign in
bridge/src/lib/authToken.ts
111 lines 3.2 kB history raw
1import { crypto } from 'bitcoinjs-lib';
2import { ecdsaSign } from 'secp256k1';
3import Web3 from 'web3';
4import { hexToBytes } from 'web3-utils';
5import WalletConnect from '@walletconnect/client';
7import { WALLET_TYPES } from './constants';
8import BridgeWallet from './types/BridgeWallet';
9import { Hash } from '@urbit/roller-api';
10import { keccak256 } from 'ethereumjs-util';
12const MESSAGE = 'Bridge Authentication Token';
14function signMessage(privateKey: Buffer, useLegacyTokenSigning = false) {
15 const msg = '\x19Ethereum Signed Message:\n' + MESSAGE.length + MESSAGE;
16 const hashed = useLegacyTokenSigning
17 ? crypto.sha256(Buffer.from(msg))
18 : keccak256(Buffer.from(msg));
19 const { signature } = ecdsaSign(Buffer.from(hashed), privateKey);
21 // add key recovery parameter
22 const ethSignature = new Uint8Array(65);
23 ethSignature.set(signature);
24 const v = (ethSignature[32] & 1) + 27;
25 ethSignature[64] = v;
27 return ethSignature;
30export function signTransactionHash(msg: Hash, prvKey: Buffer) {
31 // msg is a keccak-256 hash
32 //
33 const hashed = Buffer.from(hexToBytes(msg));
34 const { signature, recid } = ecdsaSign(hashed, prvKey);
35 // add key recovery parameter
36 const ethSignature = new Uint8Array(65);
37 ethSignature.set(signature);
38 ethSignature[64] = recid;
39 return `0x${Buffer.from(ethSignature).toString('hex')}`;
42type MetamaskAuthTokenArgs = {
43 address: string;
44 web3: Web3;
45 walletType: symbol;
46};
48type WalletConnectAuthTokenArgs = {
49 address: string;
50 connector: WalletConnect;
51 walletType: symbol;
52};
54type DefaultAuthTokenArgs = {
55 wallet: BridgeWallet;
56 walletType?: symbol;
57 useLegacyTokenSigning?: boolean;
58};
60type GetAuthTokenArgs =
61 | MetamaskAuthTokenArgs
62 | WalletConnectAuthTokenArgs
63 | DefaultAuthTokenArgs;
65const getMetamaskAuthToken = ({ address, web3 }: MetamaskAuthTokenArgs) => {
66 if (window.ethereum) {
67 //NOTE this doesn't _seem_ to be affected by #596,
68 // but web3.eth.personal.sign hits it semi-reliably?
69 // no idea what's going on, we should figure it out,
70 // but we apply this bandaid to hopefully stop the bleeding.
71 return window.ethereum.request({
72 method: 'personal_sign',
73 params: [MESSAGE, address],
74 from: address,
75 });
76 } else {
77 return web3.eth.personal.sign(MESSAGE, address, '');
78 }
79};
81const getWalletConnectAuthToken = ({
82 address,
83 connector,
84}: WalletConnectAuthTokenArgs) => {
85 return connector.signPersonalMessage([MESSAGE, address]);
86};
88const getDefaultAuthToken = ({
89 wallet,
90 useLegacyTokenSigning = false,
91}: DefaultAuthTokenArgs) => {
92 const signature = signMessage(wallet.privateKey!, useLegacyTokenSigning);
94 const token = `0x${Buffer.from(signature).toString('hex')}`;
96 return token;
97};
99export const getAuthToken = async ({
100 walletType,
101 ...args
102}: GetAuthTokenArgs) => {
103 switch (walletType) {
104 case WALLET_TYPES.METAMASK:
105 return getMetamaskAuthToken(args as MetamaskAuthTokenArgs);
106 case WALLET_TYPES.WALLET_CONNECT:
107 return getWalletConnectAuthToken(args as WalletConnectAuthTokenArgs);
108 default:
109 return getDefaultAuthToken(args as DefaultAuthTokenArgs);
110 }
111};