@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,160 @@
1
+ import {
2
+ ProviderMessage, EventType, ProviderTransport,
3
+ ProviderEventTypes, ProviderMessageRequest, ProviderMessageResponse, WalletSession, OpenWalletIntent, ConnectDetails
4
+ } from '../../types'
5
+
6
+ import { JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network'
7
+
8
+ export class MuxMessageProvider implements ProviderTransport {
9
+
10
+ private messageProviders: ProviderTransport[]
11
+ private provider: ProviderTransport | undefined
12
+
13
+ constructor(...messageProviders: ProviderTransport[]) {
14
+ this.messageProviders = messageProviders
15
+ this.provider = undefined
16
+ }
17
+
18
+ add(...messageProviders: ProviderTransport[]) {
19
+ this.messageProviders.push(...messageProviders)
20
+ }
21
+
22
+ register = () => {
23
+ if (this.messageProviders.length === 1) {
24
+ this.provider = this.messageProviders[0]
25
+ this.provider.register()
26
+ return
27
+ }
28
+
29
+ this.messageProviders.forEach(m => {
30
+ m.register()
31
+
32
+ m.once('open', () => {
33
+ // the first one to open is the winner, and others will be unregistered
34
+ if (!this.provider) {
35
+ this.provider = m
36
+
37
+ // unregister other providers
38
+ this.messageProviders.forEach(m => {
39
+ if (this.provider !== m) {
40
+ m.unregister()
41
+ }
42
+ })
43
+ }
44
+ })
45
+ })
46
+ }
47
+
48
+ unregister = () => {
49
+ this.messageProviders.forEach(m => m.unregister())
50
+ this.provider = undefined
51
+ }
52
+
53
+ openWallet = (path?: string, intent?: OpenWalletIntent, networkId?: string | number): void => {
54
+ if (this.provider) {
55
+ this.provider.openWallet(path, intent, networkId)
56
+ return
57
+ }
58
+ this.messageProviders.forEach(m => m.openWallet(path, intent, networkId))
59
+ }
60
+
61
+ closeWallet() {
62
+ if (this.provider) {
63
+ this.provider.closeWallet()
64
+ }
65
+ }
66
+
67
+ isOpened(): boolean {
68
+ if (this.provider) {
69
+ return this.provider.isOpened()
70
+ }
71
+ return false
72
+ }
73
+
74
+ isConnected(): boolean {
75
+ if (this.provider) {
76
+ return this.provider.isConnected()
77
+ }
78
+ return false
79
+ }
80
+
81
+ on<K extends keyof ProviderEventTypes>(event: K, fn: ProviderEventTypes[K]) {
82
+ if (this.provider) {
83
+ this.provider.on(event, fn)
84
+ return
85
+ }
86
+ this.messageProviders.forEach(m => {
87
+ m.on(event, fn)
88
+ })
89
+ }
90
+
91
+ once<K extends keyof ProviderEventTypes>(event: K, fn: ProviderEventTypes[K]) {
92
+ if (this.provider) {
93
+ this.provider.once(event, fn)
94
+ return
95
+ }
96
+ this.messageProviders.forEach(m => {
97
+ m.once(event, fn)
98
+ })
99
+ }
100
+
101
+ emit<K extends keyof ProviderEventTypes>(event: K, ...args: Parameters<ProviderEventTypes[K]>): boolean {
102
+ if (this.provider) {
103
+ return this.provider.emit(event, ...args)
104
+ }
105
+ for (let i=0; i < this.messageProviders.length; i++) {
106
+ this.messageProviders[i].emit(event, ...args)
107
+ }
108
+ return true
109
+ }
110
+
111
+ sendAsync = async (request: JsonRpcRequest, callback: JsonRpcResponseCallback, chainId?: number) => {
112
+ if (this.provider) {
113
+ this.provider.sendAsync(request, callback, chainId)
114
+ return
115
+ }
116
+ throw new Error('impossible state, wallet must be opened first')
117
+ }
118
+
119
+ sendMessage(message: ProviderMessage<any>) {
120
+ if (!message.idx || message.idx <= 0) {
121
+ throw new Error('message idx is empty')
122
+ }
123
+
124
+ if (this.provider) {
125
+ this.provider.sendMessage(message)
126
+ } else {
127
+ throw new Error('impossible state, wallet must be opened first')
128
+ }
129
+ }
130
+
131
+ sendMessageRequest = async (message: ProviderMessageRequest): Promise<ProviderMessageResponse> => {
132
+ if (this.provider) {
133
+ return this.provider.sendMessageRequest(message)
134
+ }
135
+ throw new Error('impossible state, wallet must be opened first')
136
+ }
137
+
138
+ handleMessage(message: ProviderMessage<any>): void {
139
+ if (this.provider) {
140
+ this.provider.handleMessage(message)
141
+ return
142
+ }
143
+ throw new Error('impossible state, wallet must be opened first')
144
+ }
145
+
146
+ waitUntilOpened = async (): Promise<WalletSession | undefined> => {
147
+ if (this.provider) {
148
+ return this.provider.waitUntilOpened()
149
+ }
150
+ return Promise.race(this.messageProviders.map(p => p.waitUntilOpened()))
151
+ }
152
+
153
+ waitUntilConnected = async (): Promise<ConnectDetails> => {
154
+ if (this.provider) {
155
+ return this.provider.waitUntilConnected()
156
+ }
157
+ throw new Error('impossible state, wallet must be opened first')
158
+ }
159
+
160
+ }
@@ -0,0 +1,3 @@
1
+ export * from './proxy-message-channel'
2
+ export * from './proxy-message-provider'
3
+ export * from './proxy-message-handler'
@@ -0,0 +1,58 @@
1
+ import { EventEmitter2 as EventEmitter } from 'eventemitter2'
2
+ import { ProviderMessage, ProviderMessageTransport, ProviderEventTypes, TypedEventEmitter } from '../../types'
3
+
4
+ export class ProxyMessageChannel {
5
+ app: ProxyMessageChannelPort
6
+ wallet: ProxyMessageChannelPort
7
+
8
+ constructor() {
9
+ const port1 = new ProxyMessageChannelPort()
10
+ const port2 = new ProxyMessageChannelPort()
11
+
12
+ port1.conn = port2
13
+ port2.conn = port1
14
+
15
+ this.app = port1
16
+ this.wallet = port2
17
+ }
18
+ }
19
+
20
+ export class ProxyMessageChannelPort implements ProviderMessageTransport {
21
+ conn: ProviderMessageTransport
22
+ events: TypedEventEmitter<ProxyEventTypes> = new EventEmitter() as TypedEventEmitter<ProxyEventTypes>
23
+
24
+
25
+ // handle messages which hit this port
26
+ handleMessage = (message: ProviderMessage<any>): void => {
27
+ throw new Error('ProxyMessageChannelPort is not registered')
28
+ }
29
+
30
+ // send messages to the connected port
31
+ sendMessage = (message: ProviderMessage<any>): void => {
32
+ this.conn.handleMessage(message)
33
+
34
+ // trigger events
35
+ if (message.type === 'open') {
36
+ this.events.emit('open', message as any)
37
+ }
38
+ if (message.type === 'close') {
39
+ this.events.emit('close', message as any)
40
+ }
41
+ if (message.type === 'connect') {
42
+ this.events.emit('connect', message as any)
43
+ }
44
+ if (message.type === 'disconnect') {
45
+ this.events.emit('disconnect', message as any)
46
+ }
47
+ }
48
+
49
+ on<K extends keyof ProxyEventTypes>(event: K, fn: ProxyEventTypes[K]) {
50
+ this.events.on(event, fn as any)
51
+ }
52
+
53
+ once<K extends keyof ProxyEventTypes>(event: K, fn: ProxyEventTypes[K]) {
54
+ this.events.once(event, fn as any)
55
+ }
56
+ }
57
+
58
+ export type ProxyEventTypes = Pick<ProviderEventTypes, 'open' | 'close' | 'connect' | 'disconnect'>
@@ -0,0 +1,46 @@
1
+ import { BaseWalletTransport } from '../base-wallet-transport'
2
+ import { WalletRequestHandler } from '../wallet-request-handler'
3
+ import { InitState, ProviderMessage } from '../../types'
4
+ import { ProxyMessageChannelPort } from './proxy-message-channel'
5
+
6
+ export class ProxyMessageHandler extends BaseWalletTransport {
7
+
8
+ private port: ProxyMessageChannelPort
9
+
10
+ constructor(walletRequestHandler: WalletRequestHandler, port: ProxyMessageChannelPort) {
11
+ super(walletRequestHandler)
12
+ this.port = port
13
+ this._init = InitState.OK
14
+ }
15
+
16
+ register() {
17
+ this.port.handleMessage = (message: ProviderMessage<any>): void => {
18
+ this.handleMessage(message)
19
+ }
20
+ this._registered = true
21
+ }
22
+
23
+ // note: we can't decide whether to restore the session within register(), because session info is
24
+ // received asyncronously via EventType.OPEN after register() is executed.
25
+ // And in the case of a redirect/reload, EventType.OPEN is not sent at all,
26
+ // because the wallet is already open.
27
+ //
28
+ // call this method from wallet redirect hander when a session restore is needed
29
+ restoreSession() {
30
+ const cachedSession = this.getCachedTransportSession()
31
+ if (cachedSession) {
32
+ this.open(cachedSession)
33
+ }
34
+ }
35
+
36
+ unregister() {
37
+ // @ts-ignore
38
+ this.port.handleMessage = undefined
39
+ this._registered = false
40
+ }
41
+
42
+ sendMessage(message: ProviderMessage<any>) {
43
+ this.port.sendMessage(message)
44
+ }
45
+
46
+ }
@@ -0,0 +1,81 @@
1
+ import { BaseProviderTransport } from '../base-provider-transport'
2
+
3
+ import {
4
+ ProviderMessage, OpenState, OpenWalletIntent, EventType, InitState
5
+ } from '../../types'
6
+
7
+ import { ProxyMessageChannelPort, ProxyEventTypes } from './proxy-message-channel'
8
+
9
+ export class ProxyMessageProvider extends BaseProviderTransport {
10
+
11
+ private port: ProxyMessageChannelPort
12
+
13
+ constructor(port: ProxyMessageChannelPort) {
14
+ super()
15
+ this.state = OpenState.CLOSED
16
+ this.port = port
17
+ if (!port) {
18
+ throw new Error('port argument cannot be empty')
19
+ }
20
+
21
+ // disable init handshake for proxy-transport, we set it to OK, to
22
+ // consider it in completed state.
23
+ this._init = InitState.OK
24
+ }
25
+
26
+ register = () => {
27
+ this.port.handleMessage = (message: ProviderMessage<any>): void => {
28
+ this.handleMessage(message)
29
+ }
30
+
31
+ this.on('open', (...args: Parameters<ProxyEventTypes['open']>) => {
32
+ this.port.events.emit('open', ...args)
33
+ })
34
+ this.on('close', (...args: Parameters<ProxyEventTypes['close']>) => {
35
+ this.port.events.emit('close', ...args)
36
+ })
37
+ this.on('connect', (...args: Parameters<ProxyEventTypes['connect']>) => {
38
+ this.port.events.emit('connect', ...args)
39
+ })
40
+ this.on('disconnect', (...args: Parameters<ProxyEventTypes['disconnect']>) => {
41
+ this.port.events.emit('disconnect', ...args)
42
+ })
43
+
44
+ this._registered = true
45
+ }
46
+
47
+ unregister = () => {
48
+ this._registered = false
49
+ this.closeWallet()
50
+ this.events.removeAllListeners()
51
+ // @ts-ignore
52
+ this.port.handleMessage = undefined
53
+ }
54
+
55
+ openWallet = (path?: string, intent?: OpenWalletIntent, networkId?: string | number): void => {
56
+ if (this.state === OpenState.CLOSED) {
57
+ this.state = OpenState.OPENING
58
+ const sessionId = `${performance.now()}`
59
+ this._sessionId = sessionId
60
+ this.sendMessage({
61
+ idx: -1, type: EventType.OPEN, data: {
62
+ path, intent, networkId, sessionId
63
+ }
64
+ })
65
+ }
66
+ }
67
+
68
+ closeWallet() {
69
+ this.sendMessage({
70
+ idx: -1, type: EventType.CLOSE, data: null
71
+ })
72
+ this.close()
73
+ }
74
+
75
+ sendMessage(message: ProviderMessage<any>) {
76
+ if (!message.idx) {
77
+ throw new Error('message idx is empty')
78
+ }
79
+ this.port.sendMessage(message)
80
+ }
81
+ }