@dynamic-labs/sdk-react-core 4.17.0 → 4.18.0

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.
@@ -18,7 +18,6 @@ const EMBEDDED_WALLET_SESSION_SETTINGS = 'dynamic_embedded_wallet_session_settin
18
18
  const EMBEDDED_WALLET_SECURE_BANNER = 'dynamic_embedded_secure_banner';
19
19
  const PHONE_INPUT_DEFAULT_COUNTRY = 'dynamic_phone_input_default_country';
20
20
  const CAPTCHA_TOKEN = 'dynamic_captcha_token';
21
- const ZERODEV_AUTHORIZATION = 'zerodev_authorization';
22
21
  /**
23
22
  * Used to identify the purpose of a signature after phantom redirects back to the app in mobile
24
23
  */
@@ -48,4 +47,3 @@ exports.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS = SECURE_ENCLAVE_WALL
48
47
  exports.STORE_STORAGE_KEY = STORE_STORAGE_KEY;
49
48
  exports.WAGMI_LAST_SESSION_SETTINGS = WAGMI_LAST_SESSION_SETTINGS;
50
49
  exports.WALLET_PICKER_SEARCH_KEY = WALLET_PICKER_SEARCH_KEY;
51
- exports.ZERODEV_AUTHORIZATION = ZERODEV_AUTHORIZATION;
@@ -16,7 +16,6 @@ export declare const EMBEDDED_WALLET_SESSION_SETTINGS = "dynamic_embedded_wallet
16
16
  export declare const EMBEDDED_WALLET_SECURE_BANNER = "dynamic_embedded_secure_banner";
17
17
  export declare const PHONE_INPUT_DEFAULT_COUNTRY = "dynamic_phone_input_default_country";
18
18
  export declare const CAPTCHA_TOKEN = "dynamic_captcha_token";
19
- export declare const ZERODEV_AUTHORIZATION = "zerodev_authorization";
20
19
  export type PhantomSignatureState = {
21
20
  /**
22
21
  * Whether the user has agreed to transfer a wallet even if that means
@@ -14,7 +14,6 @@ const EMBEDDED_WALLET_SESSION_SETTINGS = 'dynamic_embedded_wallet_session_settin
14
14
  const EMBEDDED_WALLET_SECURE_BANNER = 'dynamic_embedded_secure_banner';
15
15
  const PHONE_INPUT_DEFAULT_COUNTRY = 'dynamic_phone_input_default_country';
16
16
  const CAPTCHA_TOKEN = 'dynamic_captcha_token';
17
- const ZERODEV_AUTHORIZATION = 'zerodev_authorization';
18
17
  /**
19
18
  * Used to identify the purpose of a signature after phantom redirects back to the app in mobile
20
19
  */
@@ -25,4 +24,4 @@ const SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS = {
25
24
  priority: ['secureStorage', 'localStorage'],
26
25
  };
27
26
 
28
- export { AUTH_EXPIRES_AT, AUTH_MIN_TOKEN, AUTH_TOKEN, BRIDGE_ONBOARDING_COMPLETED, CAPTCHA_TOKEN, CONNECTED_WALLET_NAME_SERVICE, DEVICE_FINGERPRINT, DYNAMIC_CONTEXT_LAST_SESSION_SETTINGS, EMBEDDED_WALLET_SECURE_BANNER, EMBEDDED_WALLET_SESSION_SETTINGS, LAST_USED_WALLET, NEWTOWEB3_WALLET_EXTENSION_FLAG_KEY, PHANTOM_SIGNATURE_STATE, PHONE_INPUT_DEFAULT_COUNTRY, SECURE_ENCLAVE_WALLET_SESSION_KEYS, SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS, STORE_STORAGE_KEY, WAGMI_LAST_SESSION_SETTINGS, WALLET_PICKER_SEARCH_KEY, ZERODEV_AUTHORIZATION };
27
+ export { AUTH_EXPIRES_AT, AUTH_MIN_TOKEN, AUTH_TOKEN, BRIDGE_ONBOARDING_COMPLETED, CAPTCHA_TOKEN, CONNECTED_WALLET_NAME_SERVICE, DEVICE_FINGERPRINT, DYNAMIC_CONTEXT_LAST_SESSION_SETTINGS, EMBEDDED_WALLET_SECURE_BANNER, EMBEDDED_WALLET_SESSION_SETTINGS, LAST_USED_WALLET, NEWTOWEB3_WALLET_EXTENSION_FLAG_KEY, PHANTOM_SIGNATURE_STATE, PHONE_INPUT_DEFAULT_COUNTRY, SECURE_ENCLAVE_WALLET_SESSION_KEYS, SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS, STORE_STORAGE_KEY, WAGMI_LAST_SESSION_SETTINGS, WALLET_PICKER_SEARCH_KEY };
@@ -120,6 +120,7 @@ var SimulationStatus;
120
120
  const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation, onClickBack, walletConnector, onClickClose, title, displayPoweredByDynamicFooter = false, copykey, hideModal, currentToken, isNativeToken, transactionValue, isModal, sendBalanceTransaction, }) => {
121
121
  const { primaryWallet, environmentId } = useInternalDynamicContext.useInternalDynamicContext();
122
122
  const [isGasSponsored, setIsGasSponsored] = React.useState(false);
123
+ const [isGasSponsoredLoading, setIsGasSponsoredLoading] = React.useState(false);
123
124
  const update = useForceUpdate.useForceUpdate();
124
125
  const { t } = reactI18next.useTranslation();
125
126
  const { currency } = useFetchCurrency.useFetchCurrency(walletConnector);
@@ -135,13 +136,20 @@ const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation
135
136
  status: SimulationStatus.LOADING,
136
137
  });
