@tetherto/wdk-react-native-secure-storage 1.0.0-beta.1 → 1.0.0-beta.3

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.
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Timeout constants for keychain operations
3
+ */
4
+ export declare const DEFAULT_TIMEOUT_MS = 30000;
5
+ export declare const MIN_TIMEOUT_MS = 1000;
6
+ export declare const MAX_TIMEOUT_MS: number;
7
+ /**
8
+ * Cache TTL for device authentication availability (5 minutes)
9
+ */
10
+ export declare const DEVICE_AUTH_CACHE_TTL_MS: number;
11
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,kBAAkB,QAAQ,CAAA;AACvC,eAAO,MAAM,cAAc,OAAO,CAAA;AAClC,eAAO,MAAM,cAAc,QAAgB,CAAA;AAE3C;;GAEG;AACH,eAAO,MAAM,wBAAwB,QAAgB,CAAA"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEVICE_AUTH_CACHE_TTL_MS = exports.MAX_TIMEOUT_MS = exports.MIN_TIMEOUT_MS = exports.DEFAULT_TIMEOUT_MS = void 0;
4
+ /**
5
+ * Timeout constants for keychain operations
6
+ */
7
+ exports.DEFAULT_TIMEOUT_MS = 30000;
8
+ exports.MIN_TIMEOUT_MS = 1000;
9
+ exports.MAX_TIMEOUT_MS = 5 * 60 * 1000;
10
+ /**
11
+ * Cache TTL for device authentication availability (5 minutes)
12
+ */
13
+ exports.DEVICE_AUTH_CACHE_TTL_MS = 5 * 60 * 1000;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Base error class for all secure storage errors
3
+ */
4
+ export declare class SecureStorageError extends Error {
5
+ readonly code: string;
6
+ readonly cause?: Error | undefined;
7
+ constructor(message: string, code: string, cause?: Error | undefined);
8
+ }
9
+ /**
10
+ * Error thrown when keychain operations fail
11
+ *
12
+ * Note: This is a base error class for completeness. In practice, use
13
+ * KeychainWriteError or KeychainReadError for more specific error handling.
14
+ */
15
+ export declare class KeychainError extends SecureStorageError {
16
+ constructor(message: string, cause?: Error);
17
+ }
18
+ /**
19
+ * Error thrown when keychain write operations fail
20
+ */
21
+ export declare class KeychainWriteError extends SecureStorageError {
22
+ constructor(message: string, cause?: Error);
23
+ }
24
+ /**
25
+ * Error thrown when keychain read operations fail
26
+ */
27
+ export declare class KeychainReadError extends SecureStorageError {
28
+ constructor(message: string, cause?: Error);
29
+ }
30
+ /**
31
+ * Error thrown when authentication fails or is required but unavailable
32
+ */
33
+ export declare class AuthenticationError extends SecureStorageError {
34
+ constructor(message: string, cause?: Error);
35
+ }
36
+ /**
37
+ * Error thrown when input validation fails
38
+ */
39
+ export declare class ValidationError extends SecureStorageError {
40
+ constructor(message: string);
41
+ }
42
+ /**
43
+ * Error thrown when an operation times out
44
+ */
45
+ export declare class TimeoutError extends SecureStorageError {
46
+ constructor(message: string);
47
+ }
48
+ /**
49
+ * Error thrown when device security (PIN/pattern/password/biometrics) is not enabled
50
+ *
51
+ * This error can be used by apps that want to enforce device security as a prerequisite.
52
+ * Whether to require device security is up to the app - the library will still function
53
+ * on devices without authentication configured (data remains encrypted at rest).
54
+ */
55
+ export declare class DeviceSecurityNotEnabledError extends SecureStorageError {
56
+ constructor(message?: string, cause?: Error);
57
+ }
58
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;aAGzB,IAAI,EAAE,MAAM;aACZ,KAAK,CAAC,EAAE,KAAK;gBAF7B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,KAAK,YAAA;CAYhC;AAED;;;;;GAKG;AACH,qBAAa,aAAc,SAAQ,kBAAkB;gBACvC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI3C;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,kBAAkB;gBAC5C,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI3C;AAED;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,kBAAkB;gBAC3C,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI3C;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,kBAAkB;gBAC7C,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAI3C;AAED;;GAEG;AACH,qBAAa,eAAgB,SAAQ,kBAAkB;gBACzC,OAAO,EAAE,MAAM;CAI5B;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,kBAAkB;gBACtC,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;GAMG;AACH,qBAAa,6BAA8B,SAAQ,kBAAkB;gBACvD,OAAO,GAAE,MAA0I,EAAE,KAAK,CAAC,EAAE,KAAK;CAI/K"}
package/dist/errors.js ADDED
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeviceSecurityNotEnabledError = exports.TimeoutError = exports.ValidationError = exports.AuthenticationError = exports.KeychainReadError = exports.KeychainWriteError = exports.KeychainError = exports.SecureStorageError = void 0;
4
+ /**
5
+ * Base error class for all secure storage errors
6
+ */
7
+ class SecureStorageError extends Error {
8
+ constructor(message, code, cause) {
9
+ super(message);
10
+ this.code = code;
11
+ this.cause = cause;
12
+ this.name = 'SecureStorageError';
13
+ // Maintains proper stack trace for where our error was thrown (only available on V8)
14
+ // Note: Error.captureStackTrace is V8-specific (Node.js, Chrome). In React Native,
15
+ // this will typically work on Android (V8) but may not work on iOS (JavaScriptCore).
16
+ // If unavailable, the standard Error stack trace will be used instead.
17
+ if (Error.captureStackTrace) {
18
+ Error.captureStackTrace(this, this.constructor);
19
+ }
20
+ }
21
+ }
22
+ exports.SecureStorageError = SecureStorageError;
23
+ /**
24
+ * Error thrown when keychain operations fail
25
+ *
26
+ * Note: This is a base error class for completeness. In practice, use
27
+ * KeychainWriteError or KeychainReadError for more specific error handling.
28
+ */
29
+ class KeychainError extends SecureStorageError {
30
+ constructor(message, cause) {
31
+ super(message, 'KEYCHAIN_ERROR', cause);
32
+ this.name = 'KeychainError';
33
+ }
34
+ }
35
+ exports.KeychainError = KeychainError;
36
+ /**
37
+ * Error thrown when keychain write operations fail
38
+ */
39
+ class KeychainWriteError extends SecureStorageError {
40
+ constructor(message, cause) {
41
+ super(message, 'KEYCHAIN_WRITE_ERROR', cause);
42
+ this.name = 'KeychainWriteError';
43
+ }
44
+ }
45
+ exports.KeychainWriteError = KeychainWriteError;
46
+ /**
47
+ * Error thrown when keychain read operations fail
48
+ */
49
+ class KeychainReadError extends SecureStorageError {
50
+ constructor(message, cause) {
51
+ super(message, 'KEYCHAIN_READ_ERROR', cause);
52
+ this.name = 'KeychainReadError';
53
+ }
54
+ }
55
+ exports.KeychainReadError = KeychainReadError;
56
+ /**
57
+ * Error thrown when authentication fails or is required but unavailable
58
+ */
59
+ class AuthenticationError extends SecureStorageError {
60
+ constructor(message, cause) {
61
+ super(message, 'AUTHENTICATION_ERROR', cause);
62
+ this.name = 'AuthenticationError';
63
+ }
64
+ }
65
+ exports.AuthenticationError = AuthenticationError;
66
+ /**
67
+ * Error thrown when input validation fails
68
+ */
69
+ class ValidationError extends SecureStorageError {
70
+ constructor(message) {
71
+ super(message, 'VALIDATION_ERROR');
72
+ this.name = 'ValidationError';
73
+ }
74
+ }
75
+ exports.ValidationError = ValidationError;
76
+ /**
77
+ * Error thrown when an operation times out
78
+ */
79
+ class TimeoutError extends SecureStorageError {
80
+ constructor(message) {
81
+ super(message, 'TIMEOUT_ERROR');
82
+ this.name = 'TimeoutError';
83
+ }
84
+ }
85
+ exports.TimeoutError = TimeoutError;
86
+ /**
87
+ * Error thrown when device security (PIN/pattern/password/biometrics) is not enabled
88
+ *
89
+ * This error can be used by apps that want to enforce device security as a prerequisite.
90
+ * Whether to require device security is up to the app - the library will still function
91
+ * on devices without authentication configured (data remains encrypted at rest).
92
+ */
93
+ class DeviceSecurityNotEnabledError extends SecureStorageError {
94
+ constructor(message = 'Device security is not enabled. Please set up a PIN, pattern, or password in your device settings to use secure wallet storage.', cause) {
95
+ super(message, 'DEVICE_SECURITY_NOT_ENABLED', cause);
96
+ this.name = 'DeviceSecurityNotEnabledError';
97
+ }
98
+ }
99
+ exports.DeviceSecurityNotEnabledError = DeviceSecurityNotEnabledError;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @tetherto/wdk-react-native-secure-storage
3
+ *
4
+ * Secure storage abstractions for React Native
5
+ * Provides secure storage for sensitive data (encrypted seeds, keys)
6
+ *
7
+ * **Note on Internal Types:** Some internal types like `StorageKey` are intentionally
8
+ * not exported. These are implementation details that consumers should not use directly.
9
+ * Use the public API methods (setEncryptionKey, getEncryptionKey, etc.) instead.
10
+ */
11
+ export type { SecureStorage, SecureStorageOptions, AuthenticationOptions, SecureStorageItemOptions, } from './secureStorage';
12
+ export { createSecureStorage } from './secureStorage';
13
+ export { SecureStorageError, KeychainError, KeychainWriteError, KeychainReadError, AuthenticationError, ValidationError, TimeoutError, DeviceSecurityNotEnabledError, } from './errors';
14
+ export type { Logger, LogEntry } from './logger';
15
+ export { LogLevel, defaultLogger } from './logger';
16
+ export { MAX_IDENTIFIER_LENGTH, MAX_VALUE_LENGTH } from './validation';
17
+ export { MIN_TIMEOUT_MS, MAX_TIMEOUT_MS } from './constants';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EACrB,wBAAwB,GACzB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAGrD,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,6BAA6B,GAC9B,MAAM,UAAU,CAAA;AAGjB,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAChD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGlD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGtE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ /**
3
+ * @tetherto/wdk-react-native-secure-storage
4
+ *
5
+ * Secure storage abstractions for React Native
6
+ * Provides secure storage for sensitive data (encrypted seeds, keys)
7
+ *
8
+ * **Note on Internal Types:** Some internal types like `StorageKey` are intentionally
9
+ * not exported. These are implementation details that consumers should not use directly.
10
+ * Use the public API methods (setEncryptionKey, getEncryptionKey, etc.) instead.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.MAX_TIMEOUT_MS = exports.MIN_TIMEOUT_MS = exports.MAX_VALUE_LENGTH = exports.MAX_IDENTIFIER_LENGTH = exports.defaultLogger = exports.LogLevel = exports.DeviceSecurityNotEnabledError = exports.TimeoutError = exports.ValidationError = exports.AuthenticationError = exports.KeychainReadError = exports.KeychainWriteError = exports.KeychainError = exports.SecureStorageError = exports.createSecureStorage = void 0;
14
+ var secureStorage_1 = require("./secureStorage");
15
+ Object.defineProperty(exports, "createSecureStorage", { enumerable: true, get: function () { return secureStorage_1.createSecureStorage; } });
16
+ // Error classes
17
+ var errors_1 = require("./errors");
18
+ Object.defineProperty(exports, "SecureStorageError", { enumerable: true, get: function () { return errors_1.SecureStorageError; } });
19
+ Object.defineProperty(exports, "KeychainError", { enumerable: true, get: function () { return errors_1.KeychainError; } });
20
+ Object.defineProperty(exports, "KeychainWriteError", { enumerable: true, get: function () { return errors_1.KeychainWriteError; } });
21
+ Object.defineProperty(exports, "KeychainReadError", { enumerable: true, get: function () { return errors_1.KeychainReadError; } });
22
+ Object.defineProperty(exports, "AuthenticationError", { enumerable: true, get: function () { return errors_1.AuthenticationError; } });
23
+ Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_1.ValidationError; } });
24
+ Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return errors_1.TimeoutError; } });
25
+ Object.defineProperty(exports, "DeviceSecurityNotEnabledError", { enumerable: true, get: function () { return errors_1.DeviceSecurityNotEnabledError; } });
26
+ var logger_1 = require("./logger");
27
+ Object.defineProperty(exports, "LogLevel", { enumerable: true, get: function () { return logger_1.LogLevel; } });
28
+ Object.defineProperty(exports, "defaultLogger", { enumerable: true, get: function () { return logger_1.defaultLogger; } });
29
+ // Validation constants
30
+ var validation_1 = require("./validation");
31
+ Object.defineProperty(exports, "MAX_IDENTIFIER_LENGTH", { enumerable: true, get: function () { return validation_1.MAX_IDENTIFIER_LENGTH; } });
32
+ Object.defineProperty(exports, "MAX_VALUE_LENGTH", { enumerable: true, get: function () { return validation_1.MAX_VALUE_LENGTH; } });
33
+ // Timeout constants
34
+ var constants_1 = require("./constants");
35
+ Object.defineProperty(exports, "MIN_TIMEOUT_MS", { enumerable: true, get: function () { return constants_1.MIN_TIMEOUT_MS; } });
36
+ Object.defineProperty(exports, "MAX_TIMEOUT_MS", { enumerable: true, get: function () { return constants_1.MAX_TIMEOUT_MS; } });
@@ -0,0 +1,15 @@
1
+ import * as Keychain from 'react-native-keychain';
2
+ /**
3
+ * Keychain options for setGenericPassword
4
+ */
5
+ export type KeychainOptions = Parameters<typeof Keychain.setGenericPassword>[2];
6
+ /**
7
+ * Create keychain options with conditional access control
8
+ *
9
+ * @param deviceAuthAvailable - Whether device authentication (biometrics/PIN) is available
10
+ * @param requireAuth - Whether authentication should be required for this operation
11
+ * @param syncable - Whether the value should sync across devices (default: true)
12
+ * @returns Keychain options object with appropriate access control settings
13
+ */
14
+ export declare function createKeychainOptions(deviceAuthAvailable: boolean, requireAuth?: boolean, syncable?: boolean): KeychainOptions;
15
+ //# sourceMappingURL=keychainHelpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keychainHelpers.d.ts","sourceRoot":"","sources":["../src/keychainHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,uBAAuB,CAAA;AAEjD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAA;AAE/E;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,mBAAmB,EAAE,OAAO,EAC5B,WAAW,GAAE,OAAc,EAC3B,QAAQ,GAAE,OAAc,GACvB,eAAe,CAYjB"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createKeychainOptions = createKeychainOptions;
37
+ const Keychain = __importStar(require("react-native-keychain"));
38
+ /**
39
+ * Create keychain options with conditional access control
40
+ *
41
+ * @param deviceAuthAvailable - Whether device authentication (biometrics/PIN) is available
42
+ * @param requireAuth - Whether authentication should be required for this operation
43
+ * @param syncable - Whether the value should sync across devices (default: true)
44
+ * @returns Keychain options object with appropriate access control settings
45
+ */
46
+ function createKeychainOptions(deviceAuthAvailable, requireAuth = true, syncable = true) {
47
+ const options = {
48
+ accessible: syncable
49
+ ? Keychain.ACCESSIBLE.WHEN_UNLOCKED
50
+ : Keychain.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY,
51
+ };
52
+ if (requireAuth && deviceAuthAvailable) {
53
+ options.accessControl = Keychain.ACCESS_CONTROL.BIOMETRY_ANY_OR_DEVICE_PASSCODE;
54
+ }
55
+ return options;
56
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Log levels in order of severity
3
+ */
4
+ export declare enum LogLevel {
5
+ DEBUG = 0,
6
+ INFO = 1,
7
+ WARN = 2,
8
+ ERROR = 3
9
+ }
10
+ /**
11
+ * Log entry structure
12
+ */
13
+ export interface LogEntry {
14
+ level: LogLevel;
15
+ message: string;
16
+ timestamp: number;
17
+ context?: Record<string, unknown>;
18
+ error?: Error;
19
+ }
20
+ /**
21
+ * Logger interface for structured logging
22
+ */
23
+ export interface Logger {
24
+ debug(message: string, context?: Record<string, unknown>): void;
25
+ info(message: string, context?: Record<string, unknown>): void;
26
+ warn(message: string, context?: Record<string, unknown>): void;
27
+ error(message: string, error?: Error, context?: Record<string, unknown>): void;
28
+ /**
29
+ * Set the minimum log level
30
+ * Logs below this level will be ignored
31
+ */
32
+ setLevel?(level: LogLevel): void;
33
+ }
34
+ /**
35
+ * Default logger implementation
36
+ * Uses console methods but provides structured logging interface
37
+ *
38
+ * **Default Log Level:** ERROR
39
+ *
40
+ * The default log level is set to ERROR to minimize log noise in production.
41
+ * This ensures that only critical errors are logged by default, which is appropriate
42
+ * for production environments where excessive logging can impact performance and
43
+ * expose sensitive information.
44
+ *
45
+ * For development or debugging, you can change the log level:
46
+ * ```typescript
47
+ * defaultLogger.setLevel(LogLevel.DEBUG)
48
+ * ```
49
+ *
50
+ * For production monitoring of security events, consider setting to WARN:
51
+ * ```typescript
52
+ * defaultLogger.setLevel(LogLevel.WARN)
53
+ * ```
54
+ */
55
+ declare class DefaultLogger implements Logger {
56
+ private minLevel;
57
+ /**
58
+ * Set the minimum log level
59
+ */
60
+ setLevel(level: LogLevel): void;
61
+ /**
62
+ * Internal log method
63
+ */
64
+ private log;
65
+ debug(message: string, context?: Record<string, unknown>): void;
66
+ info(message: string, context?: Record<string, unknown>): void;
67
+ warn(message: string, context?: Record<string, unknown>): void;
68
+ error(message: string, error?: Error, context?: Record<string, unknown>): void;
69
+ }
70
+ /**
71
+ * Default logger instance
72
+ */
73
+ export declare const defaultLogger: DefaultLogger;
74
+ export {};
75
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,oBAAY,QAAQ;IAClB,KAAK,IAAI;IACT,IAAI,IAAI;IACR,IAAI,IAAI;IACR,KAAK,IAAI;CACV;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,QAAQ,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACjC,KAAK,CAAC,EAAE,KAAK,CAAA;CACd;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC9D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IAC9E;;;OAGG;IACH,QAAQ,CAAC,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,cAAM,aAAc,YAAW,MAAM;IACnC,OAAO,CAAC,QAAQ,CAA2B;IAE3C;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAI/B;;OAEG;IACH,OAAO,CAAC,GAAG;IAiCX,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI9D,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAG/E;AAED;;GAEG;AACH,eAAO,MAAM,aAAa,eAAsB,CAAA"}
package/dist/logger.js ADDED
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultLogger = exports.LogLevel = void 0;
4
+ /**
5
+ * Log levels in order of severity
6
+ */
7
+ var LogLevel;
8
+ (function (LogLevel) {
9
+ LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
10
+ LogLevel[LogLevel["INFO"] = 1] = "INFO";
11
+ LogLevel[LogLevel["WARN"] = 2] = "WARN";
12
+ LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
13
+ })(LogLevel || (exports.LogLevel = LogLevel = {}));
14
+ /**
15
+ * Default logger implementation
16
+ * Uses console methods but provides structured logging interface
17
+ *
18
+ * **Default Log Level:** ERROR
19
+ *
20
+ * The default log level is set to ERROR to minimize log noise in production.
21
+ * This ensures that only critical errors are logged by default, which is appropriate
22
+ * for production environments where excessive logging can impact performance and
23
+ * expose sensitive information.
24
+ *
25
+ * For development or debugging, you can change the log level:
26
+ * ```typescript
27
+ * defaultLogger.setLevel(LogLevel.DEBUG)
28
+ * ```
29
+ *
30
+ * For production monitoring of security events, consider setting to WARN:
31
+ * ```typescript
32
+ * defaultLogger.setLevel(LogLevel.WARN)
33
+ * ```
34
+ */
35
+ class DefaultLogger {
36
+ constructor() {
37
+ this.minLevel = LogLevel.ERROR;
38
+ }
39
+ /**
40
+ * Set the minimum log level
41
+ */
42
+ setLevel(level) {
43
+ this.minLevel = level;
44
+ }
45
+ /**
46
+ * Internal log method
47
+ */
48
+ log(level, message, error, context) {
49
+ if (level < this.minLevel) {
50
+ return;
51
+ }
52
+ const entry = {
53
+ level,
54
+ message,
55
+ timestamp: Date.now(),
56
+ context,
57
+ error,
58
+ };
59
+ // In production, this could send to a logging service
60
+ // For now, use console with structured output
61
+ // Note: Sensitive data (encryption keys, seeds, etc.) should never be logged
62
+ // The logger only logs error messages and metadata, never the actual stored values
63
+ const logMessage = JSON.stringify(entry, null, 2);
64
+ if (level >= LogLevel.ERROR) {
65
+ console.error(logMessage);
66
+ }
67
+ else if (level >= LogLevel.WARN) {
68
+ console.warn(logMessage);
69
+ }
70
+ else {
71
+ console.log(logMessage);
72
+ }
73
+ }
74
+ debug(message, context) {
75
+ this.log(LogLevel.DEBUG, message, undefined, context);
76
+ }
77
+ info(message, context) {
78
+ this.log(LogLevel.INFO, message, undefined, context);
79
+ }
80
+ warn(message, context) {
81
+ this.log(LogLevel.WARN, message, undefined, context);
82
+ }
83
+ error(message, error, context) {
84
+ this.log(LogLevel.ERROR, message, error, context);
85
+ }
86
+ }
87
+ /**
88
+ * Default logger instance
89
+ */
90
+ exports.defaultLogger = new DefaultLogger();
@@ -0,0 +1,104 @@
1
+ import { Logger } from './logger';
2
+ /**
3
+ * Authentication options for biometric prompts
4
+ */
5
+ export interface AuthenticationOptions {
6
+ promptMessage?: string;
7
+ cancelLabel?: string;
8
+ disableDeviceFallback?: boolean;
9
+ }
10
+ /**
11
+ * Options for a single secure storage item
12
+ */
13
+ export interface SecureStorageItemOptions {
14
+ requireBiometrics?: boolean;
15
+ }
16
+ /**
17
+ * Options for creating secure storage instance
18
+ */
19
+ export interface SecureStorageOptions {
20
+ logger?: Logger;
21
+ authentication?: AuthenticationOptions;
22
+ timeoutMs?: number;
23
+ }
24
+ /**
25
+ * Secure storage interface
26
+ *
27
+ * All methods accept an optional identifier parameter to support multiple wallets.
28
+ * When identifier is provided, it's used to create unique storage keys for each wallet.
29
+ * When identifier is undefined or empty, default keys are used (backward compatibility).
30
+ *
31
+ * Error Handling:
32
+ * - Getters return null when data is not found
33
+ * - All methods throw SecureStorageError or subclasses on failure
34
+ * - Validation errors are thrown before any operations
35
+ */
36
+ export interface SecureStorage {
37
+ isDeviceSecurityEnabled(): Promise<boolean>;
38
+ isBiometricAvailable(): Promise<boolean>;
39
+ authenticate(): Promise<boolean>;
40
+ setEncryptionKey(key: string, identifier?: string, options?: SecureStorageItemOptions): Promise<void>;
41
+ getEncryptionKey(identifier?: string, options?: SecureStorageItemOptions): Promise<string | null>;
42
+ setEncryptedSeed(encryptedSeed: string, identifier?: string): Promise<void>;
43
+ getEncryptedSeed(identifier?: string): Promise<string | null>;
44
+ setEncryptedEntropy(encryptedEntropy: string, identifier?: string): Promise<void>;
45
+ getEncryptedEntropy(identifier?: string): Promise<string | null>;
46
+ getAllEncrypted(identifier?: string): Promise<{
47
+ encryptedSeed: string | null;
48
+ encryptedEntropy: string | null;
49
+ encryptionKey: string | null;
50
+ }>;
51
+ hasWallet(identifier?: string): Promise<boolean>;
52
+ deleteWallet(identifier?: string): Promise<void>;
53
+ /**
54
+ * Cleanup method to release resources associated with this storage instance
55
+ *
56
+ * This method should be called when the storage instance is no longer needed
57
+ * to ensure proper cleanup of resources. Note that this does NOT delete stored
58
+ * wallet data - use deleteWallet() for that purpose.
59
+ *
60
+ * Currently, this is a no-op as the module uses shared resources, but it's
61
+ * provided for future extensibility and to maintain a consistent API.
62
+ */
63
+ cleanup(): void;
64
+ }
65
+ /**
66
+ * Secure storage wrapper factory for wallet credentials
67
+ *
68
+ * Uses react-native-keychain which provides encrypted storage with selective cloud sync.
69
+ * Creates a new instance each time it's called, allowing different configurations
70
+ * for different use cases. For most apps, you should create one instance and reuse it.
71
+ *
72
+ * SECURITY:
73
+ * - Storage is app-scoped by the OS (isolated by bundle ID/package name)
74
+ * - iOS: Uses Keychain Services with iCloud Keychain sync (when user signed into iCloud)
75
+ * - Android: Uses KeyStore with Google Cloud backup (when device backup enabled)
76
+ * - Data is ALWAYS encrypted at rest by Keychain (iOS) / KeyStore (Android)
77
+ * - Cloud sync behavior:
78
+ * - Encryption key: ACCESSIBLE.WHEN_UNLOCKED enables iCloud Keychain sync (iOS) and Google Cloud backup (Android)
79
+ * - Encrypted seed and entropy: ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY prevents cloud sync (device-only storage)
80
+ * - Data is encrypted by Apple/Google's E2EE infrastructure
81
+ * - Encryption key requires device unlock + biometric/PIN authentication to access (when available)
82
+ * - Encrypted seed and entropy do not require authentication but are still encrypted at rest
83
+ * - On devices without authentication, data is still encrypted at rest but accessible when device is unlocked
84
+ * - Device-level keychain/keystore provides rate limiting and lockout mechanisms
85
+ * - Input validation prevents injection attacks
86
+ *
87
+ * Two different apps will NOT share data because storage is isolated by bundle ID/package name.
88
+ *
89
+ * @param options - Optional configuration for logger, authentication messages, and timeouts
90
+ * @returns SecureStorage instance
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const storage = createSecureStorage({
95
+ * logger: customLogger,
96
+ * authentication: {
97
+ * promptMessage: 'Authenticate to access wallet',
98
+ * },
99
+ * timeoutMs: 30000,
100
+ * })
101
+ * ```
102
+ */
103
+ export declare function createSecureStorage(options?: SecureStorageOptions): SecureStorage;
104
+ //# sourceMappingURL=secureStorage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secureStorage.d.ts","sourceRoot":"","sources":["../src/secureStorage.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,MAAM,EAAiB,MAAM,UAAU,CAAA;AAoBhD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,qBAAqB,CAAA;IACtC,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,aAAa;IAC5B,uBAAuB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3C,oBAAoB,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IACxC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;IAChC,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrG,gBAAgB,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,wBAAwB,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACjG,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3E,gBAAgB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAC7D,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjF,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAChE,eAAe,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAC5C,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;QAC5B,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAA;QAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;KAC7B,CAAC,CAAA;IACF,SAAS,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAChD,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD;;;;;;;;;OASG;IACH,OAAO,IAAI,IAAI,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,aAAa,CAsjBjF"}