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() {
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
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
}
}
}
+
+ /***
+ * 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()