OSDN Git Service

a64df1184f95d0ff87ee87fa929b2f4b43f9d1cc
[bytom/Byone.git] / src / content.js
1 import { EncryptedStream, LocalStream } from 'extension-streams'
2 import IdGenerator from '@/utils/IdGenerator'
3 import NetworkMessage from '@/messages/network'
4 import InternalMessage from '@/messages/internal'
5 import * as MsgTypes from './messages/types'
6 import * as EventNames from '@/messages/event'
7 import {strippedHost} from '@/utils/GenericTools'
8 import _ from 'lodash';
9
10
11 let stream = new WeakMap()
12 let INJECTION_SCRIPT_FILENAME = 'js/inject.js'
13 let isReady = false
14
15 class Content {
16   constructor() {
17     this.setupEncryptedStream()
18     this.injectInteractionScript()
19   }
20
21   injectInteractionScript() {
22     let script = document.createElement('script')
23     script.src = chrome.extension.getURL(INJECTION_SCRIPT_FILENAME)
24     ;(document.head || document.documentElement).appendChild(script)
25     script.onload = () => script.remove()
26   }
27
28   setupEncryptedStream() {
29     console.log('stream listening...', IdGenerator.text(256))
30
31     stream = new EncryptedStream(EventNames.BYTOM, IdGenerator.text(256))
32     stream.listenWith(msg => this.contentListener(msg))
33
34     stream.onSync(async () => {
35       const defaultAccount = await this.getDefaultAccount();
36       const net = await this.getDefaultNetwork();
37       const chain = await this.getDefaultChain()
38
39       // Pushing an instance of Bytomdapp to the web application
40       stream.send(
41         NetworkMessage.payload(MsgTypes.PUSH_BYTOM, {defaultAccount, net, chain}),
42         EventNames.INJECT
43       )
44
45       // Dispatching the loaded event to the web application.
46       isReady = true
47
48       document.dispatchEvent(new CustomEvent('chromeBytomLoaded'))
49     })
50
51     chrome.storage.onChanged.addListener(async (evt) => {
52       if(evt.bytom.newValue.settings.network !== evt.bytom.oldValue.settings.network){
53         const net = await this.getDefaultNetwork();
54         const defaultAccount = await this.getDefaultAccount();
55         stream.send(
56           NetworkMessage.payload(MsgTypes.UPDATE_BYTOM, {type:'net', value: net}),
57           EventNames.INJECT
58         )
59         stream.send(
60           NetworkMessage.payload(MsgTypes.UPDATE_BYTOM, {type:'default_account', value: defaultAccount}),
61           EventNames.INJECT
62         )
63       }else if(!_.isEqual(evt.bytom.newValue.currentAccount,evt.bytom.oldValue.currentAccount)){
64         const defaultAccount = await this.getDefaultAccount();
65         if(defaultAccount){
66           stream.send(
67             NetworkMessage.payload(MsgTypes.UPDATE_BYTOM, {type:'default_account', value: defaultAccount}),
68             EventNames.INJECT
69           )
70         }
71       }else if(evt.bytom.newValue.settings.netType!== evt.bytom.oldValue.settings.netType){
72         const chain = await this.getDefaultChain();
73         const defaultAccount = await this.getDefaultAccount();
74         stream.send(
75           NetworkMessage.payload(MsgTypes.UPDATE_BYTOM, {type:'chain', value: chain}),
76           EventNames.INJECT
77         )
78         stream.send(
79           NetworkMessage.payload(MsgTypes.UPDATE_BYTOM, {type:'default_account', value: defaultAccount}),
80           EventNames.INJECT
81         )
82       }
83     });
84   }
85
86
87   contentListener(msg) {
88     console.log('content.stream.listen:', msg, stream.key)
89
90     if (!isReady) return
91     if (!msg) return
92     if(!stream.synced && (!msg.hasOwnProperty('type') || msg.type !== 'sync')) {
93       stream.send(new Error('inject Error'), PairingTags.INJECTED);
94       return;
95     }
96
97     let networkMessage = NetworkMessage.fromJson(msg)
98     switch (msg.type) {
99       case 'sync':
100         this.sync(msg)
101         break
102       case MsgTypes.TRANSFER:
103       case MsgTypes.SIGNTRANSACTION:
104       case MsgTypes.ADVTRANSFER:
105       case MsgTypes.SIGNMESSAGE:
106       case MsgTypes.SETCHAIN:
107       case MsgTypes.SEND:
108         this.transfer(msg.type, networkMessage)
109         break
110       case MsgTypes.ENABLE:
111         this.enable(msg.type, networkMessage)
112         break
113       default:
114         stream.send(networkMessage.error('errtest'), EventNames.INJECT)
115         break
116     }
117   }
118
119   getVersion() {}
120
121   getDefaultAccount(){
122     return InternalMessage.payload(MsgTypes.REQUEST_CURRENT_ACCOUNT,{domain:strippedHost()})
123       .send()
124   }
125
126   getDefaultNetwork(){
127     return InternalMessage.signal(MsgTypes.REQUEST_CURRENT_NETWORK)
128       .send()
129   }
130
131   getDefaultChain(){
132     return InternalMessage.signal(MsgTypes.REQUEST_CURRENT_CHAIN_TYPE)
133       .send()
134   }
135
136   respond(message, payload) {
137     if (!isReady) return
138
139     console.log(222, message, payload)
140     const response =
141       !payload || payload.hasOwnProperty('isError')
142         ? message.error(payload)
143         : message.respond(payload)
144     stream.send(response, EventNames.INJECT)
145   }
146
147   sync(message) {
148     stream.key = message.handshake.length ? message.handshake : null
149     stream.send({ type: 'sync' }, EventNames.INJECT)
150     stream.synced = true
151   }
152
153   transfer(type, message) {
154     if (!isReady) return
155
156     InternalMessage.payload(type, message.payload)
157       .send()
158       .then(res => this.respond(message, res))
159   }
160
161   enable(type, networkMessage) {
162     networkMessage.payload ={
163       domain: strippedHost()
164     }
165
166     this.transfer(type, networkMessage)
167   }
168
169 }
170
171 const content = new Content()