1 import { LocalStream } from 'extension-streams'
2 import InternalMessage from '@/messages/internal'
3 import * as MsgTypes from './messages/types'
4 import NotificationService from './services/NotificationService'
5 import StorageService from './services/StorageService'
6 import Prompt from './prompts/Prompt';
7 import * as PromptTypes from './prompts/PromptTypes'
10 import Error from './utils/errors/Error'
11 import { BTM } from './utils/constants'
15 export default class Background {
17 this.setupInternalMessaging()
20 setupInternalMessaging() {
21 LocalStream.watch((request, sendResponse) => {
23 const message = InternalMessage.fromJson(request)
24 this.dispatchMessage(sendResponse, message)
28 dispatchMessage(sendResponse, message) {
29 switch (message.type) {
30 case MsgTypes.TRANSFER:
31 this.transfer(sendResponse, message.payload)
33 case MsgTypes.ADVTRANSFER:
34 this.advancedTransfer(sendResponse, message.payload)
37 this.send(sendResponse, message.payload)
39 case MsgTypes.SIGNTRANSACTION:
40 this.signTransaction(sendResponse, message.payload)
42 case MsgTypes.SIGNMESSAGE:
43 this.signMessage(sendResponse, message.payload)
45 case MsgTypes.REQUEST_CURRENT_ACCOUNT:
46 this.requestCurrentAccount(sendResponse, message.payload)
48 case MsgTypes.REQUEST_CURRENT_NETWORK:
49 this.requestCurrentNetwork(sendResponse)
51 case MsgTypes.REQUEST_CURRENT_CHAIN_TYPE:
52 this.requestCurrentChain(sendResponse)
55 Background.authenticate(sendResponse, message.payload)
57 case MsgTypes.SET_PROMPT:
58 Background.setPrompt(sendResponse, message.payload);
60 case MsgTypes.GET_PROMPT:
61 Background.getPrompt(sendResponse);
64 Background.load(sendResponse);
67 Background.update(sendResponse, message.payload);
72 static setPrompt(sendResponse, notification){
73 prompt = notification;
77 static getPrompt(sendResponse){
81 signMessage(sendResponse, payload) {
82 if(payload.address === undefined){
83 sendResponse(Error.typeMissed('address'));
86 if(payload.message === undefined){
87 sendResponse(Error.typeMissed('message'));
91 NotificationService.open(new Prompt(PromptTypes.REQUEST_SIGN, '', payload ,approved => {
92 sendResponse(approved);
96 transfer(sendResponse, payload) {
97 var promptURL = chrome.extension.getURL('pages/prompt.html')
98 var requestBody = payload
99 requestBody.type = "popup"
100 var queryString = new URLSearchParams(requestBody).toString()
101 console.log(promptURL, queryString)
103 if(requestBody.from === undefined){
104 sendResponse(Error.typeMissed('from'));
107 if(requestBody.to === undefined){
108 sendResponse(Error.typeMissed('to'));
111 if(requestBody.asset === undefined){
112 sendResponse(Error.typeMissed('asset'));
115 if(requestBody.amount === undefined){
116 sendResponse(Error.typeMissed('amount'));
120 // NotificationService.open(new Prompt(PromptTypes.REQUEST_TRANSFER, '', payload ,approved => {
121 // sendResponse(approved);
124 chrome.windows.create(
126 url: `${promptURL}#transfer?${queryString}`,
134 chrome.runtime.onMessage.addListener(function(request, sender) {
135 if(sender.tab.windowId === window.id){
136 switch (request.method){
138 if (request.action === 'success'){
139 sendResponse(request.message);
141 } else if (request.action === 'reject'){
142 sendResponse(request.message);
149 chrome.windows.onRemoved.addListener(function(windowId){
150 if(windowId === window.id) {
151 sendResponse(Error.promptClosedWithoutAction());
159 advancedTransfer(sendResponse, payload) {
161 if(payload.input === undefined){
162 sendResponse(Error.typeMissed('input'));
165 if(payload.output === undefined){
166 sendResponse(Error.typeMissed('output'));
169 if(payload.gas === undefined){
170 sendResponse(Error.typeMissed('gas'));
174 NotificationService.open(new Prompt(PromptTypes.REQUEST_ADVANCED_TRANSFER, '', payload ,approved => {
175 sendResponse(approved);
180 signTransaction(sendResponse, payload) {
181 NotificationService.open(new Prompt(PromptTypes.REQUEST_SIGN_TRANSACTION, '', payload ,approved => {
182 sendResponse(approved);
187 requestCurrentAccount(sendResponse, payload){
188 Background.load(bytom => {
189 const domain = payload.domain;
190 if(bytom.settings.domains.find(_domain => _domain === domain)) {
191 const currentAccount = bytom.currentAccount
193 if(bytom.settings.netType === 'vapor'){
195 const votes = currentAccount.votes
196 if(votes && votes.length >0 ){
197 vote = _.sumBy(votes,'total')
200 let balances = currentAccount.vpBalances ||[]
201 balances = balances.map(({ in_btc, in_cny, in_usd, name, ...keepAttrs}) => {
202 if(keepAttrs.asset === BTM)
203 return {availableBalance: (keepAttrs.balance-vote),...keepAttrs}
209 address: currentAccount.vpAddress,
210 alias:currentAccount.alias,
211 balances: balances|| [],
212 accountId: currentAccount.guid,
213 rootXPub: currentAccount.rootXPub
216 let balances = currentAccount.balances ||[]
217 balances = balances.map(({ in_btc, in_cny, in_usd, name, ...keepAttrs}) => keepAttrs)
220 address: currentAccount.address,
221 alias:currentAccount.alias,
222 balances: balances|| [],
223 accountId: currentAccount.guid,
224 rootXPub: currentAccount.rootXPub
228 sendResponse(account)
237 requestCurrentNetwork(sendResponse){
238 Background.load(bytom => {
239 sendResponse(bytom.settings.network);
243 requestCurrentChain(sendResponse){
244 Background.load(bytom => {
245 const chain = bytom.settings.netType ==='vapor'?'vapor':'bytom'
251 send(sendResponse, payload) {
252 const action = payload.action
256 case 'listAllAccount':
257 promise = accountAction.list()
270 * Returns the saved instance of Bytom from the storage
271 * @param sendResponse - Delegating response handler
274 static load(sendResponse){
275 StorageService.get().then(bytom => {
281 * Updates the Scatter instance inside persistent storage
282 * @param sendResponse - Delegating response handler
283 * @param bytom - The updated cleartext Scatter instance
286 static update(sendResponse, bytom){
287 StorageService.save(bytom).then(saved => {
292 static authenticate(sendResponse, payload){
293 Background.load(bytom => {
294 const domain = payload.domain;
295 const currentAccount = bytom.currentAccount
298 if(bytom.settings.netType === 'vapor'){
300 const votes = currentAccount.votes
301 if(votes && votes.length >0 ){
302 vote = _.sumBy(votes,'total')
305 let balances = currentAccount.vpBalances ||[]
306 balances = balances.map(({ in_btc, in_cny, in_usd, name, ...keepAttrs}) => {
307 if(keepAttrs.asset === BTM)
308 return {availableBalance: (keepAttrs.balance-vote),...keepAttrs}
314 address: currentAccount.vpAddress,
315 alias:currentAccount.alias,
316 balances: balances || [],
317 accountId: currentAccount.guid,
318 rootXPub: currentAccount.rootXPub
322 let balances = currentAccount.balances ||[]
323 balances = balances.map(({ in_btc, in_cny, in_usd, name, ...keepAttrs}) => keepAttrs)
326 address: currentAccount.address,
327 alias:currentAccount.alias,
328 balances: balances|| [],
329 accountId: currentAccount.guid,
330 rootXPub: currentAccount.rootXPub
334 if(bytom.settings.domains.find(_domain => _domain === domain)) {
335 sendResponse(account);
337 NotificationService.open(new Prompt(PromptTypes.REQUEST_AUTH, payload.domain, {}, approved => {
338 if(approved === false || approved.hasOwnProperty('isError')) sendResponse(approved);
340 bytom.settings.domains.unshift(domain);
341 if(approved === true){
342 this.update(() => sendResponse(account), bytom);
344 this.update(() => sendResponse(approved), bytom);