@0xsequence/provider 0.35.3 → 0.35.7

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.
@@ -597,9 +597,14 @@ class BaseWalletTransport {
597
597
  };
598
598
 
599
599
  this.handleMessage = async function (message) {
600
- const request = message; // ensure initial handshake is complete before accepting
600
+ const request = message; // ensure signer is ready to handle requests
601
+
602
+ if (_this.walletRequestHandler.getSigner() === undefined) {
603
+ await _this.walletRequestHandler.signerReady();
604
+ } // ensure initial handshake is complete before accepting
601
605
  // other kinds of messages.
602
606
 
607
+
603
608
  if (_this._init !== exports.InitState.OK) {
604
609
  if (request.type === exports.EventType.INIT) {
605
610
  if (_this.isValidInitAck(message)) {
@@ -671,6 +676,13 @@ class BaseWalletTransport {
671
676
  intent,
672
677
  networkId
673
678
  });
679
+ }
680
+
681
+ _this.walletRequestHandler.setOpenIntent(intent); // ensure signer is ready
682
+
683
+
684
+ if (_this.walletRequestHandler.getSigner() === undefined) {
685
+ await _this.walletRequestHandler.signerReady();
674
686
  } // init handshake for certain transports, before we can open the communication.
675
687
  //
676
688
  // for example, with the window-transport, we have to exchange messages to determine the
@@ -1455,10 +1467,7 @@ class WindowMessageProvider extends BaseProviderTransport {
1455
1467
 
1456
1468
  if (isBrowserExtension()) {
1457
1469
  windowSize = [450, 750];
1458
- windowPos = [window.screenX, window.screenY]; // windowPos = [
1459
- // Math.abs(window.screen.width / 2 - windowSize[0] / 2),
1460
- // Math.abs(window.screen.height / 2 - windowSize[1] / 2)
1461
- // ]
1470
+ windowPos = [Math.abs(window.screen.width / 2 - windowSize[0] / 2), Math.abs(window.screen.height / 2 - windowSize[1] / 2)];
1462
1471
  } else {
1463
1472
  windowSize = [450, 750];
1464
1473
  windowPos = [Math.abs(window.screenX + window.innerWidth / 2 - windowSize[0] / 2), Math.abs(window.screenY + window.innerHeight / 2 - windowSize[1] / 2)];
@@ -1619,12 +1628,6 @@ class WindowMessageHandler extends BaseWalletTransport {
1619
1628
  if (!session) {
1620
1629
  utils.logger.error('window session is undefined');
1621
1630
  return;
1622
- }
1623
-
1624
- if (session.intent && isNewWindowSession) {
1625
- window.history.replaceState({
1626
- openWalletIntent: true
1627
- }, document.title, pathname);
1628
1631
  } // record parent window instance for communication
1629
1632
 
1630
1633
 
@@ -1703,13 +1706,18 @@ class WindowMessageHandler extends BaseWalletTransport {
1703
1706
  }
1704
1707
 
1705
1708
  class WalletRequestHandler {
1709
+ // signer interface of the wallet. A null value means there is no signer (ie. user not signed in). An undefined
1710
+ // value means the signer state is unknown, usually meaning the wallet app is booting up and initializing. Of course
1711
+ // a Signer value is the actually interface to a signed-in account
1706
1712
  constructor(_signer, prompter, mainnetNetworks, testnetNetworks = []) {
1707
1713
  var _this = this;
1708
1714
 
1709
1715
  this.signer = void 0;
1716
+ this.signerReadyCallbacks = [];
1710
1717
  this.prompter = void 0;
1711
1718
  this.mainnetNetworks = void 0;
1712
1719
  this.testnetNetworks = void 0;
1720
+ this._openIntent = void 0;
1713
1721
  this._connectOptions = void 0;
1714
1722
  this._defaultNetworkId = void 0;
1715
1723
  this._chainId = void 0;
@@ -1747,6 +1755,10 @@ class WalletRequestHandler {
1747
1755
  result: null
1748
1756
  };
1749
1757
 
1758
+ if (_this.signer === undefined) {
1759
+ await _this.signerReady();
1760
+ }
1761
+
1750
1762
  try {
1751
1763
  // only allow public json rpc method to the provider when user is not logged in, aka signer is not set
1752
1764
  if ((!_this.signer || _this.signer === null) && !permittedJsonRpcMethods.includes(request.method)) {
@@ -2145,7 +2157,7 @@ class WalletRequestHandler {
2145
2157
  }
2146
2158
 
2147
2159
  async signIn(signer, options = {}) {
2148
- this.signer = signer;
2160
+ this.setSigner(signer);
2149
2161
  const {
2150
2162
  connect,
2151
2163
  mainnetNetworks,
@@ -2192,6 +2204,29 @@ class WalletRequestHandler {
2192
2204
  }
2193
2205
  }
2194
2206
 
2207
+ signOut() {
2208
+ // signed out state
2209
+ this.signer = null;
2210
+ }
2211
+
2212
+ signerReset() {
2213
+ // resetting signer puts the wallet in an uninitialized state, which requires the app to
2214
+ // re-initiatize and set the signer either as "null" (ie. no signer) or "Signer" (ie. signed in).
2215
+ this.signer = undefined;
2216
+ }
2217
+
2218
+ signerReady() {
2219
+ return new Promise((resolve, reject) => {
2220
+ if (this.signer !== undefined) {
2221
+ resolve(undefined);
2222
+ } else {
2223
+ this.signerReadyCallbacks.push(() => {
2224
+ resolve(undefined);
2225
+ });
2226
+ }
2227
+ });
2228
+ }
2229
+
2195
2230
  async connect(options) {
2196
2231
  if (!this.signer) {
2197
2232
  return {
@@ -2280,6 +2315,14 @@ class WalletRequestHandler {
2280
2315
  }
2281
2316
  }
2282
2317
 
2318
+ get openIntent() {
2319
+ return this._openIntent;
2320
+ }
2321
+
2322
+ setOpenIntent(intent) {
2323
+ this._openIntent = intent;
2324
+ }
2325
+
2283
2326
  get connectOptions() {
2284
2327
  return this._connectOptions;
2285
2328
  }
@@ -2393,6 +2436,14 @@ class WalletRequestHandler {
2393
2436
 
2394
2437
  setSigner(signer) {
2395
2438
  this.signer = signer;
2439
+
2440
+ if (signer !== undefined) {
2441
+ for (let i = 0; i < this.signerReadyCallbacks.length; i++) {
2442
+ this.signerReadyCallbacks[i]();
2443
+ }
2444
+
2445
+ this.signerReadyCallbacks = [];
2446
+ }
2396
2447
  }
2397
2448
 
2398
2449
  async handleConfirmWalletDeployPrompt(prompter, signer, chainId) {
@@ -597,9 +597,14 @@ class BaseWalletTransport {
597
597
  };
598
598
 
599
599
  this.handleMessage = async function (message) {
600
- const request = message; // ensure initial handshake is complete before accepting
600
+ const request = message; // ensure signer is ready to handle requests
601
+
602
+ if (_this.walletRequestHandler.getSigner() === undefined) {
603
+ await _this.walletRequestHandler.signerReady();
604
+ } // ensure initial handshake is complete before accepting
601
605
  // other kinds of messages.
602
606
 
607
+
603
608
  if (_this._init !== exports.InitState.OK) {
604
609
  if (request.type === exports.EventType.INIT) {
605
610
  if (_this.isValidInitAck(message)) {
@@ -671,6 +676,13 @@ class BaseWalletTransport {
671
676
  intent,
672
677
  networkId
673
678
  });
679
+ }
680
+
681
+ _this.walletRequestHandler.setOpenIntent(intent); // ensure signer is ready
682
+
683
+
684
+ if (_this.walletRequestHandler.getSigner() === undefined) {
685
+ await _this.walletRequestHandler.signerReady();
674
686
  } // init handshake for certain transports, before we can open the communication.
675
687
  //
676
688
  // for example, with the window-transport, we have to exchange messages to determine the
@@ -1455,10 +1467,7 @@ class WindowMessageProvider extends BaseProviderTransport {
1455
1467
 
1456
1468
  if (isBrowserExtension()) {
1457
1469
  windowSize = [450, 750];
1458
- windowPos = [window.screenX, window.screenY]; // windowPos = [
1459
- // Math.abs(window.screen.width / 2 - windowSize[0] / 2),
1460
- // Math.abs(window.screen.height / 2 - windowSize[1] / 2)
1461
- // ]
1470
+ windowPos = [Math.abs(window.screen.width / 2 - windowSize[0] / 2), Math.abs(window.screen.height / 2 - windowSize[1] / 2)];
1462
1471
  } else {
1463
1472
  windowSize = [450, 750];
1464
1473
  windowPos = [Math.abs(window.screenX + window.innerWidth / 2 - windowSize[0] / 2), Math.abs(window.screenY + window.innerHeight / 2 - windowSize[1] / 2)];
@@ -1619,12 +1628,6 @@ class WindowMessageHandler extends BaseWalletTransport {
1619
1628
  if (!session) {
1620
1629
  utils.logger.error('window session is undefined');
1621
1630
  return;
1622
- }
1623
-
1624
- if (session.intent && isNewWindowSession) {
1625
- window.history.replaceState({
1626
- openWalletIntent: true
1627
- }, document.title, pathname);
1628
1631
  } // record parent window instance for communication
1629
1632
 
1630
1633
 
@@ -1703,13 +1706,18 @@ class WindowMessageHandler extends BaseWalletTransport {
1703
1706
  }
1704
1707
 
1705
1708
  class WalletRequestHandler {
1709
+ // signer interface of the wallet. A null value means there is no signer (ie. user not signed in). An undefined
1710
+ // value means the signer state is unknown, usually meaning the wallet app is booting up and initializing. Of course
1711
+ // a Signer value is the actually interface to a signed-in account
1706
1712
  constructor(_signer, prompter, mainnetNetworks, testnetNetworks = []) {
1707
1713
  var _this = this;
1708
1714
 
1709
1715
  this.signer = void 0;
1716
+ this.signerReadyCallbacks = [];
1710
1717
  this.prompter = void 0;
1711
1718
  this.mainnetNetworks = void 0;
1712
1719
  this.testnetNetworks = void 0;
1720
+ this._openIntent = void 0;
1713
1721
  this._connectOptions = void 0;
1714
1722
  this._defaultNetworkId = void 0;
1715
1723
  this._chainId = void 0;
@@ -1747,6 +1755,10 @@ class WalletRequestHandler {
1747
1755
  result: null
1748
1756
  };
1749
1757
 
1758
+ if (_this.signer === undefined) {
1759
+ await _this.signerReady();
1760
+ }
1761
+
1750
1762
  try {
1751
1763
  // only allow public json rpc method to the provider when user is not logged in, aka signer is not set
1752
1764
  if ((!_this.signer || _this.signer === null) && !permittedJsonRpcMethods.includes(request.method)) {
@@ -2145,7 +2157,7 @@ class WalletRequestHandler {
2145
2157
  }
2146
2158
 
2147
2159
  async signIn(signer, options = {}) {
2148
- this.signer = signer;
2160
+ this.setSigner(signer);
2149
2161
  const {
2150
2162
  connect,
2151
2163
  mainnetNetworks,
@@ -2192,6 +2204,29 @@ class WalletRequestHandler {
2192
2204
  }
2193
2205
  }
2194
2206
 
2207
+ signOut() {
2208
+ // signed out state
2209
+ this.signer = null;
2210
+ }
2211
+
2212
+ signerReset() {
2213
+ // resetting signer puts the wallet in an uninitialized state, which requires the app to
2214
+ // re-initiatize and set the signer either as "null" (ie. no signer) or "Signer" (ie. signed in).
2215
+ this.signer = undefined;
2216
+ }
2217
+
2218
+ signerReady() {
2219
+ return new Promise((resolve, reject) => {
2220
+ if (this.signer !== undefined) {
2221
+ resolve(undefined);
2222
+ } else {
2223
+ this.signerReadyCallbacks.push(() => {
2224
+ resolve(undefined);
2225
+ });
2226
+ }
2227
+ });
2228
+ }
2229
+
2195
2230
  async connect(options) {
2196
2231
  if (!this.signer) {
2197
2232
  return {
@@ -2280,6 +2315,14 @@ class WalletRequestHandler {
2280
2315
  }
2281
2316
  }
2282
2317
 
2318
+ get openIntent() {
2319
+ return this._openIntent;
2320
+ }
2321
+
2322
+ setOpenIntent(intent) {
2323
+ this._openIntent = intent;
2324
+ }
2325
+
2283
2326
  get connectOptions() {
2284
2327
  return this._connectOptions;
2285
2328
  }
@@ -2393,6 +2436,14 @@ class WalletRequestHandler {
2393
2436
 
2394
2437
  setSigner(signer) {
2395
2438
  this.signer = signer;
2439
+
2440
+ if (signer !== undefined) {
2441
+ for (let i = 0; i < this.signerReadyCallbacks.length; i++) {
2442
+ this.signerReadyCallbacks[i]();
2443
+ }
2444
+
2445
+ this.signerReadyCallbacks = [];
2446
+ }
2396
2447
  }
2397
2448
 
2398
2449
  async handleConfirmWalletDeployPrompt(prompter, signer, chainId) {
@@ -593,9 +593,14 @@ class BaseWalletTransport {
593
593
  };
594
594
 
595
595
  this.handleMessage = async function (message) {
596
- const request = message; // ensure initial handshake is complete before accepting
596
+ const request = message; // ensure signer is ready to handle requests
597
+
598
+ if (_this.walletRequestHandler.getSigner() === undefined) {
599
+ await _this.walletRequestHandler.signerReady();
600
+ } // ensure initial handshake is complete before accepting
597
601
  // other kinds of messages.
598
602
 
603
+
599
604
  if (_this._init !== InitState.OK) {
600
605
  if (request.type === EventType.INIT) {
601
606
  if (_this.isValidInitAck(message)) {
@@ -667,6 +672,13 @@ class BaseWalletTransport {
667
672
  intent,
668
673
  networkId
669
674
  });
675
+ }
676
+
677
+ _this.walletRequestHandler.setOpenIntent(intent); // ensure signer is ready
678
+
679
+
680
+ if (_this.walletRequestHandler.getSigner() === undefined) {
681
+ await _this.walletRequestHandler.signerReady();
670
682
  } // init handshake for certain transports, before we can open the communication.
671
683
  //
672
684
  // for example, with the window-transport, we have to exchange messages to determine the
@@ -1451,10 +1463,7 @@ class WindowMessageProvider extends BaseProviderTransport {
1451
1463
 
1452
1464
  if (isBrowserExtension()) {
1453
1465
  windowSize = [450, 750];
1454
- windowPos = [window.screenX, window.screenY]; // windowPos = [
1455
- // Math.abs(window.screen.width / 2 - windowSize[0] / 2),
1456
- // Math.abs(window.screen.height / 2 - windowSize[1] / 2)
1457
- // ]
1466
+ windowPos = [Math.abs(window.screen.width / 2 - windowSize[0] / 2), Math.abs(window.screen.height / 2 - windowSize[1] / 2)];
1458
1467
  } else {
1459
1468
  windowSize = [450, 750];
1460
1469
  windowPos = [Math.abs(window.screenX + window.innerWidth / 2 - windowSize[0] / 2), Math.abs(window.screenY + window.innerHeight / 2 - windowSize[1] / 2)];
@@ -1615,12 +1624,6 @@ class WindowMessageHandler extends BaseWalletTransport {
1615
1624
  if (!session) {
1616
1625
  logger.error('window session is undefined');
1617
1626
  return;
1618
- }
1619
-
1620
- if (session.intent && isNewWindowSession) {
1621
- window.history.replaceState({
1622
- openWalletIntent: true
1623
- }, document.title, pathname);
1624
1627
  } // record parent window instance for communication
1625
1628
 
1626
1629
 
@@ -1699,13 +1702,18 @@ class WindowMessageHandler extends BaseWalletTransport {
1699
1702
  }
1700
1703
 
1701
1704
  class WalletRequestHandler {
1705
+ // signer interface of the wallet. A null value means there is no signer (ie. user not signed in). An undefined
1706
+ // value means the signer state is unknown, usually meaning the wallet app is booting up and initializing. Of course
1707
+ // a Signer value is the actually interface to a signed-in account
1702
1708
  constructor(_signer, prompter, mainnetNetworks, testnetNetworks = []) {
1703
1709
  var _this = this;
1704
1710
 
1705
1711
  this.signer = void 0;
1712
+ this.signerReadyCallbacks = [];
1706
1713
  this.prompter = void 0;
1707
1714
  this.mainnetNetworks = void 0;
1708
1715
  this.testnetNetworks = void 0;
1716
+ this._openIntent = void 0;
1709
1717
  this._connectOptions = void 0;
1710
1718
  this._defaultNetworkId = void 0;
1711
1719
  this._chainId = void 0;
@@ -1743,6 +1751,10 @@ class WalletRequestHandler {
1743
1751
  result: null
1744
1752
  };
1745
1753
 
1754
+ if (_this.signer === undefined) {
1755
+ await _this.signerReady();
1756
+ }
1757
+
1746
1758
  try {
1747
1759
  // only allow public json rpc method to the provider when user is not logged in, aka signer is not set
1748
1760
  if ((!_this.signer || _this.signer === null) && !permittedJsonRpcMethods.includes(request.method)) {
@@ -2141,7 +2153,7 @@ class WalletRequestHandler {
2141
2153
  }
2142
2154
 
2143
2155
  async signIn(signer, options = {}) {
2144
- this.signer = signer;
2156
+ this.setSigner(signer);
2145
2157
  const {
2146
2158
  connect,
2147
2159
  mainnetNetworks,
@@ -2188,6 +2200,29 @@ class WalletRequestHandler {
2188
2200
  }
2189
2201
  }
2190
2202
 
2203
+ signOut() {
2204
+ // signed out state
2205
+ this.signer = null;
2206
+ }
2207
+
2208
+ signerReset() {
2209
+ // resetting signer puts the wallet in an uninitialized state, which requires the app to
2210
+ // re-initiatize and set the signer either as "null" (ie. no signer) or "Signer" (ie. signed in).
2211
+ this.signer = undefined;
2212
+ }
2213
+
2214
+ signerReady() {
2215
+ return new Promise((resolve, reject) => {
2216
+ if (this.signer !== undefined) {
2217
+ resolve(undefined);
2218
+ } else {
2219
+ this.signerReadyCallbacks.push(() => {
2220
+ resolve(undefined);
2221
+ });
2222
+ }
2223
+ });
2224
+ }
2225
+
2191
2226
  async connect(options) {
2192
2227
  if (!this.signer) {
2193
2228
  return {
@@ -2276,6 +2311,14 @@ class WalletRequestHandler {
2276
2311
  }
2277
2312
  }
2278
2313
 
2314
+ get openIntent() {
2315
+ return this._openIntent;
2316
+ }
2317
+
2318
+ setOpenIntent(intent) {
2319
+ this._openIntent = intent;
2320
+ }
2321
+
2279
2322
  get connectOptions() {
2280
2323
  return this._connectOptions;
2281
2324
  }
@@ -2389,6 +2432,14 @@ class WalletRequestHandler {
2389
2432
 
2390
2433
  setSigner(signer) {
2391
2434
  this.signer = signer;
2435
+
2436
+ if (signer !== undefined) {
2437
+ for (let i = 0; i < this.signerReadyCallbacks.length; i++) {
2438
+ this.signerReadyCallbacks[i]();
2439
+ }
2440
+
2441
+ this.signerReadyCallbacks = [];
2442
+ }
2392
2443
  }
2393
2444
 
2394
2445
  async handleConfirmWalletDeployPrompt(prompter, signer, chainId) {
@@ -1,4 +1,4 @@
1
- import { ProviderMessageRequest, ProviderMessageResponse, ProviderMessageRequestHandler, MessageToSign, ProviderRpcError, ConnectOptions, ConnectDetails, PromptConnectDetails, WalletSession, ProviderEventTypes } from '../types';
1
+ import { ProviderMessageRequest, ProviderMessageResponse, ProviderMessageRequestHandler, MessageToSign, ProviderRpcError, ConnectOptions, ConnectDetails, PromptConnectDetails, WalletSession, OpenWalletIntent, ProviderEventTypes } from '../types';
2
2
  import { ExternalProvider } from '@ethersproject/providers';
3
3
  import { Networks, NetworkConfig, JsonRpcHandler, JsonRpcRequest, JsonRpcResponseCallback } from '@0xsequence/network';
4
4
  import { Signer } from '@0xsequence/wallet';
@@ -11,15 +11,20 @@ export interface WalletSignInOptions {
11
11
  }
12
12
  export declare class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, ProviderMessageRequestHandler {
13
13
  private signer;
14
+ private signerReadyCallbacks;
14
15
  private prompter;
15
16
  private mainnetNetworks;
16
17
  private testnetNetworks;
18
+ private _openIntent?;
17
19
  private _connectOptions?;
18
20
  private _defaultNetworkId?;
19
21
  private _chainId?;
20
22
  private events;
21
- constructor(signer: Signer | null, prompter: WalletUserPrompter | null, mainnetNetworks: Networks, testnetNetworks?: Networks);
23
+ constructor(signer: Signer | null | undefined, prompter: WalletUserPrompter | null, mainnetNetworks: Networks, testnetNetworks?: Networks);
22
24
  signIn(signer: Signer | null, options?: WalletSignInOptions): Promise<void>;
25
+ signOut(): void;
26
+ signerReset(): void;
27
+ signerReady(): Promise<unknown>;
23
28
  connect(options?: ConnectOptions): Promise<ConnectDetails>;
24
29
  promptConnect: (options?: ConnectOptions | undefined) => Promise<ConnectDetails>;
25
30
  sendMessageRequest(message: ProviderMessageRequest): Promise<ProviderMessageResponse>;
@@ -28,6 +33,8 @@ export declare class WalletRequestHandler implements ExternalProvider, JsonRpcHa
28
33
  once<K extends keyof ProviderEventTypes>(event: K, fn: ProviderEventTypes[K]): void;
29
34
  getAddress(): Promise<string>;
30
35
  getChainId(): Promise<number>;
36
+ get openIntent(): OpenWalletIntent | undefined;
37
+ setOpenIntent(intent: OpenWalletIntent | undefined): void;
31
38
  get connectOptions(): ConnectOptions | undefined;
32
39
  setConnectOptions(options: ConnectOptions | undefined): void;
33
40
  get defaultNetworkId(): string | number | undefined;
@@ -40,8 +47,8 @@ export declare class WalletRequestHandler implements ExternalProvider, JsonRpcHa
40
47
  notifyWalletContext(): Promise<void>;
41
48
  notifyClose(error?: ProviderRpcError): void;
42
49
  isSignedIn(): boolean;
43
- getSigner(): Signer | null;
44
- setSigner(signer: Signer | null): void;
50
+ getSigner(): Signer | null | undefined;
51
+ setSigner(signer: Signer | null | undefined): void;
45
52
  private handleConfirmWalletDeployPrompt;
46
53
  }
47
54
  export interface WalletUserPrompter {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xsequence/provider",
3
- "version": "0.35.3",
3
+ "version": "0.35.7",
4
4
  "description": "provider sub-package for Sequence",
5
5
  "repository": "https://github.com/0xsequence/sequence.js/tree/master/packages/provider",
6
6
  "source": "src/index.ts",
@@ -13,13 +13,13 @@
13
13
  "typecheck": "tsc --noEmit"
14
14
  },
15
15
  "dependencies": {
16
- "@0xsequence/abi": "^0.35.3",
17
- "@0xsequence/auth": "^0.35.3",
18
- "@0xsequence/config": "^0.35.3",
19
- "@0xsequence/network": "^0.35.3",
20
- "@0xsequence/transactions": "^0.35.3",
21
- "@0xsequence/utils": "^0.35.3",
22
- "@0xsequence/wallet": "^0.35.3",
16
+ "@0xsequence/abi": "^0.35.7",
17
+ "@0xsequence/auth": "^0.35.7",
18
+ "@0xsequence/config": "^0.35.7",
19
+ "@0xsequence/network": "^0.35.7",
20
+ "@0xsequence/transactions": "^0.35.7",
21
+ "@0xsequence/utils": "^0.35.7",
22
+ "@0xsequence/wallet": "^0.35.7",
23
23
  "@ethersproject/abstract-signer": "^5.5.0",
24
24
  "@ethersproject/hash": "^5.5.0",
25
25
  "@ethersproject/providers": "^5.5.1",
@@ -100,6 +100,11 @@ export abstract class BaseWalletTransport implements WalletTransport {
100
100
  handleMessage = async (message: ProviderMessage<any>) => {
101
101
  const request = message
102
102
 
103
+ // ensure signer is ready to handle requests
104
+ if (this.walletRequestHandler.getSigner() === undefined) {
105
+ await this.walletRequestHandler.signerReady()
106
+ }
107
+
103
108
  // ensure initial handshake is complete before accepting
104
109
  // other kinds of messages.
105
110
  if (this._init !== InitState.OK) {
@@ -314,6 +319,13 @@ export abstract class BaseWalletTransport implements WalletTransport {
314
319
  this.saveTransportSession({ sessionId, intent, networkId })
315
320
  }
316
321
 
322
+ this.walletRequestHandler.setOpenIntent(intent)
323
+
324
+ // ensure signer is ready
325
+ if (this.walletRequestHandler.getSigner() === undefined) {
326
+ await this.walletRequestHandler.signerReady()
327
+ }
328
+
317
329
  // init handshake for certain transports, before we can open the communication.
318
330
  //
319
331
  // for example, with the window-transport, we have to exchange messages to determine the
@@ -10,6 +10,7 @@ import {
10
10
  ConnectDetails,
11
11
  PromptConnectDetails,
12
12
  WalletSession,
13
+ OpenWalletIntent,
13
14
  ErrSignedInRequired,
14
15
  ProviderEventTypes,
15
16
  TypedEventEmitter
@@ -41,11 +42,17 @@ export interface WalletSignInOptions {
41
42
  }
42
43
 
43
44
  export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, ProviderMessageRequestHandler {
44
- private signer: Signer | null
45
+ // signer interface of the wallet. A null value means there is no signer (ie. user not signed in). An undefined
46
+ // value means the signer state is unknown, usually meaning the wallet app is booting up and initializing. Of course
47
+ // a Signer value is the actually interface to a signed-in account
48
+ private signer: Signer | null | undefined
49
+ private signerReadyCallbacks: Array<() => void> = []
50
+
45
51
  private prompter: WalletUserPrompter | null
46
52
  private mainnetNetworks: NetworkConfig[]
47
53
  private testnetNetworks: NetworkConfig[]
48
54
 
55
+ private _openIntent?: OpenWalletIntent
49
56
  private _connectOptions?: ConnectOptions
50
57
  private _defaultNetworkId?: string | number
51
58
  private _chainId?: number
@@ -53,7 +60,7 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
53
60
  private events: TypedEventEmitter<ProviderEventTypes> = new EventEmitter() as TypedEventEmitter<ProviderEventTypes>
54
61
 
55
62
  constructor(
56
- signer: Signer | null,
63
+ signer: Signer | null | undefined,
57
64
  prompter: WalletUserPrompter | null,
58
65
  mainnetNetworks: Networks,
59
66
  testnetNetworks: Networks = []
@@ -65,7 +72,7 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
65
72
  }
66
73
 
67
74
  async signIn(signer: Signer | null, options: WalletSignInOptions = {}) {
68
- this.signer = signer
75
+ this.setSigner(signer)
69
76
 
70
77
  const { connect, mainnetNetworks, testnetNetworks, defaultNetworkId } = options
71
78
 
@@ -109,6 +116,29 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
109
116
  }
110
117
  }
111
118
 
119
+ signOut() {
120
+ // signed out state
121
+ this.signer = null
122
+ }
123
+
124
+ signerReset() {
125
+ // resetting signer puts the wallet in an uninitialized state, which requires the app to
126
+ // re-initiatize and set the signer either as "null" (ie. no signer) or "Signer" (ie. signed in).
127
+ this.signer = undefined
128
+ }
129
+
130
+ signerReady() {
131
+ return new Promise((resolve, reject) => {
132
+ if (this.signer !== undefined) {
133
+ resolve(undefined)
134
+ } else {
135
+ this.signerReadyCallbacks.push(() => {
136
+ resolve(undefined)
137
+ })
138
+ }
139
+ })
140
+ }
141
+
112
142
  async connect(options?: ConnectOptions): Promise<ConnectDetails> {
113
143
  if (!this.signer) {
114
144
  return {
@@ -208,6 +238,10 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
208
238
  result: null
209
239
  }
210
240
 
241
+ if (this.signer === undefined) {
242
+ await this.signerReady()
243
+ }
244
+
211
245
  try {
212
246
  // only allow public json rpc method to the provider when user is not logged in, aka signer is not set
213
247
  if ((!this.signer || this.signer === null) && !permittedJsonRpcMethods.includes(request.method)) {
@@ -583,6 +617,14 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
583
617
  }
584
618
  }
585
619
 
620
+ get openIntent(): OpenWalletIntent | undefined {
621
+ return this._openIntent
622
+ }
623
+
624
+ setOpenIntent(intent: OpenWalletIntent | undefined) {
625
+ this._openIntent = intent
626
+ }
627
+
586
628
  get connectOptions(): ConnectOptions | undefined {
587
629
  return this._connectOptions
588
630
  }
@@ -682,12 +724,19 @@ export class WalletRequestHandler implements ExternalProvider, JsonRpcHandler, P
682
724
  return !!this.signer
683
725
  }
684
726
 
685
- getSigner(): Signer | null {
727
+ getSigner(): Signer | null | undefined {
686
728
  return this.signer
687
729
  }
688
730
 
689
- setSigner(signer: Signer | null) {
731
+ setSigner(signer: Signer | null | undefined) {
690
732
  this.signer = signer
733
+
734
+ if (signer !== undefined) {
735
+ for (let i = 0; i < this.signerReadyCallbacks.length; i++) {
736
+ this.signerReadyCallbacks[i]()
737
+ }
738
+ this.signerReadyCallbacks = []
739
+ }
691
740
  }
692
741
 
693
742
  private async handleConfirmWalletDeployPrompt(
@@ -47,10 +47,6 @@ export class WindowMessageHandler extends BaseWalletTransport {
47
47
  return
48
48
  }
49
49
 
50
- if (session.intent && isNewWindowSession) {
51
- window.history.replaceState({ openWalletIntent: true }, document.title, pathname)
52
- }
53
-
54
50
  // record parent window instance for communication
55
51
  this.parentWindow = parent.window.opener
56
52
 
@@ -106,11 +106,10 @@ export class WindowMessageProvider extends BaseProviderTransport {
106
106
 
107
107
  if (isBrowserExtension()) {
108
108
  windowSize = [450, 750]
109
- windowPos = [window.screenX, window.screenY]
110
- // windowPos = [
111
- // Math.abs(window.screen.width / 2 - windowSize[0] / 2),
112
- // Math.abs(window.screen.height / 2 - windowSize[1] / 2)
113
- // ]
109
+ windowPos = [
110
+ Math.abs(window.screen.width / 2 - windowSize[0] / 2),
111
+ Math.abs(window.screen.height / 2 - windowSize[1] / 2)
112
+ ]
114
113
  } else {
115
114
  windowSize = [450, 750]
116
115
  windowPos = [