@reown/appkit-core-react-native 0.0.0-feat-multi-social-20250701154123 → 0.0.0-feat-multi-social-20250703185818

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.
Files changed (68) hide show
  1. package/lib/commonjs/controllers/AccountController.js +20 -17
  2. package/lib/commonjs/controllers/AccountController.js.map +1 -1
  3. package/lib/commonjs/controllers/BlockchainApiController.js +8 -4
  4. package/lib/commonjs/controllers/BlockchainApiController.js.map +1 -1
  5. package/lib/commonjs/controllers/ConnectionsController.js +209 -45
  6. package/lib/commonjs/controllers/ConnectionsController.js.map +1 -1
  7. package/lib/commonjs/controllers/ModalController.js +2 -2
  8. package/lib/commonjs/controllers/ModalController.js.map +1 -1
  9. package/lib/commonjs/controllers/RouterController.js.map +1 -1
  10. package/lib/commonjs/controllers/SendController.js +19 -13
  11. package/lib/commonjs/controllers/SendController.js.map +1 -1
  12. package/lib/commonjs/controllers/SwapController.js +6 -7
  13. package/lib/commonjs/controllers/SwapController.js.map +1 -1
  14. package/lib/commonjs/controllers/TransactionsController.js +19 -15
  15. package/lib/commonjs/controllers/TransactionsController.js.map +1 -1
  16. package/lib/commonjs/utils/CoreHelperUtil.js +1 -1
  17. package/lib/commonjs/utils/CoreHelperUtil.js.map +1 -1
  18. package/lib/commonjs/utils/SwapApiUtil.js +6 -9
  19. package/lib/commonjs/utils/SwapApiUtil.js.map +1 -1
  20. package/lib/module/controllers/AccountController.js +20 -17
  21. package/lib/module/controllers/AccountController.js.map +1 -1
  22. package/lib/module/controllers/BlockchainApiController.js +8 -4
  23. package/lib/module/controllers/BlockchainApiController.js.map +1 -1
  24. package/lib/module/controllers/ConnectionsController.js +209 -45
  25. package/lib/module/controllers/ConnectionsController.js.map +1 -1
  26. package/lib/module/controllers/ModalController.js +2 -2
  27. package/lib/module/controllers/ModalController.js.map +1 -1
  28. package/lib/module/controllers/RouterController.js.map +1 -1
  29. package/lib/module/controllers/SendController.js +19 -13
  30. package/lib/module/controllers/SendController.js.map +1 -1
  31. package/lib/module/controllers/SwapController.js +6 -7
  32. package/lib/module/controllers/SwapController.js.map +1 -1
  33. package/lib/module/controllers/TransactionsController.js +19 -15
  34. package/lib/module/controllers/TransactionsController.js.map +1 -1
  35. package/lib/module/utils/CoreHelperUtil.js +1 -1
  36. package/lib/module/utils/CoreHelperUtil.js.map +1 -1
  37. package/lib/module/utils/SwapApiUtil.js +6 -9
  38. package/lib/module/utils/SwapApiUtil.js.map +1 -1
  39. package/lib/typescript/controllers/AccountController.d.ts +3 -3
  40. package/lib/typescript/controllers/AccountController.d.ts.map +1 -1
  41. package/lib/typescript/controllers/BlockchainApiController.d.ts +2 -2
  42. package/lib/typescript/controllers/BlockchainApiController.d.ts.map +1 -1
  43. package/lib/typescript/controllers/ConnectionsController.d.ts +16 -9
  44. package/lib/typescript/controllers/ConnectionsController.d.ts.map +1 -1
  45. package/lib/typescript/controllers/RouterController.d.ts +1 -1
  46. package/lib/typescript/controllers/RouterController.d.ts.map +1 -1
  47. package/lib/typescript/controllers/SendController.d.ts.map +1 -1
  48. package/lib/typescript/controllers/SwapController.d.ts +2 -1
  49. package/lib/typescript/controllers/SwapController.d.ts.map +1 -1
  50. package/lib/typescript/controllers/TransactionsController.d.ts +2 -2
  51. package/lib/typescript/controllers/TransactionsController.d.ts.map +1 -1
  52. package/lib/typescript/utils/SwapApiUtil.d.ts +2 -1
  53. package/lib/typescript/utils/SwapApiUtil.d.ts.map +1 -1
  54. package/lib/typescript/utils/TypeUtil.d.ts +16 -12
  55. package/lib/typescript/utils/TypeUtil.d.ts.map +1 -1
  56. package/package.json +2 -2
  57. package/src/controllers/AccountController.ts +26 -26
  58. package/src/controllers/BlockchainApiController.ts +11 -5
  59. package/src/controllers/ConnectionController.ts +1 -1
  60. package/src/controllers/ConnectionsController.ts +244 -65
  61. package/src/controllers/ModalController.ts +2 -2
  62. package/src/controllers/RouterController.ts +0 -3
  63. package/src/controllers/SendController.ts +31 -13
  64. package/src/controllers/SwapController.ts +10 -8
  65. package/src/controllers/TransactionsController.ts +22 -16
  66. package/src/utils/CoreHelperUtil.ts +1 -1
  67. package/src/utils/SwapApiUtil.ts +6 -15
  68. package/src/utils/TypeUtil.ts +15 -17
