@0xsequence/provider 0.0.0-2021823181734

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/CHANGELOG.md +909 -0
  2. package/README.md +4 -0
  3. package/dist/0xsequence-provider.cjs.d.ts +1 -0
  4. package/dist/0xsequence-provider.cjs.dev.js +3540 -0
  5. package/dist/0xsequence-provider.cjs.js +7 -0
  6. package/dist/0xsequence-provider.cjs.prod.js +3540 -0
  7. package/dist/0xsequence-provider.esm.js +3508 -0
  8. package/dist/declarations/src/commands/index.d.ts +20 -0
  9. package/dist/declarations/src/index.d.ts +5 -0
  10. package/dist/declarations/src/provider.d.ts +59 -0
  11. package/dist/declarations/src/transports/base-provider-transport.d.ts +40 -0
  12. package/dist/declarations/src/transports/base-wallet-transport.d.ts +38 -0
  13. package/dist/declarations/src/transports/extension-transport/base-injected-transport.d.ts +18 -0
  14. package/dist/declarations/src/transports/extension-transport/extension-message-handler.d.ts +12 -0
  15. package/dist/declarations/src/transports/extension-transport/extension-message-provider.d.ts +11 -0
  16. package/dist/declarations/src/transports/extension-transport/index.d.ts +3 -0
  17. package/dist/declarations/src/transports/index.d.ts +7 -0
  18. package/dist/declarations/src/transports/mux-transport/index.d.ts +1 -0
  19. package/dist/declarations/src/transports/mux-transport/mux-message-provider.d.ts +22 -0
  20. package/dist/declarations/src/transports/proxy-transport/index.d.ts +3 -0
  21. package/dist/declarations/src/transports/proxy-transport/proxy-message-channel.d.ts +15 -0
  22. package/dist/declarations/src/transports/proxy-transport/proxy-message-handler.d.ts +12 -0
  23. package/dist/declarations/src/transports/proxy-transport/proxy-message-provider.d.ts +12 -0
  24. package/dist/declarations/src/transports/wallet-request-handler.d.ts +51 -0
  25. package/dist/declarations/src/transports/window-transport/index.d.ts +2 -0
  26. package/dist/declarations/src/transports/window-transport/window-message-handler.d.ts +15 -0
  27. package/dist/declarations/src/transports/window-transport/window-message-provider.d.ts +13 -0
  28. package/dist/declarations/src/types.d.ts +170 -0
  29. package/dist/declarations/src/utils.d.ts +14 -0
  30. package/dist/declarations/src/wallet.d.ts +99 -0
  31. package/package.json +37 -0
  32. package/src/commands/index.ts +146 -0
  33. package/src/index.ts +5 -0
  34. package/src/provider.ts +494 -0
  35. package/src/transports/base-provider-transport.ts +411 -0
  36. package/src/transports/base-wallet-transport.ts +441 -0
  37. package/src/transports/extension-transport/base-injected-transport.ts +100 -0
  38. package/src/transports/extension-transport/extension-message-handler.ts +25 -0
  39. package/src/transports/extension-transport/extension-message-provider.ts +41 -0
  40. package/src/transports/extension-transport/index.ts +3 -0
  41. package/src/transports/index.ts +7 -0
  42. package/src/transports/mux-transport/index.ts +1 -0
  43. package/src/transports/mux-transport/mux-message-provider.ts +160 -0
  44. package/src/transports/proxy-transport/index.ts +3 -0
  45. package/src/transports/proxy-transport/proxy-message-channel.ts +58 -0
  46. package/src/transports/proxy-transport/proxy-message-handler.ts +46 -0
  47. package/src/transports/proxy-transport/proxy-message-provider.ts +81 -0
  48. package/src/transports/wallet-request-handler.ts +702 -0
  49. package/src/transports/window-transport/index.ts +2 -0
  50. package/src/transports/window-transport/window-message-handler.ts +166 -0
  51. package/src/transports/window-transport/window-message-provider.ts +183 -0
  52. package/src/types.ts +252 -0
  53. package/src/utils.ts +76 -0
  54. package/src/wallet.ts +692 -0
