@shadow-corp/nearconnect 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +546 -0
- package/build/InjectedWallet.d.ts +22 -0
- package/build/InjectedWallet.js +58 -0
- package/build/InjectedWallet.js.map +1 -0
- package/build/NearConnector.d.ts +151 -0
- package/build/NearConnector.js +536 -0
- package/build/NearConnector.js.map +1 -0
- package/build/ParentFrameWallet.d.ts +22 -0
- package/build/ParentFrameWallet.js +66 -0
- package/build/ParentFrameWallet.js.map +1 -0
- package/build/SandboxedWallet/code.d.ts +7 -0
- package/build/SandboxedWallet/code.js +324 -0
- package/build/SandboxedWallet/code.js.map +1 -0
- package/build/SandboxedWallet/executor.d.ts +23 -0
- package/build/SandboxedWallet/executor.js +338 -0
- package/build/SandboxedWallet/executor.js.map +1 -0
- package/build/SandboxedWallet/iframe.d.ts +18 -0
- package/build/SandboxedWallet/iframe.js +78 -0
- package/build/SandboxedWallet/iframe.js.map +1 -0
- package/build/SandboxedWallet/index.d.ts +24 -0
- package/build/SandboxedWallet/index.js +54 -0
- package/build/SandboxedWallet/index.js.map +1 -0
- package/build/actions/index.d.ts +3 -0
- package/build/actions/index.js +105 -0
- package/build/actions/index.js.map +1 -0
- package/build/actions/types.d.ts +76 -0
- package/build/actions/types.js +3 -0
- package/build/actions/types.js.map +1 -0
- package/build/connection/health.d.ts +213 -0
- package/build/connection/health.js +391 -0
- package/build/connection/health.js.map +1 -0
- package/build/connection/index.d.ts +4 -0
- package/build/connection/index.js +48 -0
- package/build/connection/index.js.map +1 -0
- package/build/connection/reconnect.d.ts +261 -0
- package/build/connection/reconnect.js +454 -0
- package/build/connection/reconnect.js.map +1 -0
- package/build/connection/retry.d.ts +187 -0
- package/build/connection/retry.js +427 -0
- package/build/connection/retry.js.map +1 -0
- package/build/connection/state.d.ts +222 -0
- package/build/connection/state.js +431 -0
- package/build/connection/state.js.map +1 -0
- package/build/errors.d.ts +177 -0
- package/build/errors.js +546 -0
- package/build/errors.js.map +1 -0
- package/build/hardware/errors.d.ts +36 -0
- package/build/hardware/errors.js +127 -0
- package/build/hardware/errors.js.map +1 -0
- package/build/hardware/index.d.ts +7 -0
- package/build/hardware/index.js +39 -0
- package/build/hardware/index.js.map +1 -0
- package/build/hardware/near-app.d.ts +95 -0
- package/build/hardware/near-app.js +291 -0
- package/build/hardware/near-app.js.map +1 -0
- package/build/hardware/transport.d.ts +94 -0
- package/build/hardware/transport.js +267 -0
- package/build/hardware/transport.js.map +1 -0
- package/build/hardware/types.d.ts +98 -0
- package/build/hardware/types.js +72 -0
- package/build/hardware/types.js.map +1 -0
- package/build/helpers/analytics.d.ts +191 -0
- package/build/helpers/analytics.js +304 -0
- package/build/helpers/analytics.js.map +1 -0
- package/build/helpers/base58.d.ts +6 -0
- package/build/helpers/base58.js +47 -0
- package/build/helpers/base58.js.map +1 -0
- package/build/helpers/events.d.ts +42 -0
- package/build/helpers/events.js +68 -0
- package/build/helpers/events.js.map +1 -0
- package/build/helpers/html.d.ts +8 -0
- package/build/helpers/html.js +30 -0
- package/build/helpers/html.js.map +1 -0
- package/build/helpers/indexdb.d.ts +14 -0
- package/build/helpers/indexdb.js +166 -0
- package/build/helpers/indexdb.js.map +1 -0
- package/build/helpers/manifest.d.ts +147 -0
- package/build/helpers/manifest.js +329 -0
- package/build/helpers/manifest.js.map +1 -0
- package/build/helpers/queue.d.ts +11 -0
- package/build/helpers/queue.js +48 -0
- package/build/helpers/queue.js.map +1 -0
- package/build/helpers/session.d.ts +119 -0
- package/build/helpers/session.js +289 -0
- package/build/helpers/session.js.map +1 -0
- package/build/helpers/simulation.d.ts +128 -0
- package/build/helpers/simulation.js +441 -0
- package/build/helpers/simulation.js.map +1 -0
- package/build/helpers/storage.d.ts +58 -0
- package/build/helpers/storage.js +190 -0
- package/build/helpers/storage.js.map +1 -0
- package/build/helpers/trust.d.ts +157 -0
- package/build/helpers/trust.js +340 -0
- package/build/helpers/trust.js.map +1 -0
- package/build/helpers/url.d.ts +1 -0
- package/build/helpers/url.js +13 -0
- package/build/helpers/url.js.map +1 -0
- package/build/helpers/uuid.d.ts +1 -0
- package/build/helpers/uuid.js +14 -0
- package/build/helpers/uuid.js.map +1 -0
- package/build/index.d.ts +21 -0
- package/build/index.js +167 -0
- package/build/index.js.map +1 -0
- package/build/popups/IframeWalletPopup.d.ts +16 -0
- package/build/popups/IframeWalletPopup.js +38 -0
- package/build/popups/IframeWalletPopup.js.map +1 -0
- package/build/popups/NearWalletsPopup.d.ts +25 -0
- package/build/popups/NearWalletsPopup.js +153 -0
- package/build/popups/NearWalletsPopup.js.map +1 -0
- package/build/popups/Popup.d.ts +22 -0
- package/build/popups/Popup.js +94 -0
- package/build/popups/Popup.js.map +1 -0
- package/build/popups/styles.d.ts +1 -0
- package/build/popups/styles.js +257 -0
- package/build/popups/styles.js.map +1 -0
- package/build/security/audit-log.d.ts +123 -0
- package/build/security/audit-log.js +268 -0
- package/build/security/audit-log.js.map +1 -0
- package/build/security/csp.d.ts +68 -0
- package/build/security/csp.js +328 -0
- package/build/security/csp.js.map +1 -0
- package/build/security/index.d.ts +10 -0
- package/build/security/index.js +42 -0
- package/build/security/index.js.map +1 -0
- package/build/security/origin-guard.d.ts +90 -0
- package/build/security/origin-guard.js +244 -0
- package/build/security/origin-guard.js.map +1 -0
- package/build/security/rate-limiter.d.ts +84 -0
- package/build/security/rate-limiter.js +212 -0
- package/build/security/rate-limiter.js.map +1 -0
- package/build/security/secure-storage.d.ts +77 -0
- package/build/security/secure-storage.js +242 -0
- package/build/security/secure-storage.js.map +1 -0
- package/build/security/transaction-guard.d.ts +71 -0
- package/build/security/transaction-guard.js +239 -0
- package/build/security/transaction-guard.js.map +1 -0
- package/build/types.d.ts +508 -0
- package/build/types.js +3 -0
- package/build/types.js.map +1 -0
- package/build/ui/AccountSwitcherModal.d.ts +53 -0
- package/build/ui/AccountSwitcherModal.js +239 -0
- package/build/ui/AccountSwitcherModal.js.map +1 -0
- package/build/ui/Modal.d.ts +84 -0
- package/build/ui/Modal.js +278 -0
- package/build/ui/Modal.js.map +1 -0
- package/build/ui/TransactionModal.d.ts +84 -0
- package/build/ui/TransactionModal.js +406 -0
- package/build/ui/TransactionModal.js.map +1 -0
- package/build/ui/WalletSelectorModal.d.ts +97 -0
- package/build/ui/WalletSelectorModal.js +481 -0
- package/build/ui/WalletSelectorModal.js.map +1 -0
- package/build/ui/icons.d.ts +19 -0
- package/build/ui/icons.js +65 -0
- package/build/ui/icons.js.map +1 -0
- package/build/ui/index.d.ts +10 -0
- package/build/ui/index.js +31 -0
- package/build/ui/index.js.map +1 -0
- package/build/ui/styles.d.ts +5 -0
- package/build/ui/styles.js +973 -0
- package/build/ui/styles.js.map +1 -0
- package/build/ui/theme.d.ts +133 -0
- package/build/ui/theme.js +204 -0
- package/build/ui/theme.js.map +1 -0
- package/build/wallets/external/index.d.ts +4 -0
- package/build/wallets/external/index.js +9 -0
- package/build/wallets/external/index.js.map +1 -0
- package/build/wallets/external/manager.d.ts +152 -0
- package/build/wallets/external/manager.js +586 -0
- package/build/wallets/external/manager.js.map +1 -0
- package/build/wallets/privileged/index.d.ts +5 -0
- package/build/wallets/privileged/index.js +12 -0
- package/build/wallets/privileged/index.js.map +1 -0
- package/build/wallets/privileged/ledger.d.ts +132 -0
- package/build/wallets/privileged/ledger.js +563 -0
- package/build/wallets/privileged/ledger.js.map +1 -0
- package/build/wallets/privileged/manager.d.ts +54 -0
- package/build/wallets/privileged/manager.js +174 -0
- package/build/wallets/privileged/manager.js.map +1 -0
- package/package.json +33 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Rate Limiting & Anti-Abuse Layer
|
|
4
|
+
* Prevents brute force attacks and rapid-fire abuse
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.rpcLimiter = exports.signLimiter = exports.connectLimiter = exports.RateLimiter = void 0;
|
|
8
|
+
exports.rateLimit = rateLimit;
|
|
9
|
+
exports.withRateLimit = withRateLimit;
|
|
10
|
+
class RateLimiter {
|
|
11
|
+
entries = new Map();
|
|
12
|
+
config;
|
|
13
|
+
constructor(config) {
|
|
14
|
+
this.config = {
|
|
15
|
+
maxRequests: 10,
|
|
16
|
+
windowMs: 60000, // 1 minute
|
|
17
|
+
blockDurationMs: 300000, // 5 minutes
|
|
18
|
+
slidingWindow: true,
|
|
19
|
+
...config,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Check if an action is allowed and record the request
|
|
24
|
+
*/
|
|
25
|
+
check(action) {
|
|
26
|
+
const now = Date.now();
|
|
27
|
+
const entry = this.entries.get(action) || { requests: [] };
|
|
28
|
+
// Check if currently blocked
|
|
29
|
+
if (entry.blockedUntil && entry.blockedUntil > now) {
|
|
30
|
+
const retryAfter = Math.ceil((entry.blockedUntil - now) / 1000);
|
|
31
|
+
return {
|
|
32
|
+
allowed: false,
|
|
33
|
+
retryAfter,
|
|
34
|
+
remaining: 0,
|
|
35
|
+
resetIn: entry.blockedUntil - now,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// Clean old requests outside the window
|
|
39
|
+
const windowStart = now - this.config.windowMs;
|
|
40
|
+
entry.requests = entry.requests.filter(t => t > windowStart);
|
|
41
|
+
// Check if limit exceeded
|
|
42
|
+
if (entry.requests.length >= this.config.maxRequests) {
|
|
43
|
+
// Block the action
|
|
44
|
+
entry.blockedUntil = now + this.config.blockDurationMs;
|
|
45
|
+
this.entries.set(action, entry);
|
|
46
|
+
return {
|
|
47
|
+
allowed: false,
|
|
48
|
+
retryAfter: Math.ceil(this.config.blockDurationMs / 1000),
|
|
49
|
+
remaining: 0,
|
|
50
|
+
resetIn: this.config.blockDurationMs,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// Record this request
|
|
54
|
+
entry.requests.push(now);
|
|
55
|
+
this.entries.set(action, entry);
|
|
56
|
+
// Calculate reset time
|
|
57
|
+
const oldestRequest = entry.requests[0] || now;
|
|
58
|
+
const resetIn = this.config.slidingWindow
|
|
59
|
+
? oldestRequest + this.config.windowMs - now
|
|
60
|
+
: this.config.windowMs - (now - oldestRequest);
|
|
61
|
+
return {
|
|
62
|
+
allowed: true,
|
|
63
|
+
remaining: this.config.maxRequests - entry.requests.length,
|
|
64
|
+
resetIn: Math.max(0, resetIn),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Check without recording (peek)
|
|
69
|
+
*/
|
|
70
|
+
peek(action) {
|
|
71
|
+
const now = Date.now();
|
|
72
|
+
const entry = this.entries.get(action) || { requests: [] };
|
|
73
|
+
// Check if currently blocked
|
|
74
|
+
if (entry.blockedUntil && entry.blockedUntil > now) {
|
|
75
|
+
return {
|
|
76
|
+
allowed: false,
|
|
77
|
+
retryAfter: Math.ceil((entry.blockedUntil - now) / 1000),
|
|
78
|
+
remaining: 0,
|
|
79
|
+
resetIn: entry.blockedUntil - now,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// Count recent requests
|
|
83
|
+
const windowStart = now - this.config.windowMs;
|
|
84
|
+
const recentRequests = entry.requests.filter(t => t > windowStart);
|
|
85
|
+
return {
|
|
86
|
+
allowed: recentRequests.length < this.config.maxRequests,
|
|
87
|
+
remaining: Math.max(0, this.config.maxRequests - recentRequests.length),
|
|
88
|
+
resetIn: recentRequests.length > 0
|
|
89
|
+
? (recentRequests[0] || now) + this.config.windowMs - now
|
|
90
|
+
: 0,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Reset limits for an action
|
|
95
|
+
*/
|
|
96
|
+
reset(action) {
|
|
97
|
+
this.entries.delete(action);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Reset all limits
|
|
101
|
+
*/
|
|
102
|
+
resetAll() {
|
|
103
|
+
this.entries.clear();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Manually block an action
|
|
107
|
+
*/
|
|
108
|
+
block(action, durationMs) {
|
|
109
|
+
const entry = this.entries.get(action) || { requests: [] };
|
|
110
|
+
entry.blockedUntil = Date.now() + (durationMs || this.config.blockDurationMs);
|
|
111
|
+
this.entries.set(action, entry);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Unblock an action
|
|
115
|
+
*/
|
|
116
|
+
unblock(action) {
|
|
117
|
+
const entry = this.entries.get(action);
|
|
118
|
+
if (entry) {
|
|
119
|
+
delete entry.blockedUntil;
|
|
120
|
+
this.entries.set(action, entry);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Get current status for all tracked actions
|
|
125
|
+
*/
|
|
126
|
+
getStatus() {
|
|
127
|
+
const status = new Map();
|
|
128
|
+
for (const action of this.entries.keys()) {
|
|
129
|
+
status.set(action, this.peek(action));
|
|
130
|
+
}
|
|
131
|
+
return status;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Cleanup expired entries
|
|
135
|
+
*/
|
|
136
|
+
cleanup() {
|
|
137
|
+
const now = Date.now();
|
|
138
|
+
const windowStart = now - this.config.windowMs;
|
|
139
|
+
for (const [action, entry] of this.entries.entries()) {
|
|
140
|
+
// Remove expired blocks
|
|
141
|
+
if (entry.blockedUntil && entry.blockedUntil <= now) {
|
|
142
|
+
delete entry.blockedUntil;
|
|
143
|
+
}
|
|
144
|
+
// Remove old requests
|
|
145
|
+
entry.requests = entry.requests.filter(t => t > windowStart);
|
|
146
|
+
// Remove empty entries
|
|
147
|
+
if (entry.requests.length === 0 && !entry.blockedUntil) {
|
|
148
|
+
this.entries.delete(action);
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
this.entries.set(action, entry);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
exports.RateLimiter = RateLimiter;
|
|
157
|
+
/**
|
|
158
|
+
* Pre-configured rate limiter for wallet connections
|
|
159
|
+
* Allows 5 connection attempts per minute, blocks for 2 minutes after
|
|
160
|
+
*/
|
|
161
|
+
exports.connectLimiter = new RateLimiter({
|
|
162
|
+
maxRequests: 5,
|
|
163
|
+
windowMs: 60000, // 1 minute
|
|
164
|
+
blockDurationMs: 120000, // 2 minutes
|
|
165
|
+
});
|
|
166
|
+
/**
|
|
167
|
+
* Pre-configured rate limiter for transaction signing
|
|
168
|
+
* Allows 20 signs per minute, blocks for 1 minute after
|
|
169
|
+
*/
|
|
170
|
+
exports.signLimiter = new RateLimiter({
|
|
171
|
+
maxRequests: 20,
|
|
172
|
+
windowMs: 60000, // 1 minute
|
|
173
|
+
blockDurationMs: 60000, // 1 minute
|
|
174
|
+
});
|
|
175
|
+
/**
|
|
176
|
+
* Pre-configured rate limiter for RPC calls
|
|
177
|
+
* Allows 100 calls per minute
|
|
178
|
+
*/
|
|
179
|
+
exports.rpcLimiter = new RateLimiter({
|
|
180
|
+
maxRequests: 100,
|
|
181
|
+
windowMs: 60000,
|
|
182
|
+
blockDurationMs: 30000,
|
|
183
|
+
});
|
|
184
|
+
/**
|
|
185
|
+
* Decorator to rate limit a function
|
|
186
|
+
*/
|
|
187
|
+
function rateLimit(limiter, action) {
|
|
188
|
+
return function (_target, _propertyKey, descriptor) {
|
|
189
|
+
const original = descriptor.value;
|
|
190
|
+
descriptor.value = async function (...args) {
|
|
191
|
+
const result = limiter.check(action);
|
|
192
|
+
if (!result.allowed) {
|
|
193
|
+
throw new Error(`Rate limited. Retry in ${result.retryAfter} seconds.`);
|
|
194
|
+
}
|
|
195
|
+
return original.apply(this, args);
|
|
196
|
+
};
|
|
197
|
+
return descriptor;
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Higher-order function to wrap an async function with rate limiting
|
|
202
|
+
*/
|
|
203
|
+
function withRateLimit(fn, limiter, action) {
|
|
204
|
+
return (async (...args) => {
|
|
205
|
+
const result = limiter.check(action);
|
|
206
|
+
if (!result.allowed) {
|
|
207
|
+
throw new Error(`Rate limited. Retry in ${result.retryAfter} seconds.`);
|
|
208
|
+
}
|
|
209
|
+
return fn(...args);
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=rate-limiter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/security/rate-limiter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secure Storage Layer
|
|
3
|
+
* Encrypts sensitive session data to protect against localStorage theft
|
|
4
|
+
*/
|
|
5
|
+
export interface SecureStorageOptions {
|
|
6
|
+
/** Whether to encrypt the data */
|
|
7
|
+
encrypt?: boolean;
|
|
8
|
+
/** Time to live in milliseconds */
|
|
9
|
+
ttl?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class SecureStorage {
|
|
12
|
+
private namespace;
|
|
13
|
+
private encryptionKey;
|
|
14
|
+
private initialized;
|
|
15
|
+
constructor(namespace?: string);
|
|
16
|
+
/**
|
|
17
|
+
* Initialize encryption (call once on app start)
|
|
18
|
+
* Must be called before using encrypted storage
|
|
19
|
+
*/
|
|
20
|
+
init(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Get key material from session-specific entropy
|
|
23
|
+
*/
|
|
24
|
+
private getKeyMaterial;
|
|
25
|
+
/**
|
|
26
|
+
* Get or create session-specific entropy
|
|
27
|
+
*/
|
|
28
|
+
private getOrCreateSessionEntropy;
|
|
29
|
+
/**
|
|
30
|
+
* Store data securely
|
|
31
|
+
*/
|
|
32
|
+
set<T>(key: string, value: T, options?: SecureStorageOptions): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Retrieve data
|
|
35
|
+
*/
|
|
36
|
+
get<T>(key: string, options?: SecureStorageOptions): Promise<T | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Check if a key exists
|
|
39
|
+
*/
|
|
40
|
+
has(key: string): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Remove data
|
|
43
|
+
*/
|
|
44
|
+
remove(key: string): void;
|
|
45
|
+
/**
|
|
46
|
+
* Clear all data for this namespace
|
|
47
|
+
*/
|
|
48
|
+
clear(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Cleanup expired entries
|
|
51
|
+
*/
|
|
52
|
+
cleanup(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get all keys in this namespace
|
|
55
|
+
*/
|
|
56
|
+
keys(): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Encrypt plaintext using AES-GCM
|
|
59
|
+
*/
|
|
60
|
+
private encrypt;
|
|
61
|
+
/**
|
|
62
|
+
* Decrypt ciphertext
|
|
63
|
+
*/
|
|
64
|
+
private decrypt;
|
|
65
|
+
/**
|
|
66
|
+
* Check if data looks encrypted
|
|
67
|
+
*/
|
|
68
|
+
private looksEncrypted;
|
|
69
|
+
/**
|
|
70
|
+
* Check if encryption is available
|
|
71
|
+
*/
|
|
72
|
+
isEncryptionAvailable(): boolean;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Create and initialize a secure storage instance
|
|
76
|
+
*/
|
|
77
|
+
export declare function createSecureStorage(namespace?: string): Promise<SecureStorage>;
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Secure Storage Layer
|
|
4
|
+
* Encrypts sensitive session data to protect against localStorage theft
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.SecureStorage = void 0;
|
|
8
|
+
exports.createSecureStorage = createSecureStorage;
|
|
9
|
+
class SecureStorage {
|
|
10
|
+
namespace;
|
|
11
|
+
encryptionKey = null;
|
|
12
|
+
initialized = false;
|
|
13
|
+
constructor(namespace = 'near-connect') {
|
|
14
|
+
this.namespace = namespace;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Initialize encryption (call once on app start)
|
|
18
|
+
* Must be called before using encrypted storage
|
|
19
|
+
*/
|
|
20
|
+
async init() {
|
|
21
|
+
if (this.initialized)
|
|
22
|
+
return;
|
|
23
|
+
try {
|
|
24
|
+
const keyMaterial = await this.getKeyMaterial();
|
|
25
|
+
this.encryptionKey = await crypto.subtle.deriveKey({
|
|
26
|
+
name: 'PBKDF2',
|
|
27
|
+
salt: new TextEncoder().encode(this.namespace + ':salt'),
|
|
28
|
+
iterations: 100000,
|
|
29
|
+
hash: 'SHA-256',
|
|
30
|
+
}, keyMaterial, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
|
|
31
|
+
this.initialized = true;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.warn('[SecureStorage] Encryption initialization failed, falling back to unencrypted storage', error);
|
|
35
|
+
this.initialized = true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get key material from session-specific entropy
|
|
40
|
+
*/
|
|
41
|
+
async getKeyMaterial() {
|
|
42
|
+
// Combine multiple entropy sources for key derivation
|
|
43
|
+
const entropy = [
|
|
44
|
+
navigator.userAgent,
|
|
45
|
+
window.screen.width.toString(),
|
|
46
|
+
window.screen.height.toString(),
|
|
47
|
+
new Date().getTimezoneOffset().toString(),
|
|
48
|
+
this.getOrCreateSessionEntropy(),
|
|
49
|
+
].join('|');
|
|
50
|
+
return crypto.subtle.importKey('raw', new TextEncoder().encode(entropy), 'PBKDF2', false, ['deriveKey']);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get or create session-specific entropy
|
|
54
|
+
*/
|
|
55
|
+
getOrCreateSessionEntropy() {
|
|
56
|
+
const key = `${this.namespace}:entropy`;
|
|
57
|
+
let entropy = sessionStorage.getItem(key);
|
|
58
|
+
if (!entropy) {
|
|
59
|
+
entropy = crypto.randomUUID() + crypto.randomUUID();
|
|
60
|
+
sessionStorage.setItem(key, entropy);
|
|
61
|
+
}
|
|
62
|
+
return entropy;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Store data securely
|
|
66
|
+
*/
|
|
67
|
+
async set(key, value, options = {}) {
|
|
68
|
+
if (!this.initialized) {
|
|
69
|
+
await this.init();
|
|
70
|
+
}
|
|
71
|
+
const fullKey = `${this.namespace}:${key}`;
|
|
72
|
+
const wrapper = {
|
|
73
|
+
data: value,
|
|
74
|
+
timestamp: Date.now(),
|
|
75
|
+
ttl: options.ttl,
|
|
76
|
+
encrypted: options.encrypt && this.encryptionKey !== null,
|
|
77
|
+
};
|
|
78
|
+
let stored;
|
|
79
|
+
if (options.encrypt && this.encryptionKey) {
|
|
80
|
+
stored = await this.encrypt(JSON.stringify(wrapper));
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
stored = JSON.stringify(wrapper);
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
localStorage.setItem(fullKey, stored);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
// Handle quota exceeded
|
|
90
|
+
if (error instanceof DOMException && error.name === 'QuotaExceededError') {
|
|
91
|
+
this.cleanup();
|
|
92
|
+
localStorage.setItem(fullKey, stored);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
throw error;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Retrieve data
|
|
101
|
+
*/
|
|
102
|
+
async get(key, options = {}) {
|
|
103
|
+
if (!this.initialized) {
|
|
104
|
+
await this.init();
|
|
105
|
+
}
|
|
106
|
+
const fullKey = `${this.namespace}:${key}`;
|
|
107
|
+
const stored = localStorage.getItem(fullKey);
|
|
108
|
+
if (!stored)
|
|
109
|
+
return null;
|
|
110
|
+
try {
|
|
111
|
+
let parsed;
|
|
112
|
+
// Try to decrypt if it looks encrypted (base64)
|
|
113
|
+
if (options.encrypt && this.encryptionKey && this.looksEncrypted(stored)) {
|
|
114
|
+
parsed = await this.decrypt(stored);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
parsed = stored;
|
|
118
|
+
}
|
|
119
|
+
const wrapper = JSON.parse(parsed);
|
|
120
|
+
// Check TTL
|
|
121
|
+
if (wrapper.ttl && Date.now() - wrapper.timestamp > wrapper.ttl) {
|
|
122
|
+
this.remove(key);
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
return wrapper.data;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
// Corrupted or tampered data, remove it
|
|
129
|
+
console.warn(`[SecureStorage] Failed to retrieve ${key}, removing corrupted data`);
|
|
130
|
+
this.remove(key);
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Check if a key exists
|
|
136
|
+
*/
|
|
137
|
+
has(key) {
|
|
138
|
+
return localStorage.getItem(`${this.namespace}:${key}`) !== null;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Remove data
|
|
142
|
+
*/
|
|
143
|
+
remove(key) {
|
|
144
|
+
localStorage.removeItem(`${this.namespace}:${key}`);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Clear all data for this namespace
|
|
148
|
+
*/
|
|
149
|
+
clear() {
|
|
150
|
+
const keys = Object.keys(localStorage).filter(k => k.startsWith(`${this.namespace}:`));
|
|
151
|
+
keys.forEach(k => localStorage.removeItem(k));
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Cleanup expired entries
|
|
155
|
+
*/
|
|
156
|
+
cleanup() {
|
|
157
|
+
const prefix = `${this.namespace}:`;
|
|
158
|
+
const now = Date.now();
|
|
159
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
160
|
+
const key = localStorage.key(i);
|
|
161
|
+
if (!key || !key.startsWith(prefix))
|
|
162
|
+
continue;
|
|
163
|
+
try {
|
|
164
|
+
const stored = localStorage.getItem(key);
|
|
165
|
+
if (!stored)
|
|
166
|
+
continue;
|
|
167
|
+
// Only cleanup non-encrypted entries (we can't easily check encrypted ones)
|
|
168
|
+
if (!this.looksEncrypted(stored)) {
|
|
169
|
+
const wrapper = JSON.parse(stored);
|
|
170
|
+
if (wrapper.ttl && now - wrapper.timestamp > wrapper.ttl) {
|
|
171
|
+
localStorage.removeItem(key);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// Skip malformed entries
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get all keys in this namespace
|
|
182
|
+
*/
|
|
183
|
+
keys() {
|
|
184
|
+
const prefix = `${this.namespace}:`;
|
|
185
|
+
return Object.keys(localStorage)
|
|
186
|
+
.filter(k => k.startsWith(prefix))
|
|
187
|
+
.map(k => k.slice(prefix.length));
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Encrypt plaintext using AES-GCM
|
|
191
|
+
*/
|
|
192
|
+
async encrypt(plaintext) {
|
|
193
|
+
if (!this.encryptionKey) {
|
|
194
|
+
throw new Error('Encryption not initialized');
|
|
195
|
+
}
|
|
196
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
197
|
+
const encoded = new TextEncoder().encode(plaintext);
|
|
198
|
+
const ciphertext = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, this.encryptionKey, encoded);
|
|
199
|
+
// Combine IV + ciphertext
|
|
200
|
+
const combined = new Uint8Array(iv.length + ciphertext.byteLength);
|
|
201
|
+
combined.set(iv, 0);
|
|
202
|
+
combined.set(new Uint8Array(ciphertext), iv.length);
|
|
203
|
+
return 'enc:' + btoa(String.fromCharCode(...combined));
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Decrypt ciphertext
|
|
207
|
+
*/
|
|
208
|
+
async decrypt(ciphertext) {
|
|
209
|
+
if (!this.encryptionKey) {
|
|
210
|
+
throw new Error('Encryption not initialized');
|
|
211
|
+
}
|
|
212
|
+
// Remove prefix
|
|
213
|
+
const data = ciphertext.startsWith('enc:') ? ciphertext.slice(4) : ciphertext;
|
|
214
|
+
const combined = Uint8Array.from(atob(data), c => c.charCodeAt(0));
|
|
215
|
+
const iv = combined.slice(0, 12);
|
|
216
|
+
const encryptedData = combined.slice(12);
|
|
217
|
+
const decrypted = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, this.encryptionKey, encryptedData);
|
|
218
|
+
return new TextDecoder().decode(decrypted);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Check if data looks encrypted
|
|
222
|
+
*/
|
|
223
|
+
looksEncrypted(data) {
|
|
224
|
+
return data.startsWith('enc:');
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Check if encryption is available
|
|
228
|
+
*/
|
|
229
|
+
isEncryptionAvailable() {
|
|
230
|
+
return this.encryptionKey !== null;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
exports.SecureStorage = SecureStorage;
|
|
234
|
+
/**
|
|
235
|
+
* Create and initialize a secure storage instance
|
|
236
|
+
*/
|
|
237
|
+
async function createSecureStorage(namespace) {
|
|
238
|
+
const storage = new SecureStorage(namespace);
|
|
239
|
+
await storage.init();
|
|
240
|
+
return storage;
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=secure-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secure-storage.js","sourceRoot":"","sources":["../../src/security/secure-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transaction Verification Layer
|
|
3
|
+
* Analyzes transactions for risks before signing
|
|
4
|
+
*/
|
|
5
|
+
import type { Action } from '../types';
|
|
6
|
+
export interface Transaction {
|
|
7
|
+
receiverId: string;
|
|
8
|
+
actions: Action[];
|
|
9
|
+
}
|
|
10
|
+
export interface TransactionLimits {
|
|
11
|
+
/** Max NEAR per transaction (in yoctoNEAR) */
|
|
12
|
+
maxTransferAmount?: bigint;
|
|
13
|
+
/** Max gas per action */
|
|
14
|
+
maxGasPerAction?: bigint;
|
|
15
|
+
/** Whitelist of allowed receivers */
|
|
16
|
+
allowedReceivers?: string[];
|
|
17
|
+
/** Blacklist of blocked receivers */
|
|
18
|
+
blockedReceivers?: string[];
|
|
19
|
+
/** Whitelist of allowed contract methods */
|
|
20
|
+
allowedMethods?: string[];
|
|
21
|
+
/** Blacklist of known dangerous methods */
|
|
22
|
+
blockedMethods?: string[];
|
|
23
|
+
/** Always prompt user for confirmation */
|
|
24
|
+
requireConfirmation?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface TransactionRisk {
|
|
27
|
+
level: 'low' | 'medium' | 'high' | 'critical';
|
|
28
|
+
reasons: string[];
|
|
29
|
+
requiresExplicitApproval: boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare class TransactionGuard {
|
|
32
|
+
private limits;
|
|
33
|
+
private customScamContracts;
|
|
34
|
+
constructor(limits?: TransactionLimits);
|
|
35
|
+
/**
|
|
36
|
+
* Add custom scam contracts to the blocklist
|
|
37
|
+
*/
|
|
38
|
+
addScamContract(contractId: string): void;
|
|
39
|
+
/**
|
|
40
|
+
* Remove a contract from the custom blocklist
|
|
41
|
+
*/
|
|
42
|
+
removeScamContract(contractId: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* Update transaction limits
|
|
45
|
+
*/
|
|
46
|
+
updateLimits(limits: Partial<TransactionLimits>): void;
|
|
47
|
+
/**
|
|
48
|
+
* Analyze transaction for risks before signing
|
|
49
|
+
*/
|
|
50
|
+
analyzeRisk(tx: Transaction): TransactionRisk;
|
|
51
|
+
private analyzeAction;
|
|
52
|
+
private containsSuspiciousPatterns;
|
|
53
|
+
private escalate;
|
|
54
|
+
private formatNear;
|
|
55
|
+
/**
|
|
56
|
+
* Validate transaction can proceed (returns false for critical risks)
|
|
57
|
+
*/
|
|
58
|
+
validate(tx: Transaction): {
|
|
59
|
+
valid: boolean;
|
|
60
|
+
error?: string;
|
|
61
|
+
risk: TransactionRisk;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Get human-readable risk description
|
|
65
|
+
*/
|
|
66
|
+
getRiskDescription(risk: TransactionRisk): string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create a TransactionGuard with default safe limits
|
|
70
|
+
*/
|
|
71
|
+
export declare function createDefaultTransactionGuard(): TransactionGuard;
|