@oxyhq/services 5.16.19 → 5.16.20
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/lib/commonjs/crypto/types.js +2 -0
- package/lib/commonjs/crypto/types.js.map +1 -0
- package/lib/commonjs/ui/context/OxyContext.js +37 -8
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionSocket.js +52 -2
- package/lib/commonjs/ui/hooks/useSessionSocket.js.map +1 -1
- package/lib/module/crypto/index.js +0 -1
- package/lib/module/crypto/index.js.map +1 -1
- package/lib/module/crypto/types.js +2 -0
- package/lib/module/crypto/types.js.map +1 -0
- package/lib/module/ui/context/OxyContext.js +32 -3
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/module/ui/hooks/useSessionSocket.js +52 -2
- package/lib/module/ui/hooks/useSessionSocket.js.map +1 -1
- package/lib/typescript/crypto/index.d.ts +1 -0
- package/lib/typescript/crypto/index.d.ts.map +1 -1
- package/lib/typescript/crypto/types.d.ts +18 -0
- package/lib/typescript/crypto/types.d.ts.map +1 -0
- package/lib/typescript/ui/context/OxyContext.d.ts +2 -6
- package/lib/typescript/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts +2 -6
- package/lib/typescript/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/ui/hooks/useSessionSocket.d.ts +7 -1
- package/lib/typescript/ui/hooks/useSessionSocket.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/crypto/index.ts +1 -0
- package/src/crypto/types.ts +19 -0
- package/src/ui/context/OxyContext.tsx +42 -4
- package/src/ui/context/hooks/useAuthOperations.ts +3 -3
- package/src/ui/hooks/useSessionSocket.ts +62 -2
- package/lib/commonjs/ui/hooks/useIdentityMutations.js +0 -111
- package/lib/commonjs/ui/hooks/useIdentityMutations.js.map +0 -1
- package/lib/module/ui/hooks/useIdentityMutations.js +0 -105
- package/lib/module/ui/hooks/useIdentityMutations.js.map +0 -1
- package/lib/typescript/types/bip39.d.ts +0 -32
- package/lib/typescript/ui/hooks/useIdentityMutations.d.ts +0 -41
- package/lib/typescript/ui/hooks/useIdentityMutations.d.ts.map +0 -1
- package/src/types/bip39.d.ts +0 -32
- package/src/ui/hooks/useIdentityMutations.ts +0 -115
|
@@ -7,7 +7,7 @@ import { fetchSessionsWithFallback, mapSessionsToClient } from '../../utils/sess
|
|
|
7
7
|
import { handleAuthError, isInvalidSessionError } from '../../utils/errorHandlers';
|
|
8
8
|
import type { StorageInterface } from '../../utils/storageHelpers';
|
|
9
9
|
import type { OxyServices } from '../../../core';
|
|
10
|
-
import { KeyManager, SignatureService } from '../../../crypto';
|
|
10
|
+
import { KeyManager, SignatureService, type BackupData } from '../../../crypto';
|
|
11
11
|
|
|
12
12
|
export interface UseAuthOperationsOptions {
|
|
13
13
|
oxyServices: OxyServices;
|
|
@@ -36,7 +36,7 @@ export interface UseAuthOperationsResult {
|
|
|
36
36
|
/** Create a new identity locally (offline-first) and optionally sync with server */
|
|
37
37
|
createIdentity: () => Promise<{ synced: boolean }>;
|
|
38
38
|
/** Import an existing identity from backup file data */
|
|
39
|
-
importIdentity: (backupData:
|
|
39
|
+
importIdentity: (backupData: BackupData, password: string) => Promise<{ synced: boolean }>;
|
|
40
40
|
/** Sign in with existing identity on device */
|
|
41
41
|
signIn: (deviceName?: string) => Promise<User>;
|
|
42
42
|
/** Logout from current session */
|
|
@@ -436,7 +436,7 @@ export const useAuthOperations = ({
|
|
|
436
436
|
* Import identity from backup file data (offline-first)
|
|
437
437
|
*/
|
|
438
438
|
const importIdentity = useCallback(
|
|
439
|
-
async (backupData:
|
|
439
|
+
async (backupData: BackupData, password: string): Promise<{ synced: boolean }> => {
|
|
440
440
|
if (!storage) throw new Error('Storage not initialized');
|
|
441
441
|
|
|
442
442
|
// Validate arguments - ensure backupData is an object, not a string (old signature)
|
|
@@ -13,9 +13,10 @@ interface UseSessionSocketProps {
|
|
|
13
13
|
baseURL: string;
|
|
14
14
|
onRemoteSignOut?: () => void;
|
|
15
15
|
onSessionRemoved?: (sessionId: string) => void;
|
|
16
|
+
onIdentityTransferComplete?: (data: { transferId: string; sourceDeviceId: string; publicKey: string; completedAt: string }) => void;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
export function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSessions, logout, clearSessionState, baseURL, onRemoteSignOut, onSessionRemoved }: UseSessionSocketProps) {
|
|
19
|
+
export function useSessionSocket({ userId, activeSessionId, currentDeviceId, refreshSessions, logout, clearSessionState, baseURL, onRemoteSignOut, onSessionRemoved, onIdentityTransferComplete }: UseSessionSocketProps) {
|
|
19
20
|
const socketRef = useRef<any>(null);
|
|
20
21
|
const joinedRoomRef = useRef<string | null>(null);
|
|
21
22
|
|
|
@@ -25,6 +26,7 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
|
|
|
25
26
|
const clearSessionStateRef = useRef(clearSessionState);
|
|
26
27
|
const onRemoteSignOutRef = useRef(onRemoteSignOut);
|
|
27
28
|
const onSessionRemovedRef = useRef(onSessionRemoved);
|
|
29
|
+
const onIdentityTransferCompleteRef = useRef(onIdentityTransferComplete);
|
|
28
30
|
const activeSessionIdRef = useRef(activeSessionId);
|
|
29
31
|
const currentDeviceIdRef = useRef(currentDeviceId);
|
|
30
32
|
|
|
@@ -35,9 +37,10 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
|
|
|
35
37
|
clearSessionStateRef.current = clearSessionState;
|
|
36
38
|
onRemoteSignOutRef.current = onRemoteSignOut;
|
|
37
39
|
onSessionRemovedRef.current = onSessionRemoved;
|
|
40
|
+
onIdentityTransferCompleteRef.current = onIdentityTransferComplete;
|
|
38
41
|
activeSessionIdRef.current = activeSessionId;
|
|
39
42
|
currentDeviceIdRef.current = currentDeviceId;
|
|
40
|
-
}, [refreshSessions, logout, clearSessionState, onRemoteSignOut, onSessionRemoved, activeSessionId, currentDeviceId]);
|
|
43
|
+
}, [refreshSessions, logout, clearSessionState, onRemoteSignOut, onSessionRemoved, onIdentityTransferComplete, activeSessionId, currentDeviceId]);
|
|
41
44
|
|
|
42
45
|
useEffect(() => {
|
|
43
46
|
if (!userId || !baseURL) {
|
|
@@ -192,6 +195,63 @@ export function useSessionSocket({ userId, activeSessionId, currentDeviceId, ref
|
|
|
192
195
|
}
|
|
193
196
|
});
|
|
194
197
|
}
|
|
198
|
+
} else if (data.type === 'identity_transfer_complete') {
|
|
199
|
+
// Handle identity transfer completion notification
|
|
200
|
+
const transferData = data as {
|
|
201
|
+
type: 'identity_transfer_complete';
|
|
202
|
+
transferId: string;
|
|
203
|
+
sourceDeviceId: string;
|
|
204
|
+
publicKey: string;
|
|
205
|
+
completedAt: string;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
if (__DEV__) {
|
|
209
|
+
logger.debug('Received identity_transfer_complete event', {
|
|
210
|
+
component: 'useSessionSocket',
|
|
211
|
+
transferId: transferData.transferId,
|
|
212
|
+
sourceDeviceId: transferData.sourceDeviceId,
|
|
213
|
+
currentDeviceId,
|
|
214
|
+
activeSessionId: activeSessionIdRef.current,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Check if this device is the source device
|
|
219
|
+
// Match by deviceId if available, otherwise show prompt if we have an active session
|
|
220
|
+
// (user can decide if they want to delete)
|
|
221
|
+
const isSourceDevice = transferData.sourceDeviceId && (
|
|
222
|
+
transferData.sourceDeviceId === currentDeviceId ||
|
|
223
|
+
// Fallback: if we don't have currentDeviceId but have an active session,
|
|
224
|
+
// show the prompt anyway (user can decide)
|
|
225
|
+
(currentDeviceId === null && activeSessionIdRef.current !== null)
|
|
226
|
+
);
|
|
227
|
+
|
|
228
|
+
if (isSourceDevice) {
|
|
229
|
+
if (__DEV__) {
|
|
230
|
+
logger.debug('Matched source device, showing deletion prompt', {
|
|
231
|
+
component: 'useSessionSocket',
|
|
232
|
+
transferId: transferData.transferId,
|
|
233
|
+
sourceDeviceId: transferData.sourceDeviceId,
|
|
234
|
+
currentDeviceId,
|
|
235
|
+
matchedBy: transferData.sourceDeviceId === currentDeviceId ? 'deviceId' : 'session',
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
// This is the source device - notify callback to show deletion prompt
|
|
239
|
+
if (onIdentityTransferCompleteRef.current) {
|
|
240
|
+
onIdentityTransferCompleteRef.current({
|
|
241
|
+
transferId: transferData.transferId,
|
|
242
|
+
sourceDeviceId: transferData.sourceDeviceId,
|
|
243
|
+
publicKey: transferData.publicKey,
|
|
244
|
+
completedAt: transferData.completedAt,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
} else if (__DEV__) {
|
|
248
|
+
logger.debug('Not the source device, ignoring transfer completion', {
|
|
249
|
+
component: 'useSessionSocket',
|
|
250
|
+
sourceDeviceId: transferData.sourceDeviceId,
|
|
251
|
+
currentDeviceId,
|
|
252
|
+
hasActiveSession: activeSessionIdRef.current !== null,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
195
255
|
} else {
|
|
196
256
|
// For other event types (e.g., session_created), refresh sessions (with error handling)
|
|
197
257
|
refreshSessionsRef.current().catch((error) => {
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.useCreateIdentity = useCreateIdentity;
|
|
7
|
-
exports.useImportIdentity = useImportIdentity;
|
|
8
|
-
exports.useSyncIdentity = useSyncIdentity;
|
|
9
|
-
var _reactQuery = require("@tanstack/react-query");
|
|
10
|
-
/**
|
|
11
|
-
* TanStack Query mutations for identity operations
|
|
12
|
-
* Provides offline-first mutations for identity creation, import, and sync
|
|
13
|
-
* Never deletes identity on errors - preserves user data
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Hook for creating a new identity with offline support
|
|
18
|
-
* Never deletes identity on error - preserves user data
|
|
19
|
-
*/
|
|
20
|
-
function useCreateIdentity(createIdentityFn) {
|
|
21
|
-
const queryClient = (0, _reactQuery.useQueryClient)();
|
|
22
|
-
return (0, _reactQuery.useMutation)({
|
|
23
|
-
mutationFn: createIdentityFn,
|
|
24
|
-
onSuccess: data => {
|
|
25
|
-
// Invalidate user queries to refetch after identity creation
|
|
26
|
-
queryClient.invalidateQueries({
|
|
27
|
-
queryKey: ['user']
|
|
28
|
-
});
|
|
29
|
-
queryClient.invalidateQueries({
|
|
30
|
-
queryKey: ['identity']
|
|
31
|
-
});
|
|
32
|
-
},
|
|
33
|
-
onError: error => {
|
|
34
|
-
// Never delete identity on error - just log it
|
|
35
|
-
// User can recover using backup file
|
|
36
|
-
if (__DEV__) {
|
|
37
|
-
console.warn('[useCreateIdentity] Identity creation error (identity may still exist):', error);
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
retry: false,
|
|
41
|
-
// Don't retry identity creation
|
|
42
|
-
networkMode: 'offlineFirst'
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Hook for importing an identity from backup file
|
|
48
|
-
* Never deletes identity on error - preserves user data
|
|
49
|
-
*/
|
|
50
|
-
function useImportIdentity(importIdentityFn) {
|
|
51
|
-
const queryClient = (0, _reactQuery.useQueryClient)();
|
|
52
|
-
return (0, _reactQuery.useMutation)({
|
|
53
|
-
mutationFn: variables => importIdentityFn(variables.backupData, variables.password),
|
|
54
|
-
onSuccess: data => {
|
|
55
|
-
queryClient.invalidateQueries({
|
|
56
|
-
queryKey: ['user']
|
|
57
|
-
});
|
|
58
|
-
queryClient.invalidateQueries({
|
|
59
|
-
queryKey: ['identity']
|
|
60
|
-
});
|
|
61
|
-
},
|
|
62
|
-
onError: error => {
|
|
63
|
-
// Never delete identity on error - just log it
|
|
64
|
-
if (__DEV__) {
|
|
65
|
-
console.warn('[useImportIdentity] Identity import error (identity may still exist):', error);
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
retry: false,
|
|
69
|
-
networkMode: 'offlineFirst'
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Hook for syncing identity with server
|
|
75
|
-
* Never deletes identity on error - only logs and allows retry
|
|
76
|
-
*/
|
|
77
|
-
function useSyncIdentity(syncIdentityFn) {
|
|
78
|
-
const queryClient = (0, _reactQuery.useQueryClient)();
|
|
79
|
-
return (0, _reactQuery.useMutation)({
|
|
80
|
-
mutationFn: syncIdentityFn,
|
|
81
|
-
onSuccess: user => {
|
|
82
|
-
// Update user cache
|
|
83
|
-
queryClient.setQueryData(['user', 'current'], user);
|
|
84
|
-
queryClient.invalidateQueries({
|
|
85
|
-
queryKey: ['user']
|
|
86
|
-
});
|
|
87
|
-
queryClient.invalidateQueries({
|
|
88
|
-
queryKey: ['identity']
|
|
89
|
-
});
|
|
90
|
-
},
|
|
91
|
-
onError: error => {
|
|
92
|
-
// Never delete identity on error - just log it
|
|
93
|
-
// User can retry sync later or use backup file
|
|
94
|
-
if (__DEV__) {
|
|
95
|
-
console.warn('[useSyncIdentity] Sync failed, but identity is preserved:', error);
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
retry: (failureCount, error) => {
|
|
99
|
-
// Retry up to 2 times for sync operations
|
|
100
|
-
// Don't retry if it's a network error - user can retry when online
|
|
101
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
102
|
-
const isNetworkError = errorMessage.includes('Network') || errorMessage.includes('Failed to fetch') || error?.code === 'NETWORK_ERROR';
|
|
103
|
-
if (isNetworkError) {
|
|
104
|
-
return false; // Don't retry network errors - user will retry when online
|
|
105
|
-
}
|
|
106
|
-
return failureCount < 2;
|
|
107
|
-
},
|
|
108
|
-
networkMode: 'offlineFirst'
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
//# sourceMappingURL=useIdentityMutations.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_reactQuery","require","useCreateIdentity","createIdentityFn","queryClient","useQueryClient","useMutation","mutationFn","onSuccess","data","invalidateQueries","queryKey","onError","error","__DEV__","console","warn","retry","networkMode","useImportIdentity","importIdentityFn","variables","backupData","password","useSyncIdentity","syncIdentityFn","user","setQueryData","failureCount","errorMessage","Error","message","String","isNetworkError","includes","code"],"sourceRoot":"../../../../src","sources":["ui/hooks/useIdentityMutations.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* TanStack Query mutations for identity operations
|
|
5
|
-
* Provides offline-first mutations for identity creation, import, and sync
|
|
6
|
-
* Never deletes identity on errors - preserves user data
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
10
|
-
/**
|
|
11
|
-
* Hook for creating a new identity with offline support
|
|
12
|
-
* Never deletes identity on error - preserves user data
|
|
13
|
-
*/
|
|
14
|
-
export function useCreateIdentity(createIdentityFn) {
|
|
15
|
-
const queryClient = useQueryClient();
|
|
16
|
-
return useMutation({
|
|
17
|
-
mutationFn: createIdentityFn,
|
|
18
|
-
onSuccess: data => {
|
|
19
|
-
// Invalidate user queries to refetch after identity creation
|
|
20
|
-
queryClient.invalidateQueries({
|
|
21
|
-
queryKey: ['user']
|
|
22
|
-
});
|
|
23
|
-
queryClient.invalidateQueries({
|
|
24
|
-
queryKey: ['identity']
|
|
25
|
-
});
|
|
26
|
-
},
|
|
27
|
-
onError: error => {
|
|
28
|
-
// Never delete identity on error - just log it
|
|
29
|
-
// User can recover using backup file
|
|
30
|
-
if (__DEV__) {
|
|
31
|
-
console.warn('[useCreateIdentity] Identity creation error (identity may still exist):', error);
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
retry: false,
|
|
35
|
-
// Don't retry identity creation
|
|
36
|
-
networkMode: 'offlineFirst'
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Hook for importing an identity from backup file
|
|
42
|
-
* Never deletes identity on error - preserves user data
|
|
43
|
-
*/
|
|
44
|
-
export function useImportIdentity(importIdentityFn) {
|
|
45
|
-
const queryClient = useQueryClient();
|
|
46
|
-
return useMutation({
|
|
47
|
-
mutationFn: variables => importIdentityFn(variables.backupData, variables.password),
|
|
48
|
-
onSuccess: data => {
|
|
49
|
-
queryClient.invalidateQueries({
|
|
50
|
-
queryKey: ['user']
|
|
51
|
-
});
|
|
52
|
-
queryClient.invalidateQueries({
|
|
53
|
-
queryKey: ['identity']
|
|
54
|
-
});
|
|
55
|
-
},
|
|
56
|
-
onError: error => {
|
|
57
|
-
// Never delete identity on error - just log it
|
|
58
|
-
if (__DEV__) {
|
|
59
|
-
console.warn('[useImportIdentity] Identity import error (identity may still exist):', error);
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
retry: false,
|
|
63
|
-
networkMode: 'offlineFirst'
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Hook for syncing identity with server
|
|
69
|
-
* Never deletes identity on error - only logs and allows retry
|
|
70
|
-
*/
|
|
71
|
-
export function useSyncIdentity(syncIdentityFn) {
|
|
72
|
-
const queryClient = useQueryClient();
|
|
73
|
-
return useMutation({
|
|
74
|
-
mutationFn: syncIdentityFn,
|
|
75
|
-
onSuccess: user => {
|
|
76
|
-
// Update user cache
|
|
77
|
-
queryClient.setQueryData(['user', 'current'], user);
|
|
78
|
-
queryClient.invalidateQueries({
|
|
79
|
-
queryKey: ['user']
|
|
80
|
-
});
|
|
81
|
-
queryClient.invalidateQueries({
|
|
82
|
-
queryKey: ['identity']
|
|
83
|
-
});
|
|
84
|
-
},
|
|
85
|
-
onError: error => {
|
|
86
|
-
// Never delete identity on error - just log it
|
|
87
|
-
// User can retry sync later or use backup file
|
|
88
|
-
if (__DEV__) {
|
|
89
|
-
console.warn('[useSyncIdentity] Sync failed, but identity is preserved:', error);
|
|
90
|
-
}
|
|
91
|
-
},
|
|
92
|
-
retry: (failureCount, error) => {
|
|
93
|
-
// Retry up to 2 times for sync operations
|
|
94
|
-
// Don't retry if it's a network error - user can retry when online
|
|
95
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
96
|
-
const isNetworkError = errorMessage.includes('Network') || errorMessage.includes('Failed to fetch') || error?.code === 'NETWORK_ERROR';
|
|
97
|
-
if (isNetworkError) {
|
|
98
|
-
return false; // Don't retry network errors - user will retry when online
|
|
99
|
-
}
|
|
100
|
-
return failureCount < 2;
|
|
101
|
-
},
|
|
102
|
-
networkMode: 'offlineFirst'
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
//# sourceMappingURL=useIdentityMutations.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["useMutation","useQueryClient","useCreateIdentity","createIdentityFn","queryClient","mutationFn","onSuccess","data","invalidateQueries","queryKey","onError","error","__DEV__","console","warn","retry","networkMode","useImportIdentity","importIdentityFn","variables","backupData","password","useSyncIdentity","syncIdentityFn","user","setQueryData","failureCount","errorMessage","Error","message","String","isNetworkError","includes","code"],"sourceRoot":"../../../../src","sources":["ui/hooks/useIdentityMutations.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
declare module 'bip39' {
|
|
2
|
-
export interface Wordlist {
|
|
3
|
-
[index: number]: string;
|
|
4
|
-
length: number;
|
|
5
|
-
getWord(index: number): string;
|
|
6
|
-
getWordIndex(word: string): number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const wordlists: {
|
|
10
|
-
english: string[];
|
|
11
|
-
chinese_simplified: string[];
|
|
12
|
-
chinese_traditional: string[];
|
|
13
|
-
french: string[];
|
|
14
|
-
italian: string[];
|
|
15
|
-
japanese: string[];
|
|
16
|
-
korean: string[];
|
|
17
|
-
spanish: string[];
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
// Use Uint8Array instead of Buffer for React Native compatibility
|
|
21
|
-
// In Node.js, Buffer extends Uint8Array so this is compatible
|
|
22
|
-
export function generateMnemonic(strength?: number, rng?: (size: number) => Uint8Array, wordlist?: string[]): string;
|
|
23
|
-
export function mnemonicToSeed(mnemonic: string, passphrase?: string): Promise<Uint8Array>;
|
|
24
|
-
export function mnemonicToSeedSync(mnemonic: string, passphrase?: string): Uint8Array;
|
|
25
|
-
export function mnemonicToEntropy(mnemonic: string, wordlist?: string[]): string;
|
|
26
|
-
export function entropyToMnemonic(entropy: string, wordlist?: string[]): string;
|
|
27
|
-
export function validateMnemonic(mnemonic: string, wordlist?: string[]): boolean;
|
|
28
|
-
export function mnemonicToSeedHex(mnemonic: string, passphrase?: string): Promise<string>;
|
|
29
|
-
export function mnemonicToSeedHexSync(mnemonic: string, passphrase?: string): string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TanStack Query mutations for identity operations
|
|
3
|
-
* Provides offline-first mutations for identity creation, import, and sync
|
|
4
|
-
* Never deletes identity on errors - preserves user data
|
|
5
|
-
*/
|
|
6
|
-
import type { User } from '../../models/interfaces';
|
|
7
|
-
export interface CreateIdentityResult {
|
|
8
|
-
synced: boolean;
|
|
9
|
-
}
|
|
10
|
-
export interface ImportIdentityResult {
|
|
11
|
-
synced: boolean;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Hook for creating a new identity with offline support
|
|
15
|
-
* Never deletes identity on error - preserves user data
|
|
16
|
-
*/
|
|
17
|
-
export declare function useCreateIdentity(createIdentityFn: () => Promise<CreateIdentityResult>): import("@tanstack/react-query").UseMutationResult<CreateIdentityResult, Error, void, unknown>;
|
|
18
|
-
/**
|
|
19
|
-
* Hook for importing an identity from backup file
|
|
20
|
-
* Never deletes identity on error - preserves user data
|
|
21
|
-
*/
|
|
22
|
-
export declare function useImportIdentity(importIdentityFn: (backupData: {
|
|
23
|
-
encrypted: string;
|
|
24
|
-
salt: string;
|
|
25
|
-
iv: string;
|
|
26
|
-
publicKey: string;
|
|
27
|
-
}, password: string) => Promise<ImportIdentityResult>): import("@tanstack/react-query").UseMutationResult<ImportIdentityResult, Error, {
|
|
28
|
-
backupData: {
|
|
29
|
-
encrypted: string;
|
|
30
|
-
salt: string;
|
|
31
|
-
iv: string;
|
|
32
|
-
publicKey: string;
|
|
33
|
-
};
|
|
34
|
-
password: string;
|
|
35
|
-
}, unknown>;
|
|
36
|
-
/**
|
|
37
|
-
* Hook for syncing identity with server
|
|
38
|
-
* Never deletes identity on error - only logs and allows retry
|
|
39
|
-
*/
|
|
40
|
-
export declare function useSyncIdentity(syncIdentityFn: () => Promise<User>): import("@tanstack/react-query").UseMutationResult<User, Error, void, unknown>;
|
|
41
|
-
//# sourceMappingURL=useIdentityMutations.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useIdentityMutations.d.ts","sourceRoot":"","sources":["../../../../src/ui/hooks/useIdentityMutations.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAEpD,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,gBAAgB,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,iGAqBtD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,gBAAgB,EAAE,CAAC,UAAU,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,oBAAoB,CAAC;gBAK7G;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;cAAY,MAAM;YAe7H;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,iFAoCpC"}
|
package/src/types/bip39.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
declare module 'bip39' {
|
|
2
|
-
export interface Wordlist {
|
|
3
|
-
[index: number]: string;
|
|
4
|
-
length: number;
|
|
5
|
-
getWord(index: number): string;
|
|
6
|
-
getWordIndex(word: string): number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const wordlists: {
|
|
10
|
-
english: string[];
|
|
11
|
-
chinese_simplified: string[];
|
|
12
|
-
chinese_traditional: string[];
|
|
13
|
-
french: string[];
|
|
14
|
-
italian: string[];
|
|
15
|
-
japanese: string[];
|
|
16
|
-
korean: string[];
|
|
17
|
-
spanish: string[];
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
// Use Uint8Array instead of Buffer for React Native compatibility
|
|
21
|
-
// In Node.js, Buffer extends Uint8Array so this is compatible
|
|
22
|
-
export function generateMnemonic(strength?: number, rng?: (size: number) => Uint8Array, wordlist?: string[]): string;
|
|
23
|
-
export function mnemonicToSeed(mnemonic: string, passphrase?: string): Promise<Uint8Array>;
|
|
24
|
-
export function mnemonicToSeedSync(mnemonic: string, passphrase?: string): Uint8Array;
|
|
25
|
-
export function mnemonicToEntropy(mnemonic: string, wordlist?: string[]): string;
|
|
26
|
-
export function entropyToMnemonic(entropy: string, wordlist?: string[]): string;
|
|
27
|
-
export function validateMnemonic(mnemonic: string, wordlist?: string[]): boolean;
|
|
28
|
-
export function mnemonicToSeedHex(mnemonic: string, passphrase?: string): Promise<string>;
|
|
29
|
-
export function mnemonicToSeedHexSync(mnemonic: string, passphrase?: string): string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TanStack Query mutations for identity operations
|
|
3
|
-
* Provides offline-first mutations for identity creation, import, and sync
|
|
4
|
-
* Never deletes identity on errors - preserves user data
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { useMutation, useQueryClient } from '@tanstack/react-query';
|
|
8
|
-
import type { User } from '../../models/interfaces';
|
|
9
|
-
|
|
10
|
-
export interface CreateIdentityResult {
|
|
11
|
-
synced: boolean;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface ImportIdentityResult {
|
|
15
|
-
synced: boolean;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Hook for creating a new identity with offline support
|
|
20
|
-
* Never deletes identity on error - preserves user data
|
|
21
|
-
*/
|
|
22
|
-
export function useCreateIdentity(
|
|
23
|
-
createIdentityFn: () => Promise<CreateIdentityResult>
|
|
24
|
-
) {
|
|
25
|
-
const queryClient = useQueryClient();
|
|
26
|
-
|
|
27
|
-
return useMutation({
|
|
28
|
-
mutationFn: createIdentityFn,
|
|
29
|
-
onSuccess: (data) => {
|
|
30
|
-
// Invalidate user queries to refetch after identity creation
|
|
31
|
-
queryClient.invalidateQueries({ queryKey: ['user'] });
|
|
32
|
-
queryClient.invalidateQueries({ queryKey: ['identity'] });
|
|
33
|
-
},
|
|
34
|
-
onError: (error) => {
|
|
35
|
-
// Never delete identity on error - just log it
|
|
36
|
-
// User can recover using backup file
|
|
37
|
-
if (__DEV__) {
|
|
38
|
-
console.warn('[useCreateIdentity] Identity creation error (identity may still exist):', error);
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
retry: false, // Don't retry identity creation
|
|
42
|
-
networkMode: 'offlineFirst',
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Hook for importing an identity from backup file
|
|
48
|
-
* Never deletes identity on error - preserves user data
|
|
49
|
-
*/
|
|
50
|
-
export function useImportIdentity(
|
|
51
|
-
importIdentityFn: (backupData: { encrypted: string; salt: string; iv: string; publicKey: string }, password: string) => Promise<ImportIdentityResult>
|
|
52
|
-
) {
|
|
53
|
-
const queryClient = useQueryClient();
|
|
54
|
-
|
|
55
|
-
return useMutation({
|
|
56
|
-
mutationFn: (variables: { backupData: { encrypted: string; salt: string; iv: string; publicKey: string }; password: string }) =>
|
|
57
|
-
importIdentityFn(variables.backupData, variables.password),
|
|
58
|
-
onSuccess: (data) => {
|
|
59
|
-
queryClient.invalidateQueries({ queryKey: ['user'] });
|
|
60
|
-
queryClient.invalidateQueries({ queryKey: ['identity'] });
|
|
61
|
-
},
|
|
62
|
-
onError: (error) => {
|
|
63
|
-
// Never delete identity on error - just log it
|
|
64
|
-
if (__DEV__) {
|
|
65
|
-
console.warn('[useImportIdentity] Identity import error (identity may still exist):', error);
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
retry: false,
|
|
69
|
-
networkMode: 'offlineFirst',
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Hook for syncing identity with server
|
|
75
|
-
* Never deletes identity on error - only logs and allows retry
|
|
76
|
-
*/
|
|
77
|
-
export function useSyncIdentity(
|
|
78
|
-
syncIdentityFn: () => Promise<User>
|
|
79
|
-
) {
|
|
80
|
-
const queryClient = useQueryClient();
|
|
81
|
-
|
|
82
|
-
return useMutation({
|
|
83
|
-
mutationFn: syncIdentityFn,
|
|
84
|
-
onSuccess: (user) => {
|
|
85
|
-
// Update user cache
|
|
86
|
-
queryClient.setQueryData(['user', 'current'], user);
|
|
87
|
-
queryClient.invalidateQueries({ queryKey: ['user'] });
|
|
88
|
-
queryClient.invalidateQueries({ queryKey: ['identity'] });
|
|
89
|
-
},
|
|
90
|
-
onError: (error) => {
|
|
91
|
-
// Never delete identity on error - just log it
|
|
92
|
-
// User can retry sync later or use backup file
|
|
93
|
-
if (__DEV__) {
|
|
94
|
-
console.warn('[useSyncIdentity] Sync failed, but identity is preserved:', error);
|
|
95
|
-
}
|
|
96
|
-
},
|
|
97
|
-
retry: (failureCount, error: any) => {
|
|
98
|
-
// Retry up to 2 times for sync operations
|
|
99
|
-
// Don't retry if it's a network error - user can retry when online
|
|
100
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
101
|
-
const isNetworkError =
|
|
102
|
-
errorMessage.includes('Network') ||
|
|
103
|
-
errorMessage.includes('Failed to fetch') ||
|
|
104
|
-
error?.code === 'NETWORK_ERROR';
|
|
105
|
-
|
|
106
|
-
if (isNetworkError) {
|
|
107
|
-
return false; // Don't retry network errors - user will retry when online
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return failureCount < 2;
|
|
111
|
-
},
|
|
112
|
-
networkMode: 'offlineFirst',
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
|