-
Notifications
You must be signed in to change notification settings - Fork 66
/
Copy pathindex.js
134 lines (119 loc) · 4.35 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import "regenerator-runtime/runtime";
import { ethers } from "ethers";
import { parseUnits, hexlify } from "ethers/lib/utils";
let provider;
let signer;
document.addEventListener("DOMContentLoaded", loadApp());
async function loadApp() {
provider = new ethers.providers.Web3Provider(window.ethereum, "any");
signer = provider.getSigner();
if (!signer) window.location.reload();
await provider.send("eth_requestAccounts", []);
processAction();
}
function processAction() {
const urlParams = new URLSearchParams(window.location.search);
const action = urlParams.get("action");
const chainId = urlParams.get("chainId") || 1;
const to = urlParams.get("to");
const value = urlParams.get("value");
const data = urlParams.get("data") || "";
const gasLimit = urlParams.get("gasLimit") || undefined;
const gasPrice = urlParams.get("gasPrice") || undefined;
// Signatures
const message = urlParams.get("message");
// EIP712
const domain = urlParams.get("domain") || undefined;
const types = urlParams.get("types") || undefined;
if (action === "sign" && message) {
return signMessage(message);
}
if (action === "sign-typed-data" && domain && types && message) {
return signTypedMessage(types, domain, message);
}
if (action === "send" && to && value) {
return sendTransaction(chainId, to, value, gasLimit, gasPrice, data);
}
displayResponse("Invalid URL");
}
async function sendTransaction(chainId, to, value, gasLimit, gasPrice, data) {
try {
await new Promise((resolve) => setTimeout(resolve, 1000));
const network = await provider.getNetwork();
if (network.chainId !== chainId) {
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [{ chainId: `0x${parseInt(chainId, 10).toString(16)}` }], // chainId must be in hexadecimal numbers
});
}
const from = await signer.getAddress();
const tx = await signer.sendTransaction({
from,
to,
value: parseUnits(value, "wei"),
gasLimit: gasLimit ? hexlify(Number(gasLimit)) : gasLimit,
gasPrice: gasPrice ? hexlify(Number(gasPrice)) : gasPrice,
data: data ? data : "0x",
});
console.log({ tx });
displayResponse("Transaction sent.<br><br>Copy to clipboard then continue to App", tx.hash);
} catch (error) {
copyToClipboard("error");
displayResponse("Transaction Denied");
}
}
async function signMessage(message) {
try {
await new Promise((resolve) => setTimeout(resolve, 1000));
const signature = await signer.signMessage(message);
console.log({ signature });
displayResponse("Signature complete.<br><br>Copy to clipboard then continue to App", signature);
} catch (error) {
copyToClipboard("error");
displayResponse("Signature Denied");
}
}
async function signTypedMessage(types, domain, message) {
try {
await new Promise((resolve) => setTimeout(resolve, 1000));
const signature = await signer._signTypedData(JSON.parse(domain), JSON.parse(types), JSON.parse(message))
console.log({ signature });
displayResponse("Signature complete.<br><br>Copy to clipboard then continue to App", signature);
} catch (error) {
copyToClipboard("error");
displayResponse("Signature Denied");
}
}
async function copyToClipboard(response) {
try {
// focus from metamask back to browser
window.focus();
// wait to finish focus
await new Promise((resolve) => setTimeout(resolve, 500));
// copy tx hash to clipboard
await navigator.clipboard.writeText(response);
document.getElementById("response-button").innerHTML = "Copied";
} catch {
// for metamask mobile android
const input = document.createElement("input");
input.type = "text";
input.value = response;
document.body.appendChild(input);
input.select();
document.execCommand("Copy");
input.style = "visibility: hidden";
document.getElementById("response-button").innerHTML = "Copied";
}
}
function displayResponse(text, response) {
// display error or response
const responseText = document.getElementById("response-text");
responseText.innerHTML = text;
responseText.className = "active";
if (response) {
// display button to copy tx.hash or signature
const responseButton = document.getElementById("response-button");
responseButton.className = "active";
responseButton.onclick = () => copyToClipboard(response);
}
}