@dynamic-labs/sdk-react-core 4.25.4 → 4.25.6

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 (57) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/package.cjs +1 -1
  3. package/package.js +1 -1
  4. package/package.json +11 -11
  5. package/src/lib/context/DynamicContext/hooks/useRemoveWallet/useRemoveWallet.cjs +5 -8
  6. package/src/lib/context/DynamicContext/hooks/useRemoveWallet/useRemoveWallet.js +6 -9
  7. package/src/lib/locale/en/translation.cjs +12 -0
  8. package/src/lib/locale/en/translation.d.ts +12 -0
  9. package/src/lib/locale/en/translation.js +12 -0
  10. package/src/lib/utils/hooks/useDynamicWaas/constants.cjs +2 -0
  11. package/src/lib/utils/hooks/useDynamicWaas/constants.d.ts +1 -0
  12. package/src/lib/utils/hooks/useDynamicWaas/constants.js +2 -1
  13. package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.cjs +14 -2
  14. package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.d.ts +5 -2
  15. package/src/lib/utils/hooks/useDynamicWaas/useDynamicWaas.js +15 -3
  16. package/src/lib/utils/hooks/useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/useSecureEnclaveEmbeddedWallet.cjs +11 -6
  17. package/src/lib/utils/hooks/useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/useSecureEnclaveEmbeddedWallet.js +11 -6
  18. package/src/lib/utils/hooks/useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/useTurnkey/useTurnkey.cjs +1 -1
  19. package/src/lib/utils/hooks/useEmbeddedWallet/useSecureEnclaveEmbeddedWallet/useTurnkey/useTurnkey.js +1 -1
  20. package/src/lib/utils/hooks/useEmbeddedWalletSessionKeys/useEmbeddedWalletSessionKeys.cjs +80 -60
  21. package/src/lib/utils/hooks/useEmbeddedWalletSessionKeys/useEmbeddedWalletSessionKeys.d.ts +1 -5
  22. package/src/lib/utils/hooks/useEmbeddedWalletSessionKeys/useEmbeddedWalletSessionKeys.js +81 -61
  23. package/src/lib/utils/hooks/useGetMfaToken/index.d.ts +1 -0
  24. package/src/lib/utils/hooks/useGetMfaToken/useGetMfaToken.cjs +68 -0
  25. package/src/lib/utils/hooks/useGetMfaToken/useGetMfaToken.d.ts +26 -0
  26. package/src/lib/utils/hooks/useGetMfaToken/useGetMfaToken.js +64 -0
  27. package/src/lib/utils/hooks/useMfa/useMfa.cjs +23 -12
  28. package/src/lib/utils/hooks/useMfa/useMfa.d.ts +3 -2
  29. package/src/lib/utils/hooks/useMfa/useMfa.js +23 -12
  30. package/src/lib/utils/hooks/useMfaModals/useMfaModals.cjs +7 -1
  31. package/src/lib/utils/hooks/useMfaModals/useMfaModals.js +7 -1
  32. package/src/lib/utils/hooks/usePromptMfaAuth/index.d.ts +1 -0
  33. package/src/lib/utils/hooks/usePromptMfaAuth/usePromptMfaAuth.cjs +150 -0
  34. package/src/lib/utils/hooks/usePromptMfaAuth/usePromptMfaAuth.d.ts +5 -0
  35. package/src/lib/utils/hooks/usePromptMfaAuth/usePromptMfaAuth.js +146 -0
  36. package/src/lib/utils/hooks/useSetWalletConnectorFetchers/useSetWalletConnectorFetchers.cjs +3 -0
  37. package/src/lib/utils/hooks/useSetWalletConnectorFetchers/useSetWalletConnectorFetchers.js +3 -0
  38. package/src/lib/utils/hooks/useSyncMfaFlow/useSyncMfaFlow.cjs +5 -13
  39. package/src/lib/utils/hooks/useSyncMfaFlow/useSyncMfaFlow.js +5 -13
  40. package/src/lib/utils/hooks/useVerifyWallet/useVerifyWallet.cjs +2 -2
  41. package/src/lib/utils/hooks/useVerifyWallet/useVerifyWallet.js +2 -2
  42. package/src/lib/views/EmbeddedReveal/EmbeddedRevealView/EmbeddedRevealView.cjs +6 -1
  43. package/src/lib/views/EmbeddedReveal/EmbeddedRevealView/EmbeddedRevealView.js +6 -1
  44. package/src/lib/views/MfaChooseDeviceView/MfaChooseDeviceView.cjs +5 -2
  45. package/src/lib/views/MfaChooseDeviceView/MfaChooseDeviceView.d.ts +1 -0
  46. package/src/lib/views/MfaChooseDeviceView/MfaChooseDeviceView.js +5 -2
  47. package/src/lib/views/MfaVerificationView/MfaVerificationView.cjs +18 -3
  48. package/src/lib/views/MfaVerificationView/MfaVerificationView.d.ts +2 -1
  49. package/src/lib/views/MfaVerificationView/MfaVerificationView.js +18 -3
  50. package/src/lib/views/Passkey/ConfirmPasskeyView/ConfirmPasskeyView.cjs +15 -3
  51. package/src/lib/views/Passkey/ConfirmPasskeyView/ConfirmPasskeyView.d.ts +5 -1
  52. package/src/lib/views/Passkey/ConfirmPasskeyView/ConfirmPasskeyView.js +15 -3
  53. package/src/lib/views/Passkey/SetupPasskeyView/SetupPasskeyView.cjs +16 -4
  54. package/src/lib/views/Passkey/SetupPasskeyView/SetupPasskeyView.js +16 -4
  55. package/src/lib/views/viewToComponentMap.d.ts +4 -2
  56. package/src/lib/widgets/DynamicWidget/prompts/PendingAccountSwitchToLinkModal/PendingAccountSwitchToLinkModal.cjs +7 -2
  57. package/src/lib/widgets/DynamicWidget/prompts/PendingAccountSwitchToLinkModal/PendingAccountSwitchToLinkModal.js +8 -3
