OSDN Git Service

add the sign transaction pop up and function.
[bytom/Byone.git] / src / background.js
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'
8
9 import _ from 'lodash'
10 import Error from './utils/errors/Error'
11 import { BTM } from './utils/constants'
12
13 let prompt = null;
14
15 export default class Background {
16   constructor() {
17     this.setupInternalMessaging()
18   }
19
20   setupInternalMessaging() {
21     LocalStream.watch((request, sendResponse) => {
22       console.log(request)
23       const message = InternalMessage.fromJson(request)
24       this.dispatchMessage(sendResponse, message)
25     })
26   }
27
28   dispatchMessage(sendResponse, message) {
29     switch (message.type) {
30       case MsgTypes.TRANSFER:
31         this.transfer(sendResponse, message.payload)
32         break
33       case MsgTypes.ADVTRANSFER:
34         this.advancedTransfer(sendResponse, message.payload)
35         break
36       case MsgTypes.SEND:
37         this.send(sendResponse, message.payload)
38         break
39       case MsgTypes.SIGNTRANSACTION:
40         this.signTransaction(sendResponse, message.payload)
41         break
42       case MsgTypes.SIGNMESSAGE:
43         this.signMessage(sendResponse, message.payload)
44         break
45       case MsgTypes.REQUEST_CURRENT_ACCOUNT:
46         this.requestCurrentAccount(sendResponse, message.payload)
47         break
48       case MsgTypes.REQUEST_CURRENT_NETWORK:
49         this.requestCurrentNetwork(sendResponse)
50         break
51       case MsgTypes.REQUEST_CURRENT_CHAIN_TYPE:
52         this.requestCurrentChain(sendResponse)
53         break
54       case MsgTypes.ENABLE:
55         Background.authenticate(sendResponse, message.payload)
56         break
57       case MsgTypes.SET_PROMPT:
58         Background.setPrompt(sendResponse, message.payload);
59         break;
60       case MsgTypes.GET_PROMPT:
61         Background.getPrompt(sendResponse);
62         break;
63       case MsgTypes.LOAD:
64         Background.load(sendResponse);
65         break;
66       case MsgTypes.UPDATE:
67         Background.update(sendResponse, message.payload);
68         break;
69     }
70   }
71
72   static setPrompt(sendResponse, notification){
73     prompt = notification;
74     sendResponse(true);
75   }
76
77   static getPrompt(sendResponse){
78     sendResponse(prompt);
79   }
80
81   signMessage(sendResponse, payload) {
82     if(payload.address === undefined){
83       sendResponse(Error.typeMissed('address'));
84       return false;
85     }
86     if(payload.message === undefined){
87       sendResponse(Error.typeMissed('message'));
88       return false;
89     }
90
91     NotificationService.open(new Prompt(PromptTypes.REQUEST_SIGN, '', payload ,approved => {
92      sendResponse(approved);
93     }));
94   }
95
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)
102
103     if(requestBody.from === undefined){
104       sendResponse(Error.typeMissed('from'));
105       return false;
106     }
107     if(requestBody.to === undefined){
108       sendResponse(Error.typeMissed('to'));
109       return false;
110     }
111     if(requestBody.asset === undefined){
112       sendResponse(Error.typeMissed('asset'));
113       return false;
114     }
115     if(requestBody.amount === undefined){
116       sendResponse(Error.typeMissed('amount'));
117       return false;
118     }
119
120     // NotificationService.open(new Prompt(PromptTypes.REQUEST_TRANSFER, '', payload ,approved => {
121     //   sendResponse(approved);
122     // }));
123
124       chrome.windows.create(
125       {
126         url: `${promptURL}#transfer?${queryString}`,
127         type: 'popup',
128         width: 360,
129         height: 623,
130         top: 0,
131         left: 0
132       },
133       (window) => {
134         chrome.runtime.onMessage.addListener(function(request, sender) {
135           if(sender.tab.windowId === window.id){
136             switch (request.method){
137               case 'transfer':
138                 if (request.action === 'success'){
139                   sendResponse(request.message);
140                   return true;
141                 } else if (request.action === 'reject'){
142                   sendResponse(request.message);
143                   return false;
144                 }
145             }
146           }
147         });
148
149         chrome.windows.onRemoved.addListener(function(windowId){
150           if(windowId === window.id) {
151             sendResponse(Error.promptClosedWithoutAction());
152             return false;
153           }
154         });
155       }
156     )
157   }
158
159   advancedTransfer(sendResponse, payload) {
160
161     if(payload.input === undefined){
162       sendResponse(Error.typeMissed('input'));
163       return false;
164     }
165     if(payload.output === undefined){
166       sendResponse(Error.typeMissed('output'));
167       return false;
168     }
169     if(payload.gas === undefined){
170       sendResponse(Error.typeMissed('gas'));
171       return false;
172     }
173
174     NotificationService.open(new Prompt(PromptTypes.REQUEST_ADVANCED_TRANSFER, '', payload ,approved => {
175       sendResponse(approved);
176     }));
177
178   }
179
180   signTransaction(sendResponse, payload) {
181     NotificationService.open(new Prompt(PromptTypes.REQUEST_SIGN_TRANSACTION, '', payload ,approved => {
182       sendResponse(approved);
183     }));
184
185   }
186
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
192         let account
193         if(bytom.settings.netType === 'vapor'){
194           let vote
195           const votes = currentAccount.votes
196           if(votes && votes.length >0 ){
197             vote = _.sumBy(votes,'total')
198           }
199
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}
204               else
205                 return keepAttrs
206           })
207
208           account = {
209             address: currentAccount.vpAddress,
210             alias:currentAccount.alias,
211             balances: balances|| [],
212             accountId: currentAccount.guid,
213             rootXPub: currentAccount.rootXPub
214           };
215         }else{
216           let balances = currentAccount.balances ||[]
217           balances = balances.map(({ in_btc, in_cny, in_usd, name, ...keepAttrs}) => keepAttrs)
218
219           account ={
220             address: currentAccount.address,
221             alias:currentAccount.alias,
222             balances: balances|| [],
223             accountId: currentAccount.guid,
224             rootXPub: currentAccount.rootXPub
225           };
226         }
227
228         sendResponse(account)
229       } else{
230         sendResponse(null);
231         return false;
232       }
233     })
234
235   }
236
237   requestCurrentNetwork(sendResponse){
238     Background.load(bytom => {
239         sendResponse(bytom.settings.network);
240     })
241   }
242
243   requestCurrentChain(sendResponse){
244     Background.load(bytom => {
245       const chain = bytom.settings.netType ==='vapor'?'vapor':'bytom'
246       sendResponse(chain);
247     })
248   }
249
250
251   send(sendResponse, payload) {
252     const action = payload.action
253     if(action){
254       let promise
255       switch (action){
256         case 'listAllAccount':
257           promise = accountAction.list()
258           break
259       }
260       if(promise){
261         promise.then(resp =>
262         {
263           sendResponse(resp)
264         })
265       }
266     }
267   }
268
269   /***
270    * Returns the saved instance of Bytom from the storage
271    * @param sendResponse - Delegating response handler
272    * @returns {Bytom}
273    */
274   static load(sendResponse){
275     StorageService.get().then(bytom => {
276       sendResponse(bytom)
277     })
278   }
279
280   /***
281    * Updates the Scatter instance inside persistent storage
282    * @param sendResponse - Delegating response handler
283    * @param bytom - The updated cleartext Scatter instance
284    * @returns {boolean}
285    */
286   static update(sendResponse, bytom){
287     StorageService.save(bytom).then(saved => {
288       sendResponse(bytom)
289     })
290   }
291
292   static authenticate(sendResponse, payload){
293     Background.load(bytom => {
294       const domain = payload.domain;
295       const currentAccount =  bytom.currentAccount
296
297       let account
298       if(bytom.settings.netType === 'vapor'){
299         let vote = 0
300         const votes = currentAccount.votes
301         if(votes && votes.length >0 ){
302           vote = _.sumBy(votes,'total')
303         }
304
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}
309           else
310             return keepAttrs
311         })
312
313         account ={
314           address: currentAccount.vpAddress,
315           alias:currentAccount.alias,
316           balances: balances || [],
317           accountId: currentAccount.guid,
318           rootXPub: currentAccount.rootXPub
319         };
320
321       }else{
322         let balances = currentAccount.balances ||[]
323         balances = balances.map(({ in_btc, in_cny, in_usd, name, ...keepAttrs}) => keepAttrs)
324
325         account ={
326           address: currentAccount.address,
327           alias:currentAccount.alias,
328           balances: balances|| [],
329           accountId: currentAccount.guid,
330           rootXPub: currentAccount.rootXPub
331         };
332       }
333
334       if(bytom.settings.domains.find(_domain => _domain === domain)) {
335         sendResponse(account);
336       } else{
337         NotificationService.open(new Prompt(PromptTypes.REQUEST_AUTH, payload.domain, {}, approved => {
338           if(approved === false || approved.hasOwnProperty('isError')) sendResponse(approved);
339           else {
340             bytom.settings.domains.unshift(domain);
341             if(approved === true){
342               this.update(() => sendResponse(account), bytom);
343             }else{
344               this.update(() => sendResponse(approved), bytom);
345             }
346           }
347         }));
348       }
349     })
350   }
351
352
353 }
354
355 new Background()