@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.
- package/CHANGELOG.md +909 -0
- package/README.md +4 -0
- package/dist/0xsequence-provider.cjs.d.ts +1 -0
- package/dist/0xsequence-provider.cjs.dev.js +3540 -0
- package/dist/0xsequence-provider.cjs.js +7 -0
- package/dist/0xsequence-provider.cjs.prod.js +3540 -0
- package/dist/0xsequence-provider.esm.js +3508 -0
- package/dist/declarations/src/commands/index.d.ts +20 -0
- package/dist/declarations/src/index.d.ts +5 -0
- package/dist/declarations/src/provider.d.ts +59 -0
- package/dist/declarations/src/transports/base-provider-transport.d.ts +40 -0
- package/dist/declarations/src/transports/base-wallet-transport.d.ts +38 -0
- package/dist/declarations/src/transports/extension-transport/base-injected-transport.d.ts +18 -0
- package/dist/declarations/src/transports/extension-transport/extension-message-handler.d.ts +12 -0
- package/dist/declarations/src/transports/extension-transport/extension-message-provider.d.ts +11 -0
- package/dist/declarations/src/transports/extension-transport/index.d.ts +3 -0
- package/dist/declarations/src/transports/index.d.ts +7 -0
- package/dist/declarations/src/transports/mux-transport/index.d.ts +1 -0
- package/dist/declarations/src/transports/mux-transport/mux-message-provider.d.ts +22 -0
- package/dist/declarations/src/transports/proxy-transport/index.d.ts +3 -0
- package/dist/declarations/src/transports/proxy-transport/proxy-message-channel.d.ts +15 -0
- package/dist/declarations/src/transports/proxy-transport/proxy-message-handler.d.ts +12 -0
- package/dist/declarations/src/transports/proxy-transport/proxy-message-provider.d.ts +12 -0
- package/dist/declarations/src/transports/wallet-request-handler.d.ts +51 -0
- package/dist/declarations/src/transports/window-transport/index.d.ts +2 -0
- package/dist/declarations/src/transports/window-transport/window-message-handler.d.ts +15 -0
- package/dist/declarations/src/transports/window-transport/window-message-provider.d.ts +13 -0
- package/dist/declarations/src/types.d.ts +170 -0
- package/dist/declarations/src/utils.d.ts +14 -0
- package/dist/declarations/src/wallet.d.ts +99 -0
- package/package.json +37 -0
- package/src/commands/index.ts +146 -0
- package/src/index.ts +5 -0
- package/src/provider.ts +494 -0
- package/src/transports/base-provider-transport.ts +411 -0
- package/src/transports/base-wallet-transport.ts +441 -0
- package/src/transports/extension-transport/base-injected-transport.ts +100 -0
- package/src/transports/extension-transport/extension-message-handler.ts +25 -0
- package/src/transports/extension-transport/extension-message-provider.ts +41 -0
- package/src/transports/extension-transport/index.ts +3 -0
- package/src/transports/index.ts +7 -0
- package/src/transports/mux-transport/index.ts +1 -0
- package/src/transports/mux-transport/mux-message-provider.ts +160 -0
- package/src/transports/proxy-transport/index.ts +3 -0
- package/src/transports/proxy-transport/proxy-message-channel.ts +58 -0
- package/src/transports/proxy-transport/proxy-message-handler.ts +46 -0
- package/src/transports/proxy-transport/proxy-message-provider.ts +81 -0
- package/src/transports/wallet-request-handler.ts +702 -0
- package/src/transports/window-transport/index.ts +2 -0
- package/src/transports/window-transport/window-message-handler.ts +166 -0
- package/src/transports/window-transport/window-message-provider.ts +183 -0
- package/src/types.ts +252 -0
- package/src/utils.ts +76 -0
- 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,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
|
+
}
|