revisions: for new version, new metamask API, refactoring, new method of injecting for sync mv3
This commit is contained in:
parent
3a5683b589
commit
a0a198c8e4
|
@ -30,4 +30,6 @@ npm-debug.log*
|
||||||
/plugins
|
/plugins
|
||||||
/www
|
/www
|
||||||
/src/extension/inject.js
|
/src/extension/inject.js
|
||||||
|
/src/extension/content.js
|
||||||
|
/src/extension/webInject.js
|
||||||
releases
|
releases
|
||||||
|
|
54
package.json
54
package.json
|
@ -4,51 +4,55 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "tsc --out src/extension/inject.js src/extension/inject.ts && vue-tsc --noEmit && vite build",
|
"webInject": "tsc --out src/extension/webInject.js src/extension/webInject.ts",
|
||||||
|
"inject": "tsc --out src/extension/inject.js src/extension/inject.ts",
|
||||||
|
"content": "tsc --out src/extension/content.js src/extension/content.ts",
|
||||||
|
"manifestContent" : "ts-node ./release-scripts/replace-content-manifest.ts",
|
||||||
|
"build": "yarn inject && yarn webInject && yarn content && vue-tsc --noEmit && vite build && yarn manifestContent",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"release": "yarn config set version-tag-prefix clear-wallet@v && yarn config set version-git-message 'clear-wallet@v%s' && yarn version --patch && yarn postversion",
|
"release": "yarn config set version-tag-prefix clear-wallet@v && yarn config set version-git-message 'clear-wallet@v%s' && yarn version --patch && yarn postversion",
|
||||||
"postversion": "git push",
|
"postversion": "git push",
|
||||||
"pub": "yarn build && yarn release && ts-node ./release-scripts/create-release.ts"
|
"pub": "yarn build && yarn release && ts-node ./release-scripts/create-release.ts"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@capacitor/app": "^4.0.1",
|
"@capacitor/app": "^4.1.0",
|
||||||
"@capacitor/core": "^4.3.0",
|
"@capacitor/core": "^4.4.0",
|
||||||
"@capacitor/haptics": "^4.0.1",
|
"@capacitor/haptics": "^4.0.1",
|
||||||
"@capacitor/keyboard": "^4.0.1",
|
"@capacitor/keyboard": "^4.0.1",
|
||||||
"@capacitor/status-bar": "^4.0.1",
|
"@capacitor/status-bar": "^4.0.1",
|
||||||
"@ionic/vue": "^6.3.0",
|
"@ionic/vue": "^6.3.3",
|
||||||
"@ionic/vue-router": "^6.3.0",
|
"@ionic/vue-router": "^6.3.3",
|
||||||
"@types/chrome": "^0.0.197",
|
"@types/chrome": "^0.0.200",
|
||||||
"core-js": "^3.25.2",
|
"core-js": "^3.26.0",
|
||||||
"ethers": "^5.7.1",
|
"ethers": "^5.7.2",
|
||||||
"vue": "^3.2.39",
|
"vue": "^3.2.41",
|
||||||
"vue-router": "^4.1.5"
|
"vue-router": "^4.1.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@capacitor/cli": "^4.3.0",
|
"@capacitor/cli": "^4.4.0",
|
||||||
"@crxjs/vite-plugin": "^1.0.14",
|
"@crxjs/vite-plugin": "^1.0.14",
|
||||||
"@types/archiver": "^5.3.1",
|
"@types/archiver": "^5.3.1",
|
||||||
"@types/jest": "^29.0.3",
|
"@types/jest": "^29.2.0",
|
||||||
"@types/node": "^18.7.19",
|
"@types/node": "^18.11.7",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.38.0",
|
"@typescript-eslint/eslint-plugin": "^5.41.0",
|
||||||
"@typescript-eslint/parser": "^5.38.0",
|
"@typescript-eslint/parser": "^5.41.0",
|
||||||
"@vitejs/plugin-vue": "^3.1.0",
|
"@vitejs/plugin-vue": "^3.2.0",
|
||||||
"@vue/eslint-config-typescript": "^11.0.2",
|
"@vue/eslint-config-typescript": "^11.0.2",
|
||||||
"archiver": "^5.3.1",
|
"archiver": "^5.3.1",
|
||||||
"eslint": "^8.23.1",
|
"eslint": "^8.26.0",
|
||||||
"eslint-plugin-vue": "^9.5.1",
|
"eslint-plugin-vue": "^9.6.0",
|
||||||
"http-browserify": "^1.7.0",
|
"http-browserify": "^1.7.0",
|
||||||
"https-browserify": "^1.0.0",
|
"https-browserify": "^1.0.0",
|
||||||
"jest": "^29.0.3",
|
"jest": "^29.2.2",
|
||||||
"rollup-plugin-polyfill-node": "^0.10.2",
|
"rollup-plugin-polyfill-node": "^0.11.0",
|
||||||
"sass": "^1.55.0",
|
"sass": "^1.55.0",
|
||||||
"stream-browserify": "^3.0.0",
|
"stream-browserify": "^3.0.0",
|
||||||
"ts-jest": "^29.0.1",
|
"ts-jest": "^29.0.3",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^4.8.3",
|
"typescript": "^4.8.4",
|
||||||
"util": "^0.12.4",
|
"util": "^0.12.5",
|
||||||
"vite": "^3.1.3",
|
"vite": "^3.2.0",
|
||||||
"vue-tsc": "^0.40.13",
|
"vue-tsc": "^1.0.9",
|
||||||
"yarn-upgrade-all": "^0.7.1"
|
"yarn-upgrade-all": "^0.7.1"
|
||||||
},
|
},
|
||||||
"description": "An Ionic project"
|
"description": "An Ionic project"
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
const fs = (await import('fs')).default
|
||||||
|
const pkg = JSON.parse(fs.readFileSync('dist/manifest.json').toString());
|
||||||
|
pkg.content_scripts[0].js[0] = 'src/extension/content.js'
|
||||||
|
fs.writeFileSync('dist/manifest.json', JSON.stringify(pkg, null, 2))
|
||||||
|
})();
|
94
src/App.vue
94
src/App.vue
|
@ -6,9 +6,9 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { IonApp, IonRouterOutlet } from "@ionic/vue";
|
import { IonApp, IonRouterOutlet } from "@ionic/vue";
|
||||||
import { defineComponent, onBeforeMount } from "vue";
|
import { defineComponent, onBeforeMount, onMounted } from "vue";
|
||||||
import { useRoute, useRouter } from "vue-router";
|
import { useRoute, useRouter } from "vue-router";
|
||||||
import { getSettings } from '@/utils/platform'
|
import { getSettings } from "@/utils/platform";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "App",
|
name: "App",
|
||||||
|
@ -16,49 +16,57 @@ export default defineComponent({
|
||||||
IonApp,
|
IonApp,
|
||||||
IonRouterOutlet,
|
IonRouterOutlet,
|
||||||
},
|
},
|
||||||
setup () {
|
setup() {
|
||||||
const route = useRoute()
|
const route = useRoute();
|
||||||
const router = useRouter()
|
const router = useRouter();
|
||||||
const { param, rid } = route.query;
|
const { param, rid } = route.query;
|
||||||
|
|
||||||
onBeforeMount( () => {
|
onBeforeMount(() => {
|
||||||
getSettings().then((settings) => {
|
getSettings().then((settings) => {
|
||||||
if(settings.theme !== 'system') {
|
if (settings.theme !== "system") {
|
||||||
document.body.classList.remove(settings.theme === 'dark' ? 'light': 'dark')
|
document.body.classList.remove(settings.theme === "dark" ? "light" : "dark");
|
||||||
document.body.classList.add(settings.theme)
|
document.body.classList.add(settings.theme);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
switch (route?.query?.route ?? "") {
|
onMounted(() => {
|
||||||
case "sign-msg": {
|
switch (route?.query?.route ?? "") {
|
||||||
router.push({
|
case "sign-msg": {
|
||||||
path: `/sign-msg/${rid}/${param}`
|
router.push({
|
||||||
|
path: `/sign-msg/${rid}/${param}`,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "sign-tx": {
|
||||||
|
router.push({
|
||||||
|
path: `/sign-tx/${rid}/${param}`,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "switch-network": {
|
||||||
|
router.push({
|
||||||
|
path: `/switch-network/${rid}/${param}`,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "request-network": {
|
||||||
|
router.push({
|
||||||
|
path: `/request-network/${rid}/${param}`,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "wallet-error": {
|
||||||
|
router.push({
|
||||||
|
path: `/wallet-error/${rid}/${param}`,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
router.push({ path: "/" });
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
break;
|
},
|
||||||
}
|
|
||||||
case "sign-tx": {
|
|
||||||
router.push({
|
|
||||||
path: `/sign-tx/${rid}/${param}`
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "switch-network": {
|
|
||||||
router.push({
|
|
||||||
path: `/switch-network/${rid}/${param}`
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "wallet-error": {
|
|
||||||
router.push({
|
|
||||||
path: `/wallet-error/${rid}/${param}`
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
router.push({ path: "/", })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,28 @@
|
||||||
import { getSelectedNetwork, numToHexStr } from "@/utils/platform";
|
|
||||||
import type { RequestArguments } from '@/extension/types'
|
(() =>{
|
||||||
|
try {
|
||||||
|
const metamaskStub = `
|
||||||
|
// Add MetamaskAPI STUB for wallets lib to detect wallet exists
|
||||||
|
window.ethereum = {
|
||||||
|
isMetaMask: true,
|
||||||
|
isConnected: () => false
|
||||||
|
}`;
|
||||||
|
document.documentElement.setAttribute('onreset', metamaskStub);
|
||||||
|
document.documentElement.dispatchEvent(new CustomEvent('reset'));
|
||||||
|
document.documentElement.removeAttribute('onreset');
|
||||||
|
const container = document.documentElement;
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.setAttribute('async', "false")
|
||||||
|
script.setAttribute('fetchpriority', "high")
|
||||||
|
script.src = chrome.runtime.getURL('src/extension/webInject.js')
|
||||||
|
container.prepend(script)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('MetaMask: Provider injection failed.', error);
|
||||||
|
}
|
||||||
|
chrome.runtime.connect({
|
||||||
|
name: 'content'
|
||||||
|
})
|
||||||
|
})()
|
||||||
|
|
||||||
const allowedMethods = {
|
const allowedMethods = {
|
||||||
'eth_accounts': true,
|
'eth_accounts': true,
|
||||||
|
@ -27,41 +50,46 @@ const allowedMethods = {
|
||||||
'eth_signTypedData_V3': true,
|
'eth_signTypedData_V3': true,
|
||||||
'signTypedData_v4': true,
|
'signTypedData_v4': true,
|
||||||
'eth_signTypedData_v4': true,
|
'eth_signTypedData_v4': true,
|
||||||
|
'web3_clientVersion': true,
|
||||||
|
'wallet_getPermissions': true,
|
||||||
|
'net_listening': true,
|
||||||
|
'eth_coinbase': true,
|
||||||
|
'wallet_addEthereumChain': true
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("message", (event) => {
|
window.addEventListener("message", (event) => {
|
||||||
if (event.source != window)
|
if (event.source != window)
|
||||||
return;
|
return;
|
||||||
|
console.log(event)
|
||||||
if (event.data.type && (event.data.type === "CLWALLET_CONTENT")) {
|
if (event.data.type && (event.data.type === "CLWALLET_CONTENT")) {
|
||||||
event.data.data.resId = event.data.resId
|
event.data.data.resId = event.data.resId
|
||||||
event.data.data.type = "CLWALLET_CONTENT_MSG"
|
event.data.data.type = "CLWALLET_CONTENT_MSG"
|
||||||
|
event.data.data.website = document?.location?.href ?? ''
|
||||||
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 };
|
||||||
// console.log('data back', data)
|
console.log('data back', data)
|
||||||
window.postMessage(data, "*");
|
window.postMessage(data, "*");
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const data = { type: "CLWALLET_PAGE", data: { error: true, message: 'Unknown method requested'}, resId: event.data.resId };
|
const data = { type: "CLWALLET_PAGE", data: { error: true, message: 'ClearWallet: Unknown method requested ' + event?.data?.data?.method ?? ''}, resId: event.data.resId };
|
||||||
window.postMessage(data, "*");
|
window.postMessage(data, "*");
|
||||||
}
|
}
|
||||||
} else if (event.data.type && (event.data.type === "CLWALLET_PING")) {
|
} else if (event.data.type && (event.data.type === "CLWALLET_PING")) {
|
||||||
getSelectedNetwork().then(network => {
|
event.data.data.resId = event.data.resId
|
||||||
const data = { type: "CLWALLET_PAGE_LISTENER", data: {
|
event.data.data.type = "CLWALLET_CONTENT_MSG"
|
||||||
listner: 'connect',
|
event.data.data.method = "wallet_connect"
|
||||||
data: {
|
event.data.data.params = Array(0)
|
||||||
chainId: numToHexStr(network.chainId ?? 0)
|
chrome.runtime.sendMessage(event.data.data , async (res) => {
|
||||||
}
|
window.postMessage(res, "*");
|
||||||
}};
|
|
||||||
window.postMessage(data, "*");
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
chrome.runtime.onMessage.addListener((message: RequestArguments , sender, sendResponse) => {
|
chrome.runtime.onMessage.addListener((message: any , sender, sendResponse) => {
|
||||||
if(message.type === "CLWALLET_EXT_LISTNER") {
|
if(message.type === "CLWALLET_EXT_LISTNER") {
|
||||||
const data = { type: "CLWALLET_PAGE_LISTENER", data: message.data };
|
const data = { type: "CLWALLET_PAGE_LISTENER", data: message.data };
|
||||||
// console.log('data listner', data)
|
// console.log('data listner', data)
|
||||||
|
@ -70,12 +98,3 @@ chrome.runtime.onMessage.addListener((message: RequestArguments , sender, sendRe
|
||||||
return true
|
return true
|
||||||
});
|
});
|
||||||
|
|
||||||
(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,4 +1,5 @@
|
||||||
interface RequestArguments {
|
interface RequestArguments {
|
||||||
|
id?: string | undefined
|
||||||
method: string;
|
method: string;
|
||||||
params?: unknown[] | object;
|
params?: unknown[] | object;
|
||||||
}
|
}
|
||||||
|
@ -6,41 +7,37 @@ interface RequestArguments {
|
||||||
const listners = {
|
const listners = {
|
||||||
accountsChanged: new Set<(p?: any) => void>(),
|
accountsChanged: new Set<(p?: any) => void>(),
|
||||||
connect: new Set<(p?: any) => void>(),
|
connect: new Set<(p?: any) => void>(),
|
||||||
disconnect: new Set<(p?: any) => void>,
|
disconnect: new Set<(p?: any) => void>(),
|
||||||
chainChanged: new Set<(p?: any) => void>(),
|
chainChanged: new Set<(p?: any) => void>(),
|
||||||
|
once: {
|
||||||
|
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
|
const promResolvers = new Map()
|
||||||
|
|
||||||
const listner = function(event: any) {
|
const getListnersCount = (): number => {
|
||||||
if (event.source != window) return;
|
let count = 0
|
||||||
|
for(const key of Object.keys(listners)) {
|
||||||
if (event.data.type && (event.data.type === "CLWALLET_PAGE")) {
|
if(key === 'once'){
|
||||||
if(event?.data?.data?.error){
|
for(const onceKey of Object.keys(listners[key])) {
|
||||||
promResolvers[event.data.resId].reject(event.data.data);
|
count += (<any>listners)[key][onceKey]?.length
|
||||||
}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
|
|
||||||
}
|
}
|
||||||
}
|
}else {
|
||||||
|
count += (<any>listners)[key].length
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return count
|
||||||
|
}
|
||||||
window.addEventListener("message",listner)
|
|
||||||
|
|
||||||
const sendMessage = (args: RequestArguments, ping = false) => {
|
const sendMessage = (args: RequestArguments, ping = false) => {
|
||||||
if(Object.values(promResolvers).filter(r=> r).length < 10 ) {
|
if(Object.values(promResolvers).filter(r=> r).length < 10 ) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const resId = crypto.randomUUID()
|
const resId = crypto.randomUUID()
|
||||||
promResolvers[resId] = { resolve, reject }
|
promResolvers.set(resId, { resolve, reject })
|
||||||
const data = { type: "CLWALLET_CONTENT", data: args, resId};
|
const data = { type: "CLWALLET_CONTENT", data: args, resId};
|
||||||
if (ping) {
|
if (ping) {
|
||||||
data.type = 'CLWALLET_PING'
|
data.type = 'CLWALLET_PING'
|
||||||
|
@ -55,28 +52,51 @@ if(Object.values(promResolvers).filter(r=> r).length < 10 ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const eth = new Proxy({
|
class MetaMaskAPI {
|
||||||
isConnected: () => {
|
isMetaMask = true
|
||||||
return true
|
_state = {accounts: Array(1), isConnected: true, isUnlocked: true, initialized: true, isPermanentlyDisconnected: false}
|
||||||
},
|
_sentWarnings = {enable: false, experimentalMethods: false, send: false, events: {}}
|
||||||
|
// Deprecated - hardcoded for now, websites should not access this directly since is deprecated for a long time
|
||||||
|
chainId = "0x89"
|
||||||
|
// Deprecated - hardcoded for now, websites should not access this directly since is deprecated for a long time
|
||||||
|
networkVersion = "137"
|
||||||
|
selectedAddress = null
|
||||||
|
autoRefreshOnNetworkChange = false
|
||||||
|
// Internal Simulate Metamask
|
||||||
|
_events = {}
|
||||||
|
_eventsCount = 2
|
||||||
|
_jsonRpcConnection = {}
|
||||||
|
_log = {}
|
||||||
|
_maxListeners= 100
|
||||||
|
_metamask = new Proxy({
|
||||||
|
isUnlocked: () => {
|
||||||
|
return Promise.resolve(true)
|
||||||
|
},
|
||||||
|
requestBatch: () => {
|
||||||
|
// empty
|
||||||
|
},
|
||||||
|
}, {})
|
||||||
|
_rpcEngine = {
|
||||||
|
_events: {}, _eventsCount: 0, _maxListeners: undefined, _middleware: Array(4)
|
||||||
|
}
|
||||||
|
isConnected() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
// for maximum compatibility since is cloning the same API
|
// for maximum compatibility since is cloning the same API
|
||||||
isMetaMask: true,
|
|
||||||
enable: () => {
|
enable() {
|
||||||
return sendMessage({ method: 'eth_requestAccounts', params: Array(0)})
|
return sendMessage({ method: 'eth_requestAccounts', params: Array(0)})
|
||||||
},
|
}
|
||||||
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: any, arg2: any): void {
|
||||||
sendMessage(arg1 as RequestArguments).then(result => {
|
return this.send(arg1, arg2) as any
|
||||||
if (typeof arg2 === 'function'){
|
}
|
||||||
(arg2 as (r?: any) => any )(result)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// Deprecated
|
// Deprecated
|
||||||
send: (arg1: unknown, arg2: unknown): unknown => {
|
send (arg1: unknown, arg2: unknown): unknown {
|
||||||
if( typeof arg1 === 'string' ) {
|
if( typeof arg1 === 'string' ) {
|
||||||
return sendMessage({
|
return sendMessage({
|
||||||
method: arg1,
|
method: arg1,
|
||||||
|
@ -87,12 +107,31 @@ const eth = new Proxy({
|
||||||
}else {
|
}else {
|
||||||
sendMessage(arg1 as RequestArguments).then(result => {
|
sendMessage(arg1 as RequestArguments).then(result => {
|
||||||
if (typeof arg2 === 'function'){
|
if (typeof arg2 === 'function'){
|
||||||
(arg2 as (r?: any) => any )(result)
|
(arg2 as (e?: any, r?: any) => any )(undefined, {
|
||||||
|
id: (arg1 as RequestArguments)?.id,
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: (arg1 as RequestArguments).method,
|
||||||
|
result
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
}).catch( e => {
|
||||||
|
(arg2 as (er?: any, r?: any) => any )(new Error(e), {
|
||||||
|
id: (arg1 as RequestArguments)?.id,
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: (arg1 as RequestArguments).method,
|
||||||
|
error: new Error(e)
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
on: (eventName: string, callback: () => void) => {
|
on (eventName: string, callback: () => void) {
|
||||||
|
this.addListener(eventName, callback)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
addListener (eventName: string, callback: () => void) {
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
case 'accountsChanged':
|
case 'accountsChanged':
|
||||||
listners.accountsChanged.add(callback)
|
listners.accountsChanged.add(callback)
|
||||||
|
@ -104,6 +143,7 @@ const eth = new Proxy({
|
||||||
}, true)
|
}, true)
|
||||||
break;
|
break;
|
||||||
case 'disconnect':
|
case 'disconnect':
|
||||||
|
case 'close':
|
||||||
listners.disconnect.add(callback)
|
listners.disconnect.add(callback)
|
||||||
break;
|
break;
|
||||||
// Deprecated - chainIdChanged -networkChanged
|
// Deprecated - chainIdChanged -networkChanged
|
||||||
|
@ -113,8 +153,38 @@ const eth = new Proxy({
|
||||||
listners.chainChanged.add(callback)
|
listners.chainChanged.add(callback)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
return this
|
||||||
removeListener: (eventName: string, callback: () => void) => {
|
}
|
||||||
|
|
||||||
|
once (eventName: string, callback: () => void) {
|
||||||
|
switch (eventName) {
|
||||||
|
case 'accountsChanged':
|
||||||
|
listners.once.accountsChanged.add(callback)
|
||||||
|
break
|
||||||
|
case 'connect':
|
||||||
|
listners.once.connect.add(callback)
|
||||||
|
sendMessage({
|
||||||
|
method: 'wallet_ready'
|
||||||
|
}, true)
|
||||||
|
break;
|
||||||
|
case 'disconnect':
|
||||||
|
case 'close':
|
||||||
|
listners.once.disconnect.add(callback)
|
||||||
|
break;
|
||||||
|
// Deprecated - chainIdChanged -networkChanged
|
||||||
|
case 'chainChanged':
|
||||||
|
case 'chainIdChanged':
|
||||||
|
case 'networkChanged':
|
||||||
|
listners.once.chainChanged.add(callback)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
off (eventName: string, callback: () => void) {
|
||||||
|
(this).removeListener(eventName, callback)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
removeListener (eventName: string, callback: () => void) {
|
||||||
switch (eventName) {
|
switch (eventName) {
|
||||||
case 'accountsChanged':
|
case 'accountsChanged':
|
||||||
listners.accountsChanged.delete(callback)
|
listners.accountsChanged.delete(callback)
|
||||||
|
@ -123,6 +193,7 @@ const eth = new Proxy({
|
||||||
listners.connect.delete(callback)
|
listners.connect.delete(callback)
|
||||||
break;
|
break;
|
||||||
case 'disconnect':
|
case 'disconnect':
|
||||||
|
case 'close':
|
||||||
listners.disconnect.delete(callback)
|
listners.disconnect.delete(callback)
|
||||||
break;
|
break;
|
||||||
// Deprecated - chainIdChanged -networkChanged
|
// Deprecated - chainIdChanged -networkChanged
|
||||||
|
@ -134,68 +205,185 @@ const eth = new Proxy({
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
},
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAllListeners() {
|
||||||
|
listners.accountsChanged.clear()
|
||||||
|
listners.chainChanged.clear()
|
||||||
|
listners.disconnect.clear()
|
||||||
|
listners.connect.clear()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
getMaxListeners() {
|
||||||
|
return 100
|
||||||
|
}
|
||||||
|
_getExperimentalApi () {
|
||||||
|
return this._metamask
|
||||||
|
}
|
||||||
|
eventNames () {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
listenerCount () {
|
||||||
|
return getListnersCount()
|
||||||
|
}
|
||||||
|
listners() { return [] }
|
||||||
|
rawListners() { return [] }
|
||||||
// Internal Simulate Metamask
|
// Internal Simulate Metamask
|
||||||
_warnOfDeprecation: () => null,
|
_warnOfDeprecation() { return true }
|
||||||
_state: {},
|
|
||||||
_sentWarnings: () => null,
|
_rpcRequest() { return true }
|
||||||
_rpcRequest: () => null,
|
_handleAccountsChanged() { return true }
|
||||||
_handleAccountsChanged: () => null,
|
|
||||||
// Deprecated - hardcoded for now, websites should not access this directly since is deprecated for a long time
|
_handleChainChanged() { return true }
|
||||||
chainId: "0xa",
|
_handleConnect() { return true }
|
||||||
// Deprecated - hardcoded for now, websites should not access this directly since is deprecated for a long time
|
_handleDisconnect() { return true }
|
||||||
networkVersion: 10,
|
_handleStreamDisconnect() { return true }
|
||||||
selectedAddress: null,
|
_handleUnlockStateChanged() { return true }
|
||||||
autoRefreshOnNetworkChange: false,
|
_sendSync () {
|
||||||
// Internal Simulate Metamask
|
console.error('Clear Wallet: Sync calling is deprecated and not supported')
|
||||||
_events: {},
|
}
|
||||||
_eventsCount: 0,
|
}
|
||||||
_handleChainChanged: () => null,
|
|
||||||
_handleConnect: () => null,
|
const eth = new Proxy( new MetaMaskAPI(), {
|
||||||
_handleDisconnect: () => null,
|
// set: () => { return true },
|
||||||
_handleStreamDisconnect: () => null,
|
|
||||||
_handleUnlockStateChanged: () => null,
|
|
||||||
_jsonRpcConnection: {},
|
|
||||||
_log: {},
|
|
||||||
_maxListeners: 100,
|
|
||||||
_metamask: new Proxy({}, {}),
|
|
||||||
_rpcEngine: {}
|
|
||||||
}, {
|
|
||||||
set: () => { return true },
|
|
||||||
// get: function(target, name, receiver) {
|
// get: function(target, name, receiver) {
|
||||||
// if (!(name in target)) {
|
// if (typeof (<any>target)[name] == 'function') {
|
||||||
// console.log(`Getting non-existant property '" + ${name.toString()} + "'`);
|
// return function (...args: any) {
|
||||||
// return undefined;
|
// console.dir({ call: [name, ...args] });
|
||||||
|
// return undefined;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let check = true
|
||||||
|
// setTimeout(() => check = false, 400)
|
||||||
|
// while(check){
|
||||||
|
// // igmore
|
||||||
// }
|
// }
|
||||||
// console.log(target, name, receiver)
|
|
||||||
// },
|
// },
|
||||||
deleteProperty: () => { return false },
|
deleteProperty: () => { return false },
|
||||||
})
|
})
|
||||||
|
|
||||||
const injectWallet = (win: any) => {
|
const listner = function(event: any) {
|
||||||
Object.defineProperty(win, 'ethereum', {
|
if (event.source != window) return;
|
||||||
get: function () {
|
|
||||||
return eth
|
if (event.data.type && (event.data.type === "CLWALLET_PAGE")) {
|
||||||
},
|
try {
|
||||||
set: function () {
|
if(event?.data?.data?.error){
|
||||||
return true
|
promResolvers.get(event.data.resId)?.reject(event.data.data);
|
||||||
|
console.error(event?.data?.data)
|
||||||
|
}else {
|
||||||
|
promResolvers.get(event.data.resId)?.resolve(event.data.data);
|
||||||
|
}
|
||||||
|
promResolvers.delete(event.data.resId)
|
||||||
|
} catch (e) {
|
||||||
|
console.log('Failed to connect resolve msg', e)
|
||||||
}
|
}
|
||||||
});
|
} else if( event.data.type && (event.data.type === "CLWALLET_PAGE_LISTENER")) {
|
||||||
// console.log('Clear wallet injected', (window as any).ethereum, win)
|
if((event?.data?.data?.listner ?? 'x') in listners ) {
|
||||||
|
try {
|
||||||
|
const listnerName = event?.data?.data?.listner as ('accountsChanged' | 'connect' | 'disconnect' | 'chainChanged')
|
||||||
|
if( listnerName === 'connect' && event?.data?.data?.data) {
|
||||||
|
(<any>eth).networkVersion = event?.data?.data?.data?.chainId?.toString(10) ?? '137';
|
||||||
|
(<any>eth).chainId = event?.data?.data?.data?.chainId ?? '0x89';
|
||||||
|
(<any>eth).selectedAddress = event?.data?.data?.address ?? null;
|
||||||
|
(<any>eth).isConnected = () => true;
|
||||||
|
} else if( listnerName === 'chainChanged' ) {
|
||||||
|
console.log(event?.data?.data?.data);
|
||||||
|
(<any>eth).networkVersion = event?.data?.data?.data.toString(10) ?? '137';
|
||||||
|
(<any>eth).chainId = event?.data?.data?.data ?? '0x89';
|
||||||
|
} else if ( listnerName === 'accountsChanged' ) {
|
||||||
|
(<any>eth).selectedAddress = event?.data?.data?.data?.address ?? 'dummy-string';
|
||||||
|
}
|
||||||
|
listners[listnerName].forEach(listner => listner(event?.data?.data?.data));
|
||||||
|
listners.once[listnerName].forEach(listner => {
|
||||||
|
listner(event?.data?.data?.data)
|
||||||
|
listners.once[listnerName].delete(listner)
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("message",listner)
|
||||||
|
|
||||||
|
const proxy1 = new Proxy({
|
||||||
|
// on: (event: any, callback:any) => { if (event === 'message') {
|
||||||
|
// debugger;
|
||||||
|
// callback(true, true)
|
||||||
|
// } }
|
||||||
|
}, {
|
||||||
|
get: function(target, name, receiver) {
|
||||||
|
if (typeof (<any>target)[name] == 'function') {
|
||||||
|
return function (...args: any) {
|
||||||
|
console.dir({ call: [name, ...args] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('ETH', name.toString() , target, receiver);
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const proxy2 = new Proxy({
|
||||||
|
// on: (event: any, callback:any) => { if (event === 'message') {
|
||||||
|
// debugger;
|
||||||
|
// callback(true, true)
|
||||||
|
// } }
|
||||||
|
}, {
|
||||||
|
get: function(target, name, receiver) {
|
||||||
|
if (typeof (<any>target)[name] == 'function') {
|
||||||
|
return function (...args: any) {
|
||||||
|
console.dir({ call: [name, ...args] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('web3', name.toString() , target, receiver);
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const web3Shim = {
|
||||||
|
currentProvider: eth,
|
||||||
|
__isMetaMaskShim__: true
|
||||||
}
|
}
|
||||||
injectWallet(this)
|
|
||||||
|
const injectWallet = (win: any) => {
|
||||||
|
Object.defineProperty(win, 'ethereum', {
|
||||||
|
value: eth,
|
||||||
|
});
|
||||||
|
Object.defineProperty(win, 'web3', {
|
||||||
|
value: web3Shim
|
||||||
|
});
|
||||||
|
sendMessage({
|
||||||
|
method: 'wallet_ready'
|
||||||
|
}, true)
|
||||||
|
console.log('Clear wallet injected', (window as any).ethereum, win)
|
||||||
|
}
|
||||||
|
|
||||||
|
injectWallet(this);
|
||||||
|
|
||||||
// setTimeout(() => {
|
// setTimeout(() => {
|
||||||
// console.log('Metamask clone test');
|
// // 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_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_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: '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: '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: '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')});
|
// // (<any>window).ethereum.request({method: 'wallet_switchEthereumChain', params: [{chainId: "0x89"}]}).then((res: any) => { console.log(res, '111111111')});
|
||||||
// (<any>window).ethereum.on('connect', ((a: any, b: any) => console.log('connect', a, b)));
|
// // (<any>window).ethereum2.request({method: 'wallet_switchEthereumChain', params: [{chainId: "0x89"}]}).then((res: any) => { console.log(res, '111111111')});
|
||||||
// (<any>window).ethereum.on('accountsChanged', ((a: any, b: any) => console.log('accountsChanged', a, b)));
|
// // (<any>window).ethereum.on('connect', ((a: any, b: any) => console.log('connect', a, b)));
|
||||||
// (<any>window).ethereum.on('chainChanged', ((a: any) => console.log('chainChanged', a, typeof a)));
|
// // (<any>window).ethereum.on('accountsChanged', ((a: any, b: any) => console.log('accountsChanged', a, b)));
|
||||||
|
// // (<any>window).ethereum.on('chainChanged', ((a: any) => console.log('chainChanged', a, typeof a)));
|
||||||
|
// // console.log((<any>window).ethereum.on('message', (a: any, b:any) => console.log(a,b)))
|
||||||
|
// console.log((<any>window).ethereum.toString())
|
||||||
|
// console.log((<any>window).ethereum2.toString())
|
||||||
|
// console.log((<any>window).ethereum.Symbold)
|
||||||
|
|
||||||
// }, 3500)
|
// }, 3500)
|
||||||
|
|
||||||
// console.log( (window as any).ethereum.request({method: 'eth_chainId'}))
|
// console.log( (window as any).ethereum.request({method: 'eth_chainId'}))
|
|
@ -21,7 +21,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimum_chrome_version": "93",
|
"minimum_chrome_version": "93",
|
||||||
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"tabs",
|
"tabs",
|
||||||
"notifications",
|
"notifications",
|
||||||
|
@ -50,8 +49,9 @@
|
||||||
"js": ["/src/extension/content.ts"]
|
"js": ["/src/extension/content.ts"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
"web_accessible_resources": [{
|
"web_accessible_resources": [{
|
||||||
"resources": ["src/extension/inject.js"],
|
"resources": ["src/extension/inject.js", "src/extension/webInject.js", "src/extension/content.js"],
|
||||||
"matches": ["<all_urls>"]
|
"matches": ["<all_urls>"]
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,26 @@
|
||||||
import { getSelectedAccount, getSelectedNetwork, smallRandomString, getSettings, clearPk, openTab, getUrl, addToHistory } from '@/utils/platform';
|
import { getSelectedAccount, getSelectedNetwork, smallRandomString, getSettings, clearPk, openTab, getUrl, addToHistory, getNetworks, strToHex } from '@/utils/platform';
|
||||||
import { userApprove, userReject, rIdWin, rIdData } from '@/extension/userRequest'
|
import { userApprove, userReject, rIdWin, rIdData } from '@/extension/userRequest'
|
||||||
import { signMsg, getBalance, getBlockNumber, estimateGas, sendTransaction, getGasPrice, getBlockByNumber, evmCall, getTxByHash, getTxReceipt, signTypedData } from '@/utils/wallet'
|
import { signMsg, getBalance, getBlockNumber, estimateGas, sendTransaction, getGasPrice, getBlockByNumber, evmCall, getTxByHash, getTxReceipt, signTypedData } from '@/utils/wallet'
|
||||||
import type { RequestArguments } from '@/extension/types'
|
import type { RequestArguments } from '@/extension/types'
|
||||||
import { rpcError } from '@/extension/rpcConstants'
|
import { rpcError } from '@/extension/rpcConstants'
|
||||||
import { updatePrices } from '@/utils/gecko'
|
import { updatePrices } from '@/utils/gecko'
|
||||||
|
import { mainNets, testNets } from '@/utils/networks'
|
||||||
|
|
||||||
let notificationUrl: string
|
let notificationUrl: string
|
||||||
|
|
||||||
chrome.runtime.onInstalled.addListener(() => {
|
chrome.runtime.onInstalled.addListener(() => {
|
||||||
console.log('Service worker installed');
|
console.log('Service worker installed');
|
||||||
|
|
||||||
|
chrome.runtime.onConnect.addListener(port => port.onDisconnect.addListener(() =>
|
||||||
|
{
|
||||||
|
console.log('Service worker connected');
|
||||||
|
}))
|
||||||
|
|
||||||
chrome.runtime.connect(null as unknown as string, {
|
chrome.runtime.connect(null as unknown as string, {
|
||||||
name:'sw-connection'
|
name:'sw-connection'
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
chrome.runtime.onConnect.addListener(port => port.onDisconnect.addListener(() =>
|
|
||||||
{
|
|
||||||
console.log('Service worker connected');
|
|
||||||
}))
|
|
||||||
|
|
||||||
|
|
||||||
chrome.runtime.onStartup.addListener(() => {
|
chrome.runtime.onStartup.addListener(() => {
|
||||||
console.log('Service worker startup');
|
console.log('Service worker startup');
|
||||||
})
|
})
|
||||||
|
@ -78,12 +79,12 @@ if (!chrome.notifications.onButtonClicked.hasListener(viewTxListner)){
|
||||||
chrome.notifications.onButtonClicked.addListener(viewTxListner)
|
chrome.notifications.onButtonClicked.addListener(viewTxListner)
|
||||||
}
|
}
|
||||||
|
|
||||||
chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendResponse) => {
|
const mainListner = (message: RequestArguments, sender:any, sendResponse: (a: any) => any) => {
|
||||||
if(message?.type !== "CLWALLET_CONTENT_MSG") {
|
if(message?.type !== "CLWALLET_CONTENT_MSG") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
(async () => {
|
(async () => {
|
||||||
if (!('method' in message)) {
|
if (!(message?.method)) {
|
||||||
sendResponse({
|
sendResponse({
|
||||||
code: 500,
|
code: 500,
|
||||||
message: 'Invalid request method'
|
message: 'Invalid request method'
|
||||||
|
@ -245,7 +246,7 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||||
await chrome.windows.create({
|
await chrome.windows.create({
|
||||||
height: 450,
|
height: 450,
|
||||||
width: 400,
|
width: 400,
|
||||||
url: chrome.runtime.getURL(`index.html?route=wallet-error¶m=${encodeURIComponent('No account is selected you need to have an account selected before trying to make a transaction')}&rid=${String(message?.resId ?? '')}`),
|
url: chrome.runtime.getURL(`index.html?route=wallet-error¶m=${strToHex('No account is selected you need to have an account selected before trying to make a transaction')}&rid=${String(message?.resId ?? '')}`),
|
||||||
type: 'popup'
|
type: 'popup'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
@ -254,13 +255,13 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||||
await chrome.windows.create({
|
await chrome.windows.create({
|
||||||
height: 450,
|
height: 450,
|
||||||
width: 400,
|
width: 400,
|
||||||
url: chrome.runtime.getURL(`index.html?route=wallet-error¶m=${encodeURIComponent('No network is selected you need to have a network selected before trying to make a transaction')}&rid=${String(message?.resId ?? '')}`),
|
url: chrome.runtime.getURL(`index.html?route=wallet-error¶m=${strToHex('No network is selected you need to have a network selected before trying to make a transaction')}&rid=${String(message?.resId ?? '')}`),
|
||||||
type: 'popup'
|
type: 'popup'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
params.from = account.address
|
params.from = account.address
|
||||||
const serializeParams = encodeURIComponent(JSON.stringify(params)) ?? ''
|
const serializeParams = strToHex(JSON.stringify(params)) ?? ''
|
||||||
const pEstimateGas = estimateGas({
|
const pEstimateGas = estimateGas({
|
||||||
to: params?.to ?? '',
|
to: params?.to ?? '',
|
||||||
from: params?.from ?? '',
|
from: params?.from ?? '',
|
||||||
|
@ -332,7 +333,7 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||||
chrome.windows.create({
|
chrome.windows.create({
|
||||||
height: 450,
|
height: 450,
|
||||||
width: 400,
|
width: 400,
|
||||||
url: chrome.runtime.getURL(`index.html?route=wallet-error¶m=${encodeURIComponent(String(err))}&rid=${String(message?.resId ?? '')}`),
|
url: chrome.runtime.getURL(`index.html?route=wallet-error¶m=${strToHex(String(err))}&rid=${String(message?.resId ?? '')}`),
|
||||||
type: 'popup'
|
type: 'popup'
|
||||||
})
|
})
|
||||||
chrome.notifications.create({
|
chrome.notifications.create({
|
||||||
|
@ -370,7 +371,7 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||||
await chrome.windows.create({
|
await chrome.windows.create({
|
||||||
height: 450,
|
height: 450,
|
||||||
width: 400,
|
width: 400,
|
||||||
url: chrome.runtime.getURL(`index.html?route=wallet-error¶m=${encodeURIComponent('No account is selected you need to have an account selected before trying sign a message')}&rid=${String(message?.resId ?? '')}`),
|
url: chrome.runtime.getURL(`index.html?route=wallet-error¶m=${strToHex('No account is selected you need to have an account selected before trying sign a message')}&rid=${String(message?.resId ?? '')}`),
|
||||||
type: 'popup'
|
type: 'popup'
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
@ -391,7 +392,7 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||||
chrome.windows.create({
|
chrome.windows.create({
|
||||||
height: 450,
|
height: 450,
|
||||||
width: 400,
|
width: 400,
|
||||||
url: chrome.runtime.getURL(`index.html?route=sign-msg¶m=${signMsgData}&rid=${String(message?.resId ?? '')}`),
|
url: chrome.runtime.getURL(`index.html?route=sign-msg¶m=${strToHex(signMsgData)}&rid=${String(message?.resId ?? '')}`),
|
||||||
type: 'popup'
|
type: 'popup'
|
||||||
}).then((win) => {
|
}).then((win) => {
|
||||||
userReject[String(win.id)] = reject
|
userReject[String(win.id)] = reject
|
||||||
|
@ -419,19 +420,34 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// NON Standard metamask API
|
// NON Standard / metamask API
|
||||||
|
case 'eth_coinbase': {
|
||||||
|
const account = await getSelectedAccount()
|
||||||
|
const address = account?.address ?? null
|
||||||
|
sendResponse(address)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'net_listening': {
|
||||||
|
sendResponse(true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'web3_clientVersion': {
|
||||||
|
sendResponse("MetaMask/v10.20.0")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'wallet_getPermissions':
|
||||||
case 'wallet_requestPermissions': {
|
case 'wallet_requestPermissions': {
|
||||||
const account = await getSelectedAccount()
|
const account = await getSelectedAccount()
|
||||||
const address = account?.address ? [account?.address] : []
|
const address = account?.address ? [account?.address] : []
|
||||||
sendResponse([{
|
sendResponse([{
|
||||||
caveats: {
|
id: smallRandomString(21),
|
||||||
type:'',
|
parentCapability: 'eth_accounts',
|
||||||
|
invoker: message?.website?.split('/').slice(0,3).join('/') ?? '',
|
||||||
|
caveats: [{
|
||||||
|
type:'restrictReturnedAccounts',
|
||||||
value: address
|
value: address
|
||||||
},
|
}],
|
||||||
invoker: '',
|
|
||||||
date: Date.now(),
|
date: Date.now(),
|
||||||
id: smallRandomString(),
|
|
||||||
parentCapability: Object.keys(message?.params?.[0] ?? {})?.[0] ?? 'unknown'
|
|
||||||
}])
|
}])
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -443,6 +459,10 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||||
}
|
}
|
||||||
case 'wallet_switchEthereumChain': {
|
case 'wallet_switchEthereumChain': {
|
||||||
try {
|
try {
|
||||||
|
const currentChainId = `0x${((await getSelectedNetwork())?.chainId ?? 0).toString(16)}`
|
||||||
|
if(currentChainId === String(message?.params?.[0]?.chainId ?? '' )) {
|
||||||
|
sendResponse(null)
|
||||||
|
}else {
|
||||||
await new Promise((resolve, reject) => {
|
await new Promise((resolve, reject) => {
|
||||||
chrome.windows.create({
|
chrome.windows.create({
|
||||||
height: 450,
|
height: 450,
|
||||||
|
@ -454,19 +474,89 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||||
userApprove[String(win.id)] = resolve
|
userApprove[String(win.id)] = resolve
|
||||||
rIdWin[String(win.id)] = String(message.resId)
|
rIdWin[String(win.id)] = String(message.resId)
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
||||||
sendResponse(null)
|
sendResponse(null)
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
sendResponse({
|
sendResponse({
|
||||||
error: true,
|
error: true,
|
||||||
code: rpcError.USER_REJECTED,
|
code: rpcError.USER_REJECTED,
|
||||||
message: 'User Rejected Signature'
|
message: 'User Rejected chain switch'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
case 'wallet_addEthereumChain': {
|
||||||
|
const userNetworks = await getNetworks()
|
||||||
|
const networks = {...mainNets, ...testNets, ...userNetworks}
|
||||||
|
const chainId = Number(message?.params?.[0]?.chainId ?? '0')
|
||||||
|
if(!chainId) {
|
||||||
|
sendResponse({
|
||||||
|
error: true,
|
||||||
|
code: rpcError.USER_REJECTED,
|
||||||
|
message: 'Invalid Network'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if( chainId in networks ) {
|
||||||
|
mainListner({...message, method:'wallet_switchEthereumChain', params: [{
|
||||||
|
chainId: `0x${(chainId).toString(16)}`
|
||||||
|
}] }, sender, sendResponse)
|
||||||
|
} else {
|
||||||
|
if ( !message?.params?.[0]?.chainId ||
|
||||||
|
!message?.params?.[0]?.chainName ||
|
||||||
|
!message?.params?.[0]?.rpcUrls ||
|
||||||
|
!message?.params?.[0]?.blockExplorerUrls ||
|
||||||
|
!message?.params?.[0]?.nativeCurrency?.symbol
|
||||||
|
){
|
||||||
|
sendResponse({
|
||||||
|
error: true,
|
||||||
|
code: rpcError.USER_REJECTED,
|
||||||
|
message: 'Invalid Network params chainId, chainName, rpcUrls, blockExplorerUrls, and nativeCurrency are required'
|
||||||
|
})
|
||||||
|
}else {
|
||||||
|
try {
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
chrome.windows.create({
|
||||||
|
height: 450,
|
||||||
|
width: 400,
|
||||||
|
url: chrome.runtime.getURL(`index.html?route=request-network¶m=${strToHex(JSON.stringify({...{website: message?.website ?? ''}, ...(message?.params?.[0] ?? {})}) ?? '')}&rid=${String(message?.resId ?? '')}`),
|
||||||
|
type: 'popup'
|
||||||
|
}).then((win) => {
|
||||||
|
userReject[String(win.id)] = reject
|
||||||
|
userApprove[String(win.id)] = resolve
|
||||||
|
rIdWin[String(win.id)] = String(message.resId)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
sendResponse(null)
|
||||||
|
} catch (err) {
|
||||||
|
console.log('err')
|
||||||
|
sendResponse({
|
||||||
|
error: true,
|
||||||
|
code: rpcError.USER_REJECTED,
|
||||||
|
message: 'User Rejected adding network'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
// internal messeges
|
// internal messeges
|
||||||
|
case 'wallet_connect': {
|
||||||
|
const pNetwork = getSelectedNetwork()
|
||||||
|
const pAccount = getSelectedAccount()
|
||||||
|
const [network, account] = await Promise.all([pNetwork, pAccount])
|
||||||
|
const address = account?.address ? [account?.address] : []
|
||||||
|
const chainId = `0x${(network?.chainId ?? 0).toString(16)}`
|
||||||
|
const data = { type: "CLWALLET_PAGE_LISTENER", data: {
|
||||||
|
listner: 'connect',
|
||||||
|
data: {
|
||||||
|
chainId
|
||||||
|
},
|
||||||
|
address
|
||||||
|
}};
|
||||||
|
sendResponse(data)
|
||||||
|
break
|
||||||
|
}
|
||||||
case 'wallet_approve': {
|
case 'wallet_approve': {
|
||||||
if(String(sender.tab?.windowId) in rIdWin){
|
if(String(sender.tab?.windowId) in rIdWin){
|
||||||
userApprove[String(sender.tab?.windowId)]?.(true)
|
userApprove[String(sender.tab?.windowId)]?.(true)
|
||||||
|
@ -500,7 +590,7 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||||
sendResponse({
|
sendResponse({
|
||||||
error: true,
|
error: true,
|
||||||
code: rpcError.INVALID_PARAM,
|
code: rpcError.INVALID_PARAM,
|
||||||
message: 'Invalid request method'
|
message: 'ClearWallet: Invalid request method ' + message?.method ?? ''
|
||||||
})
|
})
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -509,4 +599,6 @@ chrome.runtime.onMessage.addListener((message: RequestArguments, sender, sendRes
|
||||||
}
|
}
|
||||||
)();
|
)();
|
||||||
return true;
|
return true;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
chrome.runtime.onMessage.addListener(mainListner);
|
||||||
|
|
|
@ -0,0 +1,399 @@
|
||||||
|
const container = document.head
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.setAttribute('async', "false")
|
||||||
|
script.textContent = `
|
||||||
|
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
||||||
|
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
||||||
|
if (ar || !(i in from)) {
|
||||||
|
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
||||||
|
ar[i] = from[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return to.concat(ar || Array.prototype.slice.call(from));
|
||||||
|
};
|
||||||
|
var listners = {
|
||||||
|
accountsChanged: new Set(),
|
||||||
|
connect: new Set(),
|
||||||
|
disconnect: new Set(),
|
||||||
|
chainChanged: new Set(),
|
||||||
|
once: {
|
||||||
|
accountsChanged: new Set(),
|
||||||
|
connect: new Set(),
|
||||||
|
disconnect: new Set(),
|
||||||
|
chainChanged: new Set()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var promResolvers = new Map();
|
||||||
|
var getListnersCount = function () {
|
||||||
|
var _a;
|
||||||
|
var count = 0;
|
||||||
|
for (var _i = 0, _b = Object.keys(listners); _i < _b.length; _i++) {
|
||||||
|
var key = _b[_i];
|
||||||
|
if (key === 'once') {
|
||||||
|
for (var _c = 0, _d = Object.keys(listners[key]); _c < _d.length; _c++) {
|
||||||
|
var onceKey = _d[_c];
|
||||||
|
count += (_a = listners[key][onceKey]) === null || _a === void 0 ? void 0 : _a.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
count += listners[key].length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
};
|
||||||
|
var sendMessage = function (args, ping) {
|
||||||
|
if (ping === void 0) { ping = false; }
|
||||||
|
if (Object.values(promResolvers).filter(function (r) { return r; }).length < 10) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
var resId = crypto.randomUUID();
|
||||||
|
promResolvers.set(resId, { resolve: resolve, reject: reject });
|
||||||
|
var data = { type: "CLWALLET_CONTENT", data: args, resId: resId };
|
||||||
|
if (ping) {
|
||||||
|
data.type = 'CLWALLET_PING';
|
||||||
|
}
|
||||||
|
// console.log('data in', data)
|
||||||
|
window.postMessage(data, "*");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
reject(new Error("You have reached the maximum number of concurent wallet messeges."));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var MetaMaskAPI = /** @class */ (function () {
|
||||||
|
function MetaMaskAPI() {
|
||||||
|
this.isMetaMask = true;
|
||||||
|
this._state = { accounts: Array(1), isConnected: true, isUnlocked: true, initialized: true, isPermanentlyDisconnected: false };
|
||||||
|
this._sentWarnings = { enable: false, experimentalMethods: false, send: false, events: {} };
|
||||||
|
// Deprecated - hardcoded for now, websites should not access this directly since is deprecated for a long time
|
||||||
|
this.chainId = "0x89";
|
||||||
|
// Deprecated - hardcoded for now, websites should not access this directly since is deprecated for a long time
|
||||||
|
this.networkVersion = "137";
|
||||||
|
this.selectedAddress = null;
|
||||||
|
this.autoRefreshOnNetworkChange = false;
|
||||||
|
// Internal Simulate Metamask
|
||||||
|
this._events = {};
|
||||||
|
this._eventsCount = 2;
|
||||||
|
this._jsonRpcConnection = {};
|
||||||
|
this._log = {};
|
||||||
|
this._maxListeners = 100;
|
||||||
|
this._metamask = new Proxy({
|
||||||
|
isUnlocked: function () {
|
||||||
|
return Promise.resolve(true);
|
||||||
|
},
|
||||||
|
requestBatch: function () {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
}, {});
|
||||||
|
this._rpcEngine = {
|
||||||
|
_events: {}, _eventsCount: 0, _maxListeners: undefined, _middleware: Array(4)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
MetaMaskAPI.prototype.isConnected = function () {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
// for maximum compatibility since is cloning the same API
|
||||||
|
MetaMaskAPI.prototype.enable = function () {
|
||||||
|
return sendMessage({ method: 'eth_requestAccounts', params: Array(0) });
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.request = function (args) {
|
||||||
|
return sendMessage(args);
|
||||||
|
};
|
||||||
|
// Deprecated
|
||||||
|
MetaMaskAPI.prototype.sendAsync = function (arg1, arg2) {
|
||||||
|
return this.send(arg1, arg2);
|
||||||
|
};
|
||||||
|
// Deprecated
|
||||||
|
MetaMaskAPI.prototype.send = function (arg1, arg2) {
|
||||||
|
if (typeof arg1 === 'string') {
|
||||||
|
return sendMessage({
|
||||||
|
method: arg1,
|
||||||
|
params: arg2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if (arg2 === undefined) {
|
||||||
|
console.error('Clear Wallet: Sync calling is deprecated and not supported');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sendMessage(arg1).then(function (result) {
|
||||||
|
if (typeof arg2 === 'function') {
|
||||||
|
arg2(undefined, {
|
||||||
|
id: arg1 === null || arg1 === void 0 ? void 0 : arg1.id,
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: arg1.method,
|
||||||
|
result: result
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})["catch"](function (e) {
|
||||||
|
arg2(new Error(e), {
|
||||||
|
id: arg1 === null || arg1 === void 0 ? void 0 : arg1.id,
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: arg1.method,
|
||||||
|
error: new Error(e)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.on = function (eventName, callback) {
|
||||||
|
this.addListener(eventName, callback);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.addListener = function (eventName, callback) {
|
||||||
|
switch (eventName) {
|
||||||
|
case 'accountsChanged':
|
||||||
|
listners.accountsChanged.add(callback);
|
||||||
|
break;
|
||||||
|
case 'connect':
|
||||||
|
listners.connect.add(callback);
|
||||||
|
sendMessage({
|
||||||
|
method: 'wallet_ready'
|
||||||
|
}, true);
|
||||||
|
break;
|
||||||
|
case 'disconnect':
|
||||||
|
case 'close':
|
||||||
|
listners.disconnect.add(callback);
|
||||||
|
break;
|
||||||
|
// Deprecated - chainIdChanged -networkChanged
|
||||||
|
case 'chainChanged':
|
||||||
|
case 'chainIdChanged':
|
||||||
|
case 'networkChanged':
|
||||||
|
listners.chainChanged.add(callback);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.once = function (eventName, callback) {
|
||||||
|
switch (eventName) {
|
||||||
|
case 'accountsChanged':
|
||||||
|
listners.once.accountsChanged.add(callback);
|
||||||
|
break;
|
||||||
|
case 'connect':
|
||||||
|
listners.once.connect.add(callback);
|
||||||
|
sendMessage({
|
||||||
|
method: 'wallet_ready'
|
||||||
|
}, true);
|
||||||
|
break;
|
||||||
|
case 'disconnect':
|
||||||
|
case 'close':
|
||||||
|
listners.once.disconnect.add(callback);
|
||||||
|
break;
|
||||||
|
// Deprecated - chainIdChanged -networkChanged
|
||||||
|
case 'chainChanged':
|
||||||
|
case 'chainIdChanged':
|
||||||
|
case 'networkChanged':
|
||||||
|
listners.once.chainChanged.add(callback);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.off = function (eventName, callback) {
|
||||||
|
(this).removeListener(eventName, callback);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.removeListener = function (eventName, callback) {
|
||||||
|
switch (eventName) {
|
||||||
|
case 'accountsChanged':
|
||||||
|
listners.accountsChanged["delete"](callback);
|
||||||
|
break;
|
||||||
|
case 'connect':
|
||||||
|
listners.connect["delete"](callback);
|
||||||
|
break;
|
||||||
|
case 'disconnect':
|
||||||
|
case 'close':
|
||||||
|
listners.disconnect["delete"](callback);
|
||||||
|
break;
|
||||||
|
// Deprecated - chainIdChanged -networkChanged
|
||||||
|
case 'chainChanged':
|
||||||
|
case 'chainIdChanged':
|
||||||
|
case 'networkChanged':
|
||||||
|
listners.chainChanged["delete"](callback);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.removeAllListeners = function () {
|
||||||
|
listners.accountsChanged.clear();
|
||||||
|
listners.chainChanged.clear();
|
||||||
|
listners.disconnect.clear();
|
||||||
|
listners.connect.clear();
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.getMaxListeners = function () {
|
||||||
|
return 100;
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype._getExperimentalApi = function () {
|
||||||
|
return this._metamask;
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.eventNames = function () {
|
||||||
|
return [];
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.listenerCount = function () {
|
||||||
|
return getListnersCount();
|
||||||
|
};
|
||||||
|
MetaMaskAPI.prototype.listners = function () { return []; };
|
||||||
|
MetaMaskAPI.prototype.rawListners = function () { return []; };
|
||||||
|
// Internal Simulate Metamask
|
||||||
|
MetaMaskAPI.prototype._warnOfDeprecation = function () { return true; };
|
||||||
|
MetaMaskAPI.prototype._rpcRequest = function () { return true; };
|
||||||
|
MetaMaskAPI.prototype._handleAccountsChanged = function () { return true; };
|
||||||
|
MetaMaskAPI.prototype._handleChainChanged = function () { return true; };
|
||||||
|
MetaMaskAPI.prototype._handleConnect = function () { return true; };
|
||||||
|
MetaMaskAPI.prototype._handleDisconnect = function () { return true; };
|
||||||
|
MetaMaskAPI.prototype._handleStreamDisconnect = function () { return true; };
|
||||||
|
MetaMaskAPI.prototype._handleUnlockStateChanged = function () { return true; };
|
||||||
|
MetaMaskAPI.prototype._sendSync = function () {
|
||||||
|
console.error('Clear Wallet: Sync calling is deprecated and not supported');
|
||||||
|
};
|
||||||
|
return MetaMaskAPI;
|
||||||
|
}());
|
||||||
|
var eth = new Proxy(new MetaMaskAPI(), {
|
||||||
|
// set: () => { return true },
|
||||||
|
// get: function(target, name, receiver) {
|
||||||
|
// if (typeof (<any>target)[name] == 'function') {
|
||||||
|
// return function (...args: any) {
|
||||||
|
// console.dir({ call: [name, ...args] });
|
||||||
|
// return undefined;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// let check = true
|
||||||
|
// setTimeout(() => check = false, 400)
|
||||||
|
// while(check){
|
||||||
|
// // igmore
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
deleteProperty: function () { return false; }
|
||||||
|
});
|
||||||
|
var listner = function (event) {
|
||||||
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11;
|
||||||
|
if (event.source != window)
|
||||||
|
return;
|
||||||
|
if (event.data.type && (event.data.type === "CLWALLET_PAGE")) {
|
||||||
|
try {
|
||||||
|
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) {
|
||||||
|
(_c = promResolvers.get(event.data.resId)) === null || _c === void 0 ? void 0 : _c.reject(event.data.data);
|
||||||
|
console.error((_d = event === null || event === void 0 ? void 0 : event.data) === null || _d === void 0 ? void 0 : _d.data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(_e = promResolvers.get(event.data.resId)) === null || _e === void 0 ? void 0 : _e.resolve(event.data.data);
|
||||||
|
}
|
||||||
|
promResolvers["delete"](event.data.resId);
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.log('Failed to connect resolve msg', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (event.data.type && (event.data.type === "CLWALLET_PAGE_LISTENER")) {
|
||||||
|
if (((_h = (_g = (_f = event === null || event === void 0 ? void 0 : event.data) === null || _f === void 0 ? void 0 : _f.data) === null || _g === void 0 ? void 0 : _g.listner) !== null && _h !== void 0 ? _h : 'x') in listners) {
|
||||||
|
try {
|
||||||
|
var listnerName_1 = (_k = (_j = event === null || event === void 0 ? void 0 : event.data) === null || _j === void 0 ? void 0 : _j.data) === null || _k === void 0 ? void 0 : _k.listner;
|
||||||
|
if (listnerName_1 === 'connect' && ((_m = (_l = event === null || event === void 0 ? void 0 : event.data) === null || _l === void 0 ? void 0 : _l.data) === null || _m === void 0 ? void 0 : _m.data)) {
|
||||||
|
eth.networkVersion = (_s = (_r = (_q = (_p = (_o = event === null || event === void 0 ? void 0 : event.data) === null || _o === void 0 ? void 0 : _o.data) === null || _p === void 0 ? void 0 : _p.data) === null || _q === void 0 ? void 0 : _q.chainId) === null || _r === void 0 ? void 0 : _r.toString(10)) !== null && _s !== void 0 ? _s : '137';
|
||||||
|
eth.chainId = (_w = (_v = (_u = (_t = event === null || event === void 0 ? void 0 : event.data) === null || _t === void 0 ? void 0 : _t.data) === null || _u === void 0 ? void 0 : _u.data) === null || _v === void 0 ? void 0 : _v.chainId) !== null && _w !== void 0 ? _w : '0x89';
|
||||||
|
eth.selectedAddress = (_z = (_y = (_x = event === null || event === void 0 ? void 0 : event.data) === null || _x === void 0 ? void 0 : _x.data) === null || _y === void 0 ? void 0 : _y.address) !== null && _z !== void 0 ? _z : null;
|
||||||
|
eth.isConnected = function () { return true; };
|
||||||
|
}
|
||||||
|
else if (listnerName_1 === 'chainChanged') {
|
||||||
|
console.log((_1 = (_0 = event === null || event === void 0 ? void 0 : event.data) === null || _0 === void 0 ? void 0 : _0.data) === null || _1 === void 0 ? void 0 : _1.data);
|
||||||
|
eth.networkVersion = (_4 = (_3 = (_2 = event === null || event === void 0 ? void 0 : event.data) === null || _2 === void 0 ? void 0 : _2.data) === null || _3 === void 0 ? void 0 : _3.data.toString(10)) !== null && _4 !== void 0 ? _4 : '137';
|
||||||
|
eth.chainId = (_7 = (_6 = (_5 = event === null || event === void 0 ? void 0 : event.data) === null || _5 === void 0 ? void 0 : _5.data) === null || _6 === void 0 ? void 0 : _6.data) !== null && _7 !== void 0 ? _7 : '0x89';
|
||||||
|
}
|
||||||
|
else if (listnerName_1 === 'accountsChanged') {
|
||||||
|
eth.selectedAddress = (_11 = (_10 = (_9 = (_8 = event === null || event === void 0 ? void 0 : event.data) === null || _8 === void 0 ? void 0 : _8.data) === null || _9 === void 0 ? void 0 : _9.data) === null || _10 === void 0 ? void 0 : _10.address) !== null && _11 !== void 0 ? _11 : 'dummy-string';
|
||||||
|
}
|
||||||
|
listners[listnerName_1].forEach(function (listner) { var _a, _b; return listner((_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.data); });
|
||||||
|
listners.once[listnerName_1].forEach(function (listner) {
|
||||||
|
var _a, _b;
|
||||||
|
listner((_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.data);
|
||||||
|
listners.once[listnerName_1]["delete"](listner);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("message", listner);
|
||||||
|
var proxy1 = new Proxy({
|
||||||
|
// on: (event: any, callback:any) => { if (event === 'message') {
|
||||||
|
// debugger;
|
||||||
|
// callback(true, true)
|
||||||
|
// } }
|
||||||
|
}, {
|
||||||
|
get: function (target, name, receiver) {
|
||||||
|
if (typeof target[name] == 'function') {
|
||||||
|
return function () {
|
||||||
|
var args = [];
|
||||||
|
for (var _i = 0; _i < arguments.length; _i++) {
|
||||||
|
args[_i] = arguments[_i];
|
||||||
|
}
|
||||||
|
console.dir({ call: __spreadArray([name], args, true) });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log('ETH', name.toString(), target, receiver);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var proxy2 = new Proxy({
|
||||||
|
// on: (event: any, callback:any) => { if (event === 'message') {
|
||||||
|
// debugger;
|
||||||
|
// callback(true, true)
|
||||||
|
// } }
|
||||||
|
}, {
|
||||||
|
get: function (target, name, receiver) {
|
||||||
|
if (typeof target[name] == 'function') {
|
||||||
|
return function () {
|
||||||
|
var args = [];
|
||||||
|
for (var _i = 0; _i < arguments.length; _i++) {
|
||||||
|
args[_i] = arguments[_i];
|
||||||
|
}
|
||||||
|
console.dir({ call: __spreadArray([name], args, true) });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
console.log('web3', name.toString(), target, receiver);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var web3Shim = {
|
||||||
|
currentProvider: eth,
|
||||||
|
__isMetaMaskShim__: true
|
||||||
|
};
|
||||||
|
var injectWallet = function (win) {
|
||||||
|
Object.defineProperty(win, 'ethereum', {
|
||||||
|
value: eth
|
||||||
|
});
|
||||||
|
Object.defineProperty(win, 'web3', {
|
||||||
|
value: web3Shim
|
||||||
|
});
|
||||||
|
sendMessage({
|
||||||
|
method: 'wallet_ready'
|
||||||
|
}, true);
|
||||||
|
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')});
|
||||||
|
// // (<any>window).ethereum.request({method: 'wallet_switchEthereumChain', params: [{chainId: "0x89"}]}).then((res: any) => { console.log(res, '111111111')});
|
||||||
|
// // (<any>window).ethereum2.request({method: 'wallet_switchEthereumChain', params: [{chainId: "0x89"}]}).then((res: any) => { console.log(res, '111111111')});
|
||||||
|
// // (<any>window).ethereum.on('connect', ((a: any, b: any) => console.log('connect', a, b)));
|
||||||
|
// // (<any>window).ethereum.on('accountsChanged', ((a: any, b: any) => console.log('accountsChanged', a, b)));
|
||||||
|
// // (<any>window).ethereum.on('chainChanged', ((a: any) => console.log('chainChanged', a, typeof a)));
|
||||||
|
// // console.log((<any>window).ethereum.on('message', (a: any, b:any) => console.log(a,b)))
|
||||||
|
// console.log((<any>window).ethereum.toString())
|
||||||
|
// console.log((<any>window).ethereum2.toString())
|
||||||
|
// console.log((<any>window).ethereum.Symbold)
|
||||||
|
// }, 3500)
|
||||||
|
// console.log( (window as any).ethereum.request({method: 'eth_chainId'}))
|
||||||
|
|
||||||
|
`
|
||||||
|
container.prepend(script);
|
||||||
|
script.parentElement?.removeChild(script)
|
|
@ -1,7 +1,6 @@
|
||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router';
|
import router from './router';
|
||||||
|
|
||||||
import { IonicVue } from '@ionic/vue';
|
import { IonicVue } from '@ionic/vue';
|
||||||
|
|
||||||
/* Core CSS required for Ionic components to work properly */
|
/* Core CSS required for Ionic components to work properly */
|
||||||
|
|
|
@ -27,6 +27,10 @@ const routes: Array<RouteRecordRaw> = [
|
||||||
path: '/wallet-error/:rid/:param',
|
path: '/wallet-error/:rid/:param',
|
||||||
component: () => import('@/views/WalletError.vue'),
|
component: () => import('@/views/WalletError.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/request-network/:rid/:param',
|
||||||
|
component: () => import('@/views/RequestNetwork.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/tabs/',
|
path: '/tabs/',
|
||||||
component: AppTabs,
|
component: AppTabs,
|
||||||
|
|
|
@ -137,8 +137,16 @@ export const getRandomPk = () => {
|
||||||
).substring(0, 66)
|
).substring(0, 66)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const smallRandomString = () => {
|
export const smallRandomString = (size = 7) => {
|
||||||
return (Math.random() + 1).toString(36).substring(7);
|
if(size <= 7) {
|
||||||
|
return (Math.random() + 1).toString(36).substring(0,7);
|
||||||
|
} else {
|
||||||
|
let str = ''
|
||||||
|
for(let i = 0; i < (size / 7) << 0; i++){
|
||||||
|
str+=(Math.random() + i).toString(36).substring(0,7);
|
||||||
|
}
|
||||||
|
return str.substring(0, size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const clearPk = async (): Promise<void> => {
|
export const clearPk = async (): Promise<void> => {
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
<template>
|
||||||
|
<ion-page>
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Add and Switch Network</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content class="ion-padding">
|
||||||
|
<ion-item>
|
||||||
|
<ion-text>{{ website }}</ion-text>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item>
|
||||||
|
<ion-text>has requested network you to add and switch to the following</ion-text>
|
||||||
|
</ion-item>
|
||||||
|
<ion-list>
|
||||||
|
<ion-item>
|
||||||
|
<ion-list>
|
||||||
|
<ion-item><b>NETWORK:</b></ion-item>
|
||||||
|
<ion-item>
|
||||||
|
<ion-list>
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>Name:</ion-label>
|
||||||
|
<ion-input
|
||||||
|
style="margin-left: 0.5rem"
|
||||||
|
v-model="name"
|
||||||
|
readonly
|
||||||
|
placeholder="ex: Polygon"
|
||||||
|
></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item>
|
||||||
|
<ion-label>ChainId: </ion-label>
|
||||||
|
<ion-input
|
||||||
|
style="margin-left: 0.5rem"
|
||||||
|
v-model="chainId"
|
||||||
|
readonly
|
||||||
|
placeholder="137"
|
||||||
|
></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item button>
|
||||||
|
<ion-label>RPC URL: </ion-label>
|
||||||
|
<ion-input
|
||||||
|
style="margin-left: 0.5rem"
|
||||||
|
readonly
|
||||||
|
placeholder="https://polygon-mainnet.g.alchemy.com/..."
|
||||||
|
v-model="rpc"
|
||||||
|
></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item button>
|
||||||
|
<ion-label>Native Token Symbol: </ion-label>
|
||||||
|
<ion-input
|
||||||
|
style="margin-left: 0.5rem"
|
||||||
|
readonly
|
||||||
|
placeholder="MATIC"
|
||||||
|
v-model="symbol"
|
||||||
|
></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item button>
|
||||||
|
<ion-label>Explorer: </ion-label>
|
||||||
|
<ion-input
|
||||||
|
style="margin-left: 0.5rem"
|
||||||
|
readonly
|
||||||
|
placeholder="https://polygonscan.com"
|
||||||
|
v-model="explorer"
|
||||||
|
></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item>
|
||||||
|
<ion-button @click="onCancel">Cancel</ion-button>
|
||||||
|
<ion-button @click="onAddSwitch">Add Network and Switch</ion-button>
|
||||||
|
</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item>Auto-reject Timer: {{ timerReject }}</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
|
||||||
|
<ion-loading
|
||||||
|
:is-open="loading"
|
||||||
|
cssClass="my-custom-class"
|
||||||
|
message="Please wait..."
|
||||||
|
:duration="4000"
|
||||||
|
@didDismiss="loading = false"
|
||||||
|
/>
|
||||||
|
</ion-content>
|
||||||
|
</ion-page>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, ref } from "vue";
|
||||||
|
import {
|
||||||
|
IonContent,
|
||||||
|
IonHeader,
|
||||||
|
IonPage,
|
||||||
|
IonTitle,
|
||||||
|
IonToolbar,
|
||||||
|
IonItem,
|
||||||
|
IonLabel,
|
||||||
|
IonButton,
|
||||||
|
IonText,
|
||||||
|
IonLoading,
|
||||||
|
onIonViewWillEnter,
|
||||||
|
IonList,
|
||||||
|
IonInput,
|
||||||
|
} from "@ionic/vue";
|
||||||
|
import { useRoute } from "vue-router";
|
||||||
|
import { getUrl, saveSelectedNetwork, saveNetwork, hexTostr } from "@/utils/platform";
|
||||||
|
import type { Network } from "@/extension/types";
|
||||||
|
import { mainNets, testNets } from "@/utils/networks";
|
||||||
|
import { approve, walletPing } from "@/extension/userRequest";
|
||||||
|
import { triggerListner } from "@/extension/listners";
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: {
|
||||||
|
IonContent,
|
||||||
|
IonHeader,
|
||||||
|
IonPage,
|
||||||
|
IonTitle,
|
||||||
|
IonToolbar,
|
||||||
|
IonItem,
|
||||||
|
IonLabel,
|
||||||
|
IonButton,
|
||||||
|
IonText,
|
||||||
|
IonLoading,
|
||||||
|
IonList,
|
||||||
|
IonInput,
|
||||||
|
},
|
||||||
|
setup: () => {
|
||||||
|
const route = useRoute();
|
||||||
|
const loading = ref(true);
|
||||||
|
const rid = (route?.params?.rid as string) ?? "";
|
||||||
|
const networkData = hexTostr((route.params?.param as string) ?? "");
|
||||||
|
const alertOpen = ref(false);
|
||||||
|
const templateNetworks = Object.assign({}, mainNets, testNets) ?? {};
|
||||||
|
const timerReject = ref(140);
|
||||||
|
let interval: any;
|
||||||
|
const website = ref("");
|
||||||
|
const name = ref("");
|
||||||
|
const chainId = ref("");
|
||||||
|
const rpc = ref("");
|
||||||
|
const symbol = ref("");
|
||||||
|
const explorer = ref("");
|
||||||
|
|
||||||
|
const onCancel = () => {
|
||||||
|
window.close();
|
||||||
|
if (interval) {
|
||||||
|
try {
|
||||||
|
clearInterval(interval);
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onIonViewWillEnter(async () => {
|
||||||
|
(window as any)?.resizeTo?.(600, 600);
|
||||||
|
try {
|
||||||
|
if (!networkData) {
|
||||||
|
onCancel();
|
||||||
|
} else {
|
||||||
|
const data = JSON.parse(networkData);
|
||||||
|
name.value = data.chainName;
|
||||||
|
chainId.value = data.chainId;
|
||||||
|
rpc.value = data.rpcUrls[0];
|
||||||
|
symbol.value = data.nativeCurrency.symbol;
|
||||||
|
explorer.value = data.blockExplorerUrls[0];
|
||||||
|
website.value = data.website;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
onCancel();
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
|
||||||
|
interval = setInterval(async () => {
|
||||||
|
if (timerReject.value <= 0) {
|
||||||
|
onCancel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timerReject.value -= 1;
|
||||||
|
walletPing();
|
||||||
|
}, 1000) as any;
|
||||||
|
});
|
||||||
|
|
||||||
|
const onAddSwitch = async () => {
|
||||||
|
loading.value = true;
|
||||||
|
const network: Network = {
|
||||||
|
chainId: Number(chainId.value),
|
||||||
|
name: name.value,
|
||||||
|
explorer: explorer.value,
|
||||||
|
rpc: rpc.value,
|
||||||
|
symbol: symbol.value,
|
||||||
|
};
|
||||||
|
await saveNetwork(network);
|
||||||
|
await saveSelectedNetwork(network);
|
||||||
|
triggerListner("chainChanged", chainId.value);
|
||||||
|
approve(rid);
|
||||||
|
loading.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
onCancel,
|
||||||
|
alertOpen,
|
||||||
|
loading,
|
||||||
|
templateNetworks,
|
||||||
|
getUrl,
|
||||||
|
onAddSwitch,
|
||||||
|
timerReject,
|
||||||
|
website,
|
||||||
|
chainId,
|
||||||
|
name,
|
||||||
|
rpc,
|
||||||
|
explorer,
|
||||||
|
symbol,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -78,7 +78,7 @@ export default defineComponent({
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const rid = (route?.params?.rid as string) ?? "";
|
const rid = (route?.params?.rid as string) ?? "";
|
||||||
const signMsg = ref(hexTostr((route?.params?.param as string) ?? ""));
|
const signMsg = ref(hexTostr(hexTostr((route?.params?.param as string) ?? "")));
|
||||||
const alertOpen = ref(false);
|
const alertOpen = ref(false);
|
||||||
const alertMsg = ref("");
|
const alertMsg = ref("");
|
||||||
const timerReject = ref(140);
|
const timerReject = ref(140);
|
||||||
|
@ -130,7 +130,7 @@ export default defineComponent({
|
||||||
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();
|
||||||
|
|
|
@ -187,6 +187,7 @@ import {
|
||||||
unBlockLockout,
|
unBlockLockout,
|
||||||
getSelectedAccount,
|
getSelectedAccount,
|
||||||
strToHex,
|
strToHex,
|
||||||
|
hexTostr,
|
||||||
} from "@/utils/platform";
|
} from "@/utils/platform";
|
||||||
import { getBalance, getGasPrice, estimateGas } from "@/utils/wallet";
|
import { getBalance, getGasPrice, estimateGas } from "@/utils/wallet";
|
||||||
import type { Network } from "@/extension/types";
|
import type { Network } from "@/extension/types";
|
||||||
|
@ -216,7 +217,7 @@ export default defineComponent({
|
||||||
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 = hexTostr((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);
|
||||||
|
|
|
@ -12,64 +12,74 @@
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<ion-item v-if="networkCase === 'exists' || networkCase === 'inTemplates'">
|
<ion-item v-if="networkCase === 'exists' || networkCase === 'inTemplates'">
|
||||||
|
<ion-list>
|
||||||
|
<ion-item><b>Switch</b></ion-item>
|
||||||
|
<ion-item>From:</ion-item>
|
||||||
|
<ion-item>
|
||||||
<ion-list>
|
<ion-list>
|
||||||
<ion-item><b>Switch</b></ion-item>
|
<ion-item>Network Name: {{ selectedNetwork?.name }}</ion-item>
|
||||||
<ion-item>From:</ion-item>
|
|
||||||
<ion-item>
|
<ion-item>
|
||||||
<ion-list>
|
<ion-avatar
|
||||||
<ion-item>Network Name: {{ selectedNetwork?.name }}</ion-item>
|
v-if="(templateNetworks as any)[selectedNetwork?.chainId]?.icon"
|
||||||
<ion-item>
|
style="margin-right: 1rem; width: 1.8rem; height: 1.8rem"
|
||||||
<ion-avatar
|
>
|
||||||
v-if="(templateNetworks as any)[selectedNetwork?.chainId]?.icon"
|
<img
|
||||||
style="margin-right: 1rem; width: 1.8rem; height: 1.8rem"
|
:alt="selectedNetwork?.name"
|
||||||
>
|
:src="getUrl('assets/chain-icons/' + (templateNetworks as any)[selectedNetwork?.chainId]?.icon)"
|
||||||
<img
|
/>
|
||||||
:alt="selectedNetwork?.name"
|
</ion-avatar>
|
||||||
:src="getUrl('assets/chain-icons/' + (templateNetworks as any)[selectedNetwork?.chainId]?.icon)"
|
<ion-label>Network ID: {{ selectedNetwork?.chainId }}</ion-label>
|
||||||
/>
|
|
||||||
</ion-avatar>
|
|
||||||
<ion-label>Network ID: {{ selectedNetwork?.chainId }}</ion-label>
|
|
||||||
</ion-item>
|
|
||||||
</ion-list>
|
|
||||||
</ion-item>
|
|
||||||
<ion-item>To</ion-item>
|
|
||||||
<ion-item>
|
|
||||||
<ion-list>
|
|
||||||
<ion-item>Network Name: {{ (templateNetworks as any)[networkId]?.name }}</ion-item>
|
|
||||||
<ion-item>
|
|
||||||
<ion-avatar
|
|
||||||
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)[networkId]?.icon)"
|
|
||||||
/>
|
|
||||||
</ion-avatar>
|
|
||||||
<ion-label>Network ID: {{ (templateNetworks as any)[networkId]?.chainId }}</ion-label>
|
|
||||||
</ion-item>
|
|
||||||
</ion-list>
|
|
||||||
</ion-item>
|
|
||||||
<ion-item>
|
|
||||||
<ion-button @click="onCancel">Cancel</ion-button>
|
|
||||||
<ion-button v-if="networkCase === 'exists'" @click="onSwitchExists">Switch</ion-button>
|
|
||||||
<ion-button v-else @click="onSwitchTemplates">Add Network and Switch</ion-button>
|
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item v-else>
|
<ion-item>To</ion-item>
|
||||||
<ion-list>
|
<ion-item>
|
||||||
<ion-item>Request to change to unknown network ID: {{ networkId }}</ion-item>
|
<ion-list>
|
||||||
<ion-item>Do you want to go to {{ addChainUrl }}</ion-item>
|
<ion-item
|
||||||
<ion-item>To add it manually.</ion-item>
|
>Network Name:
|
||||||
<ion-item>
|
{{ (existingNetworks as any)[networkId]?.name }}</ion-item
|
||||||
<ion-button @click="onCancel">No</ion-button>
|
>
|
||||||
<ion-button @click="onSwitchNotExisting">Yes</ion-button>
|
<ion-item>
|
||||||
|
<ion-avatar
|
||||||
|
v-if="(existingNetworks as any)[networkId]?.icon"
|
||||||
|
style="margin-right: 1rem; width: 1.8rem; height: 1.8rem"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
:alt="(existingNetworks as any)[networkId]?.name"
|
||||||
|
:src="getUrl('assets/chain-icons/' + (existingNetworks as any)[networkId].icon)"
|
||||||
|
/>
|
||||||
|
</ion-avatar>
|
||||||
|
<ion-label
|
||||||
|
>Network ID:
|
||||||
|
{{ (existingNetworks as any)[networkId]?.chainId }}</ion-label
|
||||||
|
>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item>
|
||||||
|
<ion-button @click="onCancel">Cancel</ion-button>
|
||||||
|
<ion-button v-if="networkCase === 'exists'" @click="onSwitchExists"
|
||||||
|
>Switch</ion-button
|
||||||
|
>
|
||||||
|
<ion-button v-else @click="onSwitchTemplates"
|
||||||
|
>Add Network and Switch</ion-button
|
||||||
|
>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
<ion-item>Auto-reject Timer: {{ timerReject }}</ion-item>
|
|
||||||
</ion-list>
|
</ion-list>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item v-else>
|
||||||
|
<ion-list>
|
||||||
|
<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="onSwitchNotExisting">Yes</ion-button>
|
||||||
|
</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item>Auto-reject Timer: {{ timerReject }}</ion-item>
|
||||||
|
</ion-list>
|
||||||
|
|
||||||
<ion-alert
|
<ion-alert
|
||||||
:is-open="alertOpen"
|
:is-open="alertOpen"
|
||||||
|
@ -107,13 +117,23 @@ import {
|
||||||
IonLoading,
|
IonLoading,
|
||||||
onIonViewWillEnter,
|
onIonViewWillEnter,
|
||||||
IonList,
|
IonList,
|
||||||
|
IonAvatar,
|
||||||
} from "@ionic/vue";
|
} from "@ionic/vue";
|
||||||
// import { ethers } from "ethers";
|
// import { ethers } from "ethers";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { getSelectedNetwork, getNetworks, getUrl, saveSelectedNetwork, saveNetwork, openTab} from "@/utils/platform";
|
import {
|
||||||
|
getSelectedNetwork,
|
||||||
|
getNetworks,
|
||||||
|
getUrl,
|
||||||
|
saveSelectedNetwork,
|
||||||
|
saveNetwork,
|
||||||
|
openTab,
|
||||||
|
numToHexStr,
|
||||||
|
} from "@/utils/platform";
|
||||||
import type { Network, Networks } from "@/extension/types";
|
import type { Network, Networks } from "@/extension/types";
|
||||||
import { mainNets, testNets } from "@/utils/networks";
|
import { mainNets, testNets } from "@/utils/networks";
|
||||||
import { approve, walletPing } from '@/extension/userRequest'
|
import { approve, walletPing } from "@/extension/userRequest";
|
||||||
|
import { triggerListner } from "@/extension/listners";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -129,27 +149,29 @@ export default defineComponent({
|
||||||
IonText,
|
IonText,
|
||||||
IonLoading,
|
IonLoading,
|
||||||
IonList,
|
IonList,
|
||||||
|
IonAvatar,
|
||||||
},
|
},
|
||||||
setup: () => {
|
setup: () => {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const rid = (route?.params?.rid as string) ?? "";
|
const rid = (route?.params?.rid as string) ?? "";
|
||||||
const networkId = ref(String(Number(route?.params?.param as string ?? "")));
|
const networkId = ref(String(Number((route?.params?.param as string) ?? "")));
|
||||||
const alertOpen = ref(false);
|
const alertOpen = ref(false);
|
||||||
const selectedNetwork = (ref(null) as unknown) as Ref<Network>;
|
const selectedNetwork = (ref(null) as unknown) as Ref<Network>;
|
||||||
const alertMsg = ref("");
|
const alertMsg = ref("");
|
||||||
const networkCase = ref("");
|
const networkCase = ref("");
|
||||||
let pnetworks: Promise<Networks>;
|
let pnetworks: Promise<Networks>;
|
||||||
const templateNetworks = Object.assign({}, mainNets, testNets) ?? {};
|
const templateNetworks = Object.assign({}, mainNets, testNets) ?? {};
|
||||||
const addChainUrl = `${chainListPage}${networkId.value}`
|
const addChainUrl = `${chainListPage}${networkId.value}`;
|
||||||
const timerReject = ref(140);
|
const timerReject = ref(140);
|
||||||
let interval: any
|
let interval: any;
|
||||||
|
const existingNetworks = ref({});
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
window.close();
|
window.close();
|
||||||
if(interval) {
|
if (interval) {
|
||||||
try {
|
try {
|
||||||
clearInterval(interval)
|
clearInterval(interval);
|
||||||
} catch {
|
} catch {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
@ -157,14 +179,15 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
onIonViewWillEnter(async () => {
|
onIonViewWillEnter(async () => {
|
||||||
(window as any)?.resizeTo?.(600, 600)
|
(window as any)?.resizeTo?.(600, 600);
|
||||||
pnetworks = getNetworks();
|
pnetworks = getNetworks();
|
||||||
selectedNetwork.value = await getSelectedNetwork();
|
selectedNetwork.value = await getSelectedNetwork();
|
||||||
console.log(networkId.value)
|
console.log(networkId.value);
|
||||||
const existingNetworks = await pnetworks;
|
existingNetworks.value = await pnetworks;
|
||||||
if ((networkId.value ?? "0") in existingNetworks ?? {}) {
|
if ((networkId.value ?? "0") in existingNetworks.value ?? {}) {
|
||||||
networkCase.value = "exists";
|
networkCase.value = "exists";
|
||||||
} else if ((networkId.value ?? "0") in templateNetworks) {
|
} else if ((networkId.value ?? "0") in templateNetworks) {
|
||||||
|
existingNetworks.value = templateNetworks;
|
||||||
networkCase.value = "inTemplates";
|
networkCase.value = "inTemplates";
|
||||||
} else {
|
} else {
|
||||||
networkCase.value = "doesNotExist";
|
networkCase.value = "doesNotExist";
|
||||||
|
@ -172,38 +195,40 @@ export default defineComponent({
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
|
|
||||||
interval = setInterval(async () => {
|
interval = setInterval(async () => {
|
||||||
if(timerReject.value <= 0) {
|
if (timerReject.value <= 0) {
|
||||||
onCancel()
|
onCancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
timerReject.value -= 1
|
timerReject.value -= 1;
|
||||||
walletPing()
|
walletPing();
|
||||||
}, 1000) as any
|
}, 1000) as any;
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const onSwitchExists = async () => {
|
const onSwitchExists = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
const existingNetworks = await pnetworks;
|
const existingNetworks = await pnetworks;
|
||||||
selectedNetwork.value = existingNetworks[Number(networkId.value)]
|
selectedNetwork.value = existingNetworks[Number(networkId.value)];
|
||||||
await saveSelectedNetwork(selectedNetwork.value)
|
await saveSelectedNetwork(selectedNetwork.value);
|
||||||
|
triggerListner("chainChanged", numToHexStr(selectedNetwork.value?.chainId ?? 0));
|
||||||
approve(rid);
|
approve(rid);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSwitchTemplates = async () => {
|
const onSwitchTemplates = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
selectedNetwork.value = templateNetworks[Number(networkId.value)]
|
selectedNetwork.value = templateNetworks[Number(networkId.value)];
|
||||||
await saveNetwork(templateNetworks[Number(networkId.value)])
|
await saveNetwork(templateNetworks[Number(networkId.value)]);
|
||||||
await saveSelectedNetwork(templateNetworks[Number(networkId.value)])
|
await saveSelectedNetwork(templateNetworks[Number(networkId.value)]);
|
||||||
|
triggerListner("chainChanged", numToHexStr(selectedNetwork.value?.chainId ?? 0));
|
||||||
approve(rid);
|
approve(rid);
|
||||||
loading.value = false;
|
loading.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSwitchNotExisting = async () => {
|
const onSwitchNotExisting = async () => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
openTab(addChainUrl)
|
openTab(addChainUrl);
|
||||||
onCancel()
|
onCancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -220,7 +245,8 @@ export default defineComponent({
|
||||||
onSwitchTemplates,
|
onSwitchTemplates,
|
||||||
onSwitchNotExisting,
|
onSwitchNotExisting,
|
||||||
addChainUrl,
|
addChainUrl,
|
||||||
timerReject
|
timerReject,
|
||||||
|
existingNetworks,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -52,7 +52,7 @@ import {
|
||||||
IonLoading,
|
IonLoading,
|
||||||
} from "@ionic/vue";
|
} from "@ionic/vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
|
import { hexTostr } from "@/utils/platform";
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
@ -69,7 +69,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
setup: () => {
|
setup: () => {
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const error = decodeURIComponent((route.params?.param as string) ?? "");
|
const error = hexTostr((route.params?.param as string) ?? "");
|
||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
|
|
||||||
const onCancel = () => {
|
const onCancel = () => {
|
||||||
|
|
|
@ -31,7 +31,7 @@ export default defineConfig({
|
||||||
chunkSizeWarningLimit: 1000,
|
chunkSizeWarningLimit: 1000,
|
||||||
commonjsOptions: {
|
commonjsOptions: {
|
||||||
transformMixedEsModules: true
|
transformMixedEsModules: true
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
!production &&
|
!production &&
|
||||||
|
|
Loading…
Reference in New Issue