mirror of
https://github.com/andrei0x309/clear-wallet.git
synced 2024-11-18 23:41:10 +00:00
changes: for chrome 1.1.4
This commit is contained in:
parent
2642659ae0
commit
8cb68c4a06
7
CHANGELOG.md
Normal file
7
CHANGELOG.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# Changelog:
|
||||||
|
|
||||||
|
### Manifest Version: 1.1.4:
|
||||||
|
|
||||||
|
- Added max 10 allowed concurrent messages to the wallet to prevent abusive websites from sending too many messages.
|
||||||
|
- Added explorer-button to main wallet page for easier viewing of the selected address on the blockchain explorer.
|
||||||
|
- Show the price converted in dollars also besides the native token price on transaction view for networks: 1(Ethereum), 137(Polygon), 100(Gnosis), 10(Optimism), 56(BSC), 42161(Arbitrum One)
|
12
README.md
12
README.md
@ -8,15 +8,18 @@ Simple EVM wallet chrome extension implementation using ethers, mv3, ionc, vue.
|
|||||||
|
|
||||||
[//]: # Here is an extended article abut this repo:
|
[//]: # Here is an extended article abut this repo:
|
||||||
|
|
||||||
|
|
||||||
### FAQ
|
### FAQ
|
||||||
|
|
||||||
Q: Why using Ionic?
|
Q: Why using Ionic?
|
||||||
A: The main idea is to extend the codebase to try to aditional platforms like Desktop and Mobile, and because Ionic has a simple interface that is ready to use with no additional design work.
|
A: The main idea is to extend the codebase to try to aditional platforms like Desktop and Mobile, and because Ionic has a simple interface that is ready to use with no additional design work.
|
||||||
|
|
||||||
Q: Is released on Chrome webstore?
|
Q: Is released on Chrome webstore?
|
||||||
A: Not yet but will be probably soon
|
|
||||||
|
A: Yes, Link: [https://chrome.google.com/webstore/detail/clear-evm-wallet-clw/djlahdpfkflehaepgohnnodmaajabdlg?hl=en](https://chrome.google.com/webstore/detail/clear-evm-wallet-clw/djlahdpfkflehaepgohnnodmaajabdlg?hl=en)
|
||||||
|
|
||||||
Q: What are some features?
|
Q: What are some features?
|
||||||
|
|
||||||
A: - It assumes some knowlodege about, EVM echosystem it dosen't come with any network, you can add any EVM network you want, and lets you sleect form the templates of some more popular networks.
|
A: - It assumes some knowlodege about, EVM echosystem it dosen't come with any network, you can add any EVM network you want, and lets you sleect form the templates of some more popular networks.
|
||||||
- You can have the key stored with or without encryption, you can enable or disable autolock, you can force decryption for every message sign or transaction sign & send.
|
- You can have the key stored with or without encryption, you can enable or disable autolock, you can force decryption for every message sign or transaction sign & send.
|
||||||
- You can import, export accounts.
|
- You can import, export accounts.
|
||||||
@ -27,7 +30,12 @@ A: - It assumes some knowlodege about, EVM echosystem it dosen't come with any
|
|||||||
- Prompts only for changing the network, sending/signing transaction, sending message.
|
- Prompts only for changing the network, sending/signing transaction, sending message.
|
||||||
|
|
||||||
Q: Is this ready to use?
|
Q: Is this ready to use?
|
||||||
A: Currently is under some development but it has a nice set of features that I used, I developed this pretty fast in my free time, you should always backup your keys, and do your own research and only use what you are confortable to use. The software dosen't come with any gurantees and is released as it is. But I definitely recomand this to use for testnets and playing with any kind of experiments.
|
|
||||||
|
A: Should work on most modern websites as a Metamask replacement. Currently is under some development but it has a nice set of features that I used, I developed this pretty fast in my free time, you should always backup your keys( since I've seen even well known wallets sometimes render keys inaccessiable), and do your own research and only use what you are confortable to use. The software dosen't come with any gurantees and is released as it is. But I definitely recomand this to use for testnets and playing with any kind of experiments.
|
||||||
|
|
||||||
|
Q: Will this prject be heavely mentained.
|
||||||
|
|
||||||
|
A: Can't promisse that probably not really :(
|
||||||
|
|
||||||
## LINKS
|
## LINKS
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ window.addEventListener("message", (event) => {
|
|||||||
if((event?.data?.data?.method ?? 'x') in allowedMethods) {
|
if((event?.data?.data?.method ?? 'x') in allowedMethods) {
|
||||||
chrome.runtime.sendMessage(event.data.data, (res) => {
|
chrome.runtime.sendMessage(event.data.data, (res) => {
|
||||||
const data = { type: "CLWALLET_PAGE", data: res, resId: event.data.resId, website: window?.location?.href ?? '' };
|
const data = { type: "CLWALLET_PAGE", data: res, resId: event.data.resId, website: window?.location?.href ?? '' };
|
||||||
console.log('data back', data)
|
// console.log('data back', data)
|
||||||
window.postMessage(data, "*");
|
window.postMessage(data, "*");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -13,12 +13,11 @@ const listners = {
|
|||||||
const promResolvers = {} as any
|
const promResolvers = {} as any
|
||||||
|
|
||||||
const listner = function(event: any) {
|
const listner = function(event: any) {
|
||||||
if (event.source != window)
|
if (event.source != window) return;
|
||||||
return;
|
|
||||||
if (event.data.type && (event.data.type === "CLWALLET_PAGE")) {
|
if (event.data.type && (event.data.type === "CLWALLET_PAGE")) {
|
||||||
if(event?.data?.data?.error){
|
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 {
|
}else {
|
||||||
promResolvers[event.data.resId].resolve(event.data.data);
|
promResolvers[event.data.resId].resolve(event.data.data);
|
||||||
}
|
}
|
||||||
@ -38,16 +37,22 @@ const listner = function(event: any) {
|
|||||||
window.addEventListener("message",listner)
|
window.addEventListener("message",listner)
|
||||||
|
|
||||||
const sendMessage = (args: RequestArguments, ping = false) => {
|
const sendMessage = (args: RequestArguments, ping = false) => {
|
||||||
return new Promise((resolve, reject) => {
|
if(Object.values(promResolvers).filter(r=> r).length < 10 ) {
|
||||||
const resId = crypto.randomUUID()
|
return new Promise((resolve, reject) => {
|
||||||
promResolvers[resId] = { resolve, reject }
|
const resId = crypto.randomUUID()
|
||||||
const data = { type: "CLWALLET_CONTENT", data: args, resId};
|
promResolvers[resId] = { resolve, reject }
|
||||||
if (ping) {
|
const data = { type: "CLWALLET_CONTENT", data: args, resId};
|
||||||
data.type = 'CLWALLET_PING'
|
if (ping) {
|
||||||
|
data.type = 'CLWALLET_PING'
|
||||||
|
}
|
||||||
|
// console.log('data in', data)
|
||||||
|
window.postMessage(data, "*");
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
reject(new Error("You have reached the maximum number of concurent wallet messeges."))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
console.log('data in', data)
|
|
||||||
window.postMessage(data, "*");
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const eth = new Proxy({
|
const eth = new Proxy({
|
||||||
@ -61,7 +66,6 @@ const eth = new Proxy({
|
|||||||
},
|
},
|
||||||
request: (args: RequestArguments): Promise<unknown> => {
|
request: (args: RequestArguments): Promise<unknown> => {
|
||||||
return sendMessage(args)
|
return sendMessage(args)
|
||||||
|
|
||||||
},
|
},
|
||||||
// Deprecated
|
// Deprecated
|
||||||
sendAsync: (arg1: RequestArguments, arg2: any): void => {
|
sendAsync: (arg1: RequestArguments, arg2: any): void => {
|
||||||
@ -138,9 +142,9 @@ const eth = new Proxy({
|
|||||||
_rpcRequest: () => null,
|
_rpcRequest: () => null,
|
||||||
_handleAccountsChanged: () => null,
|
_handleAccountsChanged: () => null,
|
||||||
// Deprecated - hardcoded for now, websites should not access this directly since is deprecated for a long time
|
// Deprecated - hardcoded for now, websites should not access this directly since is deprecated for a long time
|
||||||
chainId: "0x89",
|
chainId: "0xa",
|
||||||
// Deprecated - hardcoded for now, websites should not access this directly since is deprecated for a long time
|
// Deprecated - hardcoded for now, websites should not access this directly since is deprecated for a long time
|
||||||
networkVersion: "137",
|
networkVersion: 10,
|
||||||
selectedAddress: null,
|
selectedAddress: null,
|
||||||
autoRefreshOnNetworkChange: false,
|
autoRefreshOnNetworkChange: false,
|
||||||
// Internal Simulate Metamask
|
// Internal Simulate Metamask
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
"name": "__MSG_appName__",
|
"name": "__MSG_appName__",
|
||||||
"description": "__MSG_appDesc__",
|
"description": "__MSG_appDesc__",
|
||||||
"default_locale": "en",
|
"default_locale": "en",
|
||||||
"version": "1.1.2",
|
"version": "1.1.4",
|
||||||
"version_name": "1.1.2",
|
"version_name": "1.1.4",
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "assets/extension-icon/wallet_16.png",
|
"16": "assets/extension-icon/wallet_16.png",
|
||||||
"32": "assets/extension-icon/wallet_32.png",
|
"32": "assets/extension-icon/wallet_32.png",
|
||||||
@ -23,6 +23,7 @@
|
|||||||
"minimum_chrome_version": "93",
|
"minimum_chrome_version": "93",
|
||||||
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
"tabs",
|
||||||
"notifications",
|
"notifications",
|
||||||
"storage",
|
"storage",
|
||||||
"alarms",
|
"alarms",
|
||||||
|
@ -109,3 +109,7 @@ export const testNets = {
|
|||||||
icon: 'arbitrum.webp'
|
icon: 'arbitrum.webp'
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const chainIdToPriceId = (chainId: number): string => {
|
||||||
|
return mainNets?.[chainId]?.priceId ?? 'x'
|
||||||
|
}
|
@ -19,6 +19,25 @@
|
|||||||
<p style="font-size: 0.7rem">{{ selectedAccount?.address }}</p>
|
<p style="font-size: 0.7rem">{{ selectedAccount?.address }}</p>
|
||||||
<ion-icon style="margin-left: 0.5rem" :icon="copyOutline"></ion-icon>
|
<ion-icon style="margin-left: 0.5rem" :icon="copyOutline"></ion-icon>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
<ion-item
|
||||||
|
v-if="!loading && selectedNetwork?.explorer && selectedAccount?.address"
|
||||||
|
>
|
||||||
|
<ion-button
|
||||||
|
@click="
|
||||||
|
openTab(
|
||||||
|
`${selectedNetwork.explorer}/address/${selectedAccount?.address}`.replace(
|
||||||
|
'//',
|
||||||
|
'/'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
"
|
||||||
|
expand="block"
|
||||||
|
>View Address on
|
||||||
|
{{
|
||||||
|
`${selectedNetwork.explorer}`.replace("https://", "").replace("http://", "")
|
||||||
|
}}
|
||||||
|
</ion-button>
|
||||||
|
</ion-item>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
<ion-item v-if="loading || Object.keys(networks).length < 1">
|
<ion-item v-if="loading || Object.keys(networks).length < 1">
|
||||||
<ion-label>No EVM Networks found</ion-label>
|
<ion-label>No EVM Networks found</ion-label>
|
||||||
@ -37,17 +56,6 @@
|
|||||||
<ion-label>Selected Network ID: {{ selectedNetwork?.chainId }}</ion-label>
|
<ion-label>Selected Network ID: {{ selectedNetwork?.chainId }}</ion-label>
|
||||||
<ion-button @click="networksModal = true">Select</ion-button>
|
<ion-button @click="networksModal = true">Select</ion-button>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item v-if="!loading && selectedNetwork?.explorer && selectedAccount?.address">
|
|
||||||
<ion-button
|
|
||||||
@click="
|
|
||||||
openTab(
|
|
||||||
`${selectedNetwork.explorer}/${selectedAccount?.address}`.replace('//', '/')
|
|
||||||
)
|
|
||||||
"
|
|
||||||
expand="block"
|
|
||||||
>View Address on {{ selectedNetwork.explorer }}
|
|
||||||
</ion-button>
|
|
||||||
</ion-item>
|
|
||||||
|
|
||||||
<ion-loading
|
<ion-loading
|
||||||
:is-open="loading"
|
:is-open="loading"
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
<ion-content class="ion-padding">
|
<ion-content class="ion-padding">
|
||||||
<ion-item><ion-label>Network Name: {{ selectedNetwork?.name }}</ion-label></ion-item>
|
<ion-item
|
||||||
|
><ion-label>Network Name: {{ selectedNetwork?.name }}</ion-label></ion-item
|
||||||
|
>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-avatar
|
<ion-avatar
|
||||||
v-if="(mainNets as any)[selectedNetwork?.chainId]?.icon"
|
v-if="(mainNets as any)[selectedNetwork?.chainId]?.icon"
|
||||||
@ -24,33 +26,58 @@
|
|||||||
<ion-label>Transaction to Sign & Send</ion-label>
|
<ion-label>Transaction to Sign & Send</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
Last Balance: {{ userBalance }} <span style="opacity:0.7" v-if="dollarPrice > 0">${{ dollarPrice*userBalance }}</span>
|
Last Balance: {{ userBalance }}
|
||||||
|
<span
|
||||||
|
style="font-size: 0.9rem; opacity: 0.7; margin-left: 1rem"
|
||||||
|
v-if="dollarPrice > 0"
|
||||||
|
>${{ (dollarPrice * userBalance).toFixed(3) }}</span
|
||||||
|
>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item> Contract: {{ contract }} </ion-item>
|
||||||
|
<ion-item>
|
||||||
|
Tx Total Cost: {{ totalCost }}
|
||||||
|
<span
|
||||||
|
style="font-size: 0.9rem; opacity: 0.7; margin-left: 1rem"
|
||||||
|
v-if="dollarPrice > 0"
|
||||||
|
>${{ (dollarPrice * totalCost).toFixed(3) }}</span
|
||||||
|
>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
Contract: {{ contract }}
|
Gas Fee: {{ gasFee }}
|
||||||
|
<span
|
||||||
|
style="font-size: 0.9rem; opacity: 0.7; margin-left: 1rem"
|
||||||
|
v-if="dollarPrice > 0"
|
||||||
|
>${{ (dollarPrice * gasFee).toFixed(3) }}</span
|
||||||
|
>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item> Tx value: {{ txValue }} </ion-item>
|
||||||
|
<ion-item>
|
||||||
|
Gas Limit: {{ gasLimit }}
|
||||||
|
<ion-button style="margin-left: 1rem" @click="gasLimitModal = true"
|
||||||
|
>Set manually</ion-button
|
||||||
|
>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
Tx Total Cost: {{ totalCost }} <span style="opacity:0.7" v-if="dollarPrice > 0">${{ dollarPrice*totalCost }}</span>
|
Gas Price: {{ gasPrice }}
|
||||||
</ion-item>
|
<ion-button style="margin-left: 1rem" @click="gasPriceModal = true"
|
||||||
<ion-item>
|
>Set manually</ion-button
|
||||||
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 style="margin-left: 1rem" @click="gasLimitModal=true">Set manually</ion-button>
|
|
||||||
</ion-item>
|
|
||||||
<ion-item>
|
|
||||||
Gas Price: {{ gasPrice }} <ion-button style="margin-left: 1rem" @click="gasPriceModal=true">Set manually</ion-button>
|
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-label>Raw TX:</ion-label>
|
<ion-label>Raw TX:</ion-label>
|
||||||
<ion-textarea style="overflow-y: scroll;" :rows="10" :cols="20" :value="signTxData" readonly></ion-textarea>
|
<ion-textarea
|
||||||
|
style="overflow-y: scroll"
|
||||||
|
:rows="10"
|
||||||
|
:cols="20"
|
||||||
|
:value="signTxData"
|
||||||
|
readonly
|
||||||
|
></ion-textarea>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-button @click="onCancel">Cancel</ion-button>
|
<ion-button @click="onCancel">Cancel</ion-button>
|
||||||
<ion-button :disabled="insuficientBalance" @click="onSign">{{ insuficientBalance ? "Insuficient Balance": "Send" }}</ion-button>
|
<ion-button :disabled="insuficientBalance" @click="onSign">{{
|
||||||
|
insuficientBalance ? "Insuficient Balance" : "Send"
|
||||||
|
}}</ion-button>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-alert
|
<ion-alert
|
||||||
:is-open="alertOpen"
|
:is-open="alertOpen"
|
||||||
@ -66,7 +93,7 @@
|
|||||||
<ion-list v-if="gasPriceReFetch">
|
<ion-list v-if="gasPriceReFetch">
|
||||||
<ion-item>New Fee price Timer: {{ timerFee }}</ion-item>
|
<ion-item>New Fee price Timer: {{ timerFee }}</ion-item>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
|
||||||
<ion-loading
|
<ion-loading
|
||||||
:is-open="loading"
|
:is-open="loading"
|
||||||
cssClass="my-custom-class"
|
cssClass="my-custom-class"
|
||||||
@ -76,60 +103,54 @@
|
|||||||
>
|
>
|
||||||
</ion-loading>
|
</ion-loading>
|
||||||
|
|
||||||
<ion-modal
|
<ion-modal :is-open="gasLimitModal">
|
||||||
:is-open="gasLimitModal"
|
<ion-header>
|
||||||
>
|
<ion-toolbar>
|
||||||
<ion-header>
|
<ion-buttons slot="start">
|
||||||
<ion-toolbar>
|
<ion-button @click="gasLimitModal = false">Close</ion-button>
|
||||||
<ion-buttons slot="start">
|
</ion-buttons>
|
||||||
<ion-button @click="gasLimitModal=false">Close</ion-button>
|
<ion-title>Set Gas Limit</ion-title>
|
||||||
</ion-buttons>
|
</ion-toolbar>
|
||||||
<ion-title>Set Gas Limit</ion-title>
|
</ion-header>
|
||||||
</ion-toolbar>
|
<ion-content class="ion-padding">
|
||||||
</ion-header>
|
<ion-list>
|
||||||
<ion-content class="ion-padding">
|
<ion-item>
|
||||||
<ion-list>
|
<ion-label>Limit in units</ion-label>
|
||||||
<ion-item>
|
</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-input v-model="inGasLimit" type="number"></ion-input>
|
<ion-item>
|
||||||
</ion-item>
|
<ion-button @click="setGasLimit">Set Price</ion-button>
|
||||||
<ion-item>
|
</ion-item>
|
||||||
<ion-button @click="setGasLimit">Set Price</ion-button>
|
</ion-list>
|
||||||
</ion-item>
|
</ion-content>
|
||||||
</ion-list>
|
</ion-modal>
|
||||||
</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-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-content>
|
||||||
|
|
||||||
</ion-page>
|
</ion-page>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -152,16 +173,25 @@ import {
|
|||||||
IonModal,
|
IonModal,
|
||||||
IonButtons,
|
IonButtons,
|
||||||
IonInput,
|
IonInput,
|
||||||
modalController
|
modalController,
|
||||||
} from "@ionic/vue";
|
} from "@ionic/vue";
|
||||||
import { ethers } from "ethers";
|
import { ethers } from "ethers";
|
||||||
import { approve, walletPing, walletSendData } from "@/extension/userRequest";
|
import { approve, walletPing, walletSendData } from "@/extension/userRequest";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { getSelectedNetwork, getUrl, getPrices, numToHexStr, blockLockout, unBlockLockout, getSelectedAccount, strToHex } from '@/utils/platform'
|
import {
|
||||||
import { getBalance, getGasPrice, estimateGas } from '@/utils/wallet'
|
getSelectedNetwork,
|
||||||
import type { Network } from '@/extension/types'
|
getUrl,
|
||||||
import { mainNets } from "@/utils/networks";
|
getPrices,
|
||||||
import UnlockModal from '@/views/UnlockModal.vue'
|
numToHexStr,
|
||||||
|
blockLockout,
|
||||||
|
unBlockLockout,
|
||||||
|
getSelectedAccount,
|
||||||
|
strToHex,
|
||||||
|
} from "@/utils/platform";
|
||||||
|
import { getBalance, getGasPrice, estimateGas } from "@/utils/wallet";
|
||||||
|
import type { Network } from "@/extension/types";
|
||||||
|
import { mainNets, chainIdToPriceId } from "@/utils/networks";
|
||||||
|
import UnlockModal from "@/views/UnlockModal.vue";
|
||||||
import router from "@/router";
|
import router from "@/router";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@ -180,89 +210,88 @@ export default defineComponent({
|
|||||||
IonLoading,
|
IonLoading,
|
||||||
IonModal,
|
IonModal,
|
||||||
IonButtons,
|
IonButtons,
|
||||||
IonInput
|
IonInput,
|
||||||
},
|
},
|
||||||
setup: () => {
|
setup: () => {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const rid = (route?.params?.rid as string) ?? "";
|
const rid = (route?.params?.rid as string) ?? "";
|
||||||
let isError = false
|
let isError = false;
|
||||||
const decodedParam = decodeURIComponent(route.params?.param as string ?? '')
|
const decodedParam = decodeURIComponent((route.params?.param as string) ?? "");
|
||||||
const params = JSON.parse(decodedParam)
|
const params = JSON.parse(decodedParam);
|
||||||
const signTxData = ref('');
|
const signTxData = ref("");
|
||||||
const alertOpen = ref(false);
|
const alertOpen = ref(false);
|
||||||
const alertMsg = ref('');
|
const alertMsg = ref("");
|
||||||
const loading = ref(true)
|
const loading = ref(true);
|
||||||
const contract = params.to
|
const contract = params.to;
|
||||||
const gasPrice = ref(0);
|
const gasPrice = ref(0);
|
||||||
const gasLimit = ref(0);
|
const gasLimit = ref(0);
|
||||||
const totalCost = ref(0)
|
const totalCost = ref(0);
|
||||||
const gasFee = ref(0);
|
const gasFee = ref(0);
|
||||||
const userBalance = ref(0)
|
const userBalance = ref(0);
|
||||||
const txValue = ref(0)
|
const txValue = ref(0);
|
||||||
const timerReject = ref(140)
|
const timerReject = ref(140);
|
||||||
const timerFee = ref(20)
|
const timerFee = ref(20);
|
||||||
const insuficientBalance = ref(false)
|
const insuficientBalance = ref(false);
|
||||||
const gasPriceReFetch = ref(true)
|
const gasPriceReFetch = ref(true);
|
||||||
const selectedNetwork = (ref(null) as unknown) as Ref<Network>;
|
const selectedNetwork = (ref(null) as unknown) as Ref<Network>;
|
||||||
const dollarPrice = ref(0)
|
const dollarPrice = ref(0);
|
||||||
const gasLimitModal = ref(false)
|
const gasLimitModal = ref(false);
|
||||||
const gasPriceModal = ref(false)
|
const gasPriceModal = ref(false);
|
||||||
const inGasPrice = ref(0)
|
const inGasPrice = ref(0);
|
||||||
const inGasLimit = ref(0)
|
const inGasLimit = ref(0);
|
||||||
|
|
||||||
let interval = 0
|
let interval = 0;
|
||||||
const bars = ref(0)
|
const bars = ref(0);
|
||||||
|
|
||||||
if(!rid){
|
if (!rid) {
|
||||||
isError = true;
|
isError = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!decodedParam){
|
if (!decodedParam) {
|
||||||
isError = true
|
isError = true;
|
||||||
} else {
|
} else {
|
||||||
signTxData.value = JSON.stringify( params, null, 2)
|
signTxData.value = JSON.stringify(params, null, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
const openModal = async () => {
|
const openModal = async () => {
|
||||||
const modal = await modalController.create({
|
const modal = await modalController.create({
|
||||||
component: UnlockModal,
|
component: UnlockModal,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
unlockType: 'transaction'
|
unlockType: "transaction",
|
||||||
}
|
},
|
||||||
|
});
|
||||||
});
|
modal.present();
|
||||||
modal.present();
|
const { role } = await modal.onWillDismiss();
|
||||||
const { role } = await modal.onWillDismiss();
|
if (role === "confirm") return true;
|
||||||
if(role === 'confirm') return true
|
return false;
|
||||||
return false
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const onSign = async () => {
|
const onSign = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const selectedAccount = await getSelectedAccount()
|
const selectedAccount = await getSelectedAccount();
|
||||||
loading.value = false
|
loading.value = false;
|
||||||
if ((selectedAccount.pk ?? '').length !== 66) {
|
if ((selectedAccount.pk ?? "").length !== 66) {
|
||||||
const modalResult = await openModal()
|
const modalResult = await openModal();
|
||||||
if(modalResult) {
|
if (modalResult) {
|
||||||
unBlockLockout()
|
unBlockLockout();
|
||||||
loading.value = true
|
loading.value = true;
|
||||||
approve(rid)
|
approve(rid);
|
||||||
}else {
|
} else {
|
||||||
onCancel()
|
onCancel();
|
||||||
}
|
|
||||||
}else {
|
|
||||||
unBlockLockout()
|
|
||||||
approve(rid)
|
|
||||||
}
|
}
|
||||||
loading.value = false
|
} else {
|
||||||
}
|
unBlockLockout();
|
||||||
|
approve(rid);
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
window.close();
|
window.close();
|
||||||
if(interval) {
|
if (interval) {
|
||||||
try {
|
try {
|
||||||
unBlockLockout()
|
unBlockLockout();
|
||||||
clearInterval(interval)
|
clearInterval(interval);
|
||||||
} catch {
|
} catch {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
@ -270,94 +299,101 @@ export default defineComponent({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const newGasData = () => {
|
const newGasData = () => {
|
||||||
gasFee.value = Number(ethers.utils.formatUnits(String(gasLimit.value * gasPrice.value), "gwei"))
|
gasFee.value = Number(
|
||||||
txValue.value = Number(ethers.utils.formatEther(params?.value ?? '0x0'))
|
ethers.utils.formatUnits(String(gasLimit.value * gasPrice.value), "gwei")
|
||||||
totalCost.value = gasFee.value + txValue.value
|
);
|
||||||
}
|
txValue.value = Number(ethers.utils.formatEther(params?.value ?? "0x0"));
|
||||||
|
totalCost.value = gasFee.value + txValue.value;
|
||||||
|
};
|
||||||
|
|
||||||
onIonViewWillEnter(async () => {
|
onIonViewWillEnter(async () => {
|
||||||
console.log(params.value);
|
console.log(params.value);
|
||||||
(window as any)?.resizeTo?.(600, 800)
|
(window as any)?.resizeTo?.(600, 800);
|
||||||
const pEstimateGas = estimateGas({
|
const pEstimateGas = estimateGas({
|
||||||
to: params?.to ?? '',
|
to: params?.to ?? "",
|
||||||
from: params?.from ?? '',
|
from: params?.from ?? "",
|
||||||
data: params?.data ?? '',
|
data: params?.data ?? "",
|
||||||
value: params?.value ?? '0x0'
|
value: params?.value ?? "0x0",
|
||||||
})
|
});
|
||||||
blockLockout()
|
blockLockout();
|
||||||
const pGasPrice = getGasPrice()
|
const pGasPrice = getGasPrice();
|
||||||
const pBalance = getBalance()
|
const pBalance = getBalance();
|
||||||
const pGetPrices = getPrices()
|
const pGetPrices = getPrices();
|
||||||
selectedNetwork.value = await getSelectedNetwork()
|
selectedNetwork.value = await getSelectedNetwork();
|
||||||
userBalance.value = Number(ethers.utils.formatEther((await pBalance).toString() ?? '0x0'))
|
userBalance.value = Number(
|
||||||
|
ethers.utils.formatEther((await pBalance).toString() ?? "0x0")
|
||||||
gasPrice.value = parseInt(ethers.utils.formatUnits((await pGasPrice).toString() ?? '0x0', "gwei"), 10)
|
);
|
||||||
|
|
||||||
|
gasPrice.value = parseInt(
|
||||||
|
ethers.utils.formatUnits((await pGasPrice).toString() ?? "0x0", "gwei"),
|
||||||
|
10
|
||||||
|
);
|
||||||
try {
|
try {
|
||||||
gasLimit.value = parseInt((await pEstimateGas).toString(), 10)
|
gasLimit.value = parseInt((await pEstimateGas).toString(), 10);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const errorToHex = strToHex(String(err))
|
const errorToHex = strToHex(String(err));
|
||||||
router.push(`/contract-error/${rid}/${errorToHex}/${contract}`)
|
router.push(`/contract-error/${rid}/${errorToHex}/${contract}`);
|
||||||
loading.value = false
|
loading.value = false;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
inGasPrice.value = gasPrice.value
|
inGasPrice.value = gasPrice.value;
|
||||||
inGasLimit.value = gasLimit.value
|
inGasLimit.value = gasLimit.value;
|
||||||
|
|
||||||
// console.log( 'test', ethers.utils.formatUnits((await pGasPrice).toString(), "gwei"), ethers.utils.formatUnits(ethers.utils.parseUnits(gasPrice.value.toString(), "gwei"), "gwei") )
|
// console.log( 'test', ethers.utils.formatUnits((await pGasPrice).toString(), "gwei"), ethers.utils.formatUnits(ethers.utils.parseUnits(gasPrice.value.toString(), "gwei"), "gwei") )
|
||||||
|
|
||||||
newGasData()
|
newGasData();
|
||||||
if(userBalance.value < totalCost.value){
|
if (userBalance.value < totalCost.value) {
|
||||||
insuficientBalance.value = true
|
insuficientBalance.value = true;
|
||||||
}
|
|
||||||
const prices = await pGetPrices
|
|
||||||
if ( (selectedNetwork.value?.priceId ?? 'x') in prices ){
|
|
||||||
dollarPrice.value = prices[(selectedNetwork.value?.priceId ?? 'x')]?.usd ?? 0
|
|
||||||
}
|
}
|
||||||
|
const prices = await pGetPrices;
|
||||||
|
dollarPrice.value =
|
||||||
|
prices[chainIdToPriceId(selectedNetwork.value?.chainId ?? 0)]?.usd ?? 0;
|
||||||
|
|
||||||
loading.value=false
|
loading.value = false;
|
||||||
|
|
||||||
interval = setInterval(async () => {
|
interval = setInterval(async () => {
|
||||||
if(timerReject.value <= 0) {
|
if (timerReject.value <= 0) {
|
||||||
onCancel()
|
onCancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if( gasPriceReFetch.value ) {
|
if (gasPriceReFetch.value) {
|
||||||
timerFee.value -= 1
|
timerFee.value -= 1;
|
||||||
if(timerFee.value <= 0) {
|
if (timerFee.value <= 0) {
|
||||||
timerFee.value = 20
|
timerFee.value = 20;
|
||||||
loading.value=true
|
loading.value = true;
|
||||||
gasPrice.value = parseInt(ethers.utils.formatUnits((await getGasPrice()).toString(), "gwei"), 10)
|
gasPrice.value = parseInt(
|
||||||
newGasData()
|
ethers.utils.formatUnits((await getGasPrice()).toString(), "gwei"),
|
||||||
loading.value=false
|
10
|
||||||
|
);
|
||||||
|
newGasData();
|
||||||
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
timerReject.value -= 1
|
|
||||||
bars.value++
|
|
||||||
walletPing()
|
|
||||||
}, 1000) as any
|
|
||||||
})
|
|
||||||
|
|
||||||
|
timerReject.value -= 1;
|
||||||
|
bars.value++;
|
||||||
|
walletPing();
|
||||||
|
}, 1000) as any;
|
||||||
|
});
|
||||||
|
|
||||||
const setGasLimit = () => {
|
const setGasLimit = () => {
|
||||||
gasLimit.value = inGasLimit.value
|
gasLimit.value = inGasLimit.value;
|
||||||
walletSendData(rid, {
|
walletSendData(rid, {
|
||||||
gas: numToHexStr(gasLimit.value)
|
gas: numToHexStr(gasLimit.value),
|
||||||
})
|
});
|
||||||
newGasData()
|
newGasData();
|
||||||
gasLimitModal.value = false
|
gasLimitModal.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
const setGasPrice = () => {
|
const setGasPrice = () => {
|
||||||
gasPrice.value = inGasPrice.value
|
gasPrice.value = inGasPrice.value;
|
||||||
gasPriceReFetch.value = false
|
gasPriceReFetch.value = false;
|
||||||
walletSendData(rid, {
|
walletSendData(rid, {
|
||||||
gasPrice: ethers.utils.parseUnits(gasPrice.value.toString(), "gwei")
|
gasPrice: ethers.utils.parseUnits(gasPrice.value.toString(), "gwei"),
|
||||||
})
|
});
|
||||||
newGasData()
|
newGasData();
|
||||||
gasPriceModal.value = false
|
gasPriceModal.value = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
signTxData,
|
signTxData,
|
||||||
@ -388,7 +424,7 @@ export default defineComponent({
|
|||||||
gasLimitModal,
|
gasLimitModal,
|
||||||
gasPriceModal,
|
gasPriceModal,
|
||||||
inGasPrice,
|
inGasPrice,
|
||||||
inGasLimit
|
inGasLimit,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user