chore: changes for new release

This commit is contained in:
Andrei O 2024-03-13 04:17:57 +02:00
parent c88cfc22b8
commit 5b9d04a66b
No known key found for this signature in database
GPG Key ID: B961E5B68389457E
7 changed files with 186 additions and 105 deletions

View File

@ -1,5 +1,12 @@
# Changelog # Changelog
## Manifest Version 1.3.4
- bump fake Metamask version signature to 11.0.0
- improved compatibility with older deprecated websites
- improved mimicking of Metamask API
- made the wallet compatible with fire extension on sending transaction( by mimicking new Metamask API)
## Manifest Version 1.3.3 ## Manifest Version 1.3.3
- improved eth_call and eth_blockNumber to be more compatible with older websites - improved eth_call and eth_blockNumber to be more compatible with older websites

View File

@ -20,10 +20,13 @@ const allowedMethods = {
'eth_chainId': true, 'eth_chainId': true,
'personal_sign': true, 'personal_sign': true,
'wallet_requestPermissions': true, 'wallet_requestPermissions': true,
'wallet_registerOnboarding': true,
'wallet_revokePermissions': true,
'eth_gasPrice': true, 'eth_gasPrice': true,
'eth_getBlockByNumber': true, 'eth_getBlockByNumber': true,
'eth_blockNumber': true, 'eth_blockNumber': true,
'eth_estimateGas': true, 'eth_estimateGas': true,
'eth_syncing': true,
'eth_sign': true, 'eth_sign': true,
'net_version': true, 'net_version': true,
'eth_sendTransaction': true, 'eth_sendTransaction': true,
@ -53,30 +56,29 @@ window.addEventListener("message", (event) => {
if (event.source != window) if (event.source != window)
return; return;
if (event?.data?.type === "CLWALLET_CONTENT") { if (event?.data?.type === "CLWALLET_CONTENT") {
event.data.data.resId = event.data.resId event.data.data.data.resId = event.data.resId
event.data.data.type = "CLWALLET_CONTENT_MSG" event.data.data.data.type = "CLWALLET_CONTENT_MSG"
event.data.data.website = document?.location?.href ?? '' event.data.data.data.website = document?.location?.href ?? ''
if ((event?.data?.data?.method ?? 'x') in allowedMethods) { if ((event?.data?.data?.data?.method ?? 'x') in allowedMethods) {
chrome.runtime.sendMessage(event.data.data, (res) => { chrome?.runtime?.sendMessage(event.data.data.data, (res) => {
if (chrome.runtime.lastError) { if (chrome.runtime.lastError) {
console.warn("LOC1: Error sending message:", chrome.runtime.lastError); console.warn("LOC1: Error sending message:", chrome.runtime.lastError);
} }
const data = { type: "CLWALLET_PAGE", data: res, resId: event.data.resId }; const data = { type: "CLWALLET_PAGE", data: res, resId: event.data.resId };
// console.info('data out', data) // console.info('data out', data)
window.postMessage(data, "*"); window.postMessage(data, "*");
}) })
} }
else { else {
const data = { type: "CLWALLET_PAGE", data: { error: true, message: 'ClearWallet: Unknown method requested ' + event?.data?.data?.method ?? '' }, resId: event.data.resId }; const data = { type: "CLWALLET_PAGE", data: { error: true, message: 'ClearWallet: Unknown method requested ' + event?.data?.data?.data?.method ?? '' }, resId: event.data.resId };
window.postMessage(data, "*"); window.postMessage(data, "*");
} }
} else if (event?.data?.type === "CLWALLET_PING") { } else if (event?.data?.type === "CLWALLET_PING") {
event.data.data.resId = event.data.resId event.data.data.data.resId = event.data.resId
event.data.data.type = "CLWALLET_CONTENT_MSG" event.data.data.data.type = "CLWALLET_CONTENT_MSG"
event.data.data.method = "wallet_connect" event.data.data.data.method = "wallet_connect"
event.data.data.params = Array(0) event.data.data.data.params = Array(0)
chrome.runtime.sendMessage(event.data.data, async (res) => { chrome.runtime.sendMessage(event.data.data.data, async (res) => {
if (chrome.runtime.lastError) { if (chrome.runtime.lastError) {
console.warn("LOC2: Error sending message:", chrome.runtime.lastError); console.warn("LOC2: Error sending message:", chrome.runtime.lastError);
} }

View File

@ -69,18 +69,25 @@ const getListnersCount = (): number => {
return count return count
} }
const sendMessage = (args: RequestArguments, ping = false) => { const sendMessage = (args: RequestArguments, ping = false, from = 'request'): Promise<unknown> => {
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 = [...`${Math.random().toString(16) + Date.now().toString(16)}`].slice(2).join('') const resId = [...`${Math.random().toString(16) + Date.now().toString(16)}`].slice(2).join('')
promResolvers.set(resId, { resolve, reject }) promResolvers.set(resId, { resolve, reject })
const data = { type: "CLWALLET_CONTENT", data: args, resId}; const data = {
type: "CLWALLET_CONTENT",
data: { data: args, name: 'metamask-provider' },
resId,
from,
target: 'metamask-contentscript'
}
if (ping) { if (ping) {
data.type = 'CLWALLET_PING' data.type = 'CLWALLET_PING'
} }
// console.info('data in', data) // console.info('data in', data)
window.postMessage(data, "*"); window.postMessage(data, "*");
})
})
} else { } else {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
reject(new Error("You have reached the maximum number of concurent wallet messeges.")) reject(new Error("You have reached the maximum number of concurent wallet messeges."))
@ -125,25 +132,26 @@ class MetaMaskAPI {
} }
request(args: RequestArguments): Promise<unknown> { request(args: RequestArguments): Promise<unknown> {
return sendMessage(args) return sendMessage(args) as Promise<unknown>
} }
// Deprecated // Deprecated
sendAsync (arg1: any, arg2: any): void | Promise<unknown> { sendAsync (arg1: any, arg2: any): void | Promise<unknown> {
// return this.send(arg1, arg2) as any
if( typeof arg1 === 'string' ) { if( typeof arg1 === 'string' ) {
return sendMessage({ return sendMessage({
method: arg1, method: arg1,
params: arg2 as object params: arg2 as object
}) }, false , 'sendAsync') as Promise<unknown>
}else if (typeof arg2 === 'function'){ }else if (typeof arg2 === 'function'){
sendMessage(arg1 as RequestArguments).then(result => { ((sendMessage(arg1 as RequestArguments, false, 'sendAsync') as Promise<unknown>).then(result => {
(arg2 as (e?: any, r?: any) => any )(undefined, { (arg2 as (e?: any, r?: any) => any )(undefined, {
id: (arg1 as RequestArguments)?.id, id: (arg1 as RequestArguments)?.id,
jsonrpc: '2.0', jsonrpc: '2.0',
method: (arg1 as RequestArguments).method, method: (arg1 as RequestArguments).method,
result result
} }
) )
}).catch( e => { }) as Promise<unknown>).catch( e => {
(arg2 as (er?: any, r?: any) => any )(new Error(e), { (arg2 as (er?: any, r?: any) => any )(new Error(e), {
id: (arg1 as RequestArguments)?.id, id: (arg1 as RequestArguments)?.id,
jsonrpc: '2.0', jsonrpc: '2.0',
@ -152,45 +160,83 @@ class MetaMaskAPI {
} }
) )
}) })
} } else {
return sendMessage(arg1 as RequestArguments, false, 'sendAsync') as Promise<unknown>
}
} }
// Deprecated // Deprecated
// send (arg1: unknown, arg2: unknown): unknown {
// if (arg2 === undefined) {
// if( typeof arg1 === 'string' ) {
// return sendMessage({
// method: arg1,
// params: undefined
// })
// } else if (typeof arg1 === 'object') {
// return sendMessage(arg1 as RequestArguments)
// } else {
// console.error('ERROR: Clear Wallet: faulty request')
// }
// }else if( typeof arg1 === 'string' ) {
// return sendMessage({
// method: arg1,
// params: arg2 as object
// })
// }else if (typeof arg2 === 'function'){
// sendMessage(arg1 as RequestArguments).then(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)
// }
// )
// })
// }
// }
send (arg1: unknown, arg2: unknown): unknown { send (arg1: unknown, arg2: unknown): unknown {
const resultFmt = async (result: Promise<any>) => {
return {
"id": 0,
"jsonrpc": "2.0",
result: await result
}
}
if (arg2 === undefined) { if (arg2 === undefined) {
if( typeof arg1 === 'string' ) { if( typeof arg1 === 'string' ) {
return sendMessage({
return resultFmt(sendMessage({
method: arg1, method: arg1,
params: undefined params: undefined
}) }, false, 'send'))
} else if (typeof arg1 === 'object') {
return sendMessage(arg1 as RequestArguments)
} else { } else {
console.error('ERROR: Clear Wallet: faulty request') return resultFmt(sendMessage(arg1 as RequestArguments, false, 'send'))
}
} else if (typeof arg1 === 'object') {
if( typeof arg1 === 'string' ) {
return resultFmt(sendMessage(arg1 as RequestArguments, false, 'send'))
} else {
return resultFmt(sendMessage(arg1 as RequestArguments, false, 'send'))
} }
}else if( typeof arg1 === 'string' ) { }else if( typeof arg1 === 'string' ) {
return sendMessage({ return resultFmt( sendMessage({
method: arg1, method: arg1,
params: arg2 as object params: arg2 as object
}) }, false, 'send'))
}else if (typeof arg2 === 'function'){ }else if (typeof arg2 === 'function'){
sendMessage(arg1 as RequestArguments).then(result => { return resultFmt( sendMessage(arg1 as RequestArguments, false, 'send'))
(arg2 as (e?: any, r?: any) => any )(undefined, { } else {
id: (arg1 as RequestArguments)?.id, return resultFmt(sendMessage(arg1 as RequestArguments , false, 'send'))
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) this.addListener(eventName, callback)
@ -308,7 +354,7 @@ class MetaMaskAPI {
_handleStreamDisconnect() { return true } _handleStreamDisconnect() { return true }
_handleUnlockStateChanged() { return true } _handleUnlockStateChanged() { return true }
_sendSync () { _sendSync () {
console.info('ERROR: Clear Wallet: Sync calling is deprecated and not supported') console.warn('ERROR: Clear Wallet: Sync calling is deprecated and not supported')
} }
} }
@ -318,38 +364,41 @@ const eth = new Proxy( new MetaMaskAPI(), {
const listner = function(event: any) { const listner = function(event: any) {
if (event.source != window) return; if (event.source != window) return;
const eventData = event?.data
if (event?.data?.type === "CLWALLET_PAGE") { const eventDataData = event?.data?.data
const eventDataDataData = event?.data?.data?.data
if (eventData?.type === "CLWALLET_PAGE") {
try { try {
if(event?.data?.data?.error){ if(eventData?.error){
promResolvers.get(event.data.resId)?.reject(event.data.data); promResolvers.get(eventData.resId)?.reject(eventData);
// console.info('Error: ', event?.data?.data) // console.info('Error: ', event?.data?.data)
}else { }else {
promResolvers.get(event.data.resId)?.resolve(event.data.data); promResolvers.get(eventData.resId)?.resolve(eventDataData);
} }
promResolvers.delete(event.data.resId) promResolvers.delete(event.data.resId)
} catch (e) { } catch (e) {
// console.log('Failed to connect resolve msg', e) // console.error('Failed to connect resolve msg', e)
} }
} else if(event?.data?.type === "CLWALLET_PAGE_LISTENER") { } else if(eventData?.type === "CLWALLET_PAGE_LISTENER") {
if((event?.data?.data?.listner ?? 'x') in listners ) { if((eventDataData?.listner ?? 'x') in listners ) {
try { try {
const listnerName = event?.data?.data?.listner as ('accountsChanged' | 'connect' | 'disconnect' | 'chainChanged') const listnerName = eventDataData.listner as ('accountsChanged' | 'connect' | 'disconnect' | 'chainChanged')
if( listnerName === 'connect' && event?.data?.data?.data) { if( listnerName === 'connect' && eventDataData) {
(<any>eth).networkVersion = event?.data?.data?.data?.chainId?.toString(10) ?? '137'; (<any>eth).networkVersion = eventDataDataData?.chainId?.toString(10) ?? '137';
(<any>eth).chainId = event?.data?.data?.data?.chainId ?? '0x89'; (<any>eth).chainId = eventDataDataData?.chainId ?? '0x89';
(<any>eth).selectedAddress = event?.data?.data?.address ?? null; (<any>eth).selectedAddress = eventDataData?.address?.[0] ?? null;
(<any>eth).accounts = [eventDataData.address?.[0]] ?? [];
(<any>eth).isConnected = () => true; (<any>eth).isConnected = () => true;
} else if( listnerName === 'chainChanged' ) { } else if( listnerName === 'chainChanged' ) {
// console.info(event?.data?.data?.data); (<any>eth).networkVersion = eventDataData?.toString(10) ?? '137';
(<any>eth).networkVersion = event?.data?.data?.data.toString(10) ?? '137'; (<any>eth).chainId = eventDataData ?? '0x89';
(<any>eth).chainId = event?.data?.data?.data ?? '0x89';
} else if ( listnerName === 'accountsChanged' ) { } else if ( listnerName === 'accountsChanged' ) {
(<any>eth).selectedAddress = event?.data?.data?.data?.address ?? 'dummy-string'; (<any>eth).accounts = [eventDataData?.[0]] ?? [];
(<any>eth).selectedAddress = eventDataData?.[0] ?? '';
} }
listners[listnerName].forEach(listner => listner(event?.data?.data?.data)); listners[listnerName].forEach(listner => listner(eventDataDataData));
listners.once[listnerName].forEach(listner => { listners.once[listnerName].forEach(listner => {
listner(event?.data?.data?.data) listner(eventDataData)
listners.once[listnerName].delete(listner) listners.once[listnerName].delete(listner)
}); });
} catch (e) { } catch (e) {
@ -362,37 +411,19 @@ const listner = function(event: any) {
window.addEventListener("message",listner) window.addEventListener("message",listner)
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const proxy1 = new Proxy(new MetaMaskAPI(), {
get: function (target: any, prop: any) {
// Intercept method calls and log them
if (typeof target[prop] === 'function') {
return function (...args: any[]) {
// console.log(`Calling ${prop} with arguments:`, args);
// eslint-disable-next-line prefer-spread
const result = target[prop].apply(target, args);
// console.log(`${prop} returned:`, result);
return result;
};
} else {
// console.log(`Reading ${prop}`);
return target[prop];
}
},
})
// const web3Shim = {
// currentProvider: eth, const web3Shim = {
// __isMetaMaskShim__: true currentProvider: eth,
// } __isMetaMaskShim__: true
}
const injectWallet = (win: any) => { const injectWallet = (win: any) => {
Object.defineProperty(win, 'ethereum', { Object.defineProperty(win, 'ethereum', {
value: eth, value: eth,
}); });
Object.defineProperty(win, 'web3', { Object.defineProperty(win, 'web3', {
value: eth value: web3Shim
}); });
sendMessage({ sendMessage({
method: 'wallet_ready' method: 'wallet_ready'
@ -403,6 +434,29 @@ sendMessage({
injectWallet(this); injectWallet(this);
loadEIP1193Provider(eth) loadEIP1193Provider(eth)
// HELPERS TO CLONE METAMASK API
// window.addEventListener("message" , (event) => {
// console.log('event', event)
// })
// setTimeout(() => {
// console.log('Metamask clone test');
// console.log((<any>window).ethereum.send({
// "jsonrpc": "2.0",
// "method": "eth_accounts",
// "params": [],
// "id": 0
// }))
// console.log((<any>window).ethereum.request({
// "jsonrpc": "2.0",
// "method": "eth_accounts",
// "params": [],
// "id": 0
// }))
// }, 5000)
// 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')});

View File

@ -3,8 +3,8 @@
"name": "__MSG_appName__", "name": "__MSG_appName__",
"description": "__MSG_appDesc__", "description": "__MSG_appDesc__",
"default_locale": "en", "default_locale": "en",
"version": "1.3.3", "version": "1.3.4",
"version_name": "1.3.3", "version_name": "1.3.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",

View File

@ -286,7 +286,7 @@ const mainListner = (message: RequestArguments, sender:any, sendResponse: (a: an
} }
case 'eth_blockNumber': { case 'eth_blockNumber': {
try { try {
sendResponse(await getBlockNumber()) sendResponse(numToHexStr(await getBlockNumber()))
} catch (e) { } catch (e) {
sendResponse({ sendResponse({
error: true, error: true,
@ -566,7 +566,7 @@ const mainListner = (message: RequestArguments, sender:any, sendResponse: (a: an
break break
} }
case 'web3_clientVersion': { case 'web3_clientVersion': {
sendResponse("MetaMask/v10.20.0") sendResponse("MetaMask/v11.0.0")
break break
} }
case 'wallet_getPermissions': case 'wallet_getPermissions':
@ -585,6 +585,18 @@ const mainListner = (message: RequestArguments, sender:any, sendResponse: (a: an
}]) }])
break break
} }
case 'wallet_revokePermissions': {
sendResponse(null)
break
}
case 'wallet_registerOnboarding': {
sendResponse(true)
break
}
case 'eth_syncing': {
sendResponse(false)
break
}
case 'net_version': { case 'net_version': {
const network = await getSelectedNetwork() const network = await getSelectedNetwork()
const chainId = network?.chainId ?? 0 const chainId = network?.chainId ?? 0

View File

@ -81,14 +81,23 @@ export const estimateGas = async ({to = '', from = '', data = '', value = '0x0'
} }
export const evmCall = async (params: any[]) => { export const evmCall = async (params: any[]) => {
const param1 = (params[0] ?? {to:'', from: '', data:'', value: '0x0', blockTag: 'latest' }) as {to: string, from: string, data: string, value: string, blockTag: string} const tx = {} as {to: string, from: string, data: string, value: string, blockTag: string}
const param2 = (params[1] ?? 'latest') as string const param1 = params[0] as any
param1.blockTag = param2 if(param1.to) tx.to = param1.to
if(param1.from) tx.from = param1.from
if(param1.data) tx.data = param1.data
if(param1.value) tx.value = param1.value
const param2 = params[1] as string
if (param2.startsWith('0x')) {
tx.blockTag = param2
} else {
tx.blockTag = 'latest'
}
const network = await getSelectedNetwork() const network = await getSelectedNetwork()
const provider = new ethers.JsonRpcProvider(network.rpc) const provider = new ethers.JsonRpcProvider(network.rpc)
return await provider.call(param1) const result = await provider.call(tx)
return result
} }
export const getTxByHash = async (hash: string) => { export const getTxByHash = async (hash: string) => {

View File

@ -96,7 +96,7 @@
class="exchange-btn" class="exchange-btn"
style="" style=""
/> />
<p style="font-size: 0.75rem; opacity: 0.8; padding 0.2rem;"> <p style="font-size: 0.75rem; opacity: 0.8; padding: 0.2rem">
This button does not contain any referral to maximize privacy. This button does not contain any referral to maximize privacy.
</p> </p>
</div> </div>
@ -330,10 +330,7 @@ export default defineComponent({
accounts.value.splice(0, 0, selectedAccount.value); accounts.value.splice(0, 0, selectedAccount.value);
const newAccounts = [...accounts.value]; const newAccounts = [...accounts.value];
await replaceAccounts(newAccounts); await replaceAccounts(newAccounts);
triggerListner( triggerListner("accountsChanged", [newAccounts.map((a) => a.address)?.[0]]);
"accountsChanged",
newAccounts.map((a) => a.address)
);
} }
accountsModal.value = false; accountsModal.value = false;
loading.value = false; loading.value = false;