@dynamic-labs/starknet 2.3.7 → 2.3.9

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 CHANGED
@@ -1,4 +1,19 @@
1
1
 
2
+ ### [2.3.9](https://github.com/dynamic-labs/DynamicAuth/compare/v2.3.8...v2.3.9) (2024-08-13)
3
+
4
+
5
+ ### Bug Fixes
6
+
7
+ * hcaptcha for mobile login ([#6525](https://github.com/dynamic-labs/DynamicAuth/issues/6525)) ([#6539](https://github.com/dynamic-labs/DynamicAuth/issues/6539)) ([9b3676d](https://github.com/dynamic-labs/DynamicAuth/commit/9b3676dd27c65a7e678e720e5648a166b8d514a6))
8
+
9
+ ### [2.3.8](https://github.com/dynamic-labs/DynamicAuth/compare/v2.3.7...v2.3.8) (2024-08-02)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * fetch user on refresh from backend when cookie-enabled and user not in local storage ([#6472](https://github.com/dynamic-labs/DynamicAuth/issues/6472)) ([7300a21](https://github.com/dynamic-labs/DynamicAuth/commit/7300a21d81d51ef1fc93af12d1081b5c1d57b578))
15
+ * stop filtering wallet connect on keyword "wallet" ([#6476](https://github.com/dynamic-labs/DynamicAuth/issues/6476)) ([fc1be36](https://github.com/dynamic-labs/DynamicAuth/commit/fc1be36b0370f876dcfe4e84e25ee60cf9682306)), closes [#6475](https://github.com/dynamic-labs/DynamicAuth/issues/6475)
16
+
2
17
  ### [2.3.7](https://github.com/dynamic-labs/DynamicAuth/compare/v2.3.6...v2.3.7) (2024-07-26)
3
18
 
4
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/starknet",
3
- "version": "2.3.7",
3
+ "version": "2.3.9",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/dynamic-labs/dynamic-auth.git",
@@ -31,10 +31,12 @@
31
31
  "text-encoding": "0.7.0",
32
32
  "starknetkit": "1.1.3",
33
33
  "@dynamic-labs/sdk-api-core": "0.0.497",
34
- "@dynamic-labs/rpc-provider-starknet": "2.3.7",
35
- "@dynamic-labs/utils": "2.3.7",
36
- "@dynamic-labs/wallet-book": "2.3.7",
37
- "@dynamic-labs/wallet-connector-core": "2.3.7"
34
+ "@module-federation/runtime": "0.1.19",
35
+ "@dynamic-labs/logger": "2.3.9",
36
+ "@dynamic-labs/rpc-provider-starknet": "2.3.9",
37
+ "@dynamic-labs/utils": "2.3.9",
38
+ "@dynamic-labs/wallet-book": "2.3.9",
39
+ "@dynamic-labs/wallet-connector-core": "2.3.9"
38
40
  },
39
41
  "peerDependencies": {}
40
42
  }
package/src/index.cjs CHANGED
@@ -9,6 +9,7 @@ var argentxMobile = require('./wallets/argentxMobile.cjs');
9
9
  var argentxWeb = require('./wallets/argentxWeb.cjs');
10
10
  var bitget = require('./wallets/bitget.cjs');
11
11
  var okx = require('./wallets/okx.cjs');
12
+ var metamask = require('./wallets/metamask.cjs');
12
13
  require('@dynamic-labs/rpc-provider-starknet');
13
14
 
14
15
  /* eslint-disable @typescript-eslint/no-unused-vars */
@@ -19,6 +20,7 @@ const StarknetWalletConnectors = (props) => [
19
20
  argentxWeb.ArgentXWeb,
20
21
  okx.Okx,
21
22
  bitget.Bitget,
23
+ metamask.MetaMask,
22
24
  ];
23
25
 
24
26
  exports.StarknetWalletConnectors = StarknetWalletConnectors;
package/src/index.js CHANGED
@@ -5,6 +5,7 @@ import { ArgentXMobile } from './wallets/argentxMobile.js';
5
5
  import { ArgentXWeb } from './wallets/argentxWeb.js';
6
6
  import { Bitget } from './wallets/bitget.js';
7
7
  import { Okx } from './wallets/okx.js';
8
+ import { MetaMask } from './wallets/metamask.js';
8
9
  import '@dynamic-labs/rpc-provider-starknet';
9
10
 
10
11
  /* eslint-disable @typescript-eslint/no-unused-vars */
@@ -15,6 +16,7 @@ const StarknetWalletConnectors = (props) => [
15
16
  ArgentXWeb,
16
17
  Okx,
17
18
  Bitget,
19
+ MetaMask,
18
20
  ];
19
21
 
20
22
  export { StarknetWalletConnectors };
@@ -22,6 +22,8 @@ class StarknetWalletConnector extends walletConnectorCore.WalletConnectorBase {
22
22
  this.connectedChain = 'STARK';
23
23
  this.supportedChains = ['STARK'];
24
24
  this.switchNetworkOnlyFromWallet = true;
25
+ // required for metamask snap integration as MM snaps don't have event listeners
26
+ this.canSetEventListeners = true;
25
27
  this.name = name;
26
28
  this.windowKey = windowKey;
27
29
  this.starknetNetworks = opts.starknetNetworks;
@@ -182,6 +184,24 @@ class StarknetWalletConnector extends walletConnectorCore.WalletConnectorBase {
182
184
  if (!wallet) {
183
185
  return [];
184
186
  }
187
+ try {
188
+ yield this.reconnectIfNeeded(wallet);
189
+ }
190
+ catch (e) {
191
+ return [];
192
+ }
193
+ const getSelectedAddress = () => wallet.selectedAddress
194
+ ? Promise.resolve([wallet.selectedAddress])
195
+ : Promise.reject();
196
+ return utils.retryableFn(getSelectedAddress, {
197
+ fallbackValue: [],
198
+ retryIntervalMs: 100,
199
+ retryStrategy: 'timeout-and-rejection',
200
+ });
201
+ });
202
+ }
203
+ reconnectIfNeeded(wallet) {
204
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
185
205
  const needsReconnection = !this.isProviderConnected() && (yield wallet.isPreauthorized());
186
206
  if (needsReconnection) {
187
207
  /**
@@ -199,24 +219,18 @@ class StarknetWalletConnector extends walletConnectorCore.WalletConnectorBase {
199
219
  }
200
220
  catch (_a) {
201
221
  localStorage.removeItem('dynamic_should_have_wallet');
202
- return [];
222
+ throw new Error('Could not reconnect');
203
223
  }
204
224
  }
205
225
  else {
206
226
  yield this.connect();
207
227
  }
208
228
  }
209
- const getSelectedAddress = () => wallet.selectedAddress
210
- ? Promise.resolve([wallet.selectedAddress])
211
- : Promise.reject();
212
- return utils.retryableFn(getSelectedAddress, {
213
- fallbackValue: [],
214
- retryIntervalMs: 100,
215
- retryStrategy: 'timeout-and-rejection',
216
- });
217
229
  });
218
230
  }
219
231
  setupEventListeners() {
232
+ if (!this.canSetEventListeners)
233
+ return;
220
234
  const wallet = this.getWallet();
221
235
  if (!wallet) {
222
236
  return walletConnectorCore.logger.error('Wallet has not been found');
@@ -245,6 +259,8 @@ class StarknetWalletConnector extends walletConnectorCore.WalletConnectorBase {
245
259
  }
246
260
  teardownEventListeners() {
247
261
  return _tslib.__awaiter(this, void 0, void 0, function* () {
262
+ if (!this.canSetEventListeners)
263
+ return;
248
264
  const wallet = this.getWallet();
249
265
  if (this.handleAccountChange) {
250
266
  wallet === null || wallet === void 0 ? void 0 : wallet.off(ACCOUNT_CHANGED_EVENT_LISTENER, this.handleAccountChange);
@@ -23,6 +23,7 @@ declare abstract class StarknetWalletConnector extends WalletConnectorBase {
23
23
  handleNetworkChange: NetworkChangeEventHandler | undefined;
24
24
  switchNetworkOnlyFromWallet: boolean;
25
25
  starknetNetworks: NetworkConfiguration[];
26
+ canSetEventListeners: boolean;
26
27
  constructor(name: string, windowKey: StarknetWalletKey, opts: {
27
28
  chainRpcProviders: IChainRpcProviders;
28
29
  starknetNetworks: NetworkConfiguration[];
@@ -112,6 +113,7 @@ declare abstract class StarknetWalletConnector extends WalletConnectorBase {
112
113
  getWallet(): StarknetWindowObject | undefined;
113
114
  isInstalledOnBrowser(): boolean;
114
115
  getConnectedAccounts(): Promise<string[]>;
116
+ reconnectIfNeeded(wallet: StarknetWindowObject): Promise<Promise<Promise<void>>>;
115
117
  setupEventListeners(): void;
116
118
  teardownEventListeners(): Promise<void>;
117
119
  mapNetworkNameToChainId(networkNameOrChainId: string): constants.StarknetChainId | undefined;
@@ -18,6 +18,8 @@ class StarknetWalletConnector extends WalletConnectorBase {
18
18
  this.connectedChain = 'STARK';
19
19
  this.supportedChains = ['STARK'];
20
20
  this.switchNetworkOnlyFromWallet = true;
21
+ // required for metamask snap integration as MM snaps don't have event listeners
22
+ this.canSetEventListeners = true;
21
23
  this.name = name;
22
24
  this.windowKey = windowKey;
23
25
  this.starknetNetworks = opts.starknetNetworks;
@@ -178,6 +180,24 @@ class StarknetWalletConnector extends WalletConnectorBase {
178
180
  if (!wallet) {
179
181
  return [];
180
182
  }
183
+ try {
184
+ yield this.reconnectIfNeeded(wallet);
185
+ }
186
+ catch (e) {
187
+ return [];
188
+ }
189
+ const getSelectedAddress = () => wallet.selectedAddress
190
+ ? Promise.resolve([wallet.selectedAddress])
191
+ : Promise.reject();
192
+ return retryableFn(getSelectedAddress, {
193
+ fallbackValue: [],
194
+ retryIntervalMs: 100,
195
+ retryStrategy: 'timeout-and-rejection',
196
+ });
197
+ });
198
+ }
199
+ reconnectIfNeeded(wallet) {
200
+ return __awaiter(this, void 0, void 0, function* () {
181
201
  const needsReconnection = !this.isProviderConnected() && (yield wallet.isPreauthorized());
182
202
  if (needsReconnection) {
183
203
  /**
@@ -195,24 +215,18 @@ class StarknetWalletConnector extends WalletConnectorBase {
195
215
  }
196
216
  catch (_a) {
197
217
  localStorage.removeItem('dynamic_should_have_wallet');
198
- return [];
218
+ throw new Error('Could not reconnect');
199
219
  }
200
220
  }
201
221
  else {
202
222
  yield this.connect();
203
223
  }
204
224
  }
205
- const getSelectedAddress = () => wallet.selectedAddress
206
- ? Promise.resolve([wallet.selectedAddress])
207
- : Promise.reject();
208
- return retryableFn(getSelectedAddress, {
209
- fallbackValue: [],
210
- retryIntervalMs: 100,
211
- retryStrategy: 'timeout-and-rejection',
212
- });
213
225
  });
214
226
  }
215
227
  setupEventListeners() {
228
+ if (!this.canSetEventListeners)
229
+ return;
216
230
  const wallet = this.getWallet();
217
231
  if (!wallet) {
218
232
  return logger.error('Wallet has not been found');
@@ -241,6 +255,8 @@ class StarknetWalletConnector extends WalletConnectorBase {
241
255
  }
242
256
  teardownEventListeners() {
243
257
  return __awaiter(this, void 0, void 0, function* () {
258
+ if (!this.canSetEventListeners)
259
+ return;
244
260
  const wallet = this.getWallet();
245
261
  if (this.handleAccountChange) {
246
262
  wallet === null || wallet === void 0 ? void 0 : wallet.off(ACCOUNT_CHANGED_EVENT_LISTENER, this.handleAccountChange);
package/src/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { StarknetWindowObject } from 'get-starknet-core';
2
- export type StarknetWalletKey = 'braavos' | 'argentX' | 'argentXMobile' | 'argentWebWallet' | 'okxwallet' | 'bitkeep';
2
+ export type StarknetWalletKey = 'braavos' | 'argentX' | 'argentXMobile' | 'argentWebWallet' | 'okxwallet' | 'bitkeep' | 'metamask_snap';
3
3
  export type StarknetWindowKey = `starknet_${StarknetWalletKey}` | 'starknet';
4
4
  type StarknetWindow = {
5
5
  [key in StarknetWindowKey]: StarknetWindowObject;
@@ -0,0 +1,112 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../_virtual/_tslib.cjs');
7
+ var moduleFederation = require('@module-federation/runtime/dist/index.cjs.js');
8
+
9
+ function _interopNamespace(e) {
10
+ if (e && e.__esModule) return e;
11
+ var n = Object.create(null);
12
+ if (e) {
13
+ Object.keys(e).forEach(function (k) {
14
+ if (k !== 'default') {
15
+ var d = Object.getOwnPropertyDescriptor(e, k);
16
+ Object.defineProperty(n, k, d.get ? d : {
17
+ enumerable: true,
18
+ get: function () { return e[k]; }
19
+ });
20
+ }
21
+ });
22
+ }
23
+ n["default"] = e;
24
+ return Object.freeze(n);
25
+ }
26
+
27
+ var moduleFederation__namespace = /*#__PURE__*/_interopNamespace(moduleFederation);
28
+
29
+ /**
30
+ *
31
+ * @param {IEthereum} provider the metamask window provider object
32
+ * @returns {StarknetWindowObject} the metamask provider wrapper formed into starknet window object
33
+ */
34
+ const createMetaMaskProviderWrapper = (provider) => {
35
+ let metaMaskSnapWallet;
36
+ // using @module-federation to load the get-starknet remoteEntry, as recommended
37
+ // by the starknet team. this file is a small wrapper around the metamask snap api
38
+ // to communicate with starknet, which we then wrap into a starknet window object
39
+ // and use in our starknet connector, just like braavos and argent
40
+ const initMetaMaskSnapWallet = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
41
+ if (!metaMaskSnapWallet) {
42
+ moduleFederation__namespace.init({
43
+ name: 'MetaMaskStarknetSnapWallet',
44
+ remotes: [
45
+ {
46
+ alias: 'MetaMaskStarknetSnapWallet',
47
+ entry: 'https://snaps.consensys.io/starknet/get-starknet/v1/remoteEntry.js',
48
+ name: 'MetaMaskStarknetSnapWallet',
49
+ },
50
+ ],
51
+ });
52
+ const result = yield moduleFederation__namespace.loadRemote('MetaMaskStarknetSnapWallet/index');
53
+ const { MetaMaskSnapWallet } = result;
54
+ metaMaskSnapWallet = new MetaMaskSnapWallet(provider, '*');
55
+ }
56
+ });
57
+ const metaMaskProviderWrapper = {
58
+ get account() {
59
+ return metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.account;
60
+ },
61
+ get chainId() {
62
+ return metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.chainId;
63
+ },
64
+ enable: () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
65
+ yield initMetaMaskSnapWallet();
66
+ if (!metaMaskSnapWallet) {
67
+ return [];
68
+ }
69
+ return metaMaskSnapWallet.enable();
70
+ }),
71
+ icon: '',
72
+ id: 'MetaMaskStarknetSnapWallet',
73
+ get isConnected() {
74
+ return metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.isConnected;
75
+ },
76
+ isPreauthorized: () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
77
+ var _a;
78
+ yield initMetaMaskSnapWallet();
79
+ return (_a = (yield (metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.isPreauthorized()))) !== null && _a !== void 0 ? _a : false;
80
+ }),
81
+ name: 'MetaMaskStarknetSnapWallet',
82
+ off: (
83
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
84
+ event,
85
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
86
+ handleEvent) => undefined,
87
+ on: (
88
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
89
+ event,
90
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
91
+ handleEvent) => undefined,
92
+ get provider() {
93
+ return metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.provider;
94
+ },
95
+ request: (call) => {
96
+ if (!metaMaskSnapWallet) {
97
+ throw new Error('Wallet not enabled');
98
+ }
99
+ return metaMaskSnapWallet.request(call);
100
+ },
101
+ get selectedAddress() {
102
+ return metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.selectedAddress;
103
+ },
104
+ get version() {
105
+ var _a;
106
+ return (_a = metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.version) !== null && _a !== void 0 ? _a : '0.0.0';
107
+ },
108
+ };
109
+ return metaMaskProviderWrapper;
110
+ };
111
+
112
+ exports.createMetaMaskProviderWrapper = createMetaMaskProviderWrapper;
@@ -0,0 +1,8 @@
1
+ import { StarknetWindowObject } from 'get-starknet-core';
2
+ import { IEthereum } from '@dynamic-labs/utils';
3
+ /**
4
+ *
5
+ * @param {IEthereum} provider the metamask window provider object
6
+ * @returns {StarknetWindowObject} the metamask provider wrapper formed into starknet window object
7
+ */
8
+ export declare const createMetaMaskProviderWrapper: (provider: IEthereum) => StarknetWindowObject;
@@ -0,0 +1,88 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../_virtual/_tslib.js';
3
+ import * as moduleFederation from '@module-federation/runtime/dist/index.cjs.js';
4
+
5
+ /**
6
+ *
7
+ * @param {IEthereum} provider the metamask window provider object
8
+ * @returns {StarknetWindowObject} the metamask provider wrapper formed into starknet window object
9
+ */
10
+ const createMetaMaskProviderWrapper = (provider) => {
11
+ let metaMaskSnapWallet;
12
+ // using @module-federation to load the get-starknet remoteEntry, as recommended
13
+ // by the starknet team. this file is a small wrapper around the metamask snap api
14
+ // to communicate with starknet, which we then wrap into a starknet window object
15
+ // and use in our starknet connector, just like braavos and argent
16
+ const initMetaMaskSnapWallet = () => __awaiter(void 0, void 0, void 0, function* () {
17
+ if (!metaMaskSnapWallet) {
18
+ moduleFederation.init({
19
+ name: 'MetaMaskStarknetSnapWallet',
20
+ remotes: [
21
+ {
22
+ alias: 'MetaMaskStarknetSnapWallet',
23
+ entry: 'https://snaps.consensys.io/starknet/get-starknet/v1/remoteEntry.js',
24
+ name: 'MetaMaskStarknetSnapWallet',
25
+ },
26
+ ],
27
+ });
28
+ const result = yield moduleFederation.loadRemote('MetaMaskStarknetSnapWallet/index');
29
+ const { MetaMaskSnapWallet } = result;
30
+ metaMaskSnapWallet = new MetaMaskSnapWallet(provider, '*');
31
+ }
32
+ });
33
+ const metaMaskProviderWrapper = {
34
+ get account() {
35
+ return metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.account;
36
+ },
37
+ get chainId() {
38
+ return metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.chainId;
39
+ },
40
+ enable: () => __awaiter(void 0, void 0, void 0, function* () {
41
+ yield initMetaMaskSnapWallet();
42
+ if (!metaMaskSnapWallet) {
43
+ return [];
44
+ }
45
+ return metaMaskSnapWallet.enable();
46
+ }),
47
+ icon: '',
48
+ id: 'MetaMaskStarknetSnapWallet',
49
+ get isConnected() {
50
+ return metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.isConnected;
51
+ },
52
+ isPreauthorized: () => __awaiter(void 0, void 0, void 0, function* () {
53
+ var _a;
54
+ yield initMetaMaskSnapWallet();
55
+ return (_a = (yield (metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.isPreauthorized()))) !== null && _a !== void 0 ? _a : false;
56
+ }),
57
+ name: 'MetaMaskStarknetSnapWallet',
58
+ off: (
59
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
60
+ event,
61
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
62
+ handleEvent) => undefined,
63
+ on: (
64
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
65
+ event,
66
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
67
+ handleEvent) => undefined,
68
+ get provider() {
69
+ return metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.provider;
70
+ },
71
+ request: (call) => {
72
+ if (!metaMaskSnapWallet) {
73
+ throw new Error('Wallet not enabled');
74
+ }
75
+ return metaMaskSnapWallet.request(call);
76
+ },
77
+ get selectedAddress() {
78
+ return metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.selectedAddress;
79
+ },
80
+ get version() {
81
+ var _a;
82
+ return (_a = metaMaskSnapWallet === null || metaMaskSnapWallet === void 0 ? void 0 : metaMaskSnapWallet.version) !== null && _a !== void 0 ? _a : '0.0.0';
83
+ },
84
+ };
85
+ return metaMaskProviderWrapper;
86
+ };
87
+
88
+ export { createMetaMaskProviderWrapper };
@@ -0,0 +1,121 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../_virtual/_tslib.cjs');
7
+ var utils = require('@dynamic-labs/utils');
8
+ var logger$1 = require('@dynamic-labs/logger');
9
+ var starknetWalletConnector = require('../starknetWalletConnector.cjs');
10
+ var starknetSnap = require('../utils/starknetSnap.cjs');
11
+
12
+ const logger = new logger$1.Logger('MetaMask Starknet Snap', logger$1.LogLevel.INFO);
13
+ class MetaMask extends starknetWalletConnector["default"] {
14
+ constructor(opts) {
15
+ super('MetaMask Starknet', 'metamask_snap', opts);
16
+ this.overrideKey = 'metamaskstarknet';
17
+ const { providers } = utils.Eip6963ProviderSingleton.get();
18
+ const metamaskProvider = providers.find((p) => ['io.metamask', 'io.metamask.flask'].includes(p.info.rdns));
19
+ if (metamaskProvider) {
20
+ this.provider = metamaskProvider.provider;
21
+ }
22
+ if (!window.starknet_metamask_snap && metamaskProvider) {
23
+ window.starknet_metamask_snap = starknetSnap.createMetaMaskProviderWrapper(metamaskProvider.provider);
24
+ }
25
+ }
26
+ getNetwork() {
27
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
28
+ if (!this.provider) {
29
+ logger.error('[getNetwork] - No provider found, returning undefined');
30
+ return undefined;
31
+ }
32
+ try {
33
+ logger.info('[getNetwork] - trying to fetch network using provider');
34
+ // we are using this method to get the network so that we always "see" the absolute
35
+ // active network in the companion site. when using the snap wrapper to get the network,
36
+ // we don't "see" the actual active network in the companion site – instead we see the
37
+ // network that was active at the time of the snap initialization
38
+ const result = yield this.provider.request({
39
+ method: 'wallet_invokeSnap',
40
+ params: {
41
+ request: {
42
+ method: 'starkNet_getCurrentNetwork',
43
+ params: {},
44
+ },
45
+ snapId: 'npm:@consensys/starknet-snap',
46
+ },
47
+ });
48
+ if (!('chainId' in result) || typeof result.chainId !== 'string') {
49
+ logger.error(`[getNetwork] - result.chainId should be a string, but got: ${
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ result.chainId}`);
52
+ return undefined;
53
+ }
54
+ if (result.chainId !== this.currentChainId) {
55
+ const resultChainName = this.mapChainIdToNetworkName(result.chainId);
56
+ const currentChainName = this.currentChainId
57
+ ? this.mapChainIdToNetworkName(this.currentChainId)
58
+ : undefined;
59
+ logger.info(`[getNetwork] - emitting chainChange event. got chainId: ${result.chainId} (${resultChainName}). current chainId: ${this.currentChainId} (${currentChainName})`);
60
+ this.emit('chainChange', { chain: result.chainId });
61
+ }
62
+ this.currentChainId = result.chainId;
63
+ return this.currentChainId;
64
+ }
65
+ catch (e) {
66
+ logger.error('[getNetwork] - network fetch request failed, returning undefined', e);
67
+ return undefined;
68
+ }
69
+ });
70
+ }
71
+ setupEventListeners() {
72
+ if (this.intervalId) {
73
+ return;
74
+ }
75
+ this.intervalId = setInterval(() => {
76
+ this.getNetwork().then((chainId) => {
77
+ if (!chainId) {
78
+ return;
79
+ }
80
+ const resultChainName = this.mapChainIdToNetworkName(chainId);
81
+ const currentChainName = this.currentChainId
82
+ ? this.mapChainIdToNetworkName(this.currentChainId)
83
+ : undefined;
84
+ logger.info(`[setupEventListeners] - got network: ${chainId} (${resultChainName}). current network: ${this.currentChainId} (${currentChainName})`);
85
+ if (chainId !== this.currentChainId) {
86
+ logger.info(`[setupEventListeners] - emitting chainChange event: ${chainId}`);
87
+ this.emit('chainChange', { chain: chainId });
88
+ this.currentChainId = chainId;
89
+ }
90
+ });
91
+ }, 5000);
92
+ }
93
+ teardownEventListeners() {
94
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
95
+ clearInterval(this.intervalId);
96
+ this.intervalId = undefined;
97
+ });
98
+ }
99
+ endSession() {
100
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
101
+ this.teardownEventListeners();
102
+ });
103
+ }
104
+ getConnectedAccounts() {
105
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
106
+ const wallet = this.getWallet();
107
+ if (!wallet) {
108
+ return [];
109
+ }
110
+ const isProviderConnected = this.isProviderConnected();
111
+ const isPreauthorized = yield wallet.isPreauthorized();
112
+ const shouldReconnect = !isProviderConnected && isPreauthorized;
113
+ if (shouldReconnect) {
114
+ yield this.connect();
115
+ }
116
+ return wallet.selectedAddress ? [wallet.selectedAddress] : [];
117
+ });
118
+ }
119
+ }
120
+
121
+ exports.MetaMask = MetaMask;
@@ -0,0 +1,14 @@
1
+ import { type WalletConnector } from '@dynamic-labs/wallet-connector-core';
2
+ import StarknetProvider from '../starknetWalletConnector';
3
+ export declare class MetaMask extends StarknetProvider implements WalletConnector {
4
+ overrideKey: string;
5
+ private currentChainId;
6
+ private intervalId;
7
+ private provider;
8
+ constructor(opts: any);
9
+ getNetwork(): Promise<string | undefined>;
10
+ setupEventListeners(): void;
11
+ teardownEventListeners(): Promise<void>;
12
+ endSession(): Promise<void>;
13
+ getConnectedAccounts(): Promise<string[]>;
14
+ }
@@ -0,0 +1,117 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../_virtual/_tslib.js';
3
+ import { Eip6963ProviderSingleton } from '@dynamic-labs/utils';
4
+ import { Logger, LogLevel } from '@dynamic-labs/logger';
5
+ import StarknetWalletConnector from '../starknetWalletConnector.js';
6
+ import { createMetaMaskProviderWrapper } from '../utils/starknetSnap.js';
7
+
8
+ const logger = new Logger('MetaMask Starknet Snap', LogLevel.INFO);
9
+ class MetaMask extends StarknetWalletConnector {
10
+ constructor(opts) {
11
+ super('MetaMask Starknet', 'metamask_snap', opts);
12
+ this.overrideKey = 'metamaskstarknet';
13
+ const { providers } = Eip6963ProviderSingleton.get();
14
+ const metamaskProvider = providers.find((p) => ['io.metamask', 'io.metamask.flask'].includes(p.info.rdns));
15
+ if (metamaskProvider) {
16
+ this.provider = metamaskProvider.provider;
17
+ }
18
+ if (!window.starknet_metamask_snap && metamaskProvider) {
19
+ window.starknet_metamask_snap = createMetaMaskProviderWrapper(metamaskProvider.provider);
20
+ }
21
+ }
22
+ getNetwork() {
23
+ return __awaiter(this, void 0, void 0, function* () {
24
+ if (!this.provider) {
25
+ logger.error('[getNetwork] - No provider found, returning undefined');
26
+ return undefined;
27
+ }
28
+ try {
29
+ logger.info('[getNetwork] - trying to fetch network using provider');
30
+ // we are using this method to get the network so that we always "see" the absolute
31
+ // active network in the companion site. when using the snap wrapper to get the network,
32
+ // we don't "see" the actual active network in the companion site – instead we see the
33
+ // network that was active at the time of the snap initialization
34
+ const result = yield this.provider.request({
35
+ method: 'wallet_invokeSnap',
36
+ params: {
37
+ request: {
38
+ method: 'starkNet_getCurrentNetwork',
39
+ params: {},
40
+ },
41
+ snapId: 'npm:@consensys/starknet-snap',
42
+ },
43
+ });
44
+ if (!('chainId' in result) || typeof result.chainId !== 'string') {
45
+ logger.error(`[getNetwork] - result.chainId should be a string, but got: ${
46
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
47
+ result.chainId}`);
48
+ return undefined;
49
+ }
50
+ if (result.chainId !== this.currentChainId) {
51
+ const resultChainName = this.mapChainIdToNetworkName(result.chainId);
52
+ const currentChainName = this.currentChainId
53
+ ? this.mapChainIdToNetworkName(this.currentChainId)
54
+ : undefined;
55
+ logger.info(`[getNetwork] - emitting chainChange event. got chainId: ${result.chainId} (${resultChainName}). current chainId: ${this.currentChainId} (${currentChainName})`);
56
+ this.emit('chainChange', { chain: result.chainId });
57
+ }
58
+ this.currentChainId = result.chainId;
59
+ return this.currentChainId;
60
+ }
61
+ catch (e) {
62
+ logger.error('[getNetwork] - network fetch request failed, returning undefined', e);
63
+ return undefined;
64
+ }
65
+ });
66
+ }
67
+ setupEventListeners() {
68
+ if (this.intervalId) {
69
+ return;
70
+ }
71
+ this.intervalId = setInterval(() => {
72
+ this.getNetwork().then((chainId) => {
73
+ if (!chainId) {
74
+ return;
75
+ }
76
+ const resultChainName = this.mapChainIdToNetworkName(chainId);
77
+ const currentChainName = this.currentChainId
78
+ ? this.mapChainIdToNetworkName(this.currentChainId)
79
+ : undefined;
80
+ logger.info(`[setupEventListeners] - got network: ${chainId} (${resultChainName}). current network: ${this.currentChainId} (${currentChainName})`);
81
+ if (chainId !== this.currentChainId) {
82
+ logger.info(`[setupEventListeners] - emitting chainChange event: ${chainId}`);
83
+ this.emit('chainChange', { chain: chainId });
84
+ this.currentChainId = chainId;
85
+ }
86
+ });
87
+ }, 5000);
88
+ }
89
+ teardownEventListeners() {
90
+ return __awaiter(this, void 0, void 0, function* () {
91
+ clearInterval(this.intervalId);
92
+ this.intervalId = undefined;
93
+ });
94
+ }
95
+ endSession() {
96
+ return __awaiter(this, void 0, void 0, function* () {
97
+ this.teardownEventListeners();
98
+ });
99
+ }
100
+ getConnectedAccounts() {
101
+ return __awaiter(this, void 0, void 0, function* () {
102
+ const wallet = this.getWallet();
103
+ if (!wallet) {
104
+ return [];
105
+ }
106
+ const isProviderConnected = this.isProviderConnected();
107
+ const isPreauthorized = yield wallet.isPreauthorized();
108
+ const shouldReconnect = !isProviderConnected && isPreauthorized;
109
+ if (shouldReconnect) {
110
+ yield this.connect();
111
+ }
112
+ return wallet.selectedAddress ? [wallet.selectedAddress] : [];
113
+ });
114
+ }
115
+ }
116
+
117
+ export { MetaMask };