2022-10-30 23:34:21 +00:00
import { getSelectedAccount , getSelectedNetwork , smallRandomString , getSettings , clearPk , openTab , getUrl , addToHistory , getNetworks , strToHex } from '@/utils/platform' ;
2022-10-07 17:07:59 +00:00
import { userApprove , userReject , rIdWin , rIdData } from '@/extension/userRequest'
2022-10-16 22:25:20 +00:00
import { signMsg , getBalance , getBlockNumber , estimateGas , sendTransaction , getGasPrice , getBlockByNumber , evmCall , getTxByHash , getTxReceipt , signTypedData } from '@/utils/wallet'
2022-10-07 17:07:59 +00:00
import type { RequestArguments } from '@/extension/types'
import { rpcError } from '@/extension/rpcConstants'
import { updatePrices } from '@/utils/gecko'
2022-10-30 23:34:21 +00:00
import { mainNets , testNets } from '@/utils/networks'
2022-10-07 17:07:59 +00:00
2022-10-10 00:52:23 +00:00
let notificationUrl : string
2022-10-07 17:07:59 +00:00
chrome . runtime . onInstalled . addListener ( ( ) = > {
console . log ( 'Service worker installed' ) ;
2022-10-30 23:34:21 +00:00
chrome . runtime . onConnect . addListener ( port = > port . onDisconnect . addListener ( ( ) = >
{
console . log ( 'Service worker connected' ) ;
} ) )
2022-10-07 17:07:59 +00:00
chrome . runtime . connect ( null as unknown as string , {
name : 'sw-connection'
} )
} )
chrome . runtime . onStartup . addListener ( ( ) = > {
console . log ( 'Service worker startup' ) ;
} )
chrome . runtime . onSuspend . addListener ( ( ) = > {
console . log ( 'Service worker suspend' ) ;
} )
chrome . alarms . create ( 'updatePrices' , {
periodInMinutes : 1
} )
chrome . alarms . onAlarm . addListener ( ( alarm ) = > {
if ( alarm . name === 'updatePrices' ) {
updatePrices ( ) . then ( ( ) = > {
console . log ( 'Prices updated' )
} )
}
2022-10-10 23:01:14 +00:00
getSettings ( ) . then ( ( settings ) = > {
if ( ( ( settings . lastLock + settings . lockOutPeriod * 6 e4 ) < Date . now ( ) ) && settings . lockOutEnabled && ! settings . lockOutBlocked ) {
settings . lastLock = Date . now ( )
clearPk ( )
}
} )
2022-10-07 17:07:59 +00:00
} )
2022-10-10 00:52:23 +00:00
chrome . windows . onRemoved . addListener ( async ( winId ) = > {
2022-10-07 17:07:59 +00:00
if ( winId in ( userReject ? ? { } ) ) {
userReject [ winId ] ? . ( )
}
userReject [ winId ] = undefined
userApprove [ winId ] = undefined
rIdWin [ winId ] = undefined
rIdData [ winId ] = undefined
2022-10-10 00:52:23 +00:00
const wins = await chrome . windows . getAll ( )
2022-10-07 17:07:59 +00:00
if ( wins . length === 0 ) {
2022-10-10 00:52:23 +00:00
const s = await getSettings ( )
if ( s . enableStorageEnctyption ) {
await clearPk ( )
}
2022-10-07 17:07:59 +00:00
}
} )
2022-10-10 00:52:23 +00:00
const viewTxListner = async ( id : string ) = > {
try {
const url = new URL ( notificationUrl )
openTab ( url . href )
chrome . notifications . clear ( id )
} catch {
// ignore
}
}
if ( ! chrome . notifications . onButtonClicked . hasListener ( viewTxListner ) ) {
chrome . notifications . onButtonClicked . addListener ( viewTxListner )
}
2022-10-30 23:34:21 +00:00
const mainListner = ( message : RequestArguments , sender :any , sendResponse : ( a : any ) = > any ) = > {
2022-10-15 20:20:33 +00:00
if ( message ? . type !== "CLWALLET_CONTENT_MSG" ) {
return true
}
2022-10-07 17:07:59 +00:00
( async ( ) = > {
2022-10-30 23:34:21 +00:00
if ( ! ( message ? . method ) ) {
2022-10-07 17:07:59 +00:00
sendResponse ( {
code : 500 ,
message : 'Invalid request method'
} )
} else {
// ETH API
switch ( message . method ) {
case 'eth_call' : {
2022-10-16 22:25:20 +00:00
sendResponse ( await evmCall ( message ? . params ? . [ 0 ] ) )
2022-10-07 17:07:59 +00:00
break
}
2022-10-10 00:52:23 +00:00
case 'eth_getBlockByNumber' : {
2022-10-16 23:21:07 +00:00
try {
2022-10-10 00:52:23 +00:00
const params = message ? . params ? . [ 0 ] as any
2022-10-10 23:01:14 +00:00
const block = await getBlockByNumber ( params ) as any
block . gasLimit = block . gasLimit . toHexString ( )
block . gasUsed = block . gasUsed . toHexString ( )
block . baseFeePerGas = block . baseFeePerGas . toHexString ( )
block . _difficulty = block . _difficulty . toHexString ( )
sendResponse ( block )
2022-10-16 23:21:07 +00:00
} catch {
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'No network or user selected'
} )
}
2022-10-10 00:52:23 +00:00
break ;
}
2022-10-16 22:25:20 +00:00
case 'eth_getTransactionByHash' : {
2022-10-16 23:21:07 +00:00
try {
2022-10-16 22:25:20 +00:00
sendResponse ( await getTxByHash ( message ? . params ? . [ 0 ] as string ) )
2022-10-16 23:21:07 +00:00
} catch {
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'No network or user selected'
} )
}
2022-10-16 22:25:20 +00:00
break
}
case 'eth_getTransactionReceipt' : {
2022-10-16 23:21:07 +00:00
try {
2022-10-16 22:25:20 +00:00
sendResponse ( await getTxReceipt ( message ? . params ? . [ 0 ] as string ) )
2022-10-16 23:21:07 +00:00
} catch {
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'No network or user selected'
} )
}
2022-10-16 22:25:20 +00:00
break
}
2022-10-10 00:52:23 +00:00
case 'eth_gasPrice' : {
2022-10-16 23:21:07 +00:00
try {
2022-10-10 23:01:14 +00:00
sendResponse ( ( await getGasPrice ( ) ) . toHexString ( ) )
2022-10-16 23:21:07 +00:00
} catch {
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'No network or user selected'
} )
}
2022-10-10 00:52:23 +00:00
break ;
}
2022-10-07 17:07:59 +00:00
case 'eth_getBalance' : {
2022-10-16 23:21:07 +00:00
try {
2022-10-07 17:07:59 +00:00
sendResponse ( await getBalance ( ) )
2022-10-16 23:21:07 +00:00
} catch {
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'No network or user selected'
} )
}
2022-10-07 17:07:59 +00:00
break
}
case 'eth_blockNumber' : {
2022-10-16 23:21:07 +00:00
try {
2022-10-07 17:07:59 +00:00
sendResponse ( await getBlockNumber ( ) )
2022-10-16 23:21:07 +00:00
} catch {
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'No network or user selected'
} )
}
2022-10-07 17:07:59 +00:00
break
}
case 'eth_estimateGas' : {
2022-10-16 23:21:07 +00:00
try {
2022-10-07 17:07:59 +00:00
const params = message ? . params ? . [ 0 ] as any
if ( ! params ) {
sendResponse ( {
error : true ,
code : rpcError.INVALID_PARAM ,
message : 'Invalid param for gas estimate'
} )
break
}
sendResponse ( await estimateGas ( {
to : params?.to ? ? '' ,
from : params ? . from ? ? '' ,
data : params?.data ? ? '' ,
value : params?.value ? ? '0x0'
} ) )
2022-10-16 23:21:07 +00:00
} catch {
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'No network or user selected'
} )
}
break
2022-10-07 17:07:59 +00:00
}
2022-10-16 22:25:20 +00:00
case 'eth_requestAccounts' :
2022-10-07 17:07:59 +00:00
case 'eth_accounts' : {
2022-10-18 15:04:44 +00:00
try {
2022-10-16 22:25:20 +00:00
// give only the selected address for better privacy
2022-10-07 17:07:59 +00:00
const account = await getSelectedAccount ( )
const address = account ? . address ? [ account ? . address ] : [ ]
sendResponse ( address )
2022-10-18 15:04:44 +00:00
} catch {
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'No network or user selected'
} )
}
break
2022-10-07 17:07:59 +00:00
}
case 'eth_chainId' : {
2022-10-18 15:04:44 +00:00
try {
2022-10-07 17:07:59 +00:00
const network = await getSelectedNetwork ( )
const chainId = network ? . chainId ? ? 0
sendResponse ( ` 0x ${ chainId . toString ( 16 ) } ` )
2022-10-18 15:04:44 +00:00
} catch {
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'No network or user selected'
} )
}
break
2022-10-07 17:07:59 +00:00
}
case 'eth_sendTransaction' : {
try {
const params = message ? . params ? . [ 0 ] as any
if ( ! params ) {
sendResponse ( {
error : true ,
code : rpcError.INVALID_PARAM ,
message : 'Invalid param for send transaction'
} )
break
}
const [ account , network ] = await Promise . all ( [ getSelectedAccount ( ) , getSelectedNetwork ( ) ] )
2022-10-13 20:48:07 +00:00
if ( ! account || ! ( 'address' in account ) ) {
await chrome . windows . create ( {
height : 450 ,
width : 400 ,
2022-10-30 23:34:21 +00:00
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 ? ? '' ) } ` ) ,
2022-10-13 20:48:07 +00:00
type : 'popup'
} )
return
}
if ( ! network || ! ( 'chainId' in network ) ) {
await chrome . windows . create ( {
height : 450 ,
width : 400 ,
2022-10-30 23:34:21 +00:00
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 ? ? '' ) } ` ) ,
2022-10-13 20:48:07 +00:00
type : 'popup'
} )
2022-10-07 17:07:59 +00:00
return
}
2022-10-10 23:01:14 +00:00
params . from = account . address
2022-10-30 23:34:21 +00:00
const serializeParams = strToHex ( JSON . stringify ( params ) ) ? ? ''
2022-10-07 17:07:59 +00:00
const pEstimateGas = estimateGas ( {
to : params?.to ? ? '' ,
from : params ? . from ? ? '' ,
data : params?.data ? ? '' ,
value : params?.value ? ? '0x0'
} )
const pGasPrice = getGasPrice ( )
let gWin : any
await new Promise ( ( resolve , reject ) = > {
chrome . windows . create ( {
height : 450 ,
width : 400 ,
url : chrome.runtime.getURL ( ` index.html?route=sign-tx¶m= ${ serializeParams } &rid= ${ String ( message ? . resId ? ? '' ) } ` ) ,
type : 'popup'
} ) . then ( ( win ) = > {
gWin = win
userReject [ String ( win . id ) ] = reject
userApprove [ String ( win . id ) ] = resolve
rIdWin [ String ( win . id ) ] = String ( message . resId )
rIdData [ String ( win . id ) ] = { }
} )
2022-10-10 23:01:14 +00:00
2022-10-07 17:07:59 +00:00
} )
2022-10-10 00:52:23 +00:00
try {
const tx = await sendTransaction ( { . . . params , . . . ( rIdData ? . [ String ( gWin ? . id ? ? 0 ) ] ? ? { } ) } , pEstimateGas , pGasPrice )
2022-10-16 22:25:20 +00:00
sendResponse ( tx . hash )
2022-10-10 00:52:23 +00:00
const buttons = { } as any
const network = await getSelectedNetwork ( )
2022-10-13 20:48:07 +00:00
addToHistory ( {
date : Date.now ( ) ,
txHash : tx.hash ,
chainId : network.chainId ,
. . . ( network . explorer ? { txUrl : ` ${ network . explorer } /tx/ ${ tx . hash } ` . replace ( '//' , '/' ) } : { } ) ,
webiste : ( message ? . website )
} )
2022-10-10 00:52:23 +00:00
const notificationId = crypto . randomUUID ( )
if ( network ? . explorer ) {
notificationUrl = ` ${ network . explorer } /tx/ ${ tx . hash } ` . replace ( '//' , '/' )
buttons . buttons = [ {
title : 'View Transaction' ,
} ]
setTimeout ( ( ) = > {
try {
chrome . notifications . clear ( notificationId )
} catch {
// ignore
}
} , 6 e4 )
}
2022-10-10 23:01:14 +00:00
chrome . notifications . create ( notificationId , {
2022-10-10 00:52:23 +00:00
message : 'Transaction Confirmed' ,
title : 'Success' ,
2022-10-10 23:01:14 +00:00
iconUrl : getUrl ( 'assets/extension-icon/wallet_128.png' ) ,
type : 'basic' ,
2022-10-10 00:52:23 +00:00
. . . ( buttons )
} as any )
2022-10-16 22:25:20 +00:00
const settings = await getSettings ( )
if ( settings . encryptAfterEveryTx ) {
clearPk ( )
}
2022-10-10 23:01:14 +00:00
} catch ( err ) {
2022-10-10 00:52:23 +00:00
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'TX Failed'
} )
2022-10-15 20:20:33 +00:00
chrome . windows . create ( {
height : 450 ,
width : 400 ,
2022-10-30 23:34:21 +00:00
url : chrome.runtime.getURL ( ` index.html?route=wallet-error¶m= ${ strToHex ( String ( err ) ) } &rid= ${ String ( message ? . resId ? ? '' ) } ` ) ,
2022-10-15 20:20:33 +00:00
type : 'popup'
} )
2022-10-10 00:52:23 +00:00
chrome . notifications . create ( {
message : 'Transaction Failed' ,
title : 'Error' ,
2022-10-10 23:01:14 +00:00
iconUrl : getUrl ( 'assets/extension-icon/wallet_128.png' ) ,
type : 'basic'
2022-10-10 00:52:23 +00:00
} as any )
}
2022-10-07 17:07:59 +00:00
} catch ( err ) {
2022-10-10 23:01:14 +00:00
// console.log(err)
2022-10-07 17:07:59 +00:00
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'User Rejected Signature'
} )
}
break
}
2022-10-16 22:25:20 +00:00
case 'signTypedData' :
case 'eth_signTypedData' :
case 'signTypedData_v1' :
case 'eth_signTypedData_v1' :
case 'signTypedData_v3' :
case 'eth_signTypedData_v3' :
case 'signTypedData_v4' :
case 'eth_signTypedData_v4' :
case 'personal_sign' :
case 'eth_sign' : {
2022-10-07 17:07:59 +00:00
try {
2022-10-13 20:48:07 +00:00
const account = await getSelectedAccount ( )
if ( ! account || ! ( 'address' in account ) ) {
await chrome . windows . create ( {
height : 450 ,
width : 400 ,
2022-10-30 23:34:21 +00:00
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 ? ? '' ) } ` ) ,
2022-10-13 20:48:07 +00:00
type : 'popup'
} )
return
}
2022-10-16 22:25:20 +00:00
const isTypedSigned = [
'signTypedData' ,
'eth_signTypedData' ,
'signTypedData_v1' ,
'eth_signTypedData_v1' ,
'signTypedData_v3' ,
'eth_signTypedData_v3' ,
'signTypedData_v4' ,
'eth_signTypedData_v4' ] . includes ( message ? . method ) ;
const signMsgData = isTypedSigned ? String ( message ? . params ? . [ 1 ] ? ? '' ) : String ( message ? . params ? . [ 0 ] ? ? '' ) ;
2022-10-07 17:07:59 +00:00
await new Promise ( ( resolve , reject ) = > {
chrome . windows . create ( {
height : 450 ,
width : 400 ,
2022-10-30 23:34:21 +00:00
url : chrome.runtime.getURL ( ` index.html?route=sign-msg¶m= ${ strToHex ( signMsgData ) } &rid= ${ String ( message ? . resId ? ? '' ) } ` ) ,
2022-10-07 17:07:59 +00:00
type : 'popup'
} ) . then ( ( win ) = > {
userReject [ String ( win . id ) ] = reject
userApprove [ String ( win . id ) ] = resolve
rIdWin [ String ( win . id ) ] = String ( message . resId )
} )
} )
sendResponse (
2022-10-16 22:25:20 +00:00
isTypedSigned ?
await signTypedData ( signMsgData ) :
await signMsg ( signMsgData )
2022-10-07 17:07:59 +00:00
)
2022-10-16 22:25:20 +00:00
const settings = await getSettings ( )
if ( settings . encryptAfterEveryTx ) {
clearPk ( )
}
} catch ( e ) {
console . error ( e )
2022-10-07 17:07:59 +00:00
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
message : 'User Rejected Signature'
} )
}
break
}
2022-10-30 23:34:21 +00:00
// 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' :
2022-10-07 17:07:59 +00:00
case 'wallet_requestPermissions' : {
const account = await getSelectedAccount ( )
const address = account ? . address ? [ account ? . address ] : [ ]
sendResponse ( [ {
2022-10-30 23:34:21 +00:00
id : smallRandomString ( 21 ) ,
parentCapability : 'eth_accounts' ,
invoker : message?.website?.split ( '/' ) . slice ( 0 , 3 ) . join ( '/' ) ? ? '' ,
caveats : [ {
type : 'restrictReturnedAccounts' ,
2022-10-07 17:07:59 +00:00
value : address
2022-10-30 23:34:21 +00:00
} ] ,
2022-10-07 17:07:59 +00:00
date : Date.now ( ) ,
} ] )
break
}
case 'net_version' : {
const network = await getSelectedNetwork ( )
const chainId = network ? . chainId ? ? 0
sendResponse ( chainId )
break
}
case 'wallet_switchEthereumChain' : {
try {
2022-10-30 23:34:21 +00:00
const currentChainId = ` 0x ${ ( ( await getSelectedNetwork ( ) ) ? . chainId ? ? 0 ) . toString ( 16 ) } `
if ( currentChainId === String ( message ? . params ? . [ 0 ] ? . chainId ? ? '' ) ) {
sendResponse ( null )
} else {
2022-10-07 17:07:59 +00:00
await new Promise ( ( resolve , reject ) = > {
chrome . windows . create ( {
height : 450 ,
width : 400 ,
2022-10-10 00:52:23 +00:00
url : chrome.runtime.getURL ( ` index.html?route=switch-network¶m= ${ String ( message ? . params ? . [ 0 ] ? . chainId ? ? '' ) } &rid= ${ String ( message ? . resId ? ? '' ) } ` ) ,
2022-10-07 17:07:59 +00:00
type : 'popup'
} ) . then ( ( win ) = > {
userReject [ String ( win . id ) ] = reject
userApprove [ String ( win . id ) ] = resolve
rIdWin [ String ( win . id ) ] = String ( message . resId )
} )
} )
2022-10-10 00:52:23 +00:00
sendResponse ( null )
2022-10-30 23:34:21 +00:00
}
2022-10-07 17:07:59 +00:00
} catch {
sendResponse ( {
error : true ,
code : rpcError.USER_REJECTED ,
2022-10-30 23:34:21 +00:00
message : 'User Rejected chain switch'
2022-10-07 17:07:59 +00:00
} )
}
break
}
2022-10-30 23:34:21 +00:00
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
}
2022-10-07 17:07:59 +00:00
// internal messeges
2022-10-30 23:34:21 +00:00
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
}
2022-10-07 17:07:59 +00:00
case 'wallet_approve' : {
if ( String ( sender . tab ? . windowId ) in rIdWin ) {
userApprove [ String ( sender . tab ? . windowId ) ] ? . ( true )
}
try {
chrome . windows . remove ( sender . tab ? . windowId ? ? 0 )
2022-10-15 20:20:33 +00:00
} catch ( e ) {
console . log ( e )
2022-10-07 17:07:59 +00:00
// ignore
}
break
}
case 'wallet_send_data' : {
if ( String ( sender . tab ? . windowId ) in rIdData ) {
rIdData [ String ( sender ? . tab ? . windowId ? ? '' ) ] = ( message as any ) ? . data ? ? { }
sendResponse ( true )
}
break
}
case 'wallet_get_data' : {
if ( String ( sender . tab ? . windowId ) in rIdData ) {
sendResponse ( rIdData [ String ( sender ? . tab ? . windowId ? ? '' ) ] ? ? { } )
}
break
}
case 'wallet_ping' : {
sendResponse ( true )
break
}
default : {
sendResponse ( {
error : true ,
code : rpcError.INVALID_PARAM ,
2022-10-30 23:34:21 +00:00
message : 'ClearWallet: Invalid request method ' + message ? . method ? ? ''
2022-10-07 17:07:59 +00:00
} )
break
}
}
}
}
) ( ) ;
return true ;
2022-10-30 23:34:21 +00:00
}
chrome . runtime . onMessage . addListener ( mainListner ) ;