@@ -7,21 +7,27 @@ import {
7
7
  type CaipAddress,
8
8
  type CaipNetworkId,
9
9
  type ChainNamespace,
10
- type GetBalanceResponse,
11
- type WalletInfo
10
+ type Balance,
11
+ type WalletInfo,
12
+ type ConnectionProperties,
13
+ type AccountType
12
14
  } from '@reown/appkit-common-react-native';
13
15
  import { StorageUtil } from '../utils/StorageUtil';
16
+ import { BlockchainApiController } from './BlockchainApiController';
17
+ import { SnackController } from './SnackController';
18
+ import { OptionsController } from './OptionsController';
14
19
 
15
20
  // -- Types --------------------------------------------- //
16
- type Balance = GetBalanceResponse;
17
21
 
18
22
  //TODO: balance could be elsewhere
19
23
  interface Connection {
20
24
  accounts: CaipAddress[];
21
- balances: Record<CaipAddress, Balance>; //TODO: make this an array of balances
25
+ balances: Map<CaipAddress, Balance[]>; // Changed to support multiple tokens per address
22
26
  adapter: BlockchainAdapter;
23
27
  caipNetwork: CaipNetworkId;
24
28
  wallet?: WalletInfo;
29
+ properties?: ConnectionProperties;
30
+ type?: AccountType;
25
31
  }
26
32
 
