-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex2.js
186 lines (153 loc) · 10.4 KB
/
index2.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
const BigNumber = require('bignumber.js');
const qs = require('qs');
const web3 = require('web3');
let currentTrade = {};
let currentSelectSide;
let tokens;
async function init() {
await listAvailableTokens();
}
async function listAvailableTokens(){
console.log("initializing");
let response = await fetch('https://tokens.coingecko.com/uniswap/all.json');
let tokenListJSON = await response.json();
console.log("listing available tokens: ", tokenListJSON);
tokens = tokenListJSON.tokens;
console.log("tokens: ", tokens);
// Create token list for modal
let parent = document.getElementById("token_list");
for (const i in tokens){
// Token row in the modal token list
let div = document.createElement("div");
div.className = "token_row";
let html = `
<img class="token_list_img" src="${tokens[i].logoURI}">
<span class="token_list_text">${tokens[i].symbol}</span>
`;
div.innerHTML = html;
div.onclick = () => {
selectToken(tokens[i]);
};
parent.appendChild(div);
};
}
async function selectToken(token){
closeModal();
currentTrade[currentSelectSide] = token;
console.log("currentTrade: ", currentTrade);
renderInterface();
}
function renderInterface(){
if (currentTrade.from){
console.log(currentTrade.from)
document.getElementById("from_token_img").src = currentTrade.from.logoURI;
document.getElementById("from_token_text").innerHTML = currentTrade.from.symbol;
}
if (currentTrade.to){
console.log(currentTrade.to)
document.getElementById("to_token_img").src = currentTrade.to.logoURI;
document.getElementById("to_token_text").innerHTML = currentTrade.to.symbol;
}
}
async function connect() {
if (typeof window.ethereum !== "undefined") {
try {
console.log("connecting");
await ethereum.request({ method: "eth_requestAccounts" });
} catch (error) {
console.log(error);
}
document.getElementById("login_button").innerHTML = "Connected";
// const accounts = await ethereum.request({ method: "eth_accounts" });
document.getElementById("swap_button").disabled = false;
} else {
document.getElementById("login_button").innerHTML = "Please install MetaMask";
}
}
function openModal(side){
currentSelectSide = side;
document.getElementById("token_modal").style.display = "block";
}
function closeModal(){
document.getElementById("token_modal").style.display = "none";
}
async function getPrice(){
console.log("Getting Price");
if (!currentTrade.from || !currentTrade.to || !document.getElementById("from_amount").value) return;
let amount = Number(document.getElementById("from_amount").value * 10 ** currentTrade.from.decimals);
const params = {
sellToken: currentTrade.from.address,
buyToken: currentTrade.to.address,
sellAmount: amount,
}
const headers = { '0x-api-key': '4dcbdbe2-1152-4f52-b34e-346b76d8372d' };
// This is a placeholder. Get your live API key from the 0x Dashboard (https://dashboard.0x.org/apps)
// Fetch the swap price.
const response = await fetch(`https://api.0x.org/swap/v1/price?${qs.stringify(params)}`, { headers });
swapPriceJSON = await response.json();
console.log("Price: ", swapPriceJSON);
document.getElementById("to_amount").value = swapPriceJSON.buyAmount / (10 ** currentTrade.to.decimals);
document.getElementById("gas_estimate").innerHTML = swapPriceJSON.estimatedGas;
}
async function getQuote(account){
console.log("Getting Quote");
if (!currentTrade.from || !currentTrade.to || !document.getElementById("from_amount").value) return;
let amount = Number(document.getElementById("from_amount").value * 10 ** currentTrade.from.decimals);
const params = {
sellToken: currentTrade.from.address,
buyToken: currentTrade.to.address,
sellAmount: amount,
takerAddress: account,
}
const headers = { '0x-api-key': '4dcbdbe2-1152-4f52-b34e-346b76d8372d' };
// This is a placeholder. Get your live API key from the 0x Dashboard (https://dashboard.0x.org/apps)
// Fetch the swap quote.
const response = await fetch(`https://api.0x.org/swap/v1/quote?${qs.stringify(params)}`, { headers });
swapQuoteJSON = await response.json();
console.log("Quote: ", swapQuoteJSON);
document.getElementById("to_amount").value = swapQuoteJSON.buyAmount / (10 ** currentTrade.to.decimals);
document.getElementById("gas_estimate").innerHTML = swapQuoteJSON.estimatedGas;
return swapQuoteJSON;
}
async function trySwap(){
const erc20abi= [{ "inputs": [ { "internalType": "string", "name": "name", "type": "string" }, { "internalType": "string", "name": "symbol", "type": "string" }, { "internalType": "uint256", "name": "max_supply", "type": "uint256" } ], "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "approve", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "burn", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "burnFrom", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "decimals", "outputs": [ { "internalType": "uint8", "name": "", "type": "uint8" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } ], "name": "decreaseAllowance", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "addedValue", "type": "uint256" } ], "name": "increaseAllowance", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "name", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "symbol", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalSupply", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transfer", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }]
console.log("trying swap");
// Only work if MetaMask is connect
// Connecting to Ethereum: Metamask
const web3 = new Web3(Web3.givenProvider);
// The address, if any, of the most recently used account that the caller is permitted to access
let accounts = await ethereum.request({ method: "eth_accounts" });
let takerAddress = accounts[0];
console.log("takerAddress: ", takerAddress);
const swapQuoteJSON = await getQuote(takerAddress);
// Set Token Allowance
// Set up approval amount
const fromTokenAddress = currentTrade.from.address;
const maxApproval = new BigNumber(2).pow(256).minus(1);
console.log("approval amount: ", maxApproval);
const ERC20TokenContract = new web3.eth.Contract(erc20abi, fromTokenAddress);
console.log("setup ERC20TokenContract: ", ERC20TokenContract);
// Grant the allowance target an allowance to spend our tokens.
const tx = await ERC20TokenContract.methods.approve(
swapQuoteJSON.allowanceTarget,
maxApproval,
)
.send({ from: takerAddress })
.then(tx => {
console.log("tx: ", tx)
});
// Perform the swap
const receipt = await web3.eth.sendTransaction(swapQuoteJSON);
console.log("receipt: ", receipt);
}
init();
document.getElementById("login_button").onclick = connect;
document.getElementById("from_token_select").onclick = () => {
openModal("from");
};
document.getElementById("to_token_select").onclick = () => {
openModal("to");
};
document.getElementById("modal_close").onclick = closeModal;
document.getElementById("from_amount").onblur = getPrice;
document.getElementById("swap_button").onclick = trySwap;