@@ -38,27 +38,32 @@ var getPrimaryTurnkeyWalletId = require('../../functions/getPrimaryTurnkeyWallet
38
38
  const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
39
39
  const user = useOnboardingCompleteUser.useOnboardingCompleteUserProfile();
40
40
  // scenario 1: first time session register on first transaction.
41
- // Keys will have been previously generated at this point in local storage but marked as not registered
42
- // scenario 2: 2nd time register after expiration (key refresh)
43
- // scenario 3: refresh/rerender page - session still active
44
- // scenario 4: refresh/rerender page - session no longer active
41
+ // scenario 2: refresh/rerender page - session still active and registered (keys were previously generated
42
+ // but never registered with the backend)
43
+ // scenario 3: session expired and needs to be refreshed
44
+ // Helper to get decoded session keys from storage
45
45
  const registerEmbeddedWalletSessionKey = (...args_1) => _tslib.__awaiter(void 0, [...args_1], void 0, function* ({ ignoreRestore = false, } = {}) {
46
+ if (!user) {
47
+ throw new Error('User not found');
48
+ }
46
49
  // check if session keys are already stored in session storage
47
- const sessionKeysSS = utils.StorageService.getItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
48
- const decodedSessionKeys = sessionKeysSS
49
- ? JSON.parse(Buffer.from(sessionKeysSS, 'base64').toString())
50
- : undefined;
50
+ let decodedSessionKeys = getDecodedSessionKeys();
51
51
  utils.tracing.logEvent('session-key', 'registerEmbeddedWalletSessionKey', utils.tracing.formatObject({
52
52
  hasDecodedSessionKeys: Boolean(decodedSessionKeys),
53
53
  publicKey: decodedSessionKeys === null || decodedSessionKeys === void 0 ? void 0 : decodedSessionKeys.publicKey,
54
54
  }));
55
55
  if (!decodedSessionKeys) {
56
- walletConnectorCore.logger.warn('Could not find session keys. Re-authentication is required to create new session keys.');
57
- dynamicEvents.dynamicEvents.emit('triggerLogout');
58
- throw new Error('Could not find session keys. Re-authentication is required to create new session keys.');
59
- }
60
- if (!user) {
61
- throw new Error('User not found');
56
+ // We should never be in a situation where we don't have session keys in storage.
57
+ // But right now we are in a situation where we don't have session keys in storage,
58
+ // in many situations.
59
+ // but this is a fallback to ensure that we always have session keys
60
+ // To note that this would only work if chaining is disabled in the backend
61
+ // since the original key was registered for chaining, and now we don't have it
62
+ // it will fail when interacting with the backend if chaining is enabled.
63
+ // This logic will be removed and reverted back to logging out once we find
64
+ // the culprit that cause many of these to happen.
65
+ walletConnectorCore.logger.error('Session keys not found in storage. Generating new session keys.', { userId: user === null || user === void 0 ? void 0 : user.userId });
66
+ decodedSessionKeys = yield generateSessionKey();
62
67
  }
63
68
  const isSessionKeyValid = decodedSessionKeys.expirationDate &&
64
69
  new Date() <= new Date(decodedSessionKeys.expirationDate) &&
@@ -67,7 +72,7 @@ const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
67
72
  isSessionKeyValid: Boolean(isSessionKeyValid),
68
73
  }));
