@0xsequence/provider 0.34.1 → 0.35.3

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.
@@ -494,7 +494,54 @@ const recoverWalletConfig = async (address, digest, signature, chainId, walletCo
494
494
 
495
495
  return config$1;
496
496
  };
497
- const isBrowserExtension = () => window.location.protocol === 'chrome-extension:' || window.location.protocol === 'moz-extension:'; // window.localstorage helper
497
+ const isBrowserExtension = () => window.location.protocol === 'chrome-extension:' || window.location.protocol === 'moz-extension:';
498
+ /**
499
+ * Returns the status of a signer's wallet on given chain by checking wallet deployment and config status
500
+ *
501
+ * @param {Signer} signer
502
+ * @param {number} chainId
503
+ * @return {Promise<boolean>} Promise that returns true if the wallet is up to date, false otherwise
504
+ */
505
+
506
+ const isWalletUpToDate = async (signer, chainId) => {
507
+ var _walletState$find;
508
+
509
+ const walletState = await signer.getWalletState();
510
+ const networks = await signer.getNetworks();
511
+ const walletStateForRequiredChain = walletState.find(state => state.chainId === chainId);
512
+
513
+ if (!walletStateForRequiredChain) {
514
+ throw new Error(`WalletRequestHandler: could not find wallet state for chainId ${chainId}`);
515
+ }
516
+
517
+ const isDeployed = walletStateForRequiredChain.deployed;
518
+
519
+ if (!networks) {
520
+ throw new Error(`isWalletUpToDate util: could not get networks from signer`);
521
+ }
522
+
523
+ const authChain = networks.find(network => network.isAuthChain);
524
+
525
+ if (!authChain) {
526
+ throw new Error(`isWalletUpToDate util: could not get auth chain network information`);
527
+ }
528
+
529
+ const authChainId = authChain.chainId;
530
+ const authChainConfig = (_walletState$find = walletState.find(state => state.chainId === authChainId)) == null ? void 0 : _walletState$find.config;
531
+
532
+ if (!authChainConfig) {
533
+ throw new Error(`isWalletUpToDate util: could not get auth chain config`);
534
+ }
535
+
536
+ const requiredChainConfig = walletStateForRequiredChain.config;
537
+
538
+ if (!requiredChainConfig) {
539
+ throw new Error(`isWalletUpToDate util: could not get config for chainId ${chainId}`);
540
+ }
541
+
542
+ const isUpToDate = config.isConfigEqual(authChainConfig, requiredChainConfig);
543
+ return isDeployed && isUpToDate;
544
+ }; // window.localstorage helper
498
545
 
