OSDN Git Service

add the sign transaction pop up and function.
[bytom/Byone.git] / src / background.js
index b6b4873..6461fbb 100644 (file)
@@ -1,27 +1,20 @@
 import { LocalStream } from 'extension-streams'
 import InternalMessage from '@/messages/internal'
 import * as MsgTypes from './messages/types'
+import NotificationService from './services/NotificationService'
+import StorageService from './services/StorageService'
+import Prompt from './prompts/Prompt';
+import * as PromptTypes from './prompts/PromptTypes'
 
-import accountAction from "@/models/account";
-import bytom from "@/models/bytom";
+import _ from 'lodash'
+import Error from './utils/errors/Error'
+import { BTM } from './utils/constants'
+
+let prompt = null;
 
 export default class Background {
   constructor() {
     this.setupInternalMessaging()
-    this.setupBytom()
-    window.bytomAPI = bytom
-  }
-
-  setupBytom(){
-    const network = localStorage.bytomNet||'mainnet'
-    bytom.setupNet(network)
-
-    window.addEventListener('storage', storageEventHandler, false);
-    function storageEventHandler(evt){
-      if(evt.key === 'bytomNet'){
-        bytom.setupNet( evt.newValue )
-      }
-    }
   }
 
   setupInternalMessaging() {
@@ -43,37 +36,96 @@ export default class Background {
       case MsgTypes.SEND:
         this.send(sendResponse, message.payload)
         break
+      case MsgTypes.SIGNTRANSACTION:
+        this.signTransaction(sendResponse, message.payload)
+        break
+      case MsgTypes.SIGNMESSAGE:
+        this.signMessage(sendResponse, message.payload)
+        break
+      case MsgTypes.REQUEST_CURRENT_ACCOUNT:
+        this.requestCurrentAccount(sendResponse, message.payload)
+        break
+      case MsgTypes.REQUEST_CURRENT_NETWORK:
+        this.requestCurrentNetwork(sendResponse)
+        break
+      case MsgTypes.REQUEST_CURRENT_CHAIN_TYPE:
+        this.requestCurrentChain(sendResponse)
+        break
+      case MsgTypes.ENABLE:
+        Background.authenticate(sendResponse, message.payload)
+        break
+      case MsgTypes.SET_PROMPT:
+        Background.setPrompt(sendResponse, message.payload);
+        break;
+      case MsgTypes.GET_PROMPT:
+        Background.getPrompt(sendResponse);
+        break;
+      case MsgTypes.LOAD:
+        Background.load(sendResponse);
+        break;
+      case MsgTypes.UPDATE:
+        Background.update(sendResponse, message.payload);
+        break;
     }
   }
 
-  transfer(sendResponse, payload) {
-    var promptURL = chrome.extension.getURL('pages/prompt.html')
-    var queryString = new URLSearchParams(payload).toString()
-    console.log(promptURL, queryString)
-    chrome.windows.create(
-      {
-        url: `${promptURL}#transfer?${queryString}`,
-        type: 'popup',
-        width: 350,
-        height: 623,
-        top: 0,
-        left: 0
-      },
-      () => {
-        sendResponse(true)
-      }
-    )
+  static setPrompt(sendResponse, notification){
+    prompt = notification;
+    sendResponse(true);
   }
 
-  advancedTransfer(sendResponse, payload) {
+  static getPrompt(sendResponse){
+    sendResponse(prompt);
+  }
+
+  signMessage(sendResponse, payload) {
+    if(payload.address === undefined){
+      sendResponse(Error.typeMissed('address'));
+      return false;
+    }
+    if(payload.message === undefined){
+      sendResponse(Error.typeMissed('message'));
+      return false;
+    }
+
+    NotificationService.open(new Prompt(PromptTypes.REQUEST_SIGN, '', payload ,approved => {
+     sendResponse(approved);
+    }));
+  }
+
+  transfer(sendResponse, payload) {
     var promptURL = chrome.extension.getURL('pages/prompt.html')
-    var queryString = 'object='+JSON.stringify(payload)
+    var requestBody = payload
+    requestBody.type = "popup"
+    var queryString = new URLSearchParams(requestBody).toString()
     console.log(promptURL, queryString)
-    chrome.windows.create(
+
+    if(requestBody.from === undefined){
+      sendResponse(Error.typeMissed('from'));
+      return false;
+    }
+    if(requestBody.to === undefined){
+      sendResponse(Error.typeMissed('to'));
+      return false;
+    }
+    if(requestBody.asset === undefined){
+      sendResponse(Error.typeMissed('asset'));
+      return false;
+    }
+    if(requestBody.amount === undefined){
+      sendResponse(Error.typeMissed('amount'));
+      return false;
+    }
+
+    // NotificationService.open(new Prompt(PromptTypes.REQUEST_TRANSFER, '', payload ,approved => {
+    //   sendResponse(approved);
+    // }));
+
+      chrome.windows.create(
       {
-        url: `${promptURL}#advancedTransfer?${queryString}`,
+        url: `${promptURL}#transfer?${queryString}`,
         type: 'popup',
-        width: 350,
+        width: 360,
         height: 623,
         top: 0,
         left: 0
@@ -82,31 +134,125 @@ export default class Background {
         chrome.runtime.onMessage.addListener(function(request, sender) {
           if(sender.tab.windowId === window.id){
             switch (request.method){
-              case 'advanced-transfer':
-                sendResponse(request);
-                break
+              case 'transfer':
+                if (request.action === 'success'){
+                  sendResponse(request.message);
+                  return true;
+                } else if (request.action === 'reject'){
+                  sendResponse(request.message);
+                  return false;
+                }
             }
           }
         });
+
+        chrome.windows.onRemoved.addListener(function(windowId){
+          if(windowId === window.id) {
+            sendResponse(Error.promptClosedWithoutAction());
+            return false;
+          }
+        });
       }
     )
   }
 
+  advancedTransfer(sendResponse, payload) {
+
+    if(payload.input === undefined){
+      sendResponse(Error.typeMissed('input'));
+      return false;
+    }
+    if(payload.output === undefined){
+      sendResponse(Error.typeMissed('output'));
+      return false;
+    }
+    if(payload.gas === undefined){
+      sendResponse(Error.typeMissed('gas'));
+      return false;
+    }
+
+    NotificationService.open(new Prompt(PromptTypes.REQUEST_ADVANCED_TRANSFER, '', payload ,approved => {
+      sendResponse(approved);
+    }));
+
+  }
+
+  signTransaction(sendResponse, payload) {
+    NotificationService.open(new Prompt(PromptTypes.REQUEST_SIGN_TRANSACTION, '', payload ,approved => {
+      sendResponse(approved);
+    }));
+
+  }
+
+  requestCurrentAccount(sendResponse, payload){
+    Background.load(bytom => {
+      const domain = payload.domain;
+      if(bytom.settings.domains.find(_domain => _domain === domain)) {
+        const currentAccount =  bytom.currentAccount
+        let account
+        if(bytom.settings.netType === 'vapor'){
+          let vote
+          const votes = currentAccount.votes
+          if(votes && votes.length >0 ){
+            vote = _.sumBy(votes,'total')
+          }
+
+          let balances = currentAccount.vpBalances ||[]
+          balances = balances.map(({ in_btc, in_cny, in_usd, name, ...keepAttrs}) => {
+            if(keepAttrs.asset === BTM)
+              return {availableBalance: (keepAttrs.balance-vote),...keepAttrs}
+              else
+                return keepAttrs
+          })
+
+          account = {
+            address: currentAccount.vpAddress,
+            alias:currentAccount.alias,
+            balances: balances|| [],
+            accountId: currentAccount.guid,
+            rootXPub: currentAccount.rootXPub
+          };
+        }else{
+          let balances = currentAccount.balances ||[]
+          balances = balances.map(({ in_btc, in_cny, in_usd, name, ...keepAttrs}) => keepAttrs)
+
+          account ={
+            address: currentAccount.address,
+            alias:currentAccount.alias,
+            balances: balances|| [],
+            accountId: currentAccount.guid,
+            rootXPub: currentAccount.rootXPub
+          };
+        }
+
+        sendResponse(account)
+      } else{
+        sendResponse(null);
+        return false;
+      }
+    })
+
+  }
+
+  requestCurrentNetwork(sendResponse){
+    Background.load(bytom => {
+        sendResponse(bytom.settings.network);
+    })
+  }
+
+  requestCurrentChain(sendResponse){
+    Background.load(bytom => {
+      const chain = bytom.settings.netType ==='vapor'?'vapor':'bytom'
+      sendResponse(chain);
+    })
+  }
+
+
   send(sendResponse, payload) {
     const action = payload.action
-    const body = payload.body
     if(action){
       let promise
       switch (action){
-        case 'balance':
-          const id = body.id
-          const guid = body.guid
-          promise = accountAction.balance(guid, id)
-          break
-        case 'currentAccount':
-          let account = JSON.parse(localStorage.currentAccount)
-          sendResponse(account)
-          break
         case 'listAllAccount':
           promise = accountAction.list()
           break
@@ -119,6 +265,91 @@ export default class Background {
       }
     }
   }
+
+  /***
+   * Returns the saved instance of Bytom from the storage
+   * @param sendResponse - Delegating response handler
+   * @returns {Bytom}
+   */
+  static load(sendResponse){
+    StorageService.get().then(bytom => {
+      sendResponse(bytom)
+    })
+  }
+
+  /***
+   * Updates the Scatter instance inside persistent storage
+   * @param sendResponse - Delegating response handler
+   * @param bytom - The updated cleartext Scatter instance
+   * @returns {boolean}
+   */
+  static update(sendResponse, bytom){
+    StorageService.save(bytom).then(saved => {
+      sendResponse(bytom)
+    })
+  }
+
+  static authenticate(sendResponse, payload){
+    Background.load(bytom => {
+      const domain = payload.domain;
+      const currentAccount =  bytom.currentAccount
+
+      let account
+      if(bytom.settings.netType === 'vapor'){
+        let vote = 0
+        const votes = currentAccount.votes
+        if(votes && votes.length >0 ){
+          vote = _.sumBy(votes,'total')
+        }
+
+        let balances = currentAccount.vpBalances ||[]
+        balances = balances.map(({ in_btc, in_cny, in_usd, name, ...keepAttrs}) => {
+          if(keepAttrs.asset === BTM)
+            return {availableBalance: (keepAttrs.balance-vote),...keepAttrs}
+          else
+            return keepAttrs
+        })
+
+        account ={
+          address: currentAccount.vpAddress,
+          alias:currentAccount.alias,
+          balances: balances || [],
+          accountId: currentAccount.guid,
+          rootXPub: currentAccount.rootXPub
+        };
+
+      }else{
+        let balances = currentAccount.balances ||[]
+        balances = balances.map(({ in_btc, in_cny, in_usd, name, ...keepAttrs}) => keepAttrs)
+
+        account ={
+          address: currentAccount.address,
+          alias:currentAccount.alias,
+          balances: balances|| [],
+          accountId: currentAccount.guid,
+          rootXPub: currentAccount.rootXPub
+        };
+      }
+
+      if(bytom.settings.domains.find(_domain => _domain === domain)) {
+        sendResponse(account);
+      } else{
+        NotificationService.open(new Prompt(PromptTypes.REQUEST_AUTH, payload.domain, {}, approved => {
+          if(approved === false || approved.hasOwnProperty('isError')) sendResponse(approved);
+          else {
+            bytom.settings.domains.unshift(domain);
+            if(approved === true){
+              this.update(() => sendResponse(account), bytom);
+            }else{
+              this.update(() => sendResponse(approved), bytom);
+            }
+          }
+        }));
+      }
+    })
+  }
+
+
 }
 
 new Background()