@0xsequence/provider 0.40.1 → 0.40.4
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/dist/0xsequence-provider.cjs.dev.js +285 -27
- package/dist/0xsequence-provider.cjs.prod.js +285 -27
- package/dist/0xsequence-provider.esm.js +284 -28
- package/dist/declarations/src/transports/index.d.ts +1 -0
- package/dist/declarations/src/transports/unreal-transport/index.d.ts +2 -0
- package/dist/declarations/src/transports/unreal-transport/overridelogs.d.ts +4 -0
- package/dist/declarations/src/transports/unreal-transport/unreal-message-handler.d.ts +14 -0
- package/dist/declarations/src/transports/unreal-transport/unreal-message-provider.d.ts +15 -0
- package/dist/declarations/src/types.d.ts +1 -1
- package/dist/declarations/src/wallet.d.ts +7 -5
- package/package.json +8 -8
- package/src/transports/index.ts +1 -0
- package/src/transports/unreal-transport/index.ts +2 -0
- package/src/transports/unreal-transport/overridelogs.ts +36 -0
- package/src/transports/unreal-transport/unreal-message-handler.ts +121 -0
- package/src/transports/unreal-transport/unreal-message-provider.ts +121 -0
- package/src/transports/wallet-request-handler.ts +3 -3
- package/src/types.ts +1 -1
- package/src/wallet.ts +36 -25
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ProviderMessageRequest,
|
|
3
|
+
ProviderMessage,
|
|
4
|
+
EventType,
|
|
5
|
+
InitState,
|
|
6
|
+
WindowSessionParams,
|
|
7
|
+
OpenWalletIntent,
|
|
8
|
+
ProviderRpcError,
|
|
9
|
+
TransportSession
|
|
10
|
+
} from '../../types'
|
|
11
|
+
import { WalletRequestHandler } from '../wallet-request-handler'
|
|
12
|
+
import { BaseWalletTransport } from '../base-wallet-transport'
|
|
13
|
+
import { logger, base64DecodeObject } from '@0xsequence/utils'
|
|
14
|
+
import { overrideLogs } from './overridelogs'
|
|
15
|
+
|
|
16
|
+
// all lowercase is an annoying limitation of Unreal CEF BindUObject
|
|
17
|
+
interface UnrealInjectedWalletWindow {
|
|
18
|
+
ue?: {
|
|
19
|
+
sequencewallettransport?: {
|
|
20
|
+
onmessagefromsequencejs?: (message: ProviderMessageRequest) => void
|
|
21
|
+
sendmessagetosequencejs: (message: string) => void
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
declare const window: Window & typeof globalThis & UnrealInjectedWalletWindow
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Initialized on Wallet side
|
|
29
|
+
*/
|
|
30
|
+
export class UnrealMessageHandler extends BaseWalletTransport {
|
|
31
|
+
constructor(walletRequestHandler: WalletRequestHandler) {
|
|
32
|
+
super(walletRequestHandler)
|
|
33
|
+
this._init = InitState.NIL
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async register(windowHref?: string | URL) {
|
|
37
|
+
if (window.ue?.sequencewallettransport === undefined) {
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
overrideLogs('wallet')
|
|
41
|
+
|
|
42
|
+
// record open details (sessionId + default network) from the window url
|
|
43
|
+
const { search: rawParams } = new URL(windowHref || window.location.href)
|
|
44
|
+
|
|
45
|
+
let session: TransportSession | null = this.getUnrealTransportSession(rawParams)
|
|
46
|
+
|
|
47
|
+
// provider should always include sid when opening a new window
|
|
48
|
+
const isNewWindowSession = !!session.sessionId
|
|
49
|
+
|
|
50
|
+
// attempt to restore previous session in the case of a redirect or window reload
|
|
51
|
+
if (!isNewWindowSession) {
|
|
52
|
+
session = await this.getCachedTransportSession()
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (!session) {
|
|
56
|
+
logger.error('unreal session is undefined')
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// listen for window-transport requests
|
|
61
|
+
window.ue.sequencewallettransport.onmessagefromsequencejs = this.onMessageFromUnreal
|
|
62
|
+
this._registered = true
|
|
63
|
+
|
|
64
|
+
// send open event to the app which opened us
|
|
65
|
+
this.open(session)
|
|
66
|
+
.then(opened => {
|
|
67
|
+
if (!opened) {
|
|
68
|
+
const err = `failed to open to network ${session?.networkId}`
|
|
69
|
+
logger.error(err)
|
|
70
|
+
this.notifyClose({ message: err } as ProviderRpcError)
|
|
71
|
+
window.close()
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
.catch(e => {
|
|
75
|
+
const err = `failed to open to network ${session?.networkId}, due to: ${e}`
|
|
76
|
+
logger.error(err)
|
|
77
|
+
this.notifyClose({ message: err } as ProviderRpcError)
|
|
78
|
+
window.close()
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
unregister() {
|
|
83
|
+
if (window.ue?.sequencewallettransport?.onmessagefromsequencejs === this.onMessageFromUnreal) {
|
|
84
|
+
delete window.ue.sequencewallettransport.onmessagefromsequencejs
|
|
85
|
+
}
|
|
86
|
+
this._registered = false
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// onmessage is called when (the wallet) receives request messages from the dapp
|
|
90
|
+
// over the unreal json-messaging transport
|
|
91
|
+
private onMessageFromUnreal = (request: ProviderMessageRequest) => {
|
|
92
|
+
// Wallet always expects json-rpc request messages from a dapp
|
|
93
|
+
|
|
94
|
+
logger.debug('RECEIVED MESSAGE', request)
|
|
95
|
+
|
|
96
|
+
// Handle message via the base transport
|
|
97
|
+
this.handleMessage(request)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// sendMessage sends message to the dapp window
|
|
101
|
+
sendMessage(message: ProviderMessage<any>) {
|
|
102
|
+
if (message.type !== EventType.INIT && this._init !== InitState.OK) {
|
|
103
|
+
logger.error('impossible state, should not be calling postMessage until inited')
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
// prepare payload
|
|
107
|
+
const payload = JSON.stringify(message)
|
|
108
|
+
|
|
109
|
+
// post-message to app.
|
|
110
|
+
window.ue?.sequencewallettransport?.sendmessagetosequencejs(payload)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private getUnrealTransportSession = (windowParams: string | undefined): TransportSession => {
|
|
114
|
+
const params = new WindowSessionParams(windowParams)
|
|
115
|
+
return {
|
|
116
|
+
sessionId: params.get('sid'),
|
|
117
|
+
networkId: params.get('net'),
|
|
118
|
+
intent: base64DecodeObject<OpenWalletIntent>(params.get('intent'))
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { OpenWalletIntent, ProviderMessage, InitState, WindowSessionParams } from '../../types'
|
|
2
|
+
import { BaseProviderTransport } from '../base-provider-transport'
|
|
3
|
+
import { base64EncodeObject } from '@0xsequence/utils'
|
|
4
|
+
import { overrideLogs } from './overridelogs'
|
|
5
|
+
|
|
6
|
+
let registeredUnrealMessageProvider: UnrealMessageProvider | undefined
|
|
7
|
+
|
|
8
|
+
// all lowercase is an annoying limitation of Unreal CEF BindUObject
|
|
9
|
+
interface UnrealInjectedSequenceJSWindow {
|
|
10
|
+
ue?: {
|
|
11
|
+
sequencewallettransport?: {
|
|
12
|
+
onmessagefromwallet?: (message: ProviderMessage<any>) => void
|
|
13
|
+
sendmessagetowallet: (message: string) => void
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare const window: Window & typeof globalThis & UnrealInjectedSequenceJSWindow
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Initialized on dApp side
|
|
22
|
+
*/
|
|
23
|
+
export class UnrealMessageProvider extends BaseProviderTransport {
|
|
24
|
+
private walletURL: URL
|
|
25
|
+
|
|
26
|
+
constructor(walletAppURL: string) {
|
|
27
|
+
super()
|
|
28
|
+
this.walletURL = new URL(walletAppURL)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
register = () => {
|
|
32
|
+
overrideLogs('dapp')
|
|
33
|
+
if (registeredUnrealMessageProvider) {
|
|
34
|
+
// overriding the registered message provider
|
|
35
|
+
registeredUnrealMessageProvider.unregister()
|
|
36
|
+
registeredUnrealMessageProvider = this
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// listen for incoming messages from wallet
|
|
40
|
+
if (window.ue?.sequencewallettransport) {
|
|
41
|
+
window.ue.sequencewallettransport.onmessagefromwallet = this.onUnrealCallback
|
|
42
|
+
}
|
|
43
|
+
registeredUnrealMessageProvider = this
|
|
44
|
+
|
|
45
|
+
this._registered = true
|
|
46
|
+
console.log('registering transport!')
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
unregister = () => {
|
|
50
|
+
this._registered = false
|
|
51
|
+
this.closeWallet()
|
|
52
|
+
|
|
53
|
+
// disable message listener
|
|
54
|
+
if (registeredUnrealMessageProvider === this) {
|
|
55
|
+
registeredUnrealMessageProvider = undefined
|
|
56
|
+
}
|
|
57
|
+
if (window.ue?.sequencewallettransport?.onmessagefromwallet === this.onUnrealCallback) {
|
|
58
|
+
delete window.ue.sequencewallettransport.onmessagefromwallet
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// clear event listeners
|
|
62
|
+
this.events.removeAllListeners()
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
openWallet = (path?: string, intent?: OpenWalletIntent, networkId?: string | number): void => {
|
|
66
|
+
if (this.isOpened()) {
|
|
67
|
+
// TODO focus wallet
|
|
68
|
+
console.log('wallet already open!')
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
console.log('opening wallet!')
|
|
73
|
+
// Instantiate new walletURL for this call
|
|
74
|
+
const walletURL = new URL(this.walletURL.href)
|
|
75
|
+
const windowSessionParams = new WindowSessionParams()
|
|
76
|
+
|
|
77
|
+
if (path) {
|
|
78
|
+
walletURL.pathname = path.toLowerCase()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Set session, intent and network id on walletURL
|
|
82
|
+
this._init = InitState.NIL
|
|
83
|
+
this._sessionId = `${performance.now()}`
|
|
84
|
+
windowSessionParams.set('sid', this._sessionId)
|
|
85
|
+
|
|
86
|
+
if (intent) {
|
|
87
|
+
// encode intent as base64 url-encoded param
|
|
88
|
+
windowSessionParams.set('intent', base64EncodeObject(intent))
|
|
89
|
+
}
|
|
90
|
+
if (networkId) {
|
|
91
|
+
windowSessionParams.set('net', `${networkId}`)
|
|
92
|
+
}
|
|
93
|
+
// serialize params
|
|
94
|
+
walletURL.search = windowSessionParams.toString()
|
|
95
|
+
|
|
96
|
+
console.log('opening wallet to', walletURL.href)
|
|
97
|
+
|
|
98
|
+
window.open(walletURL.href)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
closeWallet() {
|
|
102
|
+
this.close()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// onmessage, receives ProviderMessageResponse from the wallet unreal transport
|
|
106
|
+
private onUnrealCallback = (message: ProviderMessage<any>) => {
|
|
107
|
+
if (!message) {
|
|
108
|
+
throw new Error('ProviderMessage object is empty')
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// handle message with base message provider
|
|
112
|
+
this.handleMessage(message)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// all lowercase is an annoying limitation of Unreal CEF BindUObject
|
|
116
|
+
sendMessage(message: ProviderMessage<unknown>) {
|
|
117
|
+
const postedMessage = typeof message !== 'string' ? JSON.stringify(message) : message
|
|
118
|
+
console.log('Sending message to wallet:', postedMessage)
|
|
119
|
+
window.ue?.sequencewallettransport?.sendmessagetowallet(postedMessage)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -300,17 +300,17 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
|
|
|
300
300
|
|
|
301
301
|
// Message must be prefixed with "\x19Ethereum Signed Message:\n"
|
|
302
302
|
// as defined by EIP-191
|
|
303
|
-
|
|
303
|
+
const prefixedMessage = prefixEIP191Message(message)
|
|
304
304
|
|
|
305
305
|
// TODO:
|
|
306
306
|
// if (process.env.TEST_MODE === 'true' && this.prompter === null) {
|
|
307
307
|
if (this.prompter === null) {
|
|
308
308
|
// prompter is null, so we'll sign from here
|
|
309
|
-
sig = await signer.signMessage(
|
|
309
|
+
sig = await signer.signMessage(prefixedMessage, chainId)
|
|
310
310
|
} else {
|
|
311
311
|
const promptResultForDeployment = await this.handleConfirmWalletDeployPrompt(this.prompter, signer, chainId)
|
|
312
312
|
if (promptResultForDeployment) {
|
|
313
|
-
sig = await this.prompter.promptSignMessage({ chainId: chainId, message }, this.connectOptions)
|
|
313
|
+
sig = await this.prompter.promptSignMessage({ chainId: chainId, message: prefixedMessage }, this.connectOptions)
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
|
package/src/types.ts
CHANGED
package/src/wallet.ts
CHANGED
|
@@ -19,9 +19,15 @@ import {
|
|
|
19
19
|
} from '@0xsequence/network'
|
|
20
20
|
import { WalletConfig, WalletState } from '@0xsequence/config'
|
|
21
21
|
import { logger } from '@0xsequence/utils'
|
|
22
|
-
import { JsonRpcProvider
|
|
22
|
+
import { JsonRpcProvider } from '@ethersproject/providers'
|
|
23
23
|
import { Web3Provider, Web3Signer } from './provider'
|
|
24
|
-
import {
|
|
24
|
+
import {
|
|
25
|
+
MuxMessageProvider,
|
|
26
|
+
WindowMessageProvider,
|
|
27
|
+
ProxyMessageProvider,
|
|
28
|
+
ProxyMessageChannelPort,
|
|
29
|
+
UnrealMessageProvider
|
|
30
|
+
} from './transports'
|
|
25
31
|
import { WalletSession, ProviderEventTypes, ConnectOptions, OpenWalletIntent, ConnectDetails } from './types'
|
|
26
32
|
import { ethers } from 'ethers'
|
|
27
33
|
import { ExtensionMessageProvider } from './transports/extension-transport/extension-message-provider'
|
|
@@ -29,14 +35,11 @@ import { LocalStore, ItemStore, LocalStorage } from './utils'
|
|
|
29
35
|
import { WalletUtils } from './utils/index'
|
|
30
36
|
|
|
31
37
|
import { Runtime } from 'webextension-polyfill-ts'
|
|
32
|
-
import { sequence } from '../../0xsequence/src'
|
|
33
38
|
|
|
34
39
|
export interface WalletProvider {
|
|
35
40
|
connect(options?: ConnectOptions): Promise<ConnectDetails>
|
|
36
|
-
// authorize(options?: ConnectOptions): Promise<ConnectDetails>
|
|
37
41
|
disconnect(): void
|
|
38
42
|
|
|
39
|
-
isOpened(): boolean
|
|
40
43
|
isConnected(): boolean
|
|
41
44
|
getSession(): WalletSession | undefined
|
|
42
45
|
|
|
@@ -45,6 +48,7 @@ export interface WalletProvider {
|
|
|
45
48
|
getChainId(): Promise<number>
|
|
46
49
|
getAuthChainId(): Promise<number>
|
|
47
50
|
|
|
51
|
+
isOpened(): boolean
|
|
48
52
|
openWallet(path?: string, intent?: OpenWalletIntent, networkId?: string | number): Promise<boolean>
|
|
49
53
|
closeWallet(): void
|
|
50
54
|
|
|
@@ -87,6 +91,7 @@ export class Wallet implements WalletProvider {
|
|
|
87
91
|
windowMessageProvider?: WindowMessageProvider
|
|
88
92
|
proxyMessageProvider?: ProxyMessageProvider
|
|
89
93
|
extensionMessageProvider?: ExtensionMessageProvider
|
|
94
|
+
unrealMessageProvider?: UnrealMessageProvider
|
|
90
95
|
}
|
|
91
96
|
|
|
92
97
|
private networks: NetworkConfig[]
|
|
@@ -149,6 +154,10 @@ export class Wallet implements WalletProvider {
|
|
|
149
154
|
//
|
|
150
155
|
// this.transport.messageProvider.add(this.transport.extensionMessageProvider)
|
|
151
156
|
}
|
|
157
|
+
if (this.config.transports?.unrealTransport?.enabled) {
|
|
158
|
+
this.transport.unrealMessageProvider = new UnrealMessageProvider(this.config.walletAppURL)
|
|
159
|
+
this.transport.messageProvider.add(this.transport.unrealMessageProvider)
|
|
160
|
+
}
|
|
152
161
|
this.transport.messageProvider.register()
|
|
153
162
|
|
|
154
163
|
// .....
|
|
@@ -238,13 +247,23 @@ export class Wallet implements WalletProvider {
|
|
|
238
247
|
this.transport.messageProvider.on('walletContext', (walletContext: WalletContext) => {
|
|
239
248
|
this.useSession({ walletContext: walletContext }, true)
|
|
240
249
|
})
|
|
250
|
+
}
|
|
241
251
|
|
|
242
|
-
|
|
243
|
-
|
|
252
|
+
loadSession = async (): Promise<WalletSession | undefined> => {
|
|
253
|
+
const data = await LocalStorage.getInstance().getItem('@sequence.session')
|
|
254
|
+
if (!data || data === '') {
|
|
255
|
+
return undefined
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
const session = JSON.parse(data) as WalletSession
|
|
244
259
|
if (session) {
|
|
245
260
|
this.useSession(session, false)
|
|
246
261
|
}
|
|
247
|
-
|
|
262
|
+
return session
|
|
263
|
+
} catch (err) {
|
|
264
|
+
logger.warn('loadSession failed, unable to parse session payload from storage.')
|
|
265
|
+
return undefined
|
|
266
|
+
}
|
|
248
267
|
}
|
|
249
268
|
|
|
250
269
|
connect = async (options?: ConnectOptions): Promise<ConnectDetails> => {
|
|
@@ -549,24 +568,10 @@ export class Wallet implements WalletProvider {
|
|
|
549
568
|
this.transport.messageProvider!.once(event, fn)
|
|
550
569
|
}
|
|
551
570
|
|
|
552
|
-
private
|
|
553
|
-
const data = await LocalStorage.getInstance().getItem('@sequence.session')
|
|
554
|
-
if (!data || data === '') {
|
|
555
|
-
return undefined
|
|
556
|
-
}
|
|
557
|
-
try {
|
|
558
|
-
const session = JSON.parse(data) as WalletSession
|
|
559
|
-
return session
|
|
560
|
-
} catch (err) {
|
|
561
|
-
logger.warn('loadSession failed, unable to parse session payload from localStorage.')
|
|
562
|
-
return undefined
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
private saveSession = (session: WalletSession) => {
|
|
571
|
+
private saveSession = async (session: WalletSession) => {
|
|
567
572
|
logger.debug('wallet provider: saving session')
|
|
568
573
|
const data = JSON.stringify(session)
|
|
569
|
-
LocalStorage.getInstance().setItem('@sequence.session', data)
|
|
574
|
+
await LocalStorage.getInstance().setItem('@sequence.session', data)
|
|
570
575
|
}
|
|
571
576
|
|
|
572
577
|
private useSession = async (session: WalletSession, autoSave: boolean = true) => {
|
|
@@ -698,6 +703,11 @@ export interface ProviderConfig {
|
|
|
698
703
|
enabled: boolean
|
|
699
704
|
runtime: Runtime.Static
|
|
700
705
|
}
|
|
706
|
+
|
|
707
|
+
// Unreal Engine transport (optional)
|
|
708
|
+
unrealTransport?: {
|
|
709
|
+
enabled: boolean
|
|
710
|
+
}
|
|
701
711
|
}
|
|
702
712
|
|
|
703
713
|
// Sequence Wallet Modules Context override. By default (and recommended), the
|
|
@@ -720,11 +730,12 @@ export const DefaultProviderConfig: ProviderConfig = {
|
|
|
720
730
|
|
|
721
731
|
let walletInstance: Wallet | undefined
|
|
722
732
|
|
|
723
|
-
export const initWallet = (network?: string | number, config?: Partial<ProviderConfig>) => {
|
|
733
|
+
export const initWallet = async (network?: string | number, config?: Partial<ProviderConfig>) => {
|
|
724
734
|
if (walletInstance && walletInstance.isOpened()) {
|
|
725
735
|
walletInstance.closeWallet()
|
|
726
736
|
}
|
|
727
737
|
walletInstance = new Wallet(network, config)
|
|
738
|
+
await walletInstance.loadSession()
|
|
728
739
|
return walletInstance
|
|
729
740
|
}
|
|
730
741
|
|