499
546
  class LocalStore {
500
547
  constructor(key, def) {
@@ -1403,8 +1450,20 @@ class WindowMessageProvider extends BaseProviderTransport {
1403
1450
  } // Open popup window on center of the app window
1404
1451
 
1405
1452
 
1406
- const windowSize = [450, 750];
1407
- const windowPos = [Math.abs(window.screenX + window.innerWidth / 2 - windowSize[0] / 2), Math.abs(window.screenY + window.innerHeight / 2 - windowSize[1] / 2)];
1453
+ let windowSize;
1454
+ let windowPos;
1455
+
1456
+ if (isBrowserExtension()) {
1457
+ 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
+ // ]
1462
+ } else {
1463
+ windowSize = [450, 750];
1464
+ windowPos = [Math.abs(window.screenX + window.innerWidth / 2 - windowSize[0] / 2), Math.abs(window.screenY + window.innerHeight / 2 - windowSize[1] / 2)];
1465
+ }
1466
+
1408
1467
  const windowFeatures = `toolbar=0,location=0,menubar=0,scrollbars=yes,status=yes` + `,width=${windowSize[0]},height=${windowSize[1]}` + `,left=${windowPos[0]},top=${windowPos[1]}`; // serialize params
1409
1468
 
1410
1469
  walletURL.search = windowSessionParams.toString();
@@ -1536,7 +1595,7 @@ class WindowMessageHandler extends BaseWalletTransport {
1536
1595
  this._init = exports.InitState.NIL;
1537
1596
  }
1538
1597
 
1539
- register() {
1598
+ register(windowHref) {
1540
1599
  const isPopup = parent.window.opener !== null;
1541
1600
  this._isPopup = isPopup;
1542
1601
 
@@ -1548,7 +1607,7 @@ class WindowMessageHandler extends BaseWalletTransport {
1548
1607
  const {
1549
1608
  pathname,
1550
1609
  search: rawParams
1551
- } = new URL(window.location.href);
1610
+ } = new URL(windowHref || window.location.href);
1552
1611
  let session = this.getWindowTransportSession(rawParams); // provider should always include sid when opening a new window
1553
1612
 
1554
1613
  const isNewWindowSession = !!session.sessionId; // attempt to restore previous session in the case of a redirect or window reload
@@ -1733,37 +1792,21 @@ class WalletRequestHandler {
1733
1792
  }
1734
1793
 
1735
1794
  case 'personal_sign':
1795
+ case 'eth_sign':
1736
1796
  {
1737
1797
  // note: message from json-rpc input is in hex format
1738
- const [message, signingAddress] = request.params;
1739
- let sig = ''; // TODO:
1740
- // if (process.env.TEST_MODE === 'true' && this.prompter === null) {
1798
+ let message; // there is a difference in the order of the params:
1799
+ // personal_sign: [data, address]
1800
+ // eth_sign: [address, data]
1741
1801
 
1742
- if (_this.prompter === null) {
1743
- // prompter is null, so we'll sign from here
1744
- sig = await signer.signMessage(ethers.ethers.utils.arrayify(message), chainId);
1802
+ if (request.method === 'personal_sign') {
1803
+ const [data, address] = request.params;
1804
+ message = data;
1745
1805
  } else {
1746
- // prompt user to provide the response
1747
- sig = await _this.prompter.promptSignMessage({
1748
- chainId: chainId,
1749
- message: message
1750
- });
1806
+ const [address, data] = request.params;
1807
+ message = data;
1751
1808
  }
1752
1809
 
1753
- if (sig && sig.length > 0) {
1754
- response.result = sig;
1755
- } else {
1756
- // The user has declined the request when value is null
1757
- throw new Error('declined by user');
1758
- }
1759
-
1760
- break;
1761
- }
1762
-
1763
- case 'eth_sign':
1764
- {
1765
- // note: message from json-rpc input is in hex format
1766
- const [signingAddress, message] = request.params;
1767
1810
  let sig = ''; // TODO:
1768
1811
  // if (process.env.TEST_MODE === 'true' && this.prompter === null) {
1769
1812
 
@@ -1771,11 +1814,14 @@ class WalletRequestHandler {
1771
1814
  // prompter is null, so we'll sign from here
1772
1815
  sig = await signer.signMessage(ethers.ethers.utils.arrayify(message), chainId);
1773
1816
  } else {
1774
- // prompt user to provide the response
1775
- sig = await _this.prompter.promptSignMessage({
1776
- chainId: chainId,
1777
- message: message
1778
- });
1817
+ const promptResultForDeployment = await _this.handleConfirmWalletDeployPrompt(_this.prompter, signer, chainId);
1818
+
1819
+ if (promptResultForDeployment) {
1820
+ sig = await _this.prompter.promptSignMessage({
1821
+ chainId: chainId,
1822
+ message: message
1823
+ });
1824
+ }
1779
1825
  }
1780
1826
 
1781
1827
  if (sig && sig.length > 0) {
@@ -1814,11 +1860,14 @@ class WalletRequestHandler {
1814
1860
  // prompter is null, so we'll sign from here
1815
1861
  sig = await signer.signTypedData(typedData.domain, typedData.types, typedData.message, chainId);
1816
1862
  } else {
1817
- // prompt user to provide the response
1818
- sig = await _this.prompter.promptSignMessage({
1819
- chainId: chainId,
1820
- typedData: typedData
1821
- });
1863
+ const promptResultForDeployment = await _this.handleConfirmWalletDeployPrompt(_this.prompter, signer, chainId);
1864
+
1865
+ if (promptResultForDeployment) {
1866
+ sig = await _this.prompter.promptSignMessage({
1867
+ chainId: chainId,
1868
+ typedData: typedData
1869
+ });
1870
+ }
1822
1871
  }
1823
1872
 
1824
1873
  if (sig && sig.length > 0) {
@@ -2346,6 +2395,35 @@ class WalletRequestHandler {
2346
2395
  this.signer = signer;
2347
2396
  }
2348
2397
 
2398
+ async handleConfirmWalletDeployPrompt(prompter, signer, chainId) {
2399
+ // check if wallet is deployed and up to date, if not, prompt user to deploy
2400
+ // if no chainId is provided, we'll assume the wallet is auth chain wallet and is up to date
2401
+ if (!chainId) {
2402
+ return true;
2403
+ }
2404
+
2405
+ const isUpToDate = await isWalletUpToDate(signer, chainId);
2406
+
2407
+ if (isUpToDate) {
2408
+ return true;
2409
+ }
2410
+
2411
+ const promptResult = await prompter.promptConfirmWalletDeploy(chainId); // if client returned true, check again to make sure wallet is deployed and up to date
2412
+
2413
+ if (promptResult) {
2414
+ const isPromptResultCorrect = await isWalletUpToDate(signer, chainId);
2415
+
2416
+ if (!isPromptResultCorrect) {
2417
+ utils.logger.error('WalletRequestHandler: result for promptConfirmWalletDeploy is not correct');
2418
+ return false;
2419
+ } else {
2420
+ return true;
2421
+ }
2422
+ }
2423
+
2424
+ return false;
2425
+ }
2426
+
2349
2427
  }
2350
2428
  const permittedJsonRpcMethods = ['net_version', 'eth_chainId', 'eth_getBalance', 'eth_getTransactionCount', 'eth_blockNumber', 'eth_getBlockByNumber', 'eth_getBlockByHash', 'eth_getTransactionByHash', 'eth_getCode', 'eth_estimateGas', 'eth_gasPrice', 'sequence_getWalletContext', 'sequence_getNetworks', 'sequence_setDefaultNetwork'];
2351
2429
 
@@ -3580,5 +3658,6 @@ exports.WindowSessionParams = WindowSessionParams;
3580
3658
  exports.isBrowserExtension = isBrowserExtension;
3581
3659
  exports.isSequenceProvider = isSequenceProvider;
3582
3660
  exports.isValidSignature = isValidSignature;
3661
+ exports.isWalletUpToDate = isWalletUpToDate;
3583
3662
  exports.nextMessageIdx = nextMessageIdx;
3584
3663
  exports.recoverWalletConfig = recoverWalletConfig;
@@ -494,7 +494,54 @@ const recoverWalletConfig = async (address, digest, signature, chainId, walletCo
494
494
 
495
495
  return config$1;
496
496
  };
497
- const isBrowserExtension = () => window.location.protocol === 'chrome-extension:' || window.location.protocol === 'moz-extension:'; // window.localstorage helper
497
+ const isBrowserExtension = () => window.location.protocol === 'chrome-extension:' || window.location.protocol === 'moz-extension:';
498
+ /**
499
+ * Returns the status of a signer's wallet on given chain by checking wallet deployment and config status
500
+ *
501
+ * @param {Signer} signer
502
+ * @param {number} chainId
503
+ * @return {Promise<boolean>} Promise that returns true if the wallet is up to date, false otherwise
504
+ */
505
+
506
+ const isWalletUpToDate = async (signer, chainId) => {
507
+ var _walletState$find;
508
+
509
+ const walletState = await signer.getWalletState();
510
+ const networks = await signer.getNetworks();
511
+ const walletStateForRequiredChain = walletState.find(state => state.chainId === chainId);
512
+
513
+ if (!walletStateForRequiredChain) {
514
+ throw new Error(`WalletRequestHandler: could not find wallet state for chainId ${chainId}`);
515
+ }
516
+
517
+ const isDeployed = walletStateForRequiredChain.deployed;
518
+
519
+ if (!networks) {
520
+ throw new Error(`isWalletUpToDate util: could not get networks from signer`);
521
+ }
522
+
523
+ const authChain = networks.find(network => network.isAuthChain);
524
+
525
+ if (!authChain) {
526
+ throw new Error(`isWalletUpToDate util: could not get auth chain network information`);
527
+ }
528
+
529
+ const authChainId = authChain.chainId;
530
+ const authChainConfig = (_walletState$find = walletState.find(state => state.chainId === authChainId)) == null ? void 0 : _walletState$find.config;
531
+
532
+ if (!authChainConfig) {
533
+ throw new Error(`isWalletUpToDate util: could not get auth chain config`);
534
+ }
535
+
536
+ const requiredChainConfig = walletStateForRequiredChain.config;
537
+
538
+ if (!requiredChainConfig) {
539
+ throw new Error(`isWalletUpToDate util: could not get config for chainId ${chainId}`);
540
+ }
541
+
542
+ const isUpToDate = config.isConfigEqual(authChainConfig, requiredChainConfig);
543
+ return isDeployed && isUpToDate;
544
+ }; // window.localstorage helper
498
545
 
499
546
  class LocalStore {
500
547
  constructor(key, def) {
@@ -1403,8 +1450,20 @@ class WindowMessageProvider extends BaseProviderTransport {
1403
1450
  } // Open popup window on center of the app window
1404
1451
 
1405
1452
 
1406
- const windowSize = [450, 750];
1407
- const windowPos = [Math.abs(window.screenX + window.innerWidth / 2 - windowSize[0] / 2), Math.abs(window.screenY + window.innerHeight / 2 - windowSize[1] / 2)];
1453
+ let windowSize;
1454
+ let windowPos;
1455
+
1456
+ if (isBrowserExtension()) {
1457
+ 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
+ // ]
1462
+ } else {
1463
+ windowSize = [450, 750];
1464
+ windowPos = [Math.abs(window.screenX + window.innerWidth / 2 - windowSize[0] / 2), Math.abs(window.screenY + window.innerHeight / 2 - windowSize[1] / 2)];
1465
+ }
1466
+
1408
1467
  const windowFeatures = `toolbar=0,location=0,menubar=0,scrollbars=yes,status=yes` + `,width=${windowSize[0]},height=${windowSize[1]}` + `,left=${windowPos[0]},top=${windowPos[1]}`; // serialize params
1409
1468
 
1410
1469
  walletURL.search = windowSessionParams.toString();
@@ -1536,7 +1595,7 @@ class WindowMessageHandler extends BaseWalletTransport {
1536
1595
  this._init = exports.InitState.NIL;
1537
1596
  }
1538
1597
 
1539
- register() {
1598
+ register(windowHref) {
1540
1599
  const isPopup = parent.window.opener !== null;
1541
1600
  this._isPopup = isPopup;
1542
1601
 
@@ -1548,7 +1607,7 @@ class WindowMessageHandler extends BaseWalletTransport {
1548
1607
  const {
1549
1608
  pathname,
1550
1609
  search: rawParams
1551
- } = new URL(window.location.href);
1610
+ } = new URL(windowHref || window.location.href);
1552
1611
  let session = this.getWindowTransportSession(rawParams); // provider should always include sid when opening a new window
1553
1612
 
1554
1613
  const isNewWindowSession = !!session.sessionId; // attempt to restore previous session in the case of a redirect or window reload
@@ -1733,37 +1792,21 @@ class WalletRequestHandler {
1733
1792
  }
1734
1793
 
1735
1794
  case 'personal_sign':
1795
+ case 'eth_sign':
1736
1796
  {
1737
1797
  // note: message from json-rpc input is in hex format
1738
- const [message, signingAddress] = request.params;
1739
- let sig = ''; // TODO:
1740
- // if (process.env.TEST_MODE === 'true' && this.prompter === null) {
1798
+ let message; // there is a difference in the order of the params:
1799
+ // personal_sign: [data, address]
1800
+ // eth_sign: [address, data]
1741
1801
 
1742
- if (_this.prompter === null) {
1743
- // prompter is null, so we'll sign from here
1744
- sig = await signer.signMessage(ethers.ethers.utils.arrayify(message), chainId);
1802
+ if (request.method === 'personal_sign') {
1803
+ const [data, address] = request.params;
1804
+ message = data;
1745
1805
  } else {
1746
- // prompt user to provide the response
1747
- sig = await _this.prompter.promptSignMessage({
1748
- chainId: chainId,
1749
- message: message
1750
- });
1806
+ const [address, data] = request.params;
1807
+ message = data;
1751
1808
  }
1752
1809
 
1753
- if (sig && sig.length > 0) {
1754
- response.result = sig;
1755
- } else {
1756
- // The user has declined the request when value is null
1757
- throw new Error('declined by user');
1758
- }
1759
-
1760
- break;
1761
- }
1762
-
1763
- case 'eth_sign':
1764
- {
1765
- // note: message from json-rpc input is in hex format
1766
- const [signingAddress, message] = request.params;
1767
1810
  let sig = ''; // TODO:
1768
1811
  // if (process.env.TEST_MODE === 'true' && this.prompter === null) {
1769
1812
 
@@ -1771,11 +1814,14 @@ class WalletRequestHandler {
1771
1814
  // prompter is null, so we'll sign from here
1772
1815
  sig = await signer.signMessage(ethers.ethers.utils.arrayify(message), chainId);
1773
1816
  } else {
1774
- // prompt user to provide the response
1775
- sig = await _this.prompter.promptSignMessage({
1776
- chainId: chainId,
1777
- message: message
1778
- });
1817
+ const promptResultForDeployment = await _this.handleConfirmWalletDeployPrompt(_this.prompter, signer, chainId);
1818
+
1819
+ if (promptResultForDeployment) {
1820
+ sig = await _this.prompter.promptSignMessage({
1821
+ chainId: chainId,
1822
+ message: message
1823
+ });
1824
+ }
1779
1825
  }
1780
1826
 
1781
1827
  if (sig && sig.length > 0) {
@@ -1814,11 +1860,14 @@ class WalletRequestHandler {
1814
1860
  // prompter is null, so we'll sign from here
1815
1861
  sig = await signer.signTypedData(typedData.domain, typedData.types, typedData.message, chainId);
1816
1862
  } else {
1817
- // prompt user to provide the response
1818
- sig = await _this.prompter.promptSignMessage({
1819
- chainId: chainId,
1820
- typedData: typedData
1821
- });
1863
+ const promptResultForDeployment = await _this.handleConfirmWalletDeployPrompt(_this.prompter, signer, chainId);
1864
+
1865
+ if (promptResultForDeployment) {
1866
+ sig = await _this.prompter.promptSignMessage({
1867
+ chainId: chainId,
1868
+ typedData: typedData
1869
+ });
1870
+ }
1822
1871
  }
1823
1872
 
1824
1873
  if (sig && sig.length > 0) {
@@ -2346,6 +2395,35 @@ class WalletRequestHandler {
2346
2395
  this.signer = signer;
2347
2396
  }
2348
2397
 
2398
+ async handleConfirmWalletDeployPrompt(prompter, signer, chainId) {
2399
+ // check if wallet is deployed and up to date, if not, prompt user to deploy
2400
+ // if no chainId is provided, we'll assume the wallet is auth chain wallet and is up to date
2401
+ if (!chainId) {
2402
+ return true;
2403
+ }
2404
+
2405
+ const isUpToDate = await isWalletUpToDate(signer, chainId);
2406
+
2407
+ if (isUpToDate) {
2408
+ return true;
2409
+ }
2410
+
2411
+ const promptResult = await prompter.promptConfirmWalletDeploy(chainId); // if client returned true, check again to make sure wallet is deployed and up to date
2412
+
2413
+ if (promptResult) {
2414
+ const isPromptResultCorrect = await isWalletUpToDate(signer, chainId);
2415
+
2416
+ if (!isPromptResultCorrect) {
2417
+ utils.logger.error('WalletRequestHandler: result for promptConfirmWalletDeploy is not correct');
2418
+ return false;
2419
+ } else {
2420
+ return true;
2421
+ }
2422
+ }
2423
+
2424
+ return false;
2425
+ }
2426
+
2349
2427
  }
2350
2428
  const permittedJsonRpcMethods = ['net_version', 'eth_chainId', 'eth_getBalance', 'eth_getTransactionCount', 'eth_blockNumber', 'eth_getBlockByNumber', 'eth_getBlockByHash', 'eth_getTransactionByHash', 'eth_getCode', 'eth_estimateGas', 'eth_gasPrice', 'sequence_getWalletContext', 'sequence_getNetworks', 'sequence_setDefaultNetwork'];
2351
2429
 
@@ -3580,5 +3658,6 @@ exports.WindowSessionParams = WindowSessionParams;
3580
3658
  exports.isBrowserExtension = isBrowserExtension;
3581
3659
  exports.isSequenceProvider = isSequenceProvider;
3582
3660
  exports.isValidSignature = isValidSignature;
3661
+ exports.isWalletUpToDate = isWalletUpToDate;
3583
3662
  exports.nextMessageIdx = nextMessageIdx;
3584
3663
  exports.recoverWalletConfig = recoverWalletConfig;