@@ -0,0 +1,441 @@
1
+ import { ethers } from 'ethers'
2
+ import {
3
+ WalletTransport,
4
+ ProviderMessage,
5
+ ProviderMessageRequest,
6
+ EventType,
7
+ ProviderMessageResponse,
8
+ ProviderMessageTransport,
9
+ ProviderRpcError,
10
+ InitState,
11
+ ConnectDetails,
12
+ OpenWalletIntent,
13
+ WalletSession,
14
+ TransportSession
15
+ } from '../types'
16
+
17
+ import { WalletRequestHandler } from './wallet-request-handler'
18
+
19
+ import { NetworkConfig, WalletContext, JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network'
20
+ import { logger, sanitizeAlphanumeric, sanitizeHost, sanitizeNumberString } from '@0xsequence/utils'
21
+ import { AuthorizationOptions } from '@0xsequence/auth'
22
+
23
+ import { PROVIDER_OPEN_TIMEOUT } from './base-provider-transport'
24
+ import { isBrowserExtension } from '../utils'
25
+
26
+ const TRANSPORT_SESSION_LS_KEY = '@sequence.transportSession'
27
+
28
+ export abstract class BaseWalletTransport implements WalletTransport {
29
+ protected walletRequestHandler: WalletRequestHandler
30
+ protected _sessionId: string
31
+ protected _registered: boolean
32
+
33
+ protected _init: InitState
34
+ protected _initNonce: string
35
+ protected _initCallback?: (error?: string) => void
36
+
37
+ // appOrigin identifies the dapp's origin which opened the app. A transport
38
+ // will auto-detect and set this value if it can. This is determined
39
+ // as the parent app/window which opened the wallet.
40
+ protected appOrigin?: string
41
+
42
+ constructor(walletRequestHandler: WalletRequestHandler) {
43
+ this.walletRequestHandler = walletRequestHandler
44
+ this._init = InitState.NIL
45
+
46
+ this.walletRequestHandler.on('connect', (connectDetails: ConnectDetails) => {
47
+ if (!this.registered) return
48
+ // means user has logged in and wallet is connected to the app
49
+ this.notifyConnect(connectDetails)
50
+ })
51
+
52
+ this.walletRequestHandler.on('disconnect', (error?: ProviderRpcError) => {
53
+ if (!this.registered) return
54
+ // means user has logged out the app / disconnected wallet from the app
55
+ this.notifyDisconnect(error)
56
+ })
57
+
58
+ this.walletRequestHandler.on('accountsChanged', (accounts: string[]) => {
59
+ if (!this.registered) return
60
+ this.notifyAccountsChanged(accounts)
61
+ })
62
+
63
+ this.walletRequestHandler.on('networks', (networks: NetworkConfig[]) => {
64
+ if (!this.registered) return
65
+ this.notifyNetworks(networks)
66
+ if (!networks || networks.length === 0) {
67
+ this.notifyChainChanged('0x0')
68
+ } else {
69
+ this.notifyChainChanged(ethers.utils.hexlify(networks[0].chainId))
70
+ }
71
+ })
72
+
73
+ this.walletRequestHandler.on('walletContext', (walletContext: WalletContext) => {
74
+ if (!this.registered || !walletContext) return
75
+ this.notifyWalletContext(walletContext)
76
+ })
77
+
78
+ this.walletRequestHandler.on('close', (error?: ProviderRpcError) => {
79
+ if (!this.registered) return
80
+ this.notifyClose(error)
81
+ })
82
+ }
83
+
84
+ get registered(): boolean {
85
+ return this._registered
86
+ }
87
+
88
+ register() {
89
+ throw new Error('abstract method')
90
+ }
91
+
92
+ unregister() {
93
+ throw new Error('abstract method')
94
+ }
95
+
96
+ sendAsync = async (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => {
97
+ throw new Error('abstract method')
98
+ }
99
+
100
+ handleMessage = async (message: ProviderMessage<any>) => {
101
+ const request = message
102
+
103
+ // ensure initial handshake is complete before accepting
104
+ // other kinds of messages.
105
+ if (this._init !== InitState.OK) {
106
+ if (request.type === EventType.INIT) {
107
+ if (this.isValidInitAck(message)) {
108
+ // successful init
109
+ if (this._initCallback) this._initCallback()
110
+ } else {
111
+ // failed init
112
+ if (this._initCallback) this._initCallback('invalid init')
113
+ return
114
+ }
115
+ } else {
116
+ // we expect init message first. do nothing here.
117
+ }
118
+ return
119
+ }
120
+
121
+ // handle request
122
+ switch (request.type) {
123
+ case EventType.OPEN: {
124
+ if (this._init !== InitState.OK) return
125
+ const session: TransportSession = {
126
+ sessionId: request.data.sessionId,
127
+ intent: request.data.intent,
128
+ networkId: request.data.networkId
129
+ }
130
+ await this.open(session)
131
+ return
132
+ }
133
+
134
+ case EventType.CLOSE: {
135
+ if (this._init !== InitState.OK) return
136
+ // noop. just here to capture the message so event emitters may be notified
137
+ return
138
+ }
139
+
140
+ case EventType.MESSAGE: {
141
+ const response = await this.walletRequestHandler.sendMessageRequest(request)
142
+ this.sendMessage(response)
143
+
144
+ if (response.data.error) {
145
+ // TODO: for certain errors, whenever we want to render something to the UI
146
+ // we should throw
147
+ }
148
+ return
149
+ }
150
+
151
+ default: {
152
+ logger.error(`unexpected payload type ${request.type}`)
153
+ }
154
+ }
155
+ }
156
+
157
+ // sendMessageRequest sends a ProviderMessageRequest to the wallet post-message transport
158
+ sendMessageRequest = async (message: ProviderMessageRequest): Promise<ProviderMessageResponse> => {
159
+ return this.walletRequestHandler.sendMessageRequest(message)
160
+ }
161
+
162
+ sendMessage(message: ProviderMessage<any>) {
163
+ throw new Error('abstract method')
164
+ }
165
+
166
+ notifyOpen(openInfo: { chainId?: string; sessionId?: string; session?: WalletSession; error?: string }) {
167
+ const { chainId, sessionId, session, error } = openInfo
168
+ this.sendMessage({
169
+ idx: -1,
170
+ type: EventType.OPEN,
171
+ data: {
172
+ chainId,
173
+ sessionId,
174
+ session,
175
+ error
176
+ }
177
+ })
178
+ }
179
+
180
+ notifyClose(error?: ProviderRpcError) {
181
+ this.sendMessage({
182
+ idx: -1,
183
+ type: EventType.CLOSE,
184
+ data: error ? { error } : null
185
+ })
186
+ }
187
+
188
+ notifyConnect(connectDetails: ConnectDetails) {
189
+ this.sendMessage({
190
+ idx: -1,
191
+ type: EventType.CONNECT,
192
+ data: connectDetails
193
+ })
194
+ }
195
+
196
+ notifyDisconnect(error?: ProviderRpcError) {
197
+ this.sendMessage({
198
+ idx: -1,
199
+ type: EventType.DISCONNECT,
200
+ data: error ? { error } : null
201
+ })
202
+ }
203
+
204
+ notifyAccountsChanged(accounts: string[]) {
205
+ this.sendMessage({
206
+ idx: -1,
207
+ type: EventType.ACCOUNTS_CHANGED,
208
+ data: accounts
209
+ })
210
+ }
211
+
212
+ notifyChainChanged(chainIdHex: string) {
213
+ this.sendMessage({
214
+ idx: -1,
215
+ type: EventType.CHAIN_CHANGED,
216
+ data: chainIdHex
217
+ })
218
+ }
219
+
220
+ notifyNetworks(networks: NetworkConfig[]) {
221
+ this.sendMessage({
222
+ idx: -1,
223
+ type: EventType.NETWORKS,
224
+ data: networks
225
+ })
226
+ }
227
+
228
+ notifyWalletContext(walletContext: WalletContext) {
229
+ this.sendMessage({
230
+ idx: -1,
231
+ type: EventType.WALLET_CONTEXT,
232
+ data: walletContext
233
+ })
234
+ }
235
+
236
+ protected isValidInitAck(message: ProviderMessage<any>): boolean {
237
+ if (this._init === InitState.OK) {
238
+ // we're already in init state, we shouldn't handle this message
239
+ logger.warn("isValidInitAck, already in init'd state, so inquiry is invalid.")
240
+ return false
241
+ }
242
+ if (message.type !== EventType.INIT) {
243
+ logger.warn('isValidInitAck, invalid message type, expecting init')
244
+ return false
245
+ }
246
+
247
+ const { sessionId, nonce } = (message.data as any) as { sessionId: string; nonce: string }
248
+ if (!sessionId || sessionId.length === 0 || !nonce || nonce.length === 0) {
249
+ logger.error('invalid init ack')
250
+ return false
251
+ }
252
+ if (sessionId !== this._sessionId || nonce !== this._initNonce) {
253
+ logger.error('invalid init ack match')
254
+ return false
255
+ }
256
+
257
+ // all checks pass, its true
258
+ return true
259
+ }
260
+
261
+ private init(): Promise<void> {
262
+ return new Promise<void>((resolve, reject) => {
263
+ // avoid re-init`ing, or if there is a transport which doesn't require
264
+ // it, then it may set this._init to OK in its constructor.
265
+ if (this._init === InitState.OK) {
266
+ resolve()
267
+ return
268
+ }
269
+ if (this._init !== InitState.NIL || this._initCallback) {
270
+ reject('transport init is in progress')
271
+ return
272
+ }
273
+
274
+ // start init timeout, if we don't receive confirmation
275
+ // from provider within this amount of time, then we timeout
276
+ const initTimeout = setTimeout(() => {
277
+ logger.warn('transport init timed out')
278
+ if (this._initCallback) {
279
+ this._initCallback('transport init timed out')
280
+ }
281
+ }, PROVIDER_OPEN_TIMEOUT / 2)
282
+
283
+ // setup callback as we receive the init message async in the handleMessage function
284
+ this._initCallback = (error?: string) => {
285
+ this._initCallback = undefined // reset
286
+ clearTimeout(initTimeout)
287
+ if (error) {
288
+ reject(error)
289
+ } else {
290
+ this._init = InitState.OK
291
+ resolve()
292
+ }
293
+ }
294
+
295
+ // send init request with random nonce to the provider, where we expect
296
+ // for the provider to echo it back to us as complete handshake
297
+ this._initNonce = `${performance.now()}`
298
+ this.sendMessage({
299
+ idx: -1,
300
+ type: EventType.INIT,
301
+ data: { nonce: this._initNonce }
302
+ })
303
+ this._init = InitState.SENT_NONCE
304
+
305
+ // NOTE: the promise will resolve in the _initCallback method
306
+ // which will be called from either handleMessage or the initTimeout
307
+ })
308
+ }
309
+
310
+ protected open = async ({ sessionId, intent, networkId }: TransportSession): Promise<boolean> => {
311
+ if (sessionId) {
312
+ this._sessionId = sanitizeNumberString(sessionId)
313
+ // persist transport session in localstorage for restoring after redirect/reload
314
+ this.saveTransportSession({ sessionId, intent, networkId })
315
+ }
316
+
317
+ // init handshake for certain transports, before we can open the communication.
318
+ //
319
+ // for example, with the window-transport, we have to exchange messages to determine the
320
+ // origin host of the dapp.
321
+ await this.init()
322
+
323
+ // Prepare connect options from intent
324
+ if (intent && intent.type === 'connect' && intent.options) {
325
+ const connectOptions = intent.options
326
+ const authorizeOptions: AuthorizationOptions = connectOptions // overlapping types
327
+
328
+ // Sanity/integrity check the intent payload, and set authorization origin
329
+ // if its been determined as part of the init handshake from earlier.
330
+ if (this.appOrigin && authorizeOptions?.origin) {
331
+ if (!isBrowserExtension()) {
332
+ if (authorizeOptions.origin !== this.appOrigin) {
333
+ throw new Error('origin is invalid')
334
+ } else {
335
+ // request origin and derived origins match, lets carry on
336
+ }
337
+ }
338
+ } else if (!this.appOrigin && authorizeOptions?.origin) {
339
+ // ie. when we can't determine the origin in our transport, but dapp provides it to us.
340
+ // we just sanitize the origin host.
341
+ connectOptions.origin = sanitizeHost(authorizeOptions.origin)
342
+ } else if (this.appOrigin) {
343
+ // ie. when we auto-determine the origin such as in window-transport
344
+ connectOptions.origin = this.appOrigin
345
+ }
346
+ if (connectOptions.app) {
347
+ connectOptions.app = sanitizeAlphanumeric(connectOptions.app)
348
+ }
349
+
350
+ // Set connect options on the walletRequestHandler as our primary
351
+ // wallet controller
352
+ this.walletRequestHandler.setConnectOptions(connectOptions)
353
+ if (connectOptions.networkId) {
354
+ networkId = connectOptions.networkId
355
+ }
356
+ } else {
357
+ this.walletRequestHandler.setConnectOptions(undefined)
358
+ }
359
+
360
+ // Notify open and proceed to prompt for connection if intended
361
+ if (!this.walletRequestHandler.isSignedIn()) {
362
+ // open wallet without a specific connected chainId, as the user is not signed in
363
+ this.notifyOpen({
364
+ sessionId: this._sessionId
365
+ })
366
+ return true
367
+ } else {
368
+ // Set default network, in case of error chainId will be undefined or 0
369
+ let chainId: number | undefined = undefined
370
+ try {
371
+ if (networkId) {
372
+ chainId = await this.walletRequestHandler.setDefaultNetwork(networkId, false)
373
+ } else {
374
+ chainId = await this.walletRequestHandler.getChainId()
375
+ }
376
+ } catch (err) {
377
+ console.error(err)
378
+ }
379
+
380
+ // Failed to set default network on open -- quit + close
381
+ if (!chainId || chainId <= 0) {
382
+ this.notifyOpen({
383
+ sessionId: this._sessionId,
384
+ error: `failed to open wallet on network ${networkId}`
385
+ })
386
+ return false
387
+ }
388
+
389
+ // prompt user with a connect request. the options will be used as previously set above.
390
+ // upon success, the walletRequestHandler will notify the dapp with the ConnectDetails.
391
+ // upon cancellation by user, the walletRequestHandler will throw an error
392
+
393
+ if (intent && intent.type === 'connect') {
394
+ // notify wallet is opened, without session details
395
+ this.notifyOpen({
396
+ sessionId: this._sessionId
397
+ })
398
+
399
+ try {
400
+ const connectDetails = await this.walletRequestHandler.promptConnect(intent.options)
401
+ if (connectDetails.connected) {
402
+ this.walletRequestHandler.notifyConnect(connectDetails)
403
+ }
404
+ } catch (err) {
405
+ logger.warn('promptConnect not connected:', err)
406
+ } finally {
407
+ // auto-close by default, unless intent is to keep open
408
+ if (!intent.options || intent.options.keepWalletOpened !== true) {
409
+ this.notifyClose()
410
+ }
411
+ }
412
+ } else {
413
+ // user is already connected, notify session details.
414
+ // TODO: in future, keep list if 'connected' dapps / sessions in the session
415
+ // controller, and only sync with allowed apps
416
+ this.notifyOpen({
417
+ sessionId: this._sessionId,
418
+ chainId: `${chainId}`,
419
+ session: await this.walletRequestHandler.walletSession()
420
+ })
421
+ }
422
+ }
423
+
424
+ return true
425
+ }
426
+
427
+ private saveTransportSession = (session: TransportSession) => {
428
+ window.localStorage.setItem(TRANSPORT_SESSION_LS_KEY, JSON.stringify(session))
429
+ }
430
+
431
+ protected getCachedTransportSession = (): TransportSession | null => {
432
+ const session = window.localStorage.getItem(TRANSPORT_SESSION_LS_KEY)
433
+
434
+ try {
435
+ return session ? (JSON.parse(session) as TransportSession) : null
436
+ } catch (err) {
437
+ console.error(`unable to parse transport session: ${session}`)
438
+ return null
439
+ }
440
+ }
441
+ }
@@ -0,0 +1,100 @@
1
+ import { JsonRpcRequest, JsonRpcResponse } from '@0xsequence/network'
2
+ import { EventEmitter2 as EventEmitter } from 'eventemitter2'
3
+ import {
4
+ ProviderMessageResponseCallback,
5
+ ProviderMessage,
6
+ EventType,
7
+ ProviderMessageRequest,
8
+ ProviderMessageResponse
9
+ } from '../../types'
10
+
11
+ interface Stream {
12
+ on(ev: string | symbol, fn: (...args: any[]) => void): void
13
+ writable: boolean
14
+ write(chunk: any, cb?: (error: Error | null | undefined) => void): boolean
15
+ }
16
+
17
+ // to be used on injected window.ethereum EIP1193 proxy
18
+ export abstract class BaseInjectedTransport extends EventEmitter {
19
+ protected responseCallbacks = new Map<number, ProviderMessageResponseCallback>()
20
+
21
+ private _messageIdx = 0
22
+ protected nextMessageIdx = () => ++this._messageIdx
23
+
24
+ constructor(private stream: Stream) {
25
+ super()
26
+
27
+ this.stream.on('data', this.handleMessage)
28
+ }
29
+
30
+ private handleMessage = (message: ProviderMessage<JsonRpcResponse>) => {
31
+ if (!message.type || !message.data) {
32
+ return
33
+ }
34
+
35
+ console.log('[received message]', message)
36
+
37
+ const requestIdx = message.idx
38
+ const responseCallback = this.responseCallbacks.get(requestIdx)
39
+ if (requestIdx) {
40
+ this.responseCallbacks.delete(requestIdx)
41
+ }
42
+
43
+ switch (message.type) {
44
+ case EventType.MESSAGE:
45
+ if (responseCallback) {
46
+ this.emit(EventType.MESSAGE, message)
47
+ responseCallback(message.data.error, message)
48
+ } else {
49
+ // NOTE: this would occur if 'idx' isn't set, which should never happen
50
+ // or when we register two handler, or duplicate messages with the same idx are sent,
51
+ // all of which should be prevented prior to getting to this point
52
+ throw new Error('impossible state')
53
+ }
54
+ break
55
+ case EventType.DISCONNECT:
56
+ case EventType.ACCOUNTS_CHANGED:
57
+ case EventType.CHAIN_CHANGED:
58
+ this.emit(message.type, message.data)
59
+ break
60
+ default:
61
+ console.error('unknown message type', message)
62
+ break
63
+ }
64
+ }
65
+
66
+ protected sendMessageRequest = async (message: ProviderMessageRequest): Promise<ProviderMessageResponse> => {
67
+ return new Promise((resolve, reject) => {
68
+ if (!message.idx || message.idx <= 0) {
69
+ reject(new Error('message idx not set'))
70
+ }
71
+
72
+ const responseCallback: ProviderMessageResponseCallback = (error: any, response?: ProviderMessageResponse) => {
73
+ if (error) {
74
+ reject(error)
75
+ } else if (response) {
76
+ resolve(response)
77
+ } else {
78
+ throw new Error('no valid response to return')
79
+ }
80
+ }
81
+
82
+ const { idx } = message
83
+ if (!this.responseCallbacks.get(idx)) {
84
+ this.responseCallbacks.set(idx, responseCallback)
85
+ } else {
86
+ reject(new Error('duplicate message idx, should never happen'))
87
+ }
88
+
89
+ this.sendMessage(message)
90
+ })
91
+ }
92
+
93
+ private sendMessage(message: ProviderMessage<JsonRpcRequest>) {
94
+ if (!this.stream.writable) {
95
+ console.error('window post message stream is not writable')
96
+ }
97
+
98
+ this.stream.write(message)
99
+ }
100
+ }
@@ -0,0 +1,25 @@
1
+ import { WalletRequestHandler } from '../wallet-request-handler'
2
+ import { BaseWalletTransport } from '../base-wallet-transport'
3
+ import { InitState, ProviderMessage } from '../../types'
4
+ import { Runtime } from 'webextension-polyfill-ts'
5
+
6
+ export const CHANNEL_ID = 'sequence-extension-message-handler'
7
+
8
+ export class ExtensionMessageHandler extends BaseWalletTransport {
9
+ private port: any
10
+
11
+ constructor(walletRequestHandler: WalletRequestHandler, public runtime: Runtime.Static) {
12
+ super(walletRequestHandler)
13
+ this._init = InitState.OK
14
+ }
15
+
16
+ register() {
17
+ this._registered = true
18
+ this.port = this.runtime.connect({ name: CHANNEL_ID })
19
+ }
20
+
21
+ sendMessage(message: ProviderMessage<any>) {
22
+ console.log('[ExtensionMessageHandler send]', message)
23
+ this.port.postMessage(message)
24
+ }
25
+ }
@@ -0,0 +1,41 @@
1
+ import { InitState, OpenWalletIntent, ProviderMessage } from '../../types'
2
+ import { BaseProviderTransport } from '../base-provider-transport'
3
+ import { CHANNEL_ID } from './extension-message-handler'
4
+
5
+ import { Runtime } from 'webextension-polyfill-ts'
6
+
7
+ export class ExtensionMessageProvider extends BaseProviderTransport {
8
+ constructor(runtime: Runtime.Static) {
9
+ super()
10
+
11
+ runtime.onConnect.addListener(port => {
12
+ if (port.name === CHANNEL_ID) {
13
+ this._init = InitState.OK
14
+
15
+ port.onMessage.addListener((message: ProviderMessage<any>) => {
16
+ this.handleMessage(message)
17
+ })
18
+ }
19
+ })
20
+ }
21
+
22
+ register = () => {
23
+ this._registered = true
24
+ }
25
+
26
+ sendMessage(message: ProviderMessage<any>) {
27
+ //noop
28
+ }
29
+
30
+ unregister() {
31
+ //noop
32
+ }
33
+
34
+ openWallet(path?: string, intent?: OpenWalletIntent, networkId?: string | number) {
35
+ //noop
36
+ }
37
+
38
+ closeWallet() {
39
+ //noop
40
+ }
41
+ }
@@ -0,0 +1,3 @@
1
+ export * from './extension-message-handler'
2
+ export * from './extension-message-provider'
3
+ export * from './base-injected-transport'
@@ -0,0 +1,7 @@
1
+ export * from './base-provider-transport'
2
+ export * from './base-wallet-transport'
3
+ export * from './proxy-transport'
4
+ export * from './mux-transport'
5
+ export * from './window-transport'
6
+ export * from './wallet-request-handler'
7
+ export * from './extension-transport'
@@ -0,0 +1 @@
1
+ export * from './mux-message-provider'