137
138
  const [recipient, setRecipient] = React.useState(undefined);
139
+ const isFetchingSimulationRef = React.useRef(false);
138
140
  const fetchSimulationResult = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
139
141
  var _a, _b, _c, _d, _e, _f, _g;
140
142
  if (simulationState.status !== SimulationStatus.LOADING) {
141
143
  return;
142
144
  }
145
+ if (isFetchingSimulationRef.current) {
146
+ // Already fetching, prevent duplicate call
147
+ return;
148
+ }
149
+ isFetchingSimulationRef.current = true;
143
150
  if (sendBalanceTransaction || hideModal) {
144
151
  setSimulationState({ status: SimulationStatus.SKIPPED });
152
+ isFetchingSimulationRef.current = false;
145
153
  return;
146
154
  }
147
155
  if (!primaryWallet || (!chainId && (primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.chain) !== 'SOL')) {
@@ -151,13 +159,16 @@ const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation
151
159
  primaryWallet,
152
160
  });
153
161
  setSimulationState({ status: SimulationStatus.FAILED });
162
+ isFetchingSimulationRef.current = false;
154
163
  return;
155
164
  }
156
165
  try {
157
166
  let result;
158
167
  if (primaryWallet.connector.key === 'zerodev') {
159
168
  const connector = primaryWallet.connector;
160
- const { userOperation } = yield connector.getCurrentUserOperation(transaction);
169
+ const { userOperation, sponsored } = yield connector.getCurrentUserOperation(transaction);
170
+ setIsGasSponsored(sponsored);
171
+ setIsGasSponsoredLoading(false);
161
172
  if (userOperation) {
162
173
  const formattedUserOperation = yield connector.formatUserOperation(userOperation);
163
174
  // Set the gas fee on the transaction, only for zero dev
@@ -224,6 +235,9 @@ const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation
224
235
  logger.logger.error('[TransactionConfirmationView] Simulation failed:', error);
225
236
  setSimulationState({ status: SimulationStatus.FAILED });
226
237
  }
238
+ finally {
239
+ isFetchingSimulationRef.current = false;
240
+ }
227
241
  }), [
228
242
  sendBalanceTransaction,
229
243
  hideModal,
@@ -232,6 +246,8 @@ const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation
232
246
  environmentId,
233
247
  transaction,
234
248
  walletConnector,
249
+ simulationState.status,
250
+ setSimulationState,
235
251
  ]);
236
252
  React.useEffect(() => {
237
253
  if (simulationState.status === SimulationStatus.SUCCESS ||
@@ -253,21 +269,6 @@ const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation
253
269
  }
254
270
  transaction.fetchFee().finally(update);
255
271
  }, [primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.chain, transaction, update]);
256
- const { isLoading: isGasSponsoredLoading } = usePromise.usePromise(() => {
257
- if (!walletConnectorCore.isAccountAbstractionConnector(walletConnector)) {
258
- return false;
259
- }
260
- return walletConnector.canSponsorTransactionGas(transaction);
261
- }, {
262
- initialData: false,
263
- onReject: logger.logger.error,
264
- onResolve: (isGasSponsored) => {
265
- setIsGasSponsored(isGasSponsored);
266
- if (!isGasSponsored && walletConnectorCore.isAccountAbstractionConnector(walletConnector)) {
267
- walletConnector.disableGasSponsorshipOnce();
268
- }
269
- },
270
- });
271
272
  React.useEffect(() => {
272
273
  var _a;
273
274
  // solana gas sponsorship check
@@ -1,7 +1,7 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../../_virtual/_tslib.js';
3
3
  import { jsx, jsxs } from 'react/jsx-runtime';
4
- import { useState, useMemo, useCallback, useEffect } from 'react';
4
+ import { useState, useMemo, useRef, useCallback, useEffect } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import bs58 from 'bs58';
7
7
  import { isAccountAbstractionConnector } from '@dynamic-labs/wallet-connector-core';
@@ -112,6 +112,7 @@ var SimulationStatus;
112
112
  const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation, onClickBack, walletConnector, onClickClose, title, displayPoweredByDynamicFooter = false, copykey, hideModal, currentToken, isNativeToken, transactionValue, isModal, sendBalanceTransaction, }) => {
113
113
  const { primaryWallet, environmentId } = useInternalDynamicContext();
114
114
  const [isGasSponsored, setIsGasSponsored] = useState(false);
115
+ const [isGasSponsoredLoading, setIsGasSponsoredLoading] = useState(false);
115
116
  const update = useForceUpdate();
116
117
  const { t } = useTranslation();
117
118
  const { currency } = useFetchCurrency(walletConnector);
@@ -127,13 +128,20 @@ const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation
127
128
  status: SimulationStatus.LOADING,
128
129
  });
129
130
  const [recipient, setRecipient] = useState(undefined);
131
+ const isFetchingSimulationRef = useRef(false);
130
132
  const fetchSimulationResult = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
131
133
  var _a, _b, _c, _d, _e, _f, _g;
132
134
  if (simulationState.status !== SimulationStatus.LOADING) {
133
135
  return;
134
136
  }
137
+ if (isFetchingSimulationRef.current) {
138
+ // Already fetching, prevent duplicate call
139
+ return;
140
+ }
141
+ isFetchingSimulationRef.current = true;
135
142
  if (sendBalanceTransaction || hideModal) {
136
143
  setSimulationState({ status: SimulationStatus.SKIPPED });
144
+ isFetchingSimulationRef.current = false;
137
145
  return;
138
146
  }
139
147
  if (!primaryWallet || (!chainId && (primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.chain) !== 'SOL')) {
@@ -143,13 +151,16 @@ const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation
143
151
  primaryWallet,
144
152
  });
145
153
  setSimulationState({ status: SimulationStatus.FAILED });
154
+ isFetchingSimulationRef.current = false;
146
155
  return;
147
156
  }
148
157
  try {
149
158
  let result;
150
159
  if (primaryWallet.connector.key === 'zerodev') {
151
160
  const connector = primaryWallet.connector;
152
- const { userOperation } = yield connector.getCurrentUserOperation(transaction);
161
+ const { userOperation, sponsored } = yield connector.getCurrentUserOperation(transaction);
162
+ setIsGasSponsored(sponsored);
163
+ setIsGasSponsoredLoading(false);
153
164
  if (userOperation) {
154
165
  const formattedUserOperation = yield connector.formatUserOperation(userOperation);
155
166
  // Set the gas fee on the transaction, only for zero dev
@@ -216,6 +227,9 @@ const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation
216
227
  logger.error('[TransactionConfirmationView] Simulation failed:', error);
217
228
  setSimulationState({ status: SimulationStatus.FAILED });
218
229
  }
230
+ finally {
231
+ isFetchingSimulationRef.current = false;
232
+ }
219
233
  }), [
220
234
  sendBalanceTransaction,
221
235
  hideModal,
@@ -224,6 +238,8 @@ const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation
224
238
  environmentId,
225
239
  transaction,
226
240
  walletConnector,
241
+ simulationState.status,
242
+ setSimulationState,
227
243
  ]);
228
244
  useEffect(() => {
229
245
  if (simulationState.status === SimulationStatus.SUCCESS ||
@@ -245,21 +261,6 @@ const TransactionConfirmationView = ({ transaction, onError, onSuccess, mutation
245
261
  }
246
262
  transaction.fetchFee().finally(update);
247
263
  }, [primaryWallet === null || primaryWallet === void 0 ? void 0 : primaryWallet.chain, transaction, update]);
248
- const { isLoading: isGasSponsoredLoading } = usePromise(() => {
249
- if (!isAccountAbstractionConnector(walletConnector)) {
250
- return false;
251
- }
252
- return walletConnector.canSponsorTransactionGas(transaction);
253
- }, {
254
- initialData: false,
255
- onReject: logger.error,
256
- onResolve: (isGasSponsored) => {
257
- setIsGasSponsored(isGasSponsored);
258
- if (!isGasSponsored && isAccountAbstractionConnector(walletConnector)) {
259
- walletConnector.disableGasSponsorshipOnce();
260
- }
261
- },
262
- });
263
264
  useEffect(() => {
264
265
  var _a;
265
266
  // solana gas sponsorship check