mirror of
https://github.com/andrei0x309/clear-wallet.git
synced 2024-12-19 00:00:45 +00:00
dev: 1.0.2
This commit is contained in:
parent
9932a1a522
commit
610fdc6afb
1
.gitignore
vendored
1
.gitignore
vendored
@ -29,3 +29,4 @@ npm-debug.log*
|
||||
/platforms
|
||||
/plugins
|
||||
/www
|
||||
/src/extension/inject.js
|
||||
|
@ -4,7 +4,14 @@ const allowedMethods = {
|
||||
'eth_requestAccounts' : true,
|
||||
'eth_chainId': true,
|
||||
'personal_sign' : true,
|
||||
'wallet_requestPermissions': true
|
||||
'wallet_requestPermissions': true,
|
||||
'eth_gasPrice': true,
|
||||
'eth_getBlockByNumber': true,
|
||||
'eth_blockNumber': true,
|
||||
'eth_estimateGas': true,
|
||||
'eth_sign': true,
|
||||
'net_version': true,
|
||||
'eth_sendTransaction': true,
|
||||
}
|
||||
|
||||
window.addEventListener("message", (event) => {
|
||||
@ -13,19 +20,23 @@ window.addEventListener("message", (event) => {
|
||||
|
||||
if (event.data.type && (event.data.type == "CLWALLET_CONTENT")) {
|
||||
event.data.data.resId = event.data.resId
|
||||
console.log('data in', event?.data)
|
||||
if(event?.data?.data?.method ?? 'x' in allowedMethods)
|
||||
|
||||
if((event?.data?.data?.method ?? 'x') in allowedMethods) {
|
||||
chrome.runtime.sendMessage(event.data.data, (res) => {
|
||||
const data = { type: "CLWALLET_PAGE", data: res, resId: event.data.resId };
|
||||
console.log('data back', data)
|
||||
window.postMessage(data, "*");
|
||||
})
|
||||
} else {
|
||||
const data = { type: "CLWALLET_PAGE", data: { error: true, message: 'Unknown method requested'}, resId: event.data.resId };
|
||||
window.postMessage(data, "*");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
(function() {
|
||||
chrome.runtime.connect({
|
||||
name: 'content'
|
||||
})
|
||||
const script = document.createElement('script')
|
||||
script.src = chrome.runtime.getURL('src/extension/inject.js')
|
||||
document.documentElement.appendChild(script)
|
||||
|
@ -1,227 +0,0 @@
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var _this = this;
|
||||
var listners = {
|
||||
accountsChanged: new Set(),
|
||||
connect: new Set(),
|
||||
disconnect: new Set,
|
||||
chainChanged: new Set()
|
||||
};
|
||||
var promResolvers = {};
|
||||
var listner = function (event) {
|
||||
var _a, _b;
|
||||
if (event.source != window)
|
||||
return;
|
||||
if (event.data.type && (event.data.type == "CLWALLET_PAGE")) {
|
||||
if ((_b = (_a = event === null || event === void 0 ? void 0 : event.data) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) {
|
||||
promResolvers[event.data.resId].reject(event.data.data);
|
||||
}
|
||||
else {
|
||||
promResolvers[event.data.resId].resolve(event.data.data);
|
||||
}
|
||||
promResolvers[event.data.resId] = undefined;
|
||||
}
|
||||
};
|
||||
window.addEventListener("message", listner);
|
||||
var sendMessage = function (args) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
var resId = crypto.randomUUID();
|
||||
promResolvers[resId] = { resolve: resolve, reject: reject };
|
||||
var data = { type: "CLWALLET_CONTENT", data: args, resId: resId };
|
||||
window.postMessage(data, "*");
|
||||
});
|
||||
};
|
||||
// chainId
|
||||
// :
|
||||
// "0x89"
|
||||
// enable
|
||||
// :
|
||||
// ƒ ()
|
||||
// isMetaMask
|
||||
// :
|
||||
// true
|
||||
// networkVersion
|
||||
// :
|
||||
// "137"
|
||||
// request
|
||||
// :
|
||||
// ƒ ()
|
||||
// selectedAddress
|
||||
// :
|
||||
// null
|
||||
// send
|
||||
// :
|
||||
// ƒ ()
|
||||
// sendAsync
|
||||
// :
|
||||
// ƒ ()
|
||||
// _events
|
||||
// :
|
||||
// {connect: ƒ}
|
||||
// _eventsCount
|
||||
// :
|
||||
// 1
|
||||
// _handleAccountsChanged
|
||||
// :
|
||||
// ƒ ()
|
||||
// _handleChainChanged
|
||||
// :
|
||||
// ƒ ()
|
||||
// _handleConnect
|
||||
// :
|
||||
// ƒ ()
|
||||
// _handleDisconnect
|
||||
// :
|
||||
// ƒ ()
|
||||
// _handleStreamDisconnect
|
||||
// :
|
||||
// ƒ ()
|
||||
// _handleUnlockStateChanged
|
||||
// :
|
||||
// ƒ ()
|
||||
// _jsonRpcConnection
|
||||
// :
|
||||
// {events: s, stream: d, middleware: ƒ}
|
||||
// _log
|
||||
// :
|
||||
// u {name: undefined, levels: {…}, methodFactory: ƒ, getLevel: ƒ, setLevel: ƒ, …}
|
||||
// _maxListeners
|
||||
// :
|
||||
// 100
|
||||
// _metamask
|
||||
// :
|
||||
// Proxy {isUnlocked: ƒ, requestBatch: ƒ}
|
||||
// _rpcEngine
|
||||
// :
|
||||
// o {_events: {…}, _eventsCount: 0, _maxListeners: undefined, _middleware: Array(3)}
|
||||
// _rpcRequest
|
||||
// :
|
||||
// ƒ ()
|
||||
// _sendSync
|
||||
// :
|
||||
// ƒ ()
|
||||
// _sentWarnings
|
||||
// :
|
||||
// {enable: false, experimentalMethods: false, send: false, events: {…}}
|
||||
// _state
|
||||
// :
|
||||
// {accounts: Array(0), isConnected: true, isUnlocked: true, initialized: true, isPermanentlyDisconnected: false}
|
||||
// _warnOfDeprecation
|
||||
// :
|
||||
// ƒ (
|
||||
var eth = new Proxy({
|
||||
isConnected: function () {
|
||||
return true;
|
||||
},
|
||||
// for maximum compatibility since is cloning the same API
|
||||
isMetaMask: true,
|
||||
enable: function () {
|
||||
return sendMessage({ method: 'eth_requestAccounts', params: Array(0) });
|
||||
},
|
||||
request: function (args) {
|
||||
return sendMessage(args);
|
||||
},
|
||||
on: function (eventName, callback) {
|
||||
switch (eventName) {
|
||||
case 'accountsChanged':
|
||||
listners.accountsChanged.add(callback);
|
||||
break;
|
||||
case 'connect':
|
||||
listners.connect.add(callback);
|
||||
break;
|
||||
case 'disconnect':
|
||||
listners.disconnect.add(callback);
|
||||
break;
|
||||
case 'chainChanged':
|
||||
listners.chainChanged.add(callback);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
},
|
||||
// Simulate Metamask
|
||||
_warnOfDeprecation: function () { return null; },
|
||||
_state: {},
|
||||
_sentWarnings: function () { return null; },
|
||||
_rpcRequest: function () { return null; },
|
||||
_handleAccountsChanged: function () { return null; },
|
||||
chainId: "0x89",
|
||||
networkVersion: "137",
|
||||
selectedAddress: null,
|
||||
send: function () { return null; },
|
||||
sendAsync: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
||||
return [2 /*return*/, null];
|
||||
}); }); },
|
||||
_events: {},
|
||||
_eventsCount: 0,
|
||||
_handleChainChanged: function () { return null; },
|
||||
_handleConnect: function () { return null; },
|
||||
_handleDisconnect: function () { return null; },
|
||||
_handleStreamDisconnect: function () { return null; },
|
||||
_handleUnlockStateChanged: function () { return null; },
|
||||
_jsonRpcConnection: {},
|
||||
_log: {},
|
||||
_maxListeners: 100,
|
||||
_metamask: new Proxy({}, {}),
|
||||
_rpcEngine: {}
|
||||
}, {
|
||||
set: function () { return false; },
|
||||
deleteProperty: function () { return false; }
|
||||
});
|
||||
var injectWallet = function (win) {
|
||||
Object.defineProperty(win, 'ethereum', {
|
||||
get: function () {
|
||||
return eth;
|
||||
},
|
||||
set: function () {
|
||||
return;
|
||||
}
|
||||
});
|
||||
window.tttest = 'test';
|
||||
// Object.defineProperty(window, 'ethereum', 444)
|
||||
console.log('Clear wallet injected', window.ethereum, win);
|
||||
};
|
||||
injectWallet(this);
|
||||
// setTimeout(() => {
|
||||
// console.log('Metamask clone test');
|
||||
// // (<any>window).ethereum.request({method: 'eth_requestAccounts', params: Array(0)}).then((res: any) => { console.log(res, '111111111')});
|
||||
// // (<any>window).ethereum.request({method: 'eth_accounts', params: Array(0)}).then((res: any) => { console.log(res, '111111111')});
|
||||
// // (<any>window).ethereum.request({method: 'eth_chainId', params: Array(0)}).then((res: any) => { console.log(res, '111111111')});
|
||||
// // (<any>window).ethereum.request({method: 'wallet_requestPermissions', params: [{eth_accounts: {}}]}).then((res: any) => { console.log(res, '111111111')});
|
||||
// // (<any>window).ethereum.request({method: 'net_version', params: []}).then((res: any) => { console.log(res, '111111111')});
|
||||
// }, 3500)
|
||||
// console.log( (window as any).ethereum.request({method: 'eth_chainId'}))
|
@ -4,10 +4,10 @@ interface RequestArguments {
|
||||
}
|
||||
|
||||
const listners = {
|
||||
accountsChanged: new Set<() => void>(),
|
||||
connect: new Set<() => void>(),
|
||||
disconnect: new Set<() => void>,
|
||||
chainChanged: new Set<() => void>(),
|
||||
accountsChanged: new Set<(p?: any) => void>(),
|
||||
connect: new Set<(p?: any) => void>(),
|
||||
disconnect: new Set<(p?: any) => void>,
|
||||
chainChanged: new Set<(p?: any) => void>(),
|
||||
}
|
||||
|
||||
const promResolvers = {} as any
|
||||
@ -15,14 +15,23 @@ const promResolvers = {} as any
|
||||
const listner = function(event: any) {
|
||||
if (event.source != window)
|
||||
return;
|
||||
|
||||
if (event.data.type && (event.data.type == "CLWALLET_PAGE")) {
|
||||
if (event.data.type && (event.data.type === "CLWALLET_PAGE")) {
|
||||
if(event?.data?.data?.error){
|
||||
promResolvers[event.data.resId].reject(event.data.data)
|
||||
promResolvers[event.data.resId].reject(event.data.data);
|
||||
console.log('rejected')
|
||||
}else {
|
||||
promResolvers[event.data.resId].resolve(event.data.data);
|
||||
}
|
||||
promResolvers[event.data.resId] = undefined;
|
||||
} else if( event.data.type && (event.data.type === "CLWALLET_PAGE_LISTENER")) {
|
||||
if((event?.data?.data?.listner ?? 'x') in listners ) {
|
||||
try {
|
||||
const listnerName = event?.data?.data?.listner as ('accountsChanged' | 'connect' | 'disconnect' | 'chainChanged')
|
||||
listners[listnerName].forEach(listner => listner(event?.data?.data?.data));
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,9 +196,7 @@ const injectWallet = (win: any) => {
|
||||
return
|
||||
}
|
||||
});
|
||||
(window as any).tttest = 'test'
|
||||
// Object.defineProperty(window, 'ethereum', 444)
|
||||
console.log('Clear wallet injected', (window as any).ethereum, win)
|
||||
console.log('Clear wallet injected', (window as any).ethereum, win)
|
||||
}
|
||||
injectWallet(this)
|
||||
|
||||
@ -202,7 +209,7 @@ injectWallet(this)
|
||||
// // (<any>window).ethereum.request({method: 'eth_chainId', params: Array(0)}).then((res: any) => { console.log(res, '111111111')});
|
||||
// // (<any>window).ethereum.request({method: 'wallet_requestPermissions', params: [{eth_accounts: {}}]}).then((res: any) => { console.log(res, '111111111')});
|
||||
// // (<any>window).ethereum.request({method: 'net_version', params: []}).then((res: any) => { console.log(res, '111111111')});
|
||||
|
||||
// // (<any>window).ethereum.request({method: 'wallet_switchEthereumChain', params: [{chainId: "0x99"}]}).then((res: any) => { console.log(res, '111111111')});
|
||||
// }, 3500)
|
||||
|
||||
// console.log( (window as any).ethereum.request({method: 'eth_chainId'}))
|
@ -23,6 +23,7 @@
|
||||
"scripting",
|
||||
"webNavigation",
|
||||
"tabs",
|
||||
"notifications",
|
||||
"storage",
|
||||
"alarms",
|
||||
"unlimitedStorage",
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { getAccounts, getSelectedAccount, getSelectedNetwork, smallRandomString, storageSave} from '@/utils/platform';
|
||||
import { getAccounts, getSelectedAccount, getSelectedNetwork, smallRandomString, getSettings, clearPk, openTab } from '@/utils/platform';
|
||||
import { userApprove, userReject, rIdWin, rIdData } from '@/extension/userRequest'
|
||||
import { signMsg, getBalance, getBlockNumber, estimateGas, sendTransaction, getGasPrice } from '@/utils/wallet'
|
||||
import { signMsg, getBalance, getBlockNumber, estimateGas, sendTransaction, getGasPrice, getBlockByNumber } from '@/utils/wallet'
|
||||
import type { RequestArguments } from '@/extension/types'
|
||||
import type { Account } from '@/extension/types'
|
||||
import { rpcError } from '@/extension/rpcConstants'
|
||||
import { updatePrices } from '@/utils/gecko'
|
||||
|
||||
let notificationUrl: string
|
||||
|
||||
chrome.runtime.onInstalled.addListener(() => {
|
||||
console.log('Service worker installed');
|
||||
chrome.runtime.connect(null as unknown as string, {
|
||||
@ -13,9 +15,9 @@ chrome.runtime.onInstalled.addListener(() => {
|
||||
})
|
||||
})
|
||||
|
||||
chrome.runtime.onConnect.addListener(port => port.onDisconnect.addListener((a) =>
|
||||
chrome.runtime.onConnect.addListener(port => port.onDisconnect.addListener(() =>
|
||||
{
|
||||
console.log('Service worker connected', storageSave('test-d', a));
|
||||
console.log('Service worker connected');
|
||||
}))
|
||||
|
||||
|
||||
@ -40,7 +42,7 @@ chrome.alarms.onAlarm.addListener((alarm) => {
|
||||
}
|
||||
})
|
||||
|
||||
chrome.windows.onRemoved.addListener((winId) => {
|
||||
chrome.windows.onRemoved.addListener(async (winId) => {
|
||||
if (winId in (userReject ?? {})){
|
||||
userReject[winId]?.()
|
||||
}
|
||||
@ -48,13 +50,29 @@ chrome.windows.onRemoved.addListener((winId) => {
|
||||
userApprove[winId] = undefined
|
||||
rIdWin[winId] = undefined
|
||||
rIdData[winId] = undefined
|
||||
chrome.windows.getAll().then((wins) => {
|
||||
const wins = await chrome.windows.getAll()
|
||||
if(wins.length === 0) {
|
||||
storageSave('test-p', 'browser-closed')
|
||||
const s = await getSettings()
|
||||
if(s.enableStorageEnctyption) {
|
||||
await clearPk()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const viewTxListner = async (id: string) => {
|
||||
try {
|
||||
const url = new URL(notificationUrl)
|
||||
openTab(url.href)
|
||||
chrome.notifications.clear(id)
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
if (!chrome.notifications.onButtonClicked.hasListener(viewTxListner)){
|
||||
chrome.notifications.onButtonClicked.addListener(viewTxListner)
|
||||
}
|
||||
|
||||
chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendResponse) => {
|
||||
console.log(message);
|
||||
(async () => {
|
||||
@ -69,6 +87,15 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||
case 'eth_call': {
|
||||
break
|
||||
}
|
||||
case 'eth_getBlockByNumber': {
|
||||
const params = message?.params?.[0] as any
|
||||
sendResponse(await getBlockByNumber(params))
|
||||
break;
|
||||
}
|
||||
case 'eth_gasPrice': {
|
||||
sendResponse(await getGasPrice())
|
||||
break;
|
||||
}
|
||||
case 'eth_getBalance': {
|
||||
sendResponse(await getBalance())
|
||||
break
|
||||
@ -153,11 +180,45 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||
})
|
||||
|
||||
})
|
||||
sendResponse(
|
||||
await sendTransaction({...params, ...(rIdData?.[String(gWin?.id ?? 0)] ?? {}) }, pEstimateGas, pGasPrice)
|
||||
)
|
||||
try {
|
||||
const tx = await sendTransaction({...params, ...(rIdData?.[String(gWin?.id ?? 0)] ?? {}) }, pEstimateGas, pGasPrice)
|
||||
sendResponse(tx)
|
||||
const buttons = {} as any
|
||||
const network = await getSelectedNetwork()
|
||||
const notificationId = crypto.randomUUID()
|
||||
if(network?.explorer) {
|
||||
notificationUrl = `${network.explorer}/tx/${tx.hash}`.replace('//', '/')
|
||||
buttons.buttons = [{
|
||||
title: 'View Transaction',
|
||||
}]
|
||||
setTimeout(() => {
|
||||
try {
|
||||
chrome.notifications.clear(notificationId)
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}, 6e4)
|
||||
}
|
||||
chrome.notifications.create({
|
||||
notificationId,
|
||||
message: 'Transaction Confirmed',
|
||||
title: 'Success',
|
||||
...(buttons)
|
||||
} as any)
|
||||
|
||||
} catch {
|
||||
sendResponse({
|
||||
error: true,
|
||||
code: rpcError.USER_REJECTED,
|
||||
message: 'TX Failed'
|
||||
})
|
||||
chrome.notifications.create({
|
||||
message: 'Transaction Failed',
|
||||
title: 'Error',
|
||||
} as any)
|
||||
}
|
||||
} catch(err) {
|
||||
console.error(err)
|
||||
// console.error(err)
|
||||
sendResponse({
|
||||
error: true,
|
||||
code: rpcError.USER_REJECTED,
|
||||
@ -223,7 +284,7 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||
chrome.windows.create({
|
||||
height: 450,
|
||||
width: 400,
|
||||
url: chrome.runtime.getURL(`index.html?route=switch-network¶m=${String(message?.params?.[0] ?? '' )}&rid=${String(message?.resId ?? '')}`),
|
||||
url: chrome.runtime.getURL(`index.html?route=switch-network¶m=${String(message?.params?.[0]?.chainId ?? '' )}&rid=${String(message?.resId ?? '')}`),
|
||||
type: 'popup'
|
||||
}).then((win) => {
|
||||
userReject[String(win.id)] = reject
|
||||
@ -232,9 +293,7 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||
})
|
||||
|
||||
})
|
||||
sendResponse(
|
||||
await signMsg(String(message?.params?.[0]) ?? '' )
|
||||
)
|
||||
sendResponse(null)
|
||||
} catch {
|
||||
sendResponse({
|
||||
error: true,
|
||||
|
@ -25,7 +25,7 @@ export interface Networks {
|
||||
|
||||
export interface RequestArguments {
|
||||
method: string;
|
||||
params?: unknown[];
|
||||
params?: any[];
|
||||
resId?: string
|
||||
}
|
||||
|
||||
@ -49,5 +49,5 @@ export interface Settings {
|
||||
lockOutPeriod: number
|
||||
lockOutEnabled: boolean
|
||||
theme: 'system' | 'light' | 'dark'
|
||||
MP: string
|
||||
lastLock: number
|
||||
}
|
@ -59,6 +59,10 @@ const routes: Array<RouteRecordRaw> = [
|
||||
path: 'add-network',
|
||||
component: () => import('@/views/AddNetwork.vue'),
|
||||
},
|
||||
{
|
||||
path: 'add-network/edit/:chainId',
|
||||
component: () => import('@/views/AddNetwork.vue'),
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
@ -59,8 +59,8 @@ export const mainNets: {[key: number]: Network} = {
|
||||
}
|
||||
|
||||
export const testNets = {
|
||||
1: {
|
||||
name: 'TESTNET Ethereum oerli',
|
||||
5: {
|
||||
name: 'TESTNET Ethereum Goerli',
|
||||
rpc: 'https://rpc.ankr.com/eth_goerli',
|
||||
chainId: 5,
|
||||
explorer: 'https://goerli.etherscan.io',
|
||||
@ -69,8 +69,8 @@ export const testNets = {
|
||||
4: {
|
||||
name: 'TESTNET Ethereum Rinkeby',
|
||||
rpc: 'https://rpc.ankr.com/eth_rinkeby',
|
||||
chainId: 5,
|
||||
explorer: 'https://goerli.etherscan.io',
|
||||
chainId: 4,
|
||||
explorer: 'https://rinkeby.etherscan.io',
|
||||
icon: 'eth.webp'
|
||||
},
|
||||
80001: {
|
||||
|
@ -75,7 +75,7 @@ export const setPrices = async (prices: Prices): Promise<void> => {
|
||||
await storageSave('prices', prices )
|
||||
}
|
||||
|
||||
export const getPrices = async (): Promise<void> => {
|
||||
export const getPrices = async (): Promise<Prices> => {
|
||||
return (await storageGet('prices'))?.prices ?? {} as unknown as Prices
|
||||
}
|
||||
|
||||
@ -108,6 +108,15 @@ export const smallRandomString = () => {
|
||||
return (Math.random() + 1).toString(36).substring(7);
|
||||
}
|
||||
|
||||
export const clearPk = async (): Promise<void> => {
|
||||
let accounts = await getAccounts()
|
||||
const accProm = accounts.map(async a => {
|
||||
return a
|
||||
})
|
||||
accounts = await Promise.all(accProm)
|
||||
await replaceAccounts(accounts)
|
||||
}
|
||||
|
||||
export const hexTostr = (hexStr: string) =>
|
||||
{
|
||||
if(hexStr.substring(0,2) === '0x') {
|
||||
@ -124,6 +133,8 @@ export const hexTostr = (hexStr: string) =>
|
||||
return hexStr
|
||||
}
|
||||
|
||||
export const numToHexStr = (num: number) => `0x${num.toString(16)}`
|
||||
|
||||
export const copyAddress = async (address: string, toastRef: Ref<boolean>) => {
|
||||
await navigator.clipboard.writeText(address)
|
||||
toastRef.value = true
|
||||
|
@ -26,6 +26,12 @@ export const getBlockNumber = async () => {
|
||||
return await provider.getBlockNumber()
|
||||
}
|
||||
|
||||
export const getBlockByNumber = async (blockNum: number) => {
|
||||
const network = await getSelectedNetwork()
|
||||
const provider = new ethers.providers.JsonRpcProvider(network.rpc)
|
||||
return await provider.getBlock(blockNum)
|
||||
}
|
||||
|
||||
export const estimateGas = async ({to = '', from = '', data = '', value = '0x0' }: {to: string, from: string, data: string, value: string}) => {
|
||||
const network = await getSelectedNetwork()
|
||||
const provider = new ethers.providers.JsonRpcProvider(network.rpc)
|
||||
|
@ -2,27 +2,37 @@
|
||||
<ion-page>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Add Network</ion-title>
|
||||
<ion-title>{{ isEdit ? 'Edit Network': 'Add Network' }}</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-button @click="templateModal=true" expand="block">Add from popular chain list</ion-button>
|
||||
<ion-item>
|
||||
<ion-label>Name</ion-label>
|
||||
<ion-input v-model="name"></ion-input>
|
||||
<ion-label>Name(*)</ion-label>
|
||||
<ion-input v-model="name" placeholder="ex: Polygon"></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>ChainId</ion-label>
|
||||
<ion-input v-model="chainId" type="number"></ion-input>
|
||||
<ion-label>ChainId(*)</ion-label>
|
||||
<ion-input v-model="chainId" placeholder="137" type="number"></ion-input>
|
||||
</ion-item>
|
||||
<ion-item button>
|
||||
<ion-icon :icon="clipboardOutline" @click="paste('pasteRpc')" />
|
||||
<ion-label>RPC URL</ion-label>
|
||||
<ion-input id="pasteRpc" v-model="rpc" ></ion-input>
|
||||
<ion-label>RPC URL(*)</ion-label>
|
||||
<ion-input id="pasteRpc" placeholder="https://polygon-mainnet.g.alchemy.com/..." v-model="rpc" ></ion-input>
|
||||
</ion-item>
|
||||
<ion-item button>
|
||||
<ion-icon :icon="clipboardOutline" @click="paste('pasteRpc')" />
|
||||
<ion-label>Native Token Symbol(?)</ion-label>
|
||||
<ion-input id="pasteRpc" placeholder="MATIC" v-model="symbol" ></ion-input>
|
||||
</ion-item>
|
||||
<ion-item button>
|
||||
<ion-icon :icon="clipboardOutline" @click="paste('pasteExplorer')" />
|
||||
<ion-label>Explorer(?)</ion-label>
|
||||
<ion-input id="pasteExplorer" placeholder="https://polygon-scan.com" v-model="explorer" ></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-button @click="onCancel">Cancel</ion-button>
|
||||
<ion-button @click="onAddNetwork">Add Network</ion-button>
|
||||
<ion-button @click="onAddNetwork">{{ isEdit ? 'Edit Network': 'Add Network' }}</ion-button>
|
||||
</ion-item>
|
||||
<ion-alert
|
||||
:is-open="alertOpen"
|
||||
@ -85,13 +95,14 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref } from "vue";
|
||||
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonItem, IonLabel, IonInput, IonButton, IonIcon,
|
||||
IonModal, IonList, IonSegment, IonSegmentButton, IonListHeader, IonButtons, IonAvatar, modalController, IonAlert
|
||||
IonModal, IonList, IonSegment, IonSegmentButton, IonListHeader, IonButtons, IonAvatar, modalController, IonAlert, onIonViewWillEnter
|
||||
} from "@ionic/vue";
|
||||
import { getNetworks, saveSelectedNetwork, saveNetwork, getUrl, paste } from "@/utils/platform";
|
||||
import { getNetworks, saveSelectedNetwork, getUrl, paste, replaceNetworks } from "@/utils/platform";
|
||||
import router from "@/router";
|
||||
import { mainNets, testNets } from "@/utils/networks"
|
||||
|
||||
import { useRoute } from 'vue-router'
|
||||
import { clipboardOutline } from "ionicons/icons";
|
||||
import type { Networks, Network } from '@/extension/types'
|
||||
|
||||
export default defineComponent({
|
||||
components: { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonItem, IonLabel, IonInput, IonButton, IonIcon,
|
||||
@ -100,10 +111,33 @@ export default defineComponent({
|
||||
const name = ref('')
|
||||
const chainId = ref(0)
|
||||
const rpc = ref('')
|
||||
const symbol = ref('')
|
||||
const explorer = ref('')
|
||||
const templateModal = ref(false)
|
||||
const currentSegment = ref('mainnets')
|
||||
const alertOpen = ref(false)
|
||||
const alertMsg = ref('')
|
||||
const route = useRoute()
|
||||
const isEdit = route.path.includes('/edit')
|
||||
const paramChainId = route.params.chainId ?? ""
|
||||
let networksProm: Promise<Networks | undefined>
|
||||
|
||||
|
||||
const fillNetworkInputs = (network: Network) => {
|
||||
name.value = network.name
|
||||
chainId.value = network.chainId
|
||||
rpc.value = network.rpc
|
||||
symbol.value = network.symbol ?? ''
|
||||
explorer.value = network.explorer ?? ''
|
||||
}
|
||||
|
||||
onIonViewWillEnter(async () => {
|
||||
if(isEdit && paramChainId) {
|
||||
networksProm = getNetworks()
|
||||
const networks = await networksProm as Networks
|
||||
fillNetworkInputs(networks[Number(paramChainId)])
|
||||
}
|
||||
})
|
||||
|
||||
const resetFields = () => {
|
||||
name.value = ''
|
||||
@ -133,25 +167,27 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
let p1 = Promise.resolve()
|
||||
const networks = await getNetworks()
|
||||
if( (Object.keys(networks).length ?? 0) < 1 ){
|
||||
p1 = saveSelectedNetwork({
|
||||
if(!networksProm) {
|
||||
networksProm = getNetworks()
|
||||
}
|
||||
const networks = await networksProm as Networks
|
||||
const network = {
|
||||
name: name.value,
|
||||
chainId: chainId.value,
|
||||
rpc: rpc.value
|
||||
})
|
||||
rpc: rpc.value,
|
||||
...( symbol.value ? {symbol: symbol.value}:{}),
|
||||
...( explorer.value ? {explorer: explorer.value}:{})
|
||||
}
|
||||
if( (Object.keys(networks).length ?? 0) < 1 ){
|
||||
p1 = saveSelectedNetwork(network)
|
||||
} else {
|
||||
|
||||
if(chainId.value in networks){
|
||||
if((chainId.value in networks) && !isEdit){
|
||||
alertMsg.value = "Network already exists."
|
||||
return alertOpen.value = true
|
||||
}
|
||||
}
|
||||
const p2 = saveNetwork({
|
||||
name: name.value,
|
||||
chainId: chainId.value,
|
||||
rpc: rpc.value
|
||||
})
|
||||
networks[chainId.value] = network
|
||||
const p2 = replaceNetworks(networks)
|
||||
await Promise.all([p1, p2])
|
||||
router.push('/')
|
||||
resetFields()
|
||||
@ -166,9 +202,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
const fillTemplate = (network: typeof mainNets[1] ) =>{
|
||||
name.value = network.name
|
||||
chainId.value = network.chainId
|
||||
rpc.value = network.rpc
|
||||
fillNetworkInputs(network)
|
||||
modalController.dismiss(null, 'cancel')
|
||||
}
|
||||
|
||||
@ -188,7 +222,10 @@ export default defineComponent({
|
||||
getUrl,
|
||||
fillTemplate,
|
||||
alertOpen,
|
||||
alertMsg
|
||||
alertMsg,
|
||||
symbol,
|
||||
explorer,
|
||||
isEdit
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,8 +27,8 @@
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-chip>Edit</ion-chip>
|
||||
<ion-chip>Delete</ion-chip>
|
||||
<router-link :to="`/add-network/edit/${network.chainId}`" ><ion-chip>Edit</ion-chip></router-link>
|
||||
<ion-chip @click="deleteNetwork">Delete</ion-chip>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
@ -37,7 +37,7 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, Ref } from "vue";
|
||||
import { getNetworks, copyAddress, getUrl } from "@/utils/platform"
|
||||
import { getNetworks, copyAddress, getUrl, replaceNetworks } from "@/utils/platform"
|
||||
import {
|
||||
IonContent,
|
||||
IonHeader,
|
||||
@ -75,7 +75,7 @@ export default defineComponent({
|
||||
IonAvatar
|
||||
},
|
||||
setup () {
|
||||
const networks = ref([]) as Ref<Networks>
|
||||
const networks = ref({}) as Ref<Networks>
|
||||
const loading = ref(true)
|
||||
const toastState = ref(false)
|
||||
|
||||
@ -89,6 +89,13 @@ export default defineComponent({
|
||||
})
|
||||
}
|
||||
|
||||
const deleteNetwork = async (chainId: number) => {
|
||||
loading.value = true
|
||||
delete networks.value[chainId]
|
||||
await replaceNetworks(networks.value)
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
onIonViewWillEnter(() => {
|
||||
loadData()
|
||||
})
|
||||
@ -101,7 +108,8 @@ export default defineComponent({
|
||||
copyAddress,
|
||||
getToastRef,
|
||||
getUrl,
|
||||
mainNets
|
||||
mainNets,
|
||||
deleteNetwork
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -88,6 +88,21 @@
|
||||
</div>
|
||||
</ion-accordion>
|
||||
<ion-accordion value="4">
|
||||
<ion-item slot="header" color="light">
|
||||
<ion-label> Import / Export Accounts</ion-label>
|
||||
</ion-item>
|
||||
<div class="ion-padding" slot="content">
|
||||
<ion-item>
|
||||
<ion-label>Import Additional Accounts</ion-label>
|
||||
<ion-button color="danger" @click="importAcc">Import</ion-button>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Export All Accounts</ion-label>
|
||||
<ion-button color="danger" @click="exportAcc">Export</ion-button>
|
||||
</ion-item>
|
||||
</div>
|
||||
</ion-accordion>
|
||||
<ion-accordion value="5">
|
||||
<ion-item slot="header" color="light">
|
||||
<ion-label>Danger</ion-label>
|
||||
</ion-item>
|
||||
@ -240,7 +255,6 @@ export default defineComponent({
|
||||
|
||||
const saveSettings = async () => {
|
||||
loading.value = true
|
||||
settings.s.lockOutPeriod = settings.s.lockOutPeriod * 6e4
|
||||
await setSettings(settings.s)
|
||||
loading.value = false
|
||||
}
|
||||
@ -278,11 +292,9 @@ export default defineComponent({
|
||||
const accProm = accounts.map(async a => {
|
||||
a.encPk = await encrypt(mpPass.value, a.pk)
|
||||
a.pk = ''
|
||||
console.log(a)
|
||||
return a
|
||||
})
|
||||
accounts = await Promise.all(accProm)
|
||||
console.log(accounts)
|
||||
await replaceAccounts(accounts)
|
||||
await saveSelectedAccount(accounts[0])
|
||||
setEncryptToggle(true)
|
||||
@ -321,13 +333,20 @@ export default defineComponent({
|
||||
// settings.s.enableStorageEnctyption = true;
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
|
||||
const importAcc = async () => {
|
||||
//
|
||||
}
|
||||
|
||||
const exportAcc = async () => {
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
onIonViewWillEnter( () => {
|
||||
getSettings().then((storeSettings) =>
|
||||
{
|
||||
settings.s = storeSettings
|
||||
settings.s.lockOutPeriod = (settings.s.lockOutPeriod / 6e4)
|
||||
loading.value = false
|
||||
})
|
||||
|
||||
@ -368,7 +387,9 @@ export default defineComponent({
|
||||
modalDismiss,
|
||||
setTime,
|
||||
toastState,
|
||||
toastMsg
|
||||
toastMsg,
|
||||
importAcc,
|
||||
exportAcc
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -17,6 +17,7 @@
|
||||
<ion-button @click="onCancel">Cancel</ion-button>
|
||||
<ion-button @click="onSign">Sign</ion-button>
|
||||
</ion-item>
|
||||
<ion-item>Auto-reject Timer: {{ timerReject }}</ion-item>
|
||||
<ion-alert
|
||||
:is-open="alertOpen"
|
||||
header="Error"
|
||||
@ -49,13 +50,14 @@ import {
|
||||
IonAlert,
|
||||
IonText,
|
||||
IonLoading,
|
||||
modalController
|
||||
modalController,
|
||||
onIonViewWillEnter
|
||||
} from "@ionic/vue";
|
||||
// import { ethers } from "ethers";
|
||||
import {
|
||||
hexTostr,
|
||||
} from "@/utils/platform";
|
||||
import { approve } from "@/extension/userRequest";
|
||||
import { approve, walletPing } from "@/extension/userRequest";
|
||||
import { useRoute } from 'vue-router';
|
||||
import { getSelectedAccount } from '@/utils/platform'
|
||||
import UnlockModal from '@/views/UnlockModal.vue'
|
||||
@ -81,11 +83,33 @@ export default defineComponent({
|
||||
const signMsg = ref(hexTostr(route?.params?.param as string ?? ''));
|
||||
const alertOpen = ref(false);
|
||||
const alertMsg = ref("");
|
||||
const timerReject = ref(140);
|
||||
let interval: any
|
||||
|
||||
const onCancel = () => {
|
||||
window.close()
|
||||
window.close();
|
||||
if(interval) {
|
||||
try {
|
||||
clearInterval(interval)
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onIonViewWillEnter(async () => {
|
||||
interval = setInterval(async () => {
|
||||
if(timerReject.value <= 0) {
|
||||
onCancel()
|
||||
return;
|
||||
}
|
||||
|
||||
timerReject.value -= 1
|
||||
walletPing()
|
||||
}, 1000) as any
|
||||
|
||||
});
|
||||
|
||||
const openModal = async () => {
|
||||
const modal = await modalController.create({
|
||||
component: UnlockModal,
|
||||
@ -123,7 +147,8 @@ export default defineComponent({
|
||||
alertOpen,
|
||||
alertMsg,
|
||||
onSign,
|
||||
loading
|
||||
loading,
|
||||
timerReject
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -24,25 +24,25 @@
|
||||
<ion-label>Transaction to Sign & Send</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
Last Balance: {{ userBalance }}
|
||||
Last Balance: {{ userBalance }} <span style="opacity:0.7" v-if="dollarPrice > 0">${{ dollarPrice*userBalance }}</span>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
Contract: {{ contract }}
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
Tx Total Cost: {{ totalCost }}
|
||||
Tx Total Cost: {{ totalCost }} <span style="opacity:0.7" v-if="dollarPrice > 0">${{ dollarPrice*totalCost }}</span>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
Gas Fee: {{ gasFee }}
|
||||
Gas Fee: {{ gasFee }} <span style="opacity:0.7" v-if="dollarPrice > 0">${{ dollarPrice*gasFee }}</span>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
Tx value: {{ txValue }}
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
Gas Limit: {{ gasLimit }} <ion-button @click="setGasLimit">Set manually</ion-button>
|
||||
Gas Limit: {{ gasLimit }} <ion-button style="margin-left: 1rem" @click="gasLimitModal=true">Set manually</ion-button>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
Gas Price: {{ gasPrice}} <ion-button @click="setGasPrice">Set manually</ion-button>
|
||||
Gas Price: {{ gasPrice }} <ion-button style="margin-left: 1rem" @click="gasPriceModal=true">Set manually</ion-button>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-label>Raw TX:</ion-label>
|
||||
@ -75,6 +75,59 @@
|
||||
@didDismiss="loading = false"
|
||||
>
|
||||
</ion-loading>
|
||||
|
||||
<ion-modal
|
||||
:is-open="gasLimitModal"
|
||||
>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-button @click="gasLimitModal=false">Close</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Set Gas Limit</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Limit in units</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-input v-model="inGasLimit" type="number"></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-button @click="setGasLimit">Set Price</ion-button>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-modal>
|
||||
|
||||
<ion-modal
|
||||
:is-open="gasPriceModal"
|
||||
>
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<ion-button @click="gasPriceModal=false">Close</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Set Gas Price</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
<ion-content class="ion-padding">
|
||||
<ion-list>
|
||||
<ion-item>
|
||||
<ion-label>Price in gwei</ion-label>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-input v-model="inGasPrice" type="number"></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-button @click="setGasPrice">Set Price</ion-button>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-modal>
|
||||
|
||||
</ion-content>
|
||||
|
||||
</ion-page>
|
||||
@ -95,12 +148,15 @@ import {
|
||||
IonTextarea,
|
||||
onIonViewWillEnter,
|
||||
IonList,
|
||||
IonLoading
|
||||
IonLoading,
|
||||
IonModal,
|
||||
IonButtons,
|
||||
IonInput
|
||||
} from "@ionic/vue";
|
||||
import { ethers } from "ethers";
|
||||
import { approve, walletPing, walletSendData } from "@/extension/userRequest";
|
||||
import { useRoute } from "vue-router";
|
||||
import { getSelectedNetwork, getUrl } from '@/utils/platform'
|
||||
import { getSelectedNetwork, getUrl, getPrices, numToHexStr } from '@/utils/platform'
|
||||
import { getBalance, getGasPrice, estimateGas } from '@/utils/wallet'
|
||||
import type { Network } from '@/extension/types'
|
||||
import { mainNets } from "@/utils/networks";
|
||||
@ -118,7 +174,10 @@ export default defineComponent({
|
||||
IonAlert,
|
||||
IonTextarea,
|
||||
IonList,
|
||||
IonLoading
|
||||
IonLoading,
|
||||
IonModal,
|
||||
IonButtons,
|
||||
IonInput
|
||||
},
|
||||
setup: () => {
|
||||
const route = useRoute();
|
||||
@ -142,6 +201,12 @@ export default defineComponent({
|
||||
const insuficientBalance = ref(false)
|
||||
const gasPriceReFetch = ref(true)
|
||||
const selectedNetwork = (ref(null) as unknown) as Ref<Network>;
|
||||
const dollarPrice = ref(0)
|
||||
const gasLimitModal = ref(false)
|
||||
const gasPriceModal = ref(false)
|
||||
const inGasPrice = ref(0)
|
||||
const inGasLimit = ref(0)
|
||||
|
||||
let interval = 0
|
||||
const bars = ref(0)
|
||||
|
||||
@ -170,6 +235,12 @@ export default defineComponent({
|
||||
}
|
||||
};
|
||||
|
||||
const newGasData = () => {
|
||||
gasFee.value = Number(ethers.utils.formatUnits(String(gasLimit.value * gasPrice.value), "gwei"))
|
||||
txValue.value = Number(ethers.utils.formatEther(params?.value ?? '0x0'))
|
||||
totalCost.value = gasFee.value + txValue.value
|
||||
}
|
||||
|
||||
onIonViewWillEnter(async () => {
|
||||
console.log(params.value);
|
||||
(window as any)?.resizeTo?.(600, 800)
|
||||
@ -181,19 +252,26 @@ export default defineComponent({
|
||||
})
|
||||
const pGasPrice = getGasPrice()
|
||||
const pBalance = getBalance()
|
||||
const pGetPrices = getPrices()
|
||||
selectedNetwork.value = await getSelectedNetwork()
|
||||
userBalance.value = Number(ethers.utils.formatEther((await pBalance).toString()))
|
||||
console.log(userBalance.value)
|
||||
|
||||
gasPrice.value = parseInt(ethers.utils.formatUnits((await pGasPrice).toString(), "gwei"), 10)
|
||||
console.log(gasPrice.value)
|
||||
gasLimit.value = parseInt((await pEstimateGas).toString(), 10)
|
||||
gasFee.value = Number(ethers.utils.formatUnits(String(gasLimit.value * gasPrice.value), "gwei"))
|
||||
txValue.value = Number(ethers.utils.formatEther(params?.value ?? '0x0'))
|
||||
totalCost.value = gasFee.value + txValue.value
|
||||
|
||||
console.log( 'test', ethers.utils.formatUnits((await pGasPrice).toString(), "gwei"), ethers.utils.formatUnits(ethers.utils.parseUnits(gasPrice.value.toString(), "gwei"), "gwei") )
|
||||
|
||||
newGasData()
|
||||
if(userBalance.value < totalCost.value){
|
||||
insuficientBalance.value = true
|
||||
}
|
||||
const prices = await pGetPrices
|
||||
console.log('dd', prices, selectedNetwork.value?.priceId)
|
||||
if ( (selectedNetwork.value?.priceId ?? 'x') in prices ){
|
||||
dollarPrice.value = prices[(selectedNetwork.value?.priceId ?? 'x')]?.usd ?? 0
|
||||
|
||||
}
|
||||
|
||||
loading.value=false
|
||||
|
||||
interval = setInterval(async () => {
|
||||
@ -207,8 +285,7 @@ export default defineComponent({
|
||||
timerFee.value = 20
|
||||
loading.value=true
|
||||
gasPrice.value = parseInt(ethers.utils.formatUnits((await getGasPrice()).toString(), "gwei"), 10)
|
||||
gasFee.value = Number(ethers.utils.formatUnits(String(gasLimit.value * gasPrice.value), "gwei"))
|
||||
txValue.value = Number(ethers.utils.formatEther(params?.value ?? '0x0'))
|
||||
newGasData()
|
||||
loading.value=false
|
||||
}
|
||||
}
|
||||
@ -218,13 +295,25 @@ export default defineComponent({
|
||||
walletPing()
|
||||
}, 1000) as any
|
||||
})
|
||||
|
||||
|
||||
const setGasLimit = () => {
|
||||
// TODO
|
||||
gasLimit.value = inGasLimit.value
|
||||
walletSendData(rid, {
|
||||
gas: numToHexStr(gasLimit.value)
|
||||
})
|
||||
newGasData()
|
||||
gasLimitModal.value = false
|
||||
}
|
||||
|
||||
const setGasPrice = () => {
|
||||
// TODO
|
||||
gasPrice.value = inGasPrice.value
|
||||
gasPriceReFetch.value = false
|
||||
walletSendData(rid, {
|
||||
gasPrice: ethers.utils.parseUnits(gasPrice.value.toString(), "gwei")
|
||||
})
|
||||
newGasData()
|
||||
gasPriceModal.value = false
|
||||
}
|
||||
|
||||
|
||||
@ -252,7 +341,12 @@ export default defineComponent({
|
||||
mainNets,
|
||||
getUrl,
|
||||
setGasLimit,
|
||||
setGasPrice
|
||||
setGasPrice,
|
||||
dollarPrice,
|
||||
gasLimitModal,
|
||||
gasPriceModal,
|
||||
inGasPrice,
|
||||
inGasLimit
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -35,18 +35,18 @@
|
||||
<ion-item>To</ion-item>
|
||||
<ion-item>
|
||||
<ion-list>
|
||||
<ion-item>Network Name: {{ (templateNetworks as any)[selectedNetwork?.chainId]?.name }}</ion-item>
|
||||
<ion-item>Network Name: {{ (templateNetworks as any)[networkId]?.name }}</ion-item>
|
||||
<ion-item>
|
||||
<ion-avatar
|
||||
v-if="(templateNetworks as any)[selectedNetwork?.chainId]?.icon"
|
||||
v-if="(templateNetworks as any)[networkId]?.icon"
|
||||
style="margin-right: 1rem; width: 1.8rem; height: 1.8rem"
|
||||
>
|
||||
<img
|
||||
:alt="selectedNetwork?.name"
|
||||
:src="getUrl('assets/chain-icons/' + (templateNetworks as any)[selectedNetwork?.chainId]?.icon)"
|
||||
:src="getUrl('assets/chain-icons/' + (templateNetworks as any)[networkId]?.icon)"
|
||||
/>
|
||||
</ion-avatar>
|
||||
<ion-label>Network ID: {{ (templateNetworks as any)[selectedNetwork?.chainId]?.chainId }}</ion-label>
|
||||
<ion-label>Network ID: {{ (templateNetworks as any)[networkId]?.chainId }}</ion-label>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-item>
|
||||
@ -59,15 +59,16 @@
|
||||
</ion-item>
|
||||
<ion-item v-else>
|
||||
<ion-list>
|
||||
<ion-item>Request to change to unknown network ID: {{ }}</ion-item>
|
||||
<ion-item>Do you want to go to {{ }}</ion-item>
|
||||
<ion-item>Request to change to unknown network ID: {{ networkId }}</ion-item>
|
||||
<ion-item>Do you want to go to {{ addChainUrl }}</ion-item>
|
||||
<ion-item>To add it manually.</ion-item>
|
||||
<ion-item>
|
||||
<ion-button @click="onCancel">No</ion-button>
|
||||
<ion-button @click="onSwitchTemplates">Yes</ion-button>
|
||||
<ion-button @click="onSwitchNotExisting">Yes</ion-button>
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-item>
|
||||
<ion-item>Auto-reject Timer: {{ timerReject }}</ion-item>
|
||||
</ion-list>
|
||||
|
||||
<ion-alert
|
||||
@ -108,11 +109,11 @@ import {
|
||||
IonList,
|
||||
} from "@ionic/vue";
|
||||
// import { ethers } from "ethers";
|
||||
import { hexTostr } from "@/utils/platform";
|
||||
import { useRoute } from "vue-router";
|
||||
import { getSelectedNetwork, getNetworks, getUrl } from "@/utils/platform";
|
||||
import type { Network } from "@/extension/types";
|
||||
import { getSelectedNetwork, getNetworks, getUrl, saveSelectedNetwork, saveNetwork, openTab} from "@/utils/platform";
|
||||
import type { Network, Networks } from "@/extension/types";
|
||||
import { mainNets, testNets } from "@/utils/networks";
|
||||
import { approve, walletPing } from '@/extension/userRequest'
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
@ -133,55 +134,76 @@ export default defineComponent({
|
||||
const route = useRoute();
|
||||
const loading = ref(true);
|
||||
const rid = (route?.params?.rid as string) ?? "";
|
||||
const networkId = ref(hexTostr((route?.params?.param as string) ?? ""));
|
||||
const networkId = ref(String(Number(route?.params?.param as string ?? "")));
|
||||
const alertOpen = ref(false);
|
||||
const selectedNetwork = (ref(null) as unknown) as Ref<Network>;
|
||||
const alertMsg = ref("");
|
||||
const networkCase = ref("");
|
||||
let pnetworks;
|
||||
let pnetworks: Promise<Networks>;
|
||||
const templateNetworks = Object.assign({}, mainNets, testNets) ?? {};
|
||||
const addChainUrl = `${chainListPage}${networkId.value}`
|
||||
const timerReject = ref(140);
|
||||
let interval: any
|
||||
|
||||
const onCancel = () => {
|
||||
window.close();
|
||||
if(interval) {
|
||||
try {
|
||||
clearInterval(interval)
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onIonViewWillEnter(async () => {
|
||||
(window as any)?.resizeTo?.(600, 600)
|
||||
pnetworks = getNetworks();
|
||||
selectedNetwork.value = await getSelectedNetwork();
|
||||
const chainId = parseInt(networkId.value, 16);
|
||||
console.log(networkId.value)
|
||||
const existingNetworks = await pnetworks;
|
||||
if ((chainId ?? "0") in existingNetworks ?? {}) {
|
||||
if ((networkId.value ?? "0") in existingNetworks ?? {}) {
|
||||
networkCase.value = "exists";
|
||||
} else if ((chainId ?? "0") in templateNetworks) {
|
||||
} else if ((networkId.value ?? "0") in templateNetworks) {
|
||||
networkCase.value = "inTemplates";
|
||||
} else {
|
||||
networkCase.value = "doesNotExist";
|
||||
}
|
||||
loading.value = false;
|
||||
|
||||
interval = setInterval(async () => {
|
||||
if(timerReject.value <= 0) {
|
||||
onCancel()
|
||||
return;
|
||||
}
|
||||
|
||||
timerReject.value -= 1
|
||||
walletPing()
|
||||
}, 1000) as any
|
||||
|
||||
});
|
||||
|
||||
const onSwitchExists = async () => {
|
||||
loading.value = true;
|
||||
|
||||
// const selectedAccount = await getSelectedAccount();
|
||||
// if ((selectedAccount.pk ?? "").length !== 66) {
|
||||
// const modalResult = await openModal();
|
||||
// if (modalResult) {
|
||||
// approve(rid);
|
||||
// } else {
|
||||
// onCancel();
|
||||
// }
|
||||
// } else {
|
||||
// approve(rid);
|
||||
// }
|
||||
// loading.value = false;
|
||||
const existingNetworks = await pnetworks;
|
||||
selectedNetwork.value = existingNetworks[Number(networkId.value)]
|
||||
await saveSelectedNetwork(selectedNetwork.value)
|
||||
approve(rid);
|
||||
loading.value = false;
|
||||
};
|
||||
const onSwitchTemplates = async () => {
|
||||
loading.value = true;
|
||||
selectedNetwork.value = templateNetworks[Number(networkId.value)]
|
||||
saveNetwork(templateNetworks[Number(networkId.value)])
|
||||
saveSelectedNetwork(templateNetworks[Number(networkId.value)])
|
||||
approve(rid);
|
||||
loading.value = true;
|
||||
};
|
||||
|
||||
const onSwitchNotExisting = async () => {
|
||||
loading.value = true;
|
||||
openTab(addChainUrl)
|
||||
onCancel()
|
||||
};
|
||||
|
||||
return {
|
||||
@ -196,7 +218,9 @@ export default defineComponent({
|
||||
templateNetworks,
|
||||
getUrl,
|
||||
onSwitchTemplates,
|
||||
onSwitchNotExisting
|
||||
onSwitchNotExisting,
|
||||
addChainUrl,
|
||||
timerReject
|
||||
};
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user