@zendfi/sdk 0.8.4 → 1.0.1
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 +45 -437
- package/dist/chunk-DAJL2Q36.mjs +907 -0
- package/dist/express.d.mts +1 -1
- package/dist/express.d.ts +1 -1
- package/dist/helpers/index.d.mts +402 -0
- package/dist/helpers/index.d.ts +402 -0
- package/dist/helpers/index.js +944 -0
- package/dist/helpers/index.mjs +17 -0
- package/dist/index.d.mts +468 -3121
- package/dist/index.d.ts +468 -3121
- package/dist/index.js +421 -4020
- package/dist/index.mjs +1188 -5267
- package/dist/nextjs.d.mts +1 -1
- package/dist/nextjs.d.ts +1 -1
- package/dist/webhook-handler-61UWBtDI.d.mts +339 -0
- package/dist/webhook-handler-61UWBtDI.d.ts +339 -0
- package/package.json +19 -15
- package/README.md.old +0 -326
- package/dist/cache-T5YPC7OK.mjs +0 -9
- package/dist/chunk-5O5NAX65.mjs +0 -366
- package/dist/webhook-handler-CdtQHVU5.d.mts +0 -1130
- package/dist/webhook-handler-CdtQHVU5.d.ts +0 -1130
package/dist/chunk-5O5NAX65.mjs
DELETED
|
@@ -1,366 +0,0 @@
|
|
|
1
|
-
// src/helpers/cache.ts
|
|
2
|
-
var SessionKeyCache = class {
|
|
3
|
-
memoryCache = /* @__PURE__ */ new Map();
|
|
4
|
-
config;
|
|
5
|
-
refreshTimers = /* @__PURE__ */ new Map();
|
|
6
|
-
constructor(config = {}) {
|
|
7
|
-
this.config = {
|
|
8
|
-
storage: config.storage || "memory",
|
|
9
|
-
ttl: config.ttl || 30 * 60 * 1e3,
|
|
10
|
-
// 30 minutes default
|
|
11
|
-
autoRefresh: config.autoRefresh || false,
|
|
12
|
-
namespace: config.namespace || "zendfi_cache",
|
|
13
|
-
debug: config.debug || false
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Get cached keypair or decrypt and cache
|
|
18
|
-
*/
|
|
19
|
-
async getCached(sessionKeyId, decryptFn, options) {
|
|
20
|
-
this.log(`getCached: ${sessionKeyId}`);
|
|
21
|
-
const memoryCached = this.memoryCache.get(sessionKeyId);
|
|
22
|
-
if (memoryCached && Date.now() < memoryCached.expiry) {
|
|
23
|
-
this.log(`Memory cache HIT: ${sessionKeyId}`);
|
|
24
|
-
return memoryCached.keypair;
|
|
25
|
-
}
|
|
26
|
-
if (this.config.storage !== "memory") {
|
|
27
|
-
const persistentCached = await this.getFromStorage(sessionKeyId);
|
|
28
|
-
if (persistentCached && Date.now() < persistentCached.expiry) {
|
|
29
|
-
if (options?.deviceFingerprint && persistentCached.deviceFingerprint) {
|
|
30
|
-
if (options.deviceFingerprint !== persistentCached.deviceFingerprint) {
|
|
31
|
-
this.log(`Device fingerprint mismatch for ${sessionKeyId}`);
|
|
32
|
-
await this.invalidate(sessionKeyId);
|
|
33
|
-
return await this.decryptAndCache(sessionKeyId, decryptFn, options);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
this.log(`Persistent cache HIT: ${sessionKeyId}`);
|
|
37
|
-
this.memoryCache.set(sessionKeyId, persistentCached);
|
|
38
|
-
return persistentCached.keypair;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
this.log(`Cache MISS: ${sessionKeyId}`);
|
|
42
|
-
return await this.decryptAndCache(sessionKeyId, decryptFn, options);
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Decrypt keypair and cache it
|
|
46
|
-
*/
|
|
47
|
-
async decryptAndCache(sessionKeyId, decryptFn, options) {
|
|
48
|
-
const keypair = await decryptFn();
|
|
49
|
-
const expiry = Date.now() + this.config.ttl;
|
|
50
|
-
const cached = {
|
|
51
|
-
keypair,
|
|
52
|
-
expiry,
|
|
53
|
-
sessionKeyId,
|
|
54
|
-
deviceFingerprint: options?.deviceFingerprint
|
|
55
|
-
};
|
|
56
|
-
this.memoryCache.set(sessionKeyId, cached);
|
|
57
|
-
if (this.config.storage !== "memory") {
|
|
58
|
-
await this.setInStorage(sessionKeyId, cached);
|
|
59
|
-
}
|
|
60
|
-
if (this.config.autoRefresh) {
|
|
61
|
-
this.setupAutoRefresh(sessionKeyId, decryptFn, options);
|
|
62
|
-
}
|
|
63
|
-
this.log(`Cached: ${sessionKeyId}, expires in ${this.config.ttl}ms`);
|
|
64
|
-
return keypair;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Invalidate cached keypair
|
|
68
|
-
*/
|
|
69
|
-
async invalidate(sessionKeyId) {
|
|
70
|
-
this.log(`Invalidating: ${sessionKeyId}`);
|
|
71
|
-
this.memoryCache.delete(sessionKeyId);
|
|
72
|
-
const timer = this.refreshTimers.get(sessionKeyId);
|
|
73
|
-
if (timer) {
|
|
74
|
-
clearTimeout(timer);
|
|
75
|
-
this.refreshTimers.delete(sessionKeyId);
|
|
76
|
-
}
|
|
77
|
-
if (this.config.storage !== "memory") {
|
|
78
|
-
await this.removeFromStorage(sessionKeyId);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Clear all cached keypairs
|
|
83
|
-
*/
|
|
84
|
-
async clear() {
|
|
85
|
-
this.log("Clearing all cache");
|
|
86
|
-
this.memoryCache.clear();
|
|
87
|
-
for (const timer of this.refreshTimers.values()) {
|
|
88
|
-
clearTimeout(timer);
|
|
89
|
-
}
|
|
90
|
-
this.refreshTimers.clear();
|
|
91
|
-
if (this.config.storage !== "memory") {
|
|
92
|
-
await this.clearStorage();
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Get cache statistics
|
|
97
|
-
*/
|
|
98
|
-
getStats() {
|
|
99
|
-
const entries = Array.from(this.memoryCache.entries()).map(([id, cached]) => ({
|
|
100
|
-
sessionKeyId: id,
|
|
101
|
-
expiresIn: Math.max(0, cached.expiry - Date.now())
|
|
102
|
-
}));
|
|
103
|
-
return { size: this.memoryCache.size, entries };
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Check if a session key is cached and valid
|
|
107
|
-
*/
|
|
108
|
-
isCached(sessionKeyId) {
|
|
109
|
-
const cached = this.memoryCache.get(sessionKeyId);
|
|
110
|
-
return cached ? Date.now() < cached.expiry : false;
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Update TTL for a cached session key
|
|
114
|
-
*/
|
|
115
|
-
async extendTTL(sessionKeyId, additionalMs) {
|
|
116
|
-
const cached = this.memoryCache.get(sessionKeyId);
|
|
117
|
-
if (!cached) return false;
|
|
118
|
-
cached.expiry += additionalMs;
|
|
119
|
-
this.memoryCache.set(sessionKeyId, cached);
|
|
120
|
-
if (this.config.storage !== "memory") {
|
|
121
|
-
await this.setInStorage(sessionKeyId, cached);
|
|
122
|
-
}
|
|
123
|
-
this.log(`Extended TTL for ${sessionKeyId} by ${additionalMs}ms`);
|
|
124
|
-
return true;
|
|
125
|
-
}
|
|
126
|
-
// ============================================
|
|
127
|
-
// Storage Backend Implementations
|
|
128
|
-
// ============================================
|
|
129
|
-
async getFromStorage(sessionKeyId) {
|
|
130
|
-
try {
|
|
131
|
-
const key = this.getStorageKey(sessionKeyId);
|
|
132
|
-
if (this.config.storage === "localStorage") {
|
|
133
|
-
const data = localStorage.getItem(key);
|
|
134
|
-
if (!data) return null;
|
|
135
|
-
const parsed = JSON.parse(data);
|
|
136
|
-
return {
|
|
137
|
-
...parsed,
|
|
138
|
-
keypair: this.deserializeKeypair(parsed.keypair)
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
if (this.config.storage === "indexedDB") {
|
|
142
|
-
return await this.getFromIndexedDB(key);
|
|
143
|
-
}
|
|
144
|
-
if (typeof this.config.storage === "object") {
|
|
145
|
-
const data = await this.config.storage.get(key);
|
|
146
|
-
if (!data) return null;
|
|
147
|
-
const parsed = JSON.parse(data);
|
|
148
|
-
return {
|
|
149
|
-
...parsed,
|
|
150
|
-
keypair: this.deserializeKeypair(parsed.keypair)
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
} catch (error) {
|
|
154
|
-
this.log(`Error reading from storage: ${error}`);
|
|
155
|
-
}
|
|
156
|
-
return null;
|
|
157
|
-
}
|
|
158
|
-
async setInStorage(sessionKeyId, cached) {
|
|
159
|
-
try {
|
|
160
|
-
const key = this.getStorageKey(sessionKeyId);
|
|
161
|
-
const serialized = {
|
|
162
|
-
...cached,
|
|
163
|
-
keypair: this.serializeKeypair(cached.keypair)
|
|
164
|
-
};
|
|
165
|
-
if (this.config.storage === "localStorage") {
|
|
166
|
-
localStorage.setItem(key, JSON.stringify(serialized));
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
if (this.config.storage === "indexedDB") {
|
|
170
|
-
await this.setInIndexedDB(key, serialized);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
if (typeof this.config.storage === "object") {
|
|
174
|
-
await this.config.storage.set(key, JSON.stringify(serialized));
|
|
175
|
-
}
|
|
176
|
-
} catch (error) {
|
|
177
|
-
this.log(`Error writing to storage: ${error}`);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
async removeFromStorage(sessionKeyId) {
|
|
181
|
-
try {
|
|
182
|
-
const key = this.getStorageKey(sessionKeyId);
|
|
183
|
-
if (this.config.storage === "localStorage") {
|
|
184
|
-
localStorage.removeItem(key);
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
if (this.config.storage === "indexedDB") {
|
|
188
|
-
await this.removeFromIndexedDB(key);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
if (typeof this.config.storage === "object") {
|
|
192
|
-
await this.config.storage.remove(key);
|
|
193
|
-
}
|
|
194
|
-
} catch (error) {
|
|
195
|
-
this.log(`Error removing from storage: ${error}`);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
async clearStorage() {
|
|
199
|
-
try {
|
|
200
|
-
if (this.config.storage === "localStorage") {
|
|
201
|
-
const keysToRemove = [];
|
|
202
|
-
for (let i = 0; i < localStorage.length; i++) {
|
|
203
|
-
const key = localStorage.key(i);
|
|
204
|
-
if (key?.startsWith(this.config.namespace)) {
|
|
205
|
-
keysToRemove.push(key);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
keysToRemove.forEach((key) => localStorage.removeItem(key));
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
if (this.config.storage === "indexedDB") {
|
|
212
|
-
await this.clearIndexedDB();
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
if (typeof this.config.storage === "object") {
|
|
216
|
-
await this.config.storage.clear();
|
|
217
|
-
}
|
|
218
|
-
} catch (error) {
|
|
219
|
-
this.log(`Error clearing storage: ${error}`);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
// ============================================
|
|
223
|
-
// IndexedDB Helpers
|
|
224
|
-
// ============================================
|
|
225
|
-
async getFromIndexedDB(key) {
|
|
226
|
-
return new Promise((resolve) => {
|
|
227
|
-
const request = indexedDB.open(this.config.namespace, 1);
|
|
228
|
-
request.onerror = () => resolve(null);
|
|
229
|
-
request.onupgradeneeded = (event) => {
|
|
230
|
-
const db = event.target.result;
|
|
231
|
-
if (!db.objectStoreNames.contains("cache")) {
|
|
232
|
-
db.createObjectStore("cache");
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
request.onsuccess = (event) => {
|
|
236
|
-
const db = event.target.result;
|
|
237
|
-
const transaction = db.transaction(["cache"], "readonly");
|
|
238
|
-
const store = transaction.objectStore("cache");
|
|
239
|
-
const getRequest = store.get(key);
|
|
240
|
-
getRequest.onsuccess = () => {
|
|
241
|
-
resolve(getRequest.result || null);
|
|
242
|
-
};
|
|
243
|
-
getRequest.onerror = () => resolve(null);
|
|
244
|
-
};
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
async setInIndexedDB(key, value) {
|
|
248
|
-
return new Promise((resolve, reject) => {
|
|
249
|
-
const request = indexedDB.open(this.config.namespace, 1);
|
|
250
|
-
request.onerror = () => reject(new Error("IndexedDB error"));
|
|
251
|
-
request.onupgradeneeded = (event) => {
|
|
252
|
-
const db = event.target.result;
|
|
253
|
-
if (!db.objectStoreNames.contains("cache")) {
|
|
254
|
-
db.createObjectStore("cache");
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
request.onsuccess = (event) => {
|
|
258
|
-
const db = event.target.result;
|
|
259
|
-
const transaction = db.transaction(["cache"], "readwrite");
|
|
260
|
-
const store = transaction.objectStore("cache");
|
|
261
|
-
store.put(value, key);
|
|
262
|
-
transaction.oncomplete = () => resolve();
|
|
263
|
-
transaction.onerror = () => reject(new Error("IndexedDB transaction error"));
|
|
264
|
-
};
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
async removeFromIndexedDB(key) {
|
|
268
|
-
return new Promise((resolve) => {
|
|
269
|
-
const request = indexedDB.open(this.config.namespace, 1);
|
|
270
|
-
request.onsuccess = (event) => {
|
|
271
|
-
const db = event.target.result;
|
|
272
|
-
const transaction = db.transaction(["cache"], "readwrite");
|
|
273
|
-
const store = transaction.objectStore("cache");
|
|
274
|
-
store.delete(key);
|
|
275
|
-
transaction.oncomplete = () => resolve();
|
|
276
|
-
};
|
|
277
|
-
request.onerror = () => resolve();
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
async clearIndexedDB() {
|
|
281
|
-
return new Promise((resolve) => {
|
|
282
|
-
const request = indexedDB.open(this.config.namespace, 1);
|
|
283
|
-
request.onsuccess = (event) => {
|
|
284
|
-
const db = event.target.result;
|
|
285
|
-
const transaction = db.transaction(["cache"], "readwrite");
|
|
286
|
-
const store = transaction.objectStore("cache");
|
|
287
|
-
store.clear();
|
|
288
|
-
transaction.oncomplete = () => resolve();
|
|
289
|
-
};
|
|
290
|
-
request.onerror = () => resolve();
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
// ============================================
|
|
294
|
-
// Serialization
|
|
295
|
-
// ============================================
|
|
296
|
-
serializeKeypair(keypair) {
|
|
297
|
-
if (keypair && typeof keypair === "object" && "secretKey" in keypair) {
|
|
298
|
-
return {
|
|
299
|
-
type: "solana",
|
|
300
|
-
secretKey: Array.from(keypair.secretKey)
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
if (keypair instanceof Uint8Array) {
|
|
304
|
-
return {
|
|
305
|
-
type: "uint8array",
|
|
306
|
-
data: Array.from(keypair)
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
return keypair;
|
|
310
|
-
}
|
|
311
|
-
deserializeKeypair(data) {
|
|
312
|
-
if (!data || typeof data !== "object") return data;
|
|
313
|
-
if (data.type === "solana" && data.secretKey) {
|
|
314
|
-
return new Uint8Array(data.secretKey);
|
|
315
|
-
}
|
|
316
|
-
if (data.type === "uint8array" && data.data) {
|
|
317
|
-
return new Uint8Array(data.data);
|
|
318
|
-
}
|
|
319
|
-
return data;
|
|
320
|
-
}
|
|
321
|
-
// ============================================
|
|
322
|
-
// Auto-Refresh
|
|
323
|
-
// ============================================
|
|
324
|
-
setupAutoRefresh(sessionKeyId, decryptFn, options) {
|
|
325
|
-
const existingTimer = this.refreshTimers.get(sessionKeyId);
|
|
326
|
-
if (existingTimer) {
|
|
327
|
-
clearTimeout(existingTimer);
|
|
328
|
-
}
|
|
329
|
-
const refreshIn = Math.max(0, this.config.ttl - 5 * 60 * 1e3);
|
|
330
|
-
const timer = setTimeout(async () => {
|
|
331
|
-
this.log(`Auto-refreshing: ${sessionKeyId}`);
|
|
332
|
-
try {
|
|
333
|
-
await this.decryptAndCache(sessionKeyId, decryptFn, options);
|
|
334
|
-
} catch (error) {
|
|
335
|
-
this.log(`Auto-refresh failed: ${error}`);
|
|
336
|
-
}
|
|
337
|
-
}, refreshIn);
|
|
338
|
-
this.refreshTimers.set(sessionKeyId, timer);
|
|
339
|
-
}
|
|
340
|
-
// ============================================
|
|
341
|
-
// Utilities
|
|
342
|
-
// ============================================
|
|
343
|
-
getStorageKey(sessionKeyId) {
|
|
344
|
-
return `${this.config.namespace}:${sessionKeyId}`;
|
|
345
|
-
}
|
|
346
|
-
log(message) {
|
|
347
|
-
if (this.config.debug) {
|
|
348
|
-
console.log(`[SessionKeyCache] ${message}`);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
};
|
|
352
|
-
var QuickCaches = {
|
|
353
|
-
/** Memory-only cache (30 minutes) */
|
|
354
|
-
memory: () => new SessionKeyCache({ storage: "memory", ttl: 30 * 60 * 1e3 }),
|
|
355
|
-
/** Persistent cache (1 hour, survives reload) */
|
|
356
|
-
persistent: () => new SessionKeyCache({ storage: "localStorage", ttl: 60 * 60 * 1e3 }),
|
|
357
|
-
/** Long-term cache (24 hours, IndexedDB) */
|
|
358
|
-
longTerm: () => new SessionKeyCache({ storage: "indexedDB", ttl: 24 * 60 * 60 * 1e3, autoRefresh: true }),
|
|
359
|
-
/** Secure cache (5 minutes, memory-only) */
|
|
360
|
-
secure: () => new SessionKeyCache({ storage: "memory", ttl: 5 * 60 * 1e3 })
|
|
361
|
-
};
|
|
362
|
-
|
|
363
|
-
export {
|
|
364
|
-
SessionKeyCache,
|
|
365
|
-
QuickCaches
|
|
366
|
-
};
|