import 'reflect-metadata' ; import * as Sentry from '@sentry/browser' ; import { Integrations } from '@sentry/tracing' ; import { browser } from 'webextension-polyfill-ts' ; import { ethErrors } from 'eth-rpc-errors' ; import { WalletController } from 'background/controller/wallet' ; import { Message } from 'utils' ; import { EVENTS } from 'consts' ; import { storage } from './webapi' ; import { permissionService , preferenceService , sessionService , keyringService , openapiService , transactionWatchService , pageStateCacheService , transactionHistoryService , contactBookService , signTextHistoryService , } from './service' ; import { providerController , walletController } from './controller' ; import i18n from './service/i18n' ; import rpcCache from './utils/rpcCache' ; import eventBus from '@/eventBus' ; import migrateData from '@/migrations' ; const { PortMessage } = Message ; let appStoreLoaded = false ; Sentry . init ( { dsn : 'https://e871ee64a51b4e8c91ea5fa50b67be6b@o460488.ingest.sentry.io/5831390' , integrations : [ new Integrations . BrowserTracing ( ) ] , release : process . env . release , tracesSampleRate : 1.0 , } ) ; function initAppMeta ( ) { const head = document . querySelector ( 'head' ) ; const icon = document . createElement ( 'link' ) ; icon . href = 'https://rabby.io/assets/images/logo-128.png' ; icon . rel = 'icon' ; head ?. appendChild ( icon ) ; const name = document . createElement ( 'meta' ) ; name . name = 'name' ; name . content = 'Rabby' ; head ?. appendChild ( name ) ; const description = document . createElement ( 'meta' ) ; description . name = 'description' ; description . content = i18n . t ( 'appDescription' ) ; head ?. appendChild ( description ) ; } async function restoreAppState ( ) { const keyringState = await storage . get ( 'keyringState' ) ; keyringService . loadStore ( keyringState ) ; keyringService . store . subscribe ( ( value ) => storage . set ( 'keyringState' , value ) ) ; await openapiService . init ( ) ; await migrateData ( ) ; await permissionService . init ( ) ; await preferenceService . init ( ) ; await transactionWatchService . init ( ) ; await pageStateCacheService . init ( ) ; await transactionHistoryService . init ( ) ; await contactBookService . init ( ) ; await signTextHistoryService . init ( ) ; rpcCache . start ( ) ; appStoreLoaded = true ; transactionWatchService . roll ( ) ; initAppMeta ( ) ; } restoreAppState ( ) ; browser . runtime . onConnect . addListener ( ( port ) => { openapiService . getConfig ( ) ; if ( port . name === 'popup' || port . name === 'notification' || port . name === 'tab' ) { const pm = new PortMessage ( port ) ; pm . listen ( ( data ) => { if ( data ?. type ) { switch ( data . type ) { case 'broadcast' : eventBus . emit ( data . method , data . params ) ; break ; case 'openapi' : if ( walletController . openapi [ data . method ] ) { return walletController . openapi [ data . method ] . apply ( null , data . params ) ; } break ; case 'controller' : default : if ( data . method ) { return walletController [ data . method ] . apply ( null , data . params ) ; } } } } ) ; const boardcastCallback = ( data ) => { pm . request ( { type : 'broadcast' , method : data . method , params : data . params , } ) ; } ; if ( port . name === 'popup' ) { preferenceService . setPopupOpen ( true ) ; port . onDisconnect . addListener ( ( ) => { preferenceService . setPopupOpen ( false ) ; } ) ; } eventBus . addEventListener ( EVENTS . broadcastToUI , boardcastCallback ) ; port . onDisconnect . addListener ( ( ) => { eventBus . removeEventListener ( EVENTS . broadcastToUI , boardcastCallback ) ; } ) ; return ; } if ( ! port . sender ?. tab ) { return ; } const pm = new PortMessage ( port ) ; pm . listen ( async ( data ) => { if ( ! appStoreLoaded ) { throw ethErrors . provider . disconnected ( ) ; } const sessionId = port . sender ?. tab ?. id ; const session = sessionService . getOrCreateSession ( sessionId ) ; const req = { data , session } ; req . session . pushMessage = ( event , data ) => { pm . send ( 'message' , { event , data } ) ; } ; return providerController ( req ) ; } ) ; } ) ; declare global { interface Window { wallet : WalletController ; } } window . wallet = new Proxy ( walletController , { get ( target , propKey , receiver ) { if ( ! appStoreLoaded ) { throw ethErrors . provider . disconnected ( ) ; } return Reflect . get ( target , propKey , receiver ) ; } , } ) ;