@dynamic-labs/sui 4.9.9 → 4.9.11

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,18 @@
1
1
 
2
+ ### [4.9.11](https://github.com/dynamic-labs/dynamic-auth/compare/v4.9.10...v4.9.11) (2025-03-26)
3
+
4
+
5
+ ### Bug Fixes
6
+
7
+ * ensure global wallet users can disconnect from dapp ([#8389](https://github.com/dynamic-labs/dynamic-auth/issues/8389)) ([79e5892](https://github.com/dynamic-labs/dynamic-auth/commit/79e58921de673757dc0662977ed4eb391aaaf632))
8
+
9
+ ### [4.9.10](https://github.com/dynamic-labs/dynamic-auth/compare/v4.9.9...v4.9.10) (2025-03-26)
10
+
11
+
12
+ ### Bug Fixes
13
+
14
+ * auto select primary wallet when embedded wallets are disabled ([#8374](https://github.com/dynamic-labs/dynamic-auth/issues/8374)) ([780f3f1](https://github.com/dynamic-labs/dynamic-auth/commit/780f3f16ebd06dd8bc41fa85e8b4393c906989e2))
15
+
2
16
  ### [4.9.9](https://github.com/dynamic-labs/dynamic-auth/compare/v4.9.8...v4.9.9) (2025-03-26)
3
17
 
4
18
 
package/package.cjs CHANGED
@@ -3,6 +3,6 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
- var version = "4.9.9";
6
+ var version = "4.9.11";
7
7
 
8
8
  exports.version = version;
package/package.js CHANGED
@@ -1,4 +1,4 @@
1
1
  'use client'
2
- var version = "4.9.9";
2
+ var version = "4.9.11";
3
3
 
4
4
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dynamic-labs/sui",
3
- "version": "4.9.9",
3
+ "version": "4.9.11",
4
4
  "description": "A React SDK for implementing wallet web3 authentication and authorization to your website.",
5
5
  "author": "Dynamic Labs, Inc.",
6
6
  "license": "MIT",
@@ -20,14 +20,15 @@
20
20
  "dependencies": {
21
21
  "@dynamic-labs/sdk-api-core": "0.0.644",
22
22
  "@mysten/wallet-standard": "0.13.29",
23
+ "@mysten/sui": "1.24.0",
23
24
  "text-encoding": "0.7.0",
24
- "@dynamic-labs/assert-package-version": "4.9.9",
25
- "@dynamic-labs/logger": "4.9.9",
26
- "@dynamic-labs/rpc-providers": "4.9.9",
27
- "@dynamic-labs/types": "4.9.9",
28
- "@dynamic-labs/utils": "4.9.9",
29
- "@dynamic-labs/wallet-book": "4.9.9",
30
- "@dynamic-labs/wallet-connector-core": "4.9.9"
25
+ "@dynamic-labs/assert-package-version": "4.9.11",
26
+ "@dynamic-labs/logger": "4.9.11",
27
+ "@dynamic-labs/rpc-providers": "4.9.11",
28
+ "@dynamic-labs/types": "4.9.11",
29
+ "@dynamic-labs/utils": "4.9.11",
30
+ "@dynamic-labs/wallet-book": "4.9.11",
31
+ "@dynamic-labs/wallet-connector-core": "4.9.11"
31
32
  },
32
33
  "peerDependencies": {}
33
34
  }
@@ -4,6 +4,7 @@
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
6
  var _tslib = require('../_virtual/_tslib.cjs');
7
+ var client = require('@mysten/sui/client');
7
8
  var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
8
9
  var utils = require('@dynamic-labs/utils');
9
10
  var logger = require('@dynamic-labs/logger');
@@ -20,6 +21,8 @@ class SuiWalletConnector extends walletConnectorCore.WalletConnectorBase {
20
21
  this.switchNetworkOnlyFromWallet = true;
21
22
  /** required for metamask snap integration as MM snaps don't have event listeners */
22
23
  this.canSetEventListeners = true;
24
+ /** Sui clients */
25
+ this.suiClients = {};
23
26
  this.name = name;
24
27
  this.wallet = opts.wallet;
25
28
  this.chainRpcProviders = opts.chainRpcProviders;
@@ -34,7 +37,7 @@ class SuiWalletConnector extends walletConnectorCore.WalletConnectorBase {
34
37
  /** Connect to the wallet using the standard:connect feature */
35
38
  connect() {
36
39
  return _tslib.__awaiter(this, void 0, void 0, function* () {
37
- var _a;
40
+ var _a, _b;
38
41
  if (this.account) {
39
42
  // Account is already connected
40
43
  return;
@@ -48,6 +51,10 @@ class SuiWalletConnector extends walletConnectorCore.WalletConnectorBase {
48
51
  const response = yield connectFeature.connect();
49
52
  this.logger.debug(`[connect] Connection returned accounts: ${response === null || response === void 0 ? void 0 : response.accounts.length}`);
50
53
  this.account = response === null || response === void 0 ? void 0 : response.accounts[0];
54
+ const primaryChain = (_b = this.account) === null || _b === void 0 ? void 0 : _b.chains[0];
55
+ if (primaryChain) {
56
+ this.activeNetworkId = networkHelpers.getSuiNetworkIdFromName(primaryChain, this.suiNetworks);
57
+ }
51
58
  }
52
59
  catch (error) {
53
60
  this.logger.error(error);
@@ -70,14 +77,10 @@ class SuiWalletConnector extends walletConnectorCore.WalletConnectorBase {
70
77
  /** Returns the network id of the account's active chain */
71
78
  getNetwork() {
72
79
  return _tslib.__awaiter(this, void 0, void 0, function* () {
73
- var _a, _b;
74
80
  if (!this.account) {
75
81
  yield this.connect();
76
82
  }
77
- if (!((_b = (_a = this.account) === null || _a === void 0 ? void 0 : _a.chains) === null || _b === void 0 ? void 0 : _b[0])) {
78
- return undefined;
79
- }
80
- return networkHelpers.getSuiNetworkIdFromName(this.account.chains[0], this.suiNetworks);
83
+ return this.activeNetworkId;
81
84
  });
82
85
  }
83
86
  getConnectedAccounts() {
@@ -112,7 +115,8 @@ class SuiWalletConnector extends walletConnectorCore.WalletConnectorBase {
112
115
  if (primaryAccount.chains && primaryAccount.chains.length > 0) {
113
116
  const [primaryChain] = primaryAccount.chains;
114
117
  const suiChainId = networkHelpers.getSuiNetworkIdFromName(primaryChain, this.suiNetworks);
115
- if (suiChainId) {
118
+ if (suiChainId && suiChainId !== this.activeNetworkId) {
119
+ this.activeNetworkId = suiChainId;
116
120
  this.emit('chainChange', {
117
121
  chain: suiChainId,
118
122
  });
@@ -122,10 +126,51 @@ class SuiWalletConnector extends walletConnectorCore.WalletConnectorBase {
122
126
  this.logger.debug('[setupEventListeners] Setting up sui wallet connector event listeners');
123
127
  eventsFeature.on('change', this.eventsHandler);
124
128
  }
129
+ /**
130
+ * Helper to get the Sui client for the current network
131
+ *
132
+ * The client will prefer the private customer rpc url if available.
133
+ */
134
+ getSuiClient(networkId) {
135
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
136
+ const clientNetworkId = networkId !== null && networkId !== void 0 ? networkId : (yield this.getNetwork());
137
+ if (!clientNetworkId) {
138
+ this.logger.error('[getSuiClient] Failed to get network id');
139
+ return undefined;
140
+ }
141
+ // Default to an existing client if available
142
+ if (this.suiClients[clientNetworkId]) {
143
+ return this.suiClients[clientNetworkId];
144
+ }
145
+ const network = this.getEnabledNetworks().find((network) => network.networkId === clientNetworkId);
146
+ const url = network ? networkHelpers.getPreferredRpcUrl(network) : undefined;
147
+ if (!url) {
148
+ this.logger.error('[getSuiClient] Failed to get network url');
149
+ return undefined;
150
+ }
151
+ this.suiClients[clientNetworkId] = new client.SuiClient({
152
+ url: url,
153
+ });
154
+ return this.suiClients[clientNetworkId];
155
+ });
156
+ }
125
157
  getBalance(address) {
126
158
  return _tslib.__awaiter(this, void 0, void 0, function* () {
127
- // Make RPC call to get balance
128
- return address;
159
+ const client = yield this.getSuiClient();
160
+ if (!client) {
161
+ this.logger.error('[getBalance] Failed to get Sui client');
162
+ return undefined;
163
+ }
164
+ const balanceResult = yield client.getBalance({
165
+ owner: address,
166
+ });
167
+ // Balance comes back as MIST, 1 SUI = 1e9 MIST
168
+ const balance = Number(balanceResult === null || balanceResult === void 0 ? void 0 : balanceResult.totalBalance) / 1e9;
169
+ if (Number.isNaN(balance)) {
170
+ this.logger.error(`[getBalance] Failed to get balance for address: ${address}`);
171
+ return undefined;
172
+ }
173
+ return balance.toFixed(6);
129
174
  });
130
175
  }
131
176
  signMessage(messageToSign) {
@@ -1,4 +1,5 @@
1
1
  import { SuiWalletFeatures, WalletAccount, WalletWithFeatures } from '@mysten/wallet-standard';
2
+ import { SuiClient } from '@mysten/sui/client';
2
3
  import { Chain, WalletConnectorBase } from '@dynamic-labs/wallet-connector-core';
3
4
  import { Logger } from '@dynamic-labs/logger';
4
5
  import { GenericNetwork } from '@dynamic-labs/types';
@@ -17,6 +18,15 @@ export declare abstract class SuiWalletConnector extends WalletConnectorBase<typ
17
18
  wallet: WalletWithFeatures<SuiWalletFeatures> | undefined;
18
19
  /** Tracks the active wallet account */
19
20
  protected account: WalletAccount | undefined;
21
+ /**
22
+ * Tracks the active network id
23
+ *
24
+ * This is needed because the account's network order doesn't update after a
25
+ * network change event.
26
+ */
27
+ protected activeNetworkId: string | undefined;
28
+ /** Sui clients */
29
+ suiClients: Record<string, SuiClient>;
20
30
  /** Enabled SUI networks */
21
31
  suiNetworks: GenericNetwork[];
22
32
  /** Dynamic logger */
@@ -32,6 +42,12 @@ export declare abstract class SuiWalletConnector extends WalletConnectorBase<typ
32
42
  getNetwork(): Promise<string | undefined>;
33
43
  getConnectedAccounts(): Promise<string[]>;
34
44
  setupEventListeners(): void;
45
+ /**
46
+ * Helper to get the Sui client for the current network
47
+ *
48
+ * The client will prefer the private customer rpc url if available.
49
+ */
50
+ getSuiClient(networkId?: string): Promise<SuiClient | undefined>;
35
51
  getBalance(address: string): Promise<string | undefined>;
36
52
  signMessage(messageToSign: string): Promise<string | undefined>;
37
53
  getWalletAccount(): Promise<WalletAccount | undefined>;
@@ -1,10 +1,11 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../_virtual/_tslib.js';
3
+ import { SuiClient } from '@mysten/sui/client';
3
4
  import { WalletConnectorBase } from '@dynamic-labs/wallet-connector-core';
4
5
  import { DynamicError } from '@dynamic-labs/utils';
5
6
  import { Logger } from '@dynamic-labs/logger';
6
7
  import { SuiWallet } from './wallet/SuiWallet.js';
7
- import { getSuiNetworkIdFromName } from './utils/network/networkHelpers.js';
8
+ import { getSuiNetworkIdFromName, getPreferredRpcUrl } from './utils/network/networkHelpers.js';
8
9
 
9
10
  class SuiWalletConnector extends WalletConnectorBase {
10
11
  constructor(name, opts) {
@@ -16,6 +17,8 @@ class SuiWalletConnector extends WalletConnectorBase {
16
17
  this.switchNetworkOnlyFromWallet = true;
17
18
  /** required for metamask snap integration as MM snaps don't have event listeners */
18
19
  this.canSetEventListeners = true;
20
+ /** Sui clients */
21
+ this.suiClients = {};
19
22
  this.name = name;
20
23
  this.wallet = opts.wallet;
21
24
  this.chainRpcProviders = opts.chainRpcProviders;
@@ -30,7 +33,7 @@ class SuiWalletConnector extends WalletConnectorBase {
30
33
  /** Connect to the wallet using the standard:connect feature */
31
34
  connect() {
32
35
  return __awaiter(this, void 0, void 0, function* () {
33
- var _a;
36
+ var _a, _b;
34
37
  if (this.account) {
35
38
  // Account is already connected
36
39
  return;
@@ -44,6 +47,10 @@ class SuiWalletConnector extends WalletConnectorBase {
44
47
  const response = yield connectFeature.connect();
45
48
  this.logger.debug(`[connect] Connection returned accounts: ${response === null || response === void 0 ? void 0 : response.accounts.length}`);
46
49
  this.account = response === null || response === void 0 ? void 0 : response.accounts[0];
50
+ const primaryChain = (_b = this.account) === null || _b === void 0 ? void 0 : _b.chains[0];
51
+ if (primaryChain) {
52
+ this.activeNetworkId = getSuiNetworkIdFromName(primaryChain, this.suiNetworks);
53
+ }
47
54
  }
48
55
  catch (error) {
49
56
  this.logger.error(error);
@@ -66,14 +73,10 @@ class SuiWalletConnector extends WalletConnectorBase {
66
73
  /** Returns the network id of the account's active chain */
67
74
  getNetwork() {
68
75
  return __awaiter(this, void 0, void 0, function* () {
69
- var _a, _b;
70
76
  if (!this.account) {
71
77
  yield this.connect();
72
78
  }
73
- if (!((_b = (_a = this.account) === null || _a === void 0 ? void 0 : _a.chains) === null || _b === void 0 ? void 0 : _b[0])) {
74
- return undefined;
75
- }
76
- return getSuiNetworkIdFromName(this.account.chains[0], this.suiNetworks);
79
+ return this.activeNetworkId;
77
80
  });
78
81
  }
79
82
  getConnectedAccounts() {
@@ -108,7 +111,8 @@ class SuiWalletConnector extends WalletConnectorBase {
108
111
  if (primaryAccount.chains && primaryAccount.chains.length > 0) {
109
112
  const [primaryChain] = primaryAccount.chains;
110
113
  const suiChainId = getSuiNetworkIdFromName(primaryChain, this.suiNetworks);
111
- if (suiChainId) {
114
+ if (suiChainId && suiChainId !== this.activeNetworkId) {
115
+ this.activeNetworkId = suiChainId;
112
116
  this.emit('chainChange', {
113
117
  chain: suiChainId,
114
118
  });
@@ -118,10 +122,51 @@ class SuiWalletConnector extends WalletConnectorBase {
118
122
  this.logger.debug('[setupEventListeners] Setting up sui wallet connector event listeners');
119
123
  eventsFeature.on('change', this.eventsHandler);
120
124
  }
125
+ /**
126
+ * Helper to get the Sui client for the current network
127
+ *
128
+ * The client will prefer the private customer rpc url if available.
129
+ */
130
+ getSuiClient(networkId) {
131
+ return __awaiter(this, void 0, void 0, function* () {
132
+ const clientNetworkId = networkId !== null && networkId !== void 0 ? networkId : (yield this.getNetwork());
133
+ if (!clientNetworkId) {
134
+ this.logger.error('[getSuiClient] Failed to get network id');
135
+ return undefined;
136
+ }
137
+ // Default to an existing client if available
138
+ if (this.suiClients[clientNetworkId]) {
139
+ return this.suiClients[clientNetworkId];
140
+ }
141
+ const network = this.getEnabledNetworks().find((network) => network.networkId === clientNetworkId);
142
+ const url = network ? getPreferredRpcUrl(network) : undefined;
143
+ if (!url) {
144
+ this.logger.error('[getSuiClient] Failed to get network url');
145
+ return undefined;
146
+ }
147
+ this.suiClients[clientNetworkId] = new SuiClient({
148
+ url: url,
149
+ });
150
+ return this.suiClients[clientNetworkId];
151
+ });
152
+ }
121
153
  getBalance(address) {
122
154
  return __awaiter(this, void 0, void 0, function* () {
123
- // Make RPC call to get balance
124
- return address;
155
+ const client = yield this.getSuiClient();
156
+ if (!client) {
157
+ this.logger.error('[getBalance] Failed to get Sui client');
158
+ return undefined;
159
+ }
160
+ const balanceResult = yield client.getBalance({
161
+ owner: address,
162
+ });
163
+ // Balance comes back as MIST, 1 SUI = 1e9 MIST
164
+ const balance = Number(balanceResult === null || balanceResult === void 0 ? void 0 : balanceResult.totalBalance) / 1e9;
165
+ if (Number.isNaN(balance)) {
166
+ this.logger.error(`[getBalance] Failed to get balance for address: ${address}`);
167
+ return undefined;
168
+ }
169
+ return balance.toFixed(6);
125
170
  });
126
171
  }
127
172
  signMessage(messageToSign) {
@@ -3,6 +3,16 @@
3
3
 
4
4
  Object.defineProperty(exports, '__esModule', { value: true });
5
5
 
6
+ /**
7
+ * Get the Sui network id from the network name
8
+ *
9
+ * The Wallet Standard API returns Sui networks in the format `sui:mainnet`,
10
+ * so we need to map that to our network id.
11
+ *
12
+ * @param name - The network name
13
+ * @param networks - The list of networks
14
+ * @returns The Sui network id
15
+ */
6
16
  const getSuiNetworkIdFromName = (name, networks) => {
7
17
  var _a;
8
18
  const suiNetworkName = name.split(':').pop();
@@ -12,5 +22,13 @@ const getSuiNetworkIdFromName = (name, networks) => {
12
22
  const chainId = (_a = networks.find((network) => network.name.toLowerCase().includes(suiNetworkName.toLowerCase()))) === null || _a === void 0 ? void 0 : _a.chainId;
13
23
  return chainId ? String(chainId) : undefined;
14
24
  };
25
+ /**
26
+ * Get the preferred RPC URL for a given network
27
+ *
28
+ * @param network - The network
29
+ * @returns The preferred RPC URL
30
+ */
31
+ const getPreferredRpcUrl = (network) => { var _a, _b, _c; return (_b = (_a = network.privateCustomerRpcUrls) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : (_c = network.rpcUrls) === null || _c === void 0 ? void 0 : _c[0]; };
15
32
 
33
+ exports.getPreferredRpcUrl = getPreferredRpcUrl;
16
34
  exports.getSuiNetworkIdFromName = getSuiNetworkIdFromName;
@@ -1,2 +1,19 @@
1
1
  import { GenericNetwork } from '@dynamic-labs/types';
2
+ /**
3
+ * Get the Sui network id from the network name
4
+ *
5
+ * The Wallet Standard API returns Sui networks in the format `sui:mainnet`,
6
+ * so we need to map that to our network id.
7
+ *
8
+ * @param name - The network name
9
+ * @param networks - The list of networks
10
+ * @returns The Sui network id
11
+ */
2
12
  export declare const getSuiNetworkIdFromName: (name: string, networks: GenericNetwork[]) => string | undefined;
13
+ /**
14
+ * Get the preferred RPC URL for a given network
15
+ *
16
+ * @param network - The network
17
+ * @returns The preferred RPC URL
18
+ */
19
+ export declare const getPreferredRpcUrl: (network: GenericNetwork) => string;
@@ -1,4 +1,14 @@
1
1
  'use client'
2
+ /**
3
+ * Get the Sui network id from the network name
4
+ *
5
+ * The Wallet Standard API returns Sui networks in the format `sui:mainnet`,
6
+ * so we need to map that to our network id.
7
+ *
8
+ * @param name - The network name
9
+ * @param networks - The list of networks
10
+ * @returns The Sui network id
11
+ */
2
12
  const getSuiNetworkIdFromName = (name, networks) => {
3
13
  var _a;
4
14
  const suiNetworkName = name.split(':').pop();
@@ -8,5 +18,12 @@ const getSuiNetworkIdFromName = (name, networks) => {
8
18
  const chainId = (_a = networks.find((network) => network.name.toLowerCase().includes(suiNetworkName.toLowerCase()))) === null || _a === void 0 ? void 0 : _a.chainId;
9
19
  return chainId ? String(chainId) : undefined;
10
20
  };
21
+ /**
22
+ * Get the preferred RPC URL for a given network
23
+ *
24
+ * @param network - The network
25
+ * @returns The preferred RPC URL
26
+ */
27
+ const getPreferredRpcUrl = (network) => { var _a, _b, _c; return (_b = (_a = network.privateCustomerRpcUrls) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : (_c = network.rpcUrls) === null || _c === void 0 ? void 0 : _c[0]; };
11
28
 
12
- export { getSuiNetworkIdFromName };
29
+ export { getPreferredRpcUrl, getSuiNetworkIdFromName };