27
33
  export interface ConnectionsControllerState {
@@ -37,59 +43,115 @@ const baseState = proxy<ConnectionsControllerState>({
37
43
  networks: []
38
44
  });
39
45
 
46
+ // -- Helper Functions --------------------------------------------- //
47
+ const getActiveConnection = (snap: ConnectionsControllerState): Connection | undefined => {
48
+ if (!snap.activeNamespace) return undefined;
49
+
50
+ return snap.connections.get(snap.activeNamespace);
51
+ };
52
+
53
+ const hasValidAccounts = (connection: Connection): boolean => {
54
+ return connection?.accounts && connection.accounts.length > 0;
55
+ };
56
+
57
+ const findSmartAccountForNetwork = (connection: Connection): CaipAddress | undefined => {
58
+ return connection.properties?.smartAccounts?.find(account =>
59
+ account.startsWith(connection.caipNetwork)
60
+ );
61
+ };
62
+
63
+ const findEOAForNetwork = (connection: Connection): CaipAddress | undefined => {
64
+ const smartAccounts = connection.properties?.smartAccounts || [];
65
+
66
+ return connection.accounts.find(
67
+ account => account.startsWith(connection.caipNetwork) && !smartAccounts.includes(account)
68
+ );
69
+ };
70
+
71
+ const getActiveAddress = (connection: Connection): CaipAddress | undefined => {
72
+ if (!hasValidAccounts(connection)) {
73
+ return undefined;
74
+ }
75
+
76
+ // For smart accounts, prioritize smart account addresses
77
+ if (connection.type === 'smartAccount') {
78
+ const smartAccount = findSmartAccountForNetwork(connection);
79
+ if (smartAccount) {
80
+ return smartAccount;
81
+ }
82
+ }
83
+
84
+ // Fall back to EOA or any account that matches the network
85
+ return findEOAForNetwork(connection);
86
+ };
87
+
88
+ const updateConnection = (namespace: ChainNamespace, updates: Partial<Connection>) => {
89
+ const connection = baseState.connections.get(namespace);
90
+ if (!connection) return;
91
+ const newConnectionsMap = new Map(baseState.connections);
92
+ newConnectionsMap.set(namespace, { ...connection, ...updates });
93
+ baseState.connections = newConnectionsMap;
94
+ };
95
+
40
96
  const derivedState = derive(
41
97
  {
42
98
  activeAddress: (get): CaipAddress | undefined => {
43
99
  const snap = get(baseState);
100
+ const connection = getActiveConnection(snap);
101
+
102
+ return connection ? getActiveAddress(connection) : undefined;
103
+ },
104
+ activeBalance: (get): Balance | undefined => {
105
+ const snap = get(baseState);
106
+ const connection = getActiveConnection(snap);
44
107
 
45
- if (!snap.activeNamespace) {
108
+ if (!connection) {
46
109
  return undefined;
47
110
  }
48
111
 
49
- const connection = snap.connections.get(snap.activeNamespace);
50
-
51
- if (!connection || !connection.accounts || connection.accounts.length === 0) {
112
+ const activeAddress = getActiveAddress(connection);
113
+ if (!activeAddress || !connection.balances || connection.balances.size === 0) {
52
114
  return undefined;
53
115
  }
54
116
 
55
- //TODO: what happens if there are several accounts on the same chain?
56
- const activeAccount = connection.accounts.find(account =>
57
- account.startsWith(connection.caipNetwork)
58
- );
59
-
60
- return activeAccount;
61
- },
62
- activeBalance: (get): Balance | undefined => {
63
- const snap = get(baseState);
64
-
65
- if (!snap.activeNamespace) return undefined;
66
- const connection = snap.connections.get(snap.activeNamespace);
67
-
68
- if (!connection || !connection.accounts || connection.accounts.length === 0) {
117
+ const addressBalances = connection.balances.get(activeAddress);
118
+ if (!addressBalances || addressBalances.length === 0) {
69
119
  return undefined;
70
120
  }
71
121
 
72
- const activeAccount = connection.accounts.find(account =>
73
- account.startsWith(connection.caipNetwork)
122
+ // Check if there's a specific token configured in OptionsController
123
+ const configuredTokens = OptionsController.state.tokens;
124
+ const activeNetwork = snap.networks.find(
125
+ network =>
126
+ network.chainNamespace === snap.activeNamespace &&
127
+ network.id?.toString() === connection.caipNetwork?.split(':')[1]
74
128
  );
75
129
 
76
- if (
77
- !connection ||
78
- !connection.balances ||
79
- !activeAccount ||
80
- Object.keys(connection.balances).length === 0
81
- ) {
82
- return undefined;
130
+ if (configuredTokens && activeNetwork) {
131
+ const configuredToken = configuredTokens[activeNetwork.caipNetworkId];
132
+ if (configuredToken) {
133
+ // Find the configured token in the balances
134
+ const specificToken = addressBalances.find(
135
+ balance => balance.contractAddress === configuredToken.address
136
+ );
137
+ if (specificToken) {
138
+ return specificToken;
139
+ }
140
+ }
141
+ }
142
+
143
+ // Return the native token (first balance without contractAddress)
144
+ const nativeToken = addressBalances.find(balance => !balance.contractAddress);
145
+ if (nativeToken) {
146
+ return nativeToken;
83
147
  }
84
148
 
85
- return connection.balances[activeAccount];
149
+ // Fallback to first available balance
150
+ return addressBalances[0];
86
151
  },
87
152
  activeNetwork: (get): AppKitNetwork | undefined => {
88
153
  const snap = get(baseState);
89
-
90
- if (!snap.activeNamespace) return undefined;
91
-
92
- const connection = snap.connections.get(snap.activeNamespace);
154
+ const connection = getActiveConnection(snap);
93
155
 
94
156
  if (!connection) return undefined;
95
157
 
@@ -101,21 +163,41 @@ const derivedState = derive(
101
163
  },
102
164
  activeCaipNetworkId: (get): CaipNetworkId | undefined => {
103
165
  const snap = get(baseState);
166
+ const connection = getActiveConnection(snap);
167
+
168
+ return connection?.caipNetwork;
169
+ },
170
+ accountType: (get): AccountType | undefined => {
171
+ const snap = get(baseState);
172
+ const connection = getActiveConnection(snap);
104
173
 
105
- if (!snap.activeNamespace) return undefined;
174
+ return connection?.type;
175
+ },
176
+ connection: (get): Connection | undefined => {
177
+ const snap = get(baseState);
106
178
 
107
- const connection = snap.connections.get(snap.activeNamespace);
179
+ return getActiveConnection(snap);
180
+ },
181
+ balances: (get): Balance[] | undefined => {
182
+ const snap = get(baseState);
108
183
 
109
- if (!connection) return undefined;
184
+ const _connection = getActiveConnection(snap);
110
185
 
111
- return connection.caipNetwork;
186
+ if (!_connection) {
187
+ return undefined;
188
+ }
189
+
190
+ const _activeAddress = getActiveAddress(_connection);
191
+
192
+ if (!_activeAddress) return [];
193
+
194
+ return _connection?.balances.get(_activeAddress);
112
195
  },
113
196
  walletInfo: (get): WalletInfo | undefined => {
114
197
  const snap = get(baseState);
198
+ const connection = getActiveConnection(snap);
115
199
 
116
- if (!snap.activeNamespace) return undefined;
117
-
118
- return snap.connections.get(snap.activeNamespace)?.wallet;
200
+ return connection?.wallet;
119
201
  }
120
202
  },
121
203
  {
@@ -132,28 +214,35 @@ export const ConnectionsController = {
132
214
  StorageUtil.setActiveNamespace(namespace);
133
215
  },
134
216
 
135
- storeConnection({
136
- namespace,
137
- adapter,
217
+ setConnection({
138
218
  accounts,
139
- chains,
140
- wallet,
141
- caipNetwork
219
+ adapter,
220
+ caipNetwork,
221
+ namespace,
222
+ properties,
223
+ wallet
142
224
  }: {
143
- namespace: ChainNamespace;
144
- adapter: BlockchainAdapter;
145
225
  accounts: CaipAddress[];
146
- chains: CaipNetworkId[];
226
+ adapter: BlockchainAdapter;
227
+ caipNetwork: CaipNetworkId;
228
+ namespace: ChainNamespace;
229
+ properties?: ConnectionProperties;
147
230
  wallet?: WalletInfo;
148
- caipNetwork?: CaipNetworkId;
149
231
  }) {
150
- const newConnectionEntry = {
151
- balances: {},
152
- caipNetwork: caipNetwork ?? chains[0]!,
232
+ const type: AccountType =
233
+ properties?.smartAccounts?.length &&
234
+ properties.smartAccounts.find(account => account.startsWith(caipNetwork))
235
+ ? 'smartAccount'
236
+ : 'eoa';
237
+
238
+ const newConnectionEntry: Connection = {
239
+ balances: new Map<CaipAddress, Balance[]>(),
240
+ caipNetwork,
153
241
  adapter: ref(adapter),
154
242
  accounts,
155
- chains,
156
- wallet
243
+ wallet,
244
+ properties,
245
+ type
157
246
  };
158
247
 
159
248
  // Create a new Map to ensure Valtio detects the change
@@ -177,14 +266,34 @@ export const ConnectionsController = {
177
266
  updateBalance(namespace: ChainNamespace, address: CaipAddress, balance: Balance) {
178
267
  const connection = baseState.connections.get(namespace);
179
268
  if (!connection) {
269
+ console.warn(`No connection found for namespace: ${namespace}`);
270
+
180
271
  return;
181
272
  }
273
+ const newBalances = new Map(connection.balances);
274
+ const existingBalances = connection.balances.get(address) || [];
275
+ // Check if this token already exists by contract address or symbol
276
+ const existingIndex = existingBalances.findIndex(existingBalance => {
277
+ if (balance.contractAddress) {
278
+ return existingBalance.contractAddress === balance.contractAddress;
279
+ }
182
280
 
183
- const newBalances = { ...connection.balances, [address]: balance };
184
- const updatedConnection = { ...connection, balances: newBalances };
185
- const newConnectionsMap = new Map(baseState.connections);
186
- newConnectionsMap.set(namespace, updatedConnection);
187
- baseState.connections = newConnectionsMap;
281
+ return existingBalance.symbol === balance.symbol;
282
+ });
283
+ let updatedBalances: Balance[];
284
+ if (existingIndex >= 0) {
285
+ // Update existing token
286
+ updatedBalances = [...existingBalances];
287
+ updatedBalances[existingIndex] = {
288
+ ...updatedBalances[existingIndex],
289
+ ...balance
290
+ };
291
+ } else {
292
+ // Add new token
293
+ updatedBalances = [...existingBalances, balance];
294
+ }
295
+ newBalances.set(address, updatedBalances);
296
+ updateConnection(namespace, { balances: newBalances });
188
297
  },
189
298
 
190
299
  setActiveNetwork(namespace: ChainNamespace, networkId: CaipNetworkId) {
@@ -213,6 +322,15 @@ export const ConnectionsController = {
213
322
  );
214
323
  },
215
324
 
325
+ setAccountType(namespace: ChainNamespace, type: AccountType) {
326
+ const connection = baseState.connections.get(namespace);
327
+ if (!connection) return;
328
+
329
+ const newConnectionsMap = new Map(baseState.connections);
330
+ newConnectionsMap.set(namespace, { ...connection, type });
331
+ baseState.connections = newConnectionsMap;
332
+ },
333
+
216
334
  async disconnect(namespace: ChainNamespace, isInternal = true) {
217
335
  const connection = baseState.connections.get(namespace);
218
336
  if (!connection) return;
@@ -287,7 +405,6 @@ export const ConnectionsController = {
287
405
  if (!baseState.activeNamespace) return undefined;
288
406
 
289
407
  const adapter = baseState.connections.get(baseState.activeNamespace)?.adapter;
290
-
291
408
  if (adapter instanceof EVMAdapter) {
292
409
  return adapter.sendTransaction(args);
293
410
  }
@@ -299,11 +416,73 @@ export const ConnectionsController = {
299
416
  if (!baseState.activeNamespace || baseState.activeNamespace !== 'eip155') return undefined;
300
417
 
301
418
  const adapter = baseState.connections.get(baseState.activeNamespace)?.adapter;
302
-
303
419
  if (adapter instanceof EVMAdapter) {
304
420
  return adapter.estimateGas(args);
305
421
  }
306
422
 
307
423
  return undefined;
424
+ },
425
+
426
+ async fetchBalance() {
427
+ const connection = getActiveConnection(baseState);
428
+ if (!connection) {
429
+ console.warn('No active connection found for balance fetch');
430
+
431
+ return;
432
+ }
433
+ const chainId = connection.caipNetwork;
434
+ const address = getActiveAddress(connection);
435
+ const namespace = baseState.activeNamespace;
436
+ if (!namespace || !address || !chainId) {
437
+ console.warn('Missing required data for balance fetch', { namespace, address, chainId });
438
+
439
+ return;
440
+ }
441
+
442
+ try {
443
+ const response = await BlockchainApiController.getBalance(address);
444
+ if (!response) {
445
+ throw new Error('Failed to fetch token balance');
446
+ }
447
+ // Update balances for each token in the response
448
+ response.balances.forEach(balance => {
449
+ this.updateBalance(namespace, address, {
450
+ name: balance.name,
451
+ symbol: balance.symbol,
452
+ amount: balance.quantity.numeric,
453
+ contractAddress: balance.address,
454
+ quantity: balance.quantity,
455
+ price: balance.price,
456
+ value: balance.value,
457
+ iconUrl: balance.iconUrl
458
+ });
459
+ });
460
+ } catch (error) {
461
+ SnackController.showError('Failed to get account balance');
462
+ }
463
+ },
464
+
465
+ getSmartAccountEnabledNetworks(): AppKitNetwork[] {
466
+ const activeConnection = getActiveConnection(baseState);
467
+ if (!activeConnection) {
468
+ return [];
469
+ }
470
+ if (!activeConnection.properties?.smartAccounts?.length) {
471
+ return [];
472
+ }
473
+ const smartAccountNetworks = new Set<CaipNetworkId>();
474
+ activeConnection.properties.smartAccounts.forEach(smartAccount => {
475
+ const parts = smartAccount.split(':');
476
+ if (parts.length >= 2) {
477
+ const networkId: CaipNetworkId = `${parts[0]}:${parts[1]}`;
478
+ smartAccountNetworks.add(networkId);
479
+ }
480
+ });
481
+
482
+ return baseState.networks.filter(network => {
483
+ const networkId: CaipNetworkId = `${network.chainNamespace}:${network.id}`;
484
+
485
+ return smartAccountNetworks.has(networkId);
486
+ });
308
487
  }
309
488
  };
@@ -5,7 +5,7 @@ import { RouterController } from './RouterController';
5
5
  import { PublicStateController } from './PublicStateController';
6
6
  import { EventsController } from './EventsController';
7
7
  import { ApiController } from './ApiController';
8
- import { ConnectorController } from './ConnectorController';
8
+ import { ConnectionsController } from './ConnectionsController';
9
9
 
10
10
  // -- Types --------------------------------------------- //
11
11
  export interface ModalControllerState {
@@ -35,7 +35,7 @@ export const ModalController = {
35
35
  if (options?.view) {
36
36
  RouterController.reset(options.view);
37
37
  } else if (AccountController.state.isConnected) {
38
- const isUniversalWallet = ConnectorController.state.connectedConnector === 'AUTH';
38
+ const isUniversalWallet = !!ConnectionsController.state.connection?.properties?.provider;
39
39
  RouterController.reset(isUniversalWallet ? 'Account' : 'AccountDefault');
40
40
  } else {
41
41
  RouterController.reset('Connect');
@@ -29,8 +29,6 @@ export interface RouterControllerState {
29
29
  | 'ConnectingSiwe'
30
30
  | 'ConnectingSocial'
31
31
  | 'ConnectingWalletConnect'
32
- | 'EmailVerifyDevice'
33
- | 'EmailVerifyOtp'
34
32
  | 'GetWallet'
35
33
  | 'Networks'
36
34
  | 'OnRamp'
@@ -48,7 +46,6 @@ export interface RouterControllerState {
48
46
  | 'UpdateEmailSecondaryOtp'
49
47
  | 'UpdateEmailWallet'
50
48
  | 'UpgradeEmailWallet'
51
- | 'UpgradeToSmartAccount'
52
49
  | 'WalletCompatibleNetworks'
53
50
  | 'WalletReceive'
54
51
  | 'WalletSend'
@@ -1,7 +1,7 @@
1
1
  import { subscribeKey as subKey } from 'valtio/vanilla/utils';
2
2
  import { proxy, ref, subscribe as sub } from 'valtio/vanilla';
3
3
  import { ContractUtil, type Balance } from '@reown/appkit-common-react-native';
4
- import { AccountController } from './AccountController';
4
+
5
5
  import { ConnectionController } from './ConnectionController';
6
6
  import { SnackController } from './SnackController';
7
7
  import { CoreHelperUtil } from '../utils/CoreHelperUtil';
@@ -91,36 +91,40 @@ export const SendController = {
91
91
  },
92
92
 
93
93
  sendToken() {
94
- if (this.state.token?.address && this.state.sendTokenAmount && this.state.receiverAddress) {
94
+ if (
95
+ this.state.token?.contractAddress &&
96
+ this.state.sendTokenAmount &&
97
+ this.state.receiverAddress
98
+ ) {
95
99
  state.loading = true;
96
100
  EventsController.sendEvent({
97
101
  type: 'track',
98
102
  event: 'SEND_INITIATED',
99
103
  properties: {
100
- isSmartAccount: AccountController.state.preferredAccountType === 'smartAccount',
101
- token: this.state.token.address,
104
+ isSmartAccount: ConnectionsController.state.accountType === 'smartAccount',
105
+ token: this.state.token.contractAddress,
102
106
  amount: this.state.sendTokenAmount,
103
107
  network: ConnectionsController.state.activeNetwork?.caipNetworkId || ''
104
108
  }
105
109
  });
106
110
  this.sendERC20Token({
107
111
  receiverAddress: this.state.receiverAddress,
108
- tokenAddress: this.state.token.address,
112
+ tokenAddress: this.state.token.contractAddress,
109
113
  sendTokenAmount: this.state.sendTokenAmount,
110
- decimals: this.state.token.quantity.decimals
114
+ decimals: this.state.token.quantity?.decimals || '0'
111
115
  });
112
116
  } else if (
113
117
  this.state.receiverAddress &&
114
118
  this.state.sendTokenAmount &&
115
119
  this.state.gasPrice &&
116
- this.state.token?.quantity.decimals
120
+ this.state.token?.quantity?.decimals
117
121
  ) {
118
122
  state.loading = true;
119
123
  EventsController.sendEvent({
120
124
  type: 'track',
121
125
  event: 'SEND_INITIATED',
122
126
  properties: {
123
- isSmartAccount: AccountController.state.preferredAccountType === 'smartAccount',
127
+ isSmartAccount: ConnectionsController.state.accountType === 'smartAccount',
124
128
  token: this.state.token?.symbol,
125
129
  amount: this.state.sendTokenAmount,
126
130
  network: ConnectionsController.state.activeNetwork?.caipNetworkId || ''
@@ -142,7 +146,13 @@ export const SendController = {
142
146
  });
143
147
 
144
148
  const to = params.receiverAddress as `0x${string}`;
145
- const address = AccountController.state.address as `0x${string}`;
149
+ const address = CoreHelperUtil.getPlainAddress(
150
+ ConnectionsController.state.activeAddress
151
+ ) as `0x${string}`;
152
+ if (!address) {
153
+ throw new Error('Invalid address');
154
+ }
155
+
146
156
  const value = ConnectionController.parseUnits(
147
157
  params.sendTokenAmount.toString(),
148
158
  Number(params.decimals)
@@ -162,7 +172,7 @@ export const SendController = {
162
172
  type: 'track',
163
173
  event: 'SEND_SUCCESS',
164
174
  properties: {
165
- isSmartAccount: AccountController.state.preferredAccountType === 'smartAccount',
175
+ isSmartAccount: ConnectionsController.state.accountType === 'smartAccount',
166
176
  token: this.state.token?.symbol || '',
167
177
  amount: params.sendTokenAmount,
168
178
  network: ConnectionsController.state.activeNetwork?.caipNetworkId || ''
@@ -175,7 +185,7 @@ export const SendController = {
175
185
  type: 'track',
176
186
  event: 'SEND_ERROR',
177
187
  properties: {
178
- isSmartAccount: AccountController.state.preferredAccountType === 'smartAccount',
188
+ isSmartAccount: ConnectionsController.state.accountType === 'smartAccount',
179
189
  token: this.state.token?.symbol || '',
180
190
  amount: params.sendTokenAmount,
181
191
  network: ConnectionsController.state.activeNetwork?.caipNetworkId || ''
@@ -198,7 +208,7 @@ export const SendController = {
198
208
 
199
209
  try {
200
210
  if (
201
- AccountController.state.address &&
211
+ ConnectionsController.state.activeAddress &&
202
212
  params.sendTokenAmount &&
203
213
  params.receiverAddress &&
204
214
  params.tokenAddress
@@ -206,8 +216,16 @@ export const SendController = {
206
216
  const tokenAddress = CoreHelperUtil.getPlainAddress(
207
217
  params.tokenAddress as `${string}:${string}:${string}`
208
218
  ) as `0x${string}`;
219
+
220
+ const fromAddress = CoreHelperUtil.getPlainAddress(
221
+ ConnectionsController.state.activeAddress
222
+ ) as `0x${string}`;
223
+ if (!fromAddress) {
224
+ throw new Error('Invalid address');
225
+ }
226
+
209
227
  await ConnectionController.writeContract({
210
- fromAddress: AccountController.state.address as `0x${string}`,
228
+ fromAddress,
211
229
  tokenAddress,
212
230
  receiverAddress: params.receiverAddress as `0x${string}`,
213
231
  tokenAmount: amount,
@@ -11,7 +11,6 @@ import { SnackController } from './SnackController';
11
11
  import { RouterController } from './RouterController';
12
12
  import type { SwapInputTarget, SwapTokenWithBalance } from '../utils/TypeUtil';
13
13
  import { ConnectorController } from './ConnectorController';
14
- import { AccountController } from './AccountController';
15
14
  import { CoreHelperUtil } from '../utils/CoreHelperUtil';
16
15
  import { TransactionsController } from './TransactionsController';
17
16
  import { EventsController } from './EventsController';
@@ -285,7 +284,7 @@ export const SwapController = {
285
284
  }, {});
286
285
  },
287
286
 
288
- async getMyTokensWithBalance(forceUpdate?: string) {
287
+ async getMyTokensWithBalance(forceUpdate?: CaipAddress[]) {
289
288
  const balances = await SwapApiUtil.getMyTokensWithBalance(forceUpdate);
290
289
  if (!balances) {
291
290
  return;
@@ -762,7 +761,10 @@ export const SwapController = {
762
761
  }
763
762
 
764
763
  try {
765
- const forceUpdateAddresses = [state.sourceToken?.address, state.toToken?.address].join(',');
764
+ const forceUpdateAddresses = [state.sourceToken?.address, state.toToken?.address].filter(
765
+ Boolean
766
+ ) as CaipAddress[];
767
+
766
768
  const transactionHash = await ConnectionsController.sendTransaction({
767
769
  address: fromAddress as `0x${string}`,
768
770
  to: data.to as `0x${string}`,
@@ -784,7 +786,7 @@ export const SwapController = {
784
786
  swapToToken: this.state.toToken?.symbol || '',
785
787
  swapFromAmount: this.state.sourceTokenAmount || '',
786
788
  swapToAmount: this.state.toTokenAmount || '',
787
- isSmartAccount: AccountController.state.preferredAccountType === 'smartAccount'
789
+ isSmartAccount: ConnectionsController.state.accountType === 'smartAccount'
788
790
  }
789
791
  });
790
792
  SwapController.resetState();
@@ -794,10 +796,10 @@ export const SwapController = {
794
796
  }
795
797
 
796
798
  SwapController.getMyTokensWithBalance(forceUpdateAddresses);
797
- AccountController.fetchTokenBalance();
799
+ ConnectionsController.fetchBalance();
798
800
 
799
801
  setTimeout(() => {
800
- TransactionsController.fetchTransactions(AccountController.state.address, true);
802
+ TransactionsController.fetchTransactions(ConnectionsController.state.activeAddress, true);
801
803
  }, 5000);
802
804
 
803
805
  return transactionHash;
@@ -816,7 +818,7 @@ export const SwapController = {
816
818
  swapToToken: this.state.toToken?.symbol || '',
817
819
  swapFromAmount: this.state.sourceTokenAmount || '',
818
820
  swapToAmount: this.state.toTokenAmount || '',
819
- isSmartAccount: AccountController.state.preferredAccountType === 'smartAccount'
821
+ isSmartAccount: ConnectionsController.state.accountType === 'smartAccount'
820
822
  }
821
823
  });
822
824
 
@@ -833,7 +835,7 @@ export const SwapController = {
833
835
  );
834
836
 
835
837
  let insufficientNetworkTokenForGas = true;
836
- if (AccountController.state.preferredAccountType === 'smartAccount') {
838
+ if (ConnectionsController.state.accountType === 'smartAccount') {
837
839
  // Smart Accounts may pay gas in any ERC20 token
838
840
  insufficientNetworkTokenForGas = false;
839
841
  } else {