69
74
  if (isSessionKeyValid) {
70
- // scenario 3
75
+ // scenario 1 - session is valid and registered
71
76
  return decodedSessionKeys;
72
77
  }
73
78
  utils.tracing.logEvent('session-key', 'decodedSessionKeys', utils.tracing.formatObject({
@@ -79,48 +84,23 @@ const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
79
84
  let privateKeyJwk;
80
85
  let prevSessionKeySignature = undefined;
81
86
  if (!decodedSessionKeys.registered) {
82
- // scenario 1
87
+ // scenario 2 - session needs to be registered
83
88
  ({ publicKey, privateKey, privateKeyJwk } = decodedSessionKeys);
84
89
  }
85
90
  else {
86
- // scenario 2 and 4
87
- const { publicKey: nextPublicKey, privateKey: nextPrivateKey, privateKeyJwk: nextPrivateKeyJwk, } = yield generateSessionKey();
88
- publicKey = nextPublicKey;
89
- privateKey = nextPrivateKey;
90
- privateKeyJwk = nextPrivateKeyJwk;
91
+ // scenario 3 - session expired singing with the old key and generating a new one
91
92
  prevSessionKeySignature = yield keyService.p256Sign(decodedSessionKeys.privateKeyJwk, user.sessionId);
92
- utils.tracing.logEvent('session-key', 'Loaded prevSessionKeySignature', utils.tracing.formatObject({ nextPublicKey, prevSessionKeySignature }));
93
- }
94
- let resp;
95
- const primaryWalletId$1 = primaryWalletId.getPrimaryWalletId();
96
- if (!primaryWalletId$1) {
97
- throw new Error('Primary wallet ID not found');
98
- }
99
- const turnkeyWalletId = getPrimaryTurnkeyWalletId.getPrimaryTurnkeyWalletId(primaryWalletId$1, user.verifiedCredentials);
100
- try {
101
- resp = yield embeddedWallets.registerSessionKey({
102
- environmentId,
103
- prevSessionKeySignature,
104
- publicKey,
105
- walletId: turnkeyWalletId,
106
- });
107
- }
108
- catch (error) {
109
- if (error instanceof utils.InvalidEmbeddedWalletSessionKeyError) {
110
- // this can happen if the public key passed during initial registration
111
- // does not match the root session public key that the backend expects
112
- walletConnectorCore.logger.warn('Invalid embedded wallet session key. Re-authentication is required to create new session keys.');
113
- dynamicEvents.dynamicEvents.emit('triggerLogout');
114
- }
115
- throw error;
93
+ ({ publicKey, privateKey, privateKeyJwk } = yield generateSessionKey());
94
+ utils.tracing.logEvent('session-key', 'Loaded prevSessionKeySignature', utils.tracing.formatObject({ prevSessionKeySignature, publicKey }));
116
95
  }
117
- const expirationDate = new Date(resp.expiresAt * 1000);
118
- utils.tracing.logEvent('session-key', 'Created new session key', utils.tracing.formatObject({
119
- expirationDate,
96
+ return registerHelper({
97
+ environmentId,
98
+ prevSessionKeySignature,
99
+ privateKey,
100
+ privateKeyJwk,
120
101
  publicKey,
121
- }));
122
- utils.StorageService.setItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, keyService.toEncodedFormat(publicKey, privateKey, privateKeyJwk, true, expirationDate), localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
123
- return { expirationDate, privateKey, publicKey };
102
+ user,
103
+ });
124
104
  });
125
105
  const generateSessionKey = () => _tslib.__awaiter(void 0, void 0, void 0, function* () {
126
106
  const { private: privateKey, public: publicKey, privateJwk, } = yield keyService.p256Keygen();
@@ -129,13 +109,15 @@ const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
129
109
  publicKey,
130
110
  }));
131
111
  utils.StorageService.setItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, keyService.toEncodedFormat(publicKey, privateKey, privateJwk, false), localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
132
- return { privateKey, privateKeyJwk: privateJwk, publicKey };
112
+ return {
113
+ privateKey,
114
+ privateKeyJwk: privateJwk,
115
+ publicKey,
116
+ registered: false,
117
+ };
133
118
  });
134
119
  const getSessionPublicKey = () => {
135
- const sessionKeysSS = utils.StorageService.getItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
136
- const decodedSessionKeys = sessionKeysSS
137
- ? JSON.parse(Buffer.from(sessionKeysSS, 'base64').toString())
138
- : undefined;
120
+ const decodedSessionKeys = getDecodedSessionKeys();
139
121
  if (!(decodedSessionKeys === null || decodedSessionKeys === void 0 ? void 0 : decodedSessionKeys.publicKey)) {
140
122
  utils.tracing.logEvent('session-key', 'getSessionPublicKey', 'Could not find session keys.');
141
123
  throw new Error('Could not find session keys.');
@@ -154,10 +136,7 @@ const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
154
136
  if (!sessionId) {
155
137
  throw new Error('Session ID not found');
156
138
  }
157
- const sessionKeysSS = utils.StorageService.getItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
158
- const decodedSessionKeys = sessionKeysSS
159
- ? JSON.parse(Buffer.from(sessionKeysSS, 'base64').toString())
160
- : undefined;
139
+ const decodedSessionKeys = getDecodedSessionKeys();
161
140
  if (!(decodedSessionKeys === null || decodedSessionKeys === void 0 ? void 0 : decodedSessionKeys.privateKeyJwk)) {
162
141
  throw new Error('Private key JWK not found');
163
142
  }
@@ -168,6 +147,47 @@ const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
168
147
  utils.tracing.logEvent('session-key', 'removeSessionKey');
169
148
  utils.StorageService.removeItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
170
149
  }, []);
150
+ /////////////////////
151
+ // Helper Methods ///
152
+ /////////////////////
153
+ const registerHelper = (_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ environmentId, prevSessionKeySignature, publicKey, privateKey, privateKeyJwk, user, }) {
154
+ let resp;
155
+ const primaryWalletId$1 = primaryWalletId.getPrimaryWalletId();
156
+ if (!primaryWalletId$1) {
157
+ throw new Error('Primary wallet ID not found');
158
+ }
159
+ const turnkeyWalletId = getPrimaryTurnkeyWalletId.getPrimaryTurnkeyWalletId(primaryWalletId$1, user.verifiedCredentials);
160
+ try {
161
+ resp = yield embeddedWallets.registerSessionKey({
162
+ environmentId,
163
+ prevSessionKeySignature,
164
+ publicKey,
165
+ walletId: turnkeyWalletId,
166
+ });
167
+ }
168
+ catch (error) {
169
+ if (error instanceof utils.InvalidEmbeddedWalletSessionKeyError) {
170
+ // this can happen if the public key passed during initial registration
171
+ // does not match the root session public key that the backend expects
172
+ walletConnectorCore.logger.warn('Invalid embedded wallet session key. Re-authentication is required to create new session keys.');
173
+ dynamicEvents.dynamicEvents.emit('triggerLogout');
174
+ }
175
+ throw error;
176
+ }
177
+ const expirationDate = new Date(resp.expiresAt * 1000);
178
+ utils.tracing.logEvent('session-key', 'Created new session key', utils.tracing.formatObject({
179
+ expirationDate,
180
+ publicKey,
181
+ }));
182
+ utils.StorageService.setItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, keyService.toEncodedFormat(publicKey, privateKey, privateKeyJwk, true, expirationDate), localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
183
+ return { expirationDate, privateKey, publicKey };
184
+ });
185
+ const getDecodedSessionKeys = () => {
186
+ const sessionKeysSS = utils.StorageService.getItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
187
+ return sessionKeysSS
188
+ ? JSON.parse(Buffer.from(sessionKeysSS, 'base64').toString())
189
+ : undefined;
190
+ };
171
191
  return {
172
192
  generateSessionKey,
173
193
  getSessionPublicKey,
@@ -10,11 +10,7 @@ export declare const useEmbeddedWalletSessionKeys: ({ environmentId, projectSett
10
10
  environmentId: string;
11
11
  projectSettings?: ProjectSettings;
12
12
  }) => {
13
- generateSessionKey: () => Promise<{
14
- privateKey: string;
15
- privateKeyJwk: JsonWebKey;
16
- publicKey: string;
17
- }>;
13
+ generateSessionKey: () => Promise<SessionKey>;
18
14
  getSessionPublicKey: () => string;
19
15
  getSignedSessionId: () => Promise<string>;
20
16
  registerEmbeddedWalletSessionKey: ({ ignoreRestore, }?: {
@@ -26,7 +26,7 @@ import '../../../locale/locale.js';
26
26
  import '../../../store/state/dynamicContextProps/dynamicContextProps.js';
27
27
  import { getPrimaryWalletId } from '../../../store/state/primaryWalletId/primaryWalletId.js';
28
28
  import '../../../store/state/connectedWalletsInfo/connectedWalletsInfo.js';
29
- import { p256Sign, toEncodedFormat, p256Keygen } from '../../functions/keyService/keyService.js';
29
+ import { p256Sign, p256Keygen, toEncodedFormat } from '../../functions/keyService/keyService.js';
30
30
  import { dynamicEvents } from '../../../events/dynamicEvents.js';
31
31
  import { useOnboardingCompleteUserProfile } from '../../../client/extension/user/useOnboardingCompleteUser/useOnboardingCompleteUser.js';
32
32
  import { getPrimaryTurnkeyWalletId } from '../../functions/getPrimaryTurnkeyWalletId/getPrimaryTurnkeyWalletId.js';
@@ -34,27 +34,32 @@ import { getPrimaryTurnkeyWalletId } from '../../functions/getPrimaryTurnkeyWall
34
34
  const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
35
35
  const user = useOnboardingCompleteUserProfile();
36
36
  // scenario 1: first time session register on first transaction.
37
- // Keys will have been previously generated at this point in local storage but marked as not registered
38
- // scenario 2: 2nd time register after expiration (key refresh)
39
- // scenario 3: refresh/rerender page - session still active
40
- // scenario 4: refresh/rerender page - session no longer active
37
+ // scenario 2: refresh/rerender page - session still active and registered (keys were previously generated
38
+ // but never registered with the backend)
39
+ // scenario 3: session expired and needs to be refreshed
40
+ // Helper to get decoded session keys from storage
41
41
  const registerEmbeddedWalletSessionKey = (...args_1) => __awaiter(void 0, [...args_1], void 0, function* ({ ignoreRestore = false, } = {}) {
42
+ if (!user) {
43
+ throw new Error('User not found');
44
+ }
42
45
  // check if session keys are already stored in session storage
43
- const sessionKeysSS = StorageService.getItem(SECURE_ENCLAVE_WALLET_SESSION_KEYS, SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
44
- const decodedSessionKeys = sessionKeysSS
45
- ? JSON.parse(Buffer.from(sessionKeysSS, 'base64').toString())
46
- : undefined;
46
+ let decodedSessionKeys = getDecodedSessionKeys();
47
47
  tracing.logEvent('session-key', 'registerEmbeddedWalletSessionKey', tracing.formatObject({
48
48
  hasDecodedSessionKeys: Boolean(decodedSessionKeys),
49
49
  publicKey: decodedSessionKeys === null || decodedSessionKeys === void 0 ? void 0 : decodedSessionKeys.publicKey,
50
50
  }));
51
51
  if (!decodedSessionKeys) {
52
- logger.warn('Could not find session keys. Re-authentication is required to create new session keys.');
53
- dynamicEvents.emit('triggerLogout');
54
- throw new Error('Could not find session keys. Re-authentication is required to create new session keys.');
55
- }
56
- if (!user) {
57
- throw new Error('User not found');
52
+ // We should never be in a situation where we don't have session keys in storage.
53
+ // But right now we are in a situation where we don't have session keys in storage,
54
+ // in many situations.
55
+ // but this is a fallback to ensure that we always have session keys
56
+ // To note that this would only work if chaining is disabled in the backend
57
+ // since the original key was registered for chaining, and now we don't have it
58
+ // it will fail when interacting with the backend if chaining is enabled.
59
+ // This logic will be removed and reverted back to logging out once we find
60
+ // the culprit that cause many of these to happen.
61
+ logger.error('Session keys not found in storage. Generating new session keys.', { userId: user === null || user === void 0 ? void 0 : user.userId });
62
+ decodedSessionKeys = yield generateSessionKey();
58
63
  }
59
64
  const isSessionKeyValid = decodedSessionKeys.expirationDate &&
60
65
  new Date() <= new Date(decodedSessionKeys.expirationDate) &&
@@ -63,7 +68,7 @@ const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
63
68
  isSessionKeyValid: Boolean(isSessionKeyValid),
64
69
  }));
65
70
  if (isSessionKeyValid) {
66
- // scenario 3
71
+ // scenario 1 - session is valid and registered
67
72
  return decodedSessionKeys;
68
73
  }
69
74
  tracing.logEvent('session-key', 'decodedSessionKeys', tracing.formatObject({
@@ -75,48 +80,23 @@ const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
75
80
  let privateKeyJwk;
76
81
  let prevSessionKeySignature = undefined;
77
82
  if (!decodedSessionKeys.registered) {
78
- // scenario 1
83
+ // scenario 2 - session needs to be registered
79
84
  ({ publicKey, privateKey, privateKeyJwk } = decodedSessionKeys);
80
85
  }
81
86
  else {
82
- // scenario 2 and 4
83
- const { publicKey: nextPublicKey, privateKey: nextPrivateKey, privateKeyJwk: nextPrivateKeyJwk, } = yield generateSessionKey();
84
- publicKey = nextPublicKey;
85
- privateKey = nextPrivateKey;
86
- privateKeyJwk = nextPrivateKeyJwk;
87
+ // scenario 3 - session expired singing with the old key and generating a new one
87
88
  prevSessionKeySignature = yield p256Sign(decodedSessionKeys.privateKeyJwk, user.sessionId);
88
- tracing.logEvent('session-key', 'Loaded prevSessionKeySignature', tracing.formatObject({ nextPublicKey, prevSessionKeySignature }));
89
- }
90
- let resp;
91
- const primaryWalletId = getPrimaryWalletId();
92
- if (!primaryWalletId) {
93
- throw new Error('Primary wallet ID not found');
94
- }
95
- const turnkeyWalletId = getPrimaryTurnkeyWalletId(primaryWalletId, user.verifiedCredentials);
96
- try {
97
- resp = yield registerSessionKey({
98
- environmentId,
99
- prevSessionKeySignature,
100
- publicKey,
101
- walletId: turnkeyWalletId,
102
- });
103
- }
104
- catch (error) {
105
- if (error instanceof InvalidEmbeddedWalletSessionKeyError) {
106
- // this can happen if the public key passed during initial registration
107
- // does not match the root session public key that the backend expects
108
- logger.warn('Invalid embedded wallet session key. Re-authentication is required to create new session keys.');
109
- dynamicEvents.emit('triggerLogout');
110
- }
111
- throw error;
89
+ ({ publicKey, privateKey, privateKeyJwk } = yield generateSessionKey());
90
+ tracing.logEvent('session-key', 'Loaded prevSessionKeySignature', tracing.formatObject({ prevSessionKeySignature, publicKey }));
112
91
  }
113
- const expirationDate = new Date(resp.expiresAt * 1000);
114
- tracing.logEvent('session-key', 'Created new session key', tracing.formatObject({
115
- expirationDate,
92
+ return registerHelper({
93
+ environmentId,
94
+ prevSessionKeySignature,
95
+ privateKey,
96
+ privateKeyJwk,
116
97
  publicKey,
117
- }));
118
- StorageService.setItem(SECURE_ENCLAVE_WALLET_SESSION_KEYS, toEncodedFormat(publicKey, privateKey, privateKeyJwk, true, expirationDate), SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
119
- return { expirationDate, privateKey, publicKey };
98
+ user,
99
+ });
120
100
  });
121
101
  const generateSessionKey = () => __awaiter(void 0, void 0, void 0, function* () {
122
102
  const { private: privateKey, public: publicKey, privateJwk, } = yield p256Keygen();
@@ -125,13 +105,15 @@ const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
125
105
  publicKey,
126
106
  }));
127
107
  StorageService.setItem(SECURE_ENCLAVE_WALLET_SESSION_KEYS, toEncodedFormat(publicKey, privateKey, privateJwk, false), SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
128
- return { privateKey, privateKeyJwk: privateJwk, publicKey };
108
+ return {
109
+ privateKey,
110
+ privateKeyJwk: privateJwk,
111
+ publicKey,
112
+ registered: false,
113
+ };
129
114
  });
130
115
  const getSessionPublicKey = () => {
131
- const sessionKeysSS = StorageService.getItem(SECURE_ENCLAVE_WALLET_SESSION_KEYS, SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
132
- const decodedSessionKeys = sessionKeysSS
133
- ? JSON.parse(Buffer.from(sessionKeysSS, 'base64').toString())
134
- : undefined;
116
+ const decodedSessionKeys = getDecodedSessionKeys();
135
117
  if (!(decodedSessionKeys === null || decodedSessionKeys === void 0 ? void 0 : decodedSessionKeys.publicKey)) {
136
118
  tracing.logEvent('session-key', 'getSessionPublicKey', 'Could not find session keys.');
137
119
  throw new Error('Could not find session keys.');
@@ -150,10 +132,7 @@ const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
150
132
  if (!sessionId) {
151
133
  throw new Error('Session ID not found');
152
134
  }
153
- const sessionKeysSS = StorageService.getItem(SECURE_ENCLAVE_WALLET_SESSION_KEYS, SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
154
- const decodedSessionKeys = sessionKeysSS
155
- ? JSON.parse(Buffer.from(sessionKeysSS, 'base64').toString())
156
- : undefined;
135
+ const decodedSessionKeys = getDecodedSessionKeys();
157
136
  if (!(decodedSessionKeys === null || decodedSessionKeys === void 0 ? void 0 : decodedSessionKeys.privateKeyJwk)) {
158
137
  throw new Error('Private key JWK not found');
159
138
  }
@@ -164,6 +143,47 @@ const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
164
143
  tracing.logEvent('session-key', 'removeSessionKey');
165
144
  StorageService.removeItem(SECURE_ENCLAVE_WALLET_SESSION_KEYS, SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
166
145
  }, []);
146
+ /////////////////////
147
+ // Helper Methods ///
148
+ /////////////////////
149
+ const registerHelper = (_a) => __awaiter(void 0, [_a], void 0, function* ({ environmentId, prevSessionKeySignature, publicKey, privateKey, privateKeyJwk, user, }) {
150
+ let resp;
151
+ const primaryWalletId = getPrimaryWalletId();
152
+ if (!primaryWalletId) {
153
+ throw new Error('Primary wallet ID not found');
154
+ }
155
+ const turnkeyWalletId = getPrimaryTurnkeyWalletId(primaryWalletId, user.verifiedCredentials);
156
+ try {
157
+ resp = yield registerSessionKey({
158
+ environmentId,
159
+ prevSessionKeySignature,
160
+ publicKey,
161
+ walletId: turnkeyWalletId,
162
+ });
163
+ }
164
+ catch (error) {
165
+ if (error instanceof InvalidEmbeddedWalletSessionKeyError) {
166
+ // this can happen if the public key passed during initial registration
167
+ // does not match the root session public key that the backend expects
168
+ logger.warn('Invalid embedded wallet session key. Re-authentication is required to create new session keys.');
169
+ dynamicEvents.emit('triggerLogout');
170
+ }
171
+ throw error;
172
+ }
173
+ const expirationDate = new Date(resp.expiresAt * 1000);
174
+ tracing.logEvent('session-key', 'Created new session key', tracing.formatObject({
175
+ expirationDate,
176
+ publicKey,
177
+ }));
178
+ StorageService.setItem(SECURE_ENCLAVE_WALLET_SESSION_KEYS, toEncodedFormat(publicKey, privateKey, privateKeyJwk, true, expirationDate), SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
179
+ return { expirationDate, privateKey, publicKey };
180
+ });
181
+ const getDecodedSessionKeys = () => {
182
+ const sessionKeysSS = StorageService.getItem(SECURE_ENCLAVE_WALLET_SESSION_KEYS, SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
183
+ return sessionKeysSS
184
+ ? JSON.parse(Buffer.from(sessionKeysSS, 'base64').toString())
185
+ : undefined;
186
+ };
167
187
  return {
168
188
  generateSessionKey,
169
189
  getSessionPublicKey,
@@ -0,0 +1 @@
1
+ export { useGetMfaToken } from './useGetMfaToken';
@@ -0,0 +1,68 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../../../_virtual/_tslib.cjs');
7
+ var React = require('react');
8
+ var client$1 = require('@dynamic-labs-sdk/client');
9
+ var utils = require('@dynamic-labs/utils');
10
+ var client = require('../../../client/client.cjs');
11
+ require('@dynamic-labs/sdk-api-core');
12
+ var logger = require('../../../shared/logger.cjs');
13
+ require('@dynamic-labs/iconic');
14
+ require('@dynamic-labs/wallet-connector-core');
15
+ require('react/jsx-runtime');
16
+ require('../../../context/ViewContext/ViewContext.cjs');
17
+ require('@dynamic-labs/wallet-book');
18
+ require('../../constants/colors.cjs');
19
+ require('../../constants/values.cjs');
20
+ require('../../../shared/consts/index.cjs');
21
+ var projectSettings = require('../../../store/state/projectSettings/projectSettings.cjs');
22
+
23
+ /**
24
+ * Get MFA token
25
+ *
26
+ * @returns Function to get MFA token
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * const App = () => {
31
+ * const getMfaToken = useGetMfaToken();
32
+ *
33
+ * return (
34
+ * <button
35
+ * onClick={() => getMfaToken({ mfaAction: MFAAction.UpdateUser })}
36
+ * >
37
+ * Get MFA token
38
+ * </button>
39
+ * );
40
+ * }
41
+ */
42
+ const useGetMfaToken = () => {
43
+ const client$2 = client.useDynamicClient();
44
+ return React.useCallback((...args_1) => _tslib.__awaiter(void 0, [...args_1], void 0, function* ({ mfaAction } = {}) {
45
+ var _a, _b, _c;
46
+ const projectSettings$1 = projectSettings.getProjectSettings();
47
+ const isMfaRequiredForAction = (_c = (_b = (_a = projectSettings$1 === null || projectSettings$1 === void 0 ? void 0 : projectSettings$1.security) === null || _a === void 0 ? void 0 : _a.mfa) === null || _b === void 0 ? void 0 : _b.actions) === null || _c === void 0 ? void 0 : _c.some((action) => action.action === mfaAction && action.required);
48
+ if (mfaAction && !isMfaRequiredForAction) {
49
+ // if mfa token is not required, return undefined
50
+ return;
51
+ }
52
+ try {
53
+ const mfaToken = client$1.consumeMfaToken(client$2);
54
+ return mfaToken;
55
+ }
56
+ catch (error) {
57
+ if (!mfaAction) {
58
+ logger.logger.warn('No MFA token found', error);
59
+ return;
60
+ }
61
+ const errorMessage = `MFA Token required for this action: ${mfaAction}`;
62
+ logger.logger.error(errorMessage, error);
63
+ throw new utils.DynamicError(errorMessage);
64
+ }
65
+ }), [client$2]);
66
+ };
67
+
68
+ exports.useGetMfaToken = useGetMfaToken;
@@ -0,0 +1,26 @@
1
+ import { MFAAction } from '@dynamic-labs/sdk-api-core';
2
+ type UseGetMfaTokenProps = {
3
+ mfaAction?: MFAAction;
4
+ };
5
+ type UseGetMfaToken = (props?: UseGetMfaTokenProps) => Promise<string | undefined>;
6
+ /**
7
+ * Get MFA token
8
+ *
9
+ * @returns Function to get MFA token
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * const App = () => {
14
+ * const getMfaToken = useGetMfaToken();
15
+ *
16
+ * return (
17
+ * <button
18
+ * onClick={() => getMfaToken({ mfaAction: MFAAction.UpdateUser })}
19
+ * >
20
+ * Get MFA token
21
+ * </button>
22
+ * );
23
+ * }
24
+ */
25
+ export declare const useGetMfaToken: () => UseGetMfaToken;
26
+ export {};
@@ -0,0 +1,64 @@
1
+ 'use client'
2
+ import { __awaiter } from '../../../../../_virtual/_tslib.js';
3
+ import { useCallback } from 'react';
4
+ import { consumeMfaToken } from '@dynamic-labs-sdk/client';
5
+ import { DynamicError } from '@dynamic-labs/utils';
6
+ import { useDynamicClient } from '../../../client/client.js';
7
+ import '@dynamic-labs/sdk-api-core';
8
+ import { logger } from '../../../shared/logger.js';
9
+ import '@dynamic-labs/iconic';
10
+ import '@dynamic-labs/wallet-connector-core';
11
+ import 'react/jsx-runtime';
12
+ import '../../../context/ViewContext/ViewContext.js';
13
+ import '@dynamic-labs/wallet-book';
14
+ import '../../constants/colors.js';
15
+ import '../../constants/values.js';
16
+ import '../../../shared/consts/index.js';
17
+ import { getProjectSettings } from '../../../store/state/projectSettings/projectSettings.js';
18
+
19
+ /**
20
+ * Get MFA token
21
+ *
22
+ * @returns Function to get MFA token
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * const App = () => {
27
+ * const getMfaToken = useGetMfaToken();
28
+ *
29
+ * return (
30
+ * <button
31
+ * onClick={() => getMfaToken({ mfaAction: MFAAction.UpdateUser })}
32
+ * >
33
+ * Get MFA token
34
+ * </button>
35
+ * );
36
+ * }
37
+ */
38
+ const useGetMfaToken = () => {
39
+ const client = useDynamicClient();
40
+ return useCallback((...args_1) => __awaiter(void 0, [...args_1], void 0, function* ({ mfaAction } = {}) {
41
+ var _a, _b, _c;
42
+ const projectSettings = getProjectSettings();
43
+ const isMfaRequiredForAction = (_c = (_b = (_a = projectSettings === null || projectSettings === void 0 ? void 0 : projectSettings.security) === null || _a === void 0 ? void 0 : _a.mfa) === null || _b === void 0 ? void 0 : _b.actions) === null || _c === void 0 ? void 0 : _c.some((action) => action.action === mfaAction && action.required);
44
+ if (mfaAction && !isMfaRequiredForAction) {
45
+ // if mfa token is not required, return undefined
46
+ return;
47
+ }
48
+ try {
49
+ const mfaToken = consumeMfaToken(client);
50
+ return mfaToken;
51
+ }
52
+ catch (error) {
53
+ if (!mfaAction) {
54
+ logger.warn('No MFA token found', error);
55
+ return;
56
+ }
57
+ const errorMessage = `MFA Token required for this action: ${mfaAction}`;
58
+ logger.error(errorMessage, error);
59
+ throw new DynamicError(errorMessage);
60
+ }
61
+ }), [client]);
62
+ };
63
+
64
+ export { useGetMfaToken };