@gvnrdao/dh-sdk 0.0.205 → 0.0.206

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.
@@ -137,11 +137,6 @@ interface BaseSDKConfig {
137
137
  extension: number;
138
138
  };
139
139
  defaultSelectedTermMonths?: number;
140
- telegram?: {
141
- chatId: string;
142
- chatToken: string;
143
- threadId?: number;
144
- };
145
140
  temperSignaturesTest?: boolean;
146
141
  }
147
142
  /**
@@ -184,19 +184,11 @@ export declare class BitcoinOperations {
184
184
  /**
185
185
  * Get balance cache statistics
186
186
  */
187
- getBalanceCacheStats(): {
188
- size: number;
189
- maxSize: number;
190
- ttlMs: number;
191
- } | null;
187
+ getBalanceCacheStats(): import("../..").CacheStats | null;
192
188
  /**
193
189
  * Get address cache statistics
194
190
  */
195
- getAddressCacheStats(): {
196
- size: number;
197
- maxSize: number;
198
- ttlMs: number;
199
- } | null;
191
+ getAddressCacheStats(): import("../..").CacheStats | null;
200
192
  /**
201
193
  * Get current network configuration
202
194
  */
@@ -1,74 +1,228 @@
1
1
  /**
2
- * Cache Manager Module
2
+ * Generic Cache Manager Module
3
3
  *
4
- * Provides a simple cache factory for SDK modules.
5
- * Each cache is an independent LRU cache with TTL support.
4
+ * Provides a type-safe, generic LRU cache with TTL support.
5
+ * Can be used for any data type (Bitcoin balances, addresses, query results, etc.)
6
+ *
7
+ * Features:
8
+ * - Generic type support
9
+ * - TTL-based expiration
10
+ * - LRU eviction policy
11
+ * - Hit/miss statistics
12
+ * - Memory-efficient
13
+ * - Thread-safe operations
6
14
  */
7
- export interface CacheConfig {
8
- maxSize: number;
9
- ttlMs: number;
15
+ import { Result } from '../../types/result';
16
+ import { SDKError } from '../../utils/error-handler';
17
+ /**
18
+ * Cache entry with metadata
19
+ */
20
+ interface CacheEntry<T> {
21
+ /** Cached value */
22
+ value: T;
23
+ /** Unix timestamp when entry was created (ms) */
24
+ timestamp: number;
25
+ /** Number of times this entry was accessed */
26
+ hits: number;
27
+ /** Unix timestamp of last access (ms) */
28
+ lastAccessed: number;
10
29
  }
30
+ /**
31
+ * Cache statistics
32
+ */
11
33
  export interface CacheStats {
34
+ /** Current number of entries in cache */
12
35
  size: number;
13
- maxSize: number;
14
- ttlMs: number;
36
+ /** Total cache hits */
37
+ hits: number;
38
+ /** Total cache misses */
39
+ misses: number;
40
+ /** Total evictions performed */
41
+ evictions: number;
42
+ /** Timestamp of oldest entry (ms) */
43
+ oldestEntry: number;
44
+ /** Timestamp of newest entry (ms) */
45
+ newestEntry: number;
46
+ /** Hit rate as percentage (0-100) */
47
+ hitRate: number;
48
+ }
49
+ /**
50
+ * Cache configuration
51
+ */
52
+ export interface CacheConfig {
53
+ /** Maximum number of entries (default: 1000) */
54
+ maxSize?: number;
55
+ /** Time-to-live in milliseconds (default: 60000 = 1 minute) */
56
+ ttlMs?: number;
57
+ /** Enable debug logging (default: false) */
58
+ debug?: boolean;
59
+ /** Cache name for logging (default: 'Cache') */
60
+ name?: string;
15
61
  }
16
62
  /**
17
- * Simple LRU Cache with TTL support
63
+ * Generic LRU Cache with TTL support
64
+ *
65
+ * @template K - Key type (usually string)
66
+ * @template V - Value type
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * // Create a cache for Bitcoin balances
71
+ * const balanceCache = new LRUCache<string, BitcoinBalance>({
72
+ * maxSize: 500,
73
+ * ttlMs: 60000,
74
+ * name: 'BitcoinBalance'
75
+ * });
76
+ *
77
+ * // Set value
78
+ * balanceCache.set('bc1q...', { balance: Satoshis(50000000n) });
79
+ *
80
+ * // Get value
81
+ * const balance = balanceCache.get('bc1q...');
82
+ * if (balance) {
83
+ * console.log('Cached balance:', balance.balance);
84
+ * }
85
+ * ```
18
86
  */
19
- export declare class Cache<T = any> {
87
+ export declare class LRUCache<K, V> {
20
88
  private cache;
21
89
  private readonly maxSize;
22
90
  private readonly ttlMs;
23
- constructor(config: CacheConfig);
91
+ private readonly debug;
92
+ private readonly name;
93
+ private stats;
94
+ constructor(config?: CacheConfig);
24
95
  /**
25
96
  * Get value from cache
97
+ *
98
+ * Returns null if:
99
+ * - Key not found
100
+ * - Entry has expired
101
+ *
102
+ * @param key - Cache key
103
+ * @returns Cached value or null
104
+ */
105
+ get(key: K): V | null;
106
+ /**
107
+ * Get value from cache with Result wrapper
108
+ *
109
+ * Useful when you want to distinguish between "not found" and "expired"
26
110
  */
27
- get(key: string): T | undefined;
111
+ getResult(key: K): Result<V, SDKError>;
28
112
  /**
29
113
  * Set value in cache
114
+ *
115
+ * If cache is full, evicts the least recently used entry
116
+ *
117
+ * @param key - Cache key
118
+ * @param value - Value to cache
119
+ * @param ttl - Optional custom TTL for this entry (ms)
30
120
  */
31
- set(key: string, value: T, ttl?: number): void;
121
+ set(key: K, value: V, ttl?: number): void;
32
122
  /**
33
- * Check if key exists in cache
123
+ * Set value in cache with Result wrapper
34
124
  */
35
- has(key: string): boolean;
125
+ setResult(key: K, value: V, ttl?: number): Result<void, SDKError>;
36
126
  /**
37
- * Delete key from cache
127
+ * Check if key exists in cache (without affecting stats)
38
128
  */
39
- delete(key: string): boolean;
129
+ has(key: K): boolean;
130
+ /**
131
+ * Delete specific key from cache
132
+ */
133
+ delete(key: K): boolean;
40
134
  /**
41
- * Clear all cache entries
135
+ * Clear entire cache
42
136
  */
43
137
  clear(): void;
44
138
  /**
45
- * Clean expired entries
139
+ * Get current cache size
46
140
  */
47
- cleanExpired(): number;
141
+ size(): number;
48
142
  /**
49
143
  * Get cache statistics
50
144
  */
51
- getStats(): {
52
- size: number;
53
- maxSize: number;
54
- ttlMs: number;
55
- };
145
+ getStats(): CacheStats;
146
+ /**
147
+ * Get hit rate percentage
148
+ */
149
+ getHitRate(): number;
150
+ /**
151
+ * Get all cached keys (for debugging)
152
+ */
153
+ getKeys(): K[];
154
+ /**
155
+ * Get all cached values (for debugging)
156
+ */
157
+ getValues(): V[];
158
+ /**
159
+ * Get all cache entries with metadata (for debugging)
160
+ */
161
+ getEntries(): Array<{
162
+ key: K;
163
+ value: V;
164
+ metadata: Omit<CacheEntry<V>, 'value'>;
165
+ }>;
166
+ /**
167
+ * Clean up expired entries
168
+ *
169
+ * Useful for periodic maintenance
170
+ *
171
+ * @returns Number of entries cleaned
172
+ */
173
+ cleanExpired(): number;
174
+ /**
175
+ * Check if cache entry is expired
176
+ */
177
+ private isExpired;
178
+ /**
179
+ * Evict least recently used entry
180
+ */
181
+ private evictLRU;
182
+ /**
183
+ * Get or compute value
184
+ *
185
+ * If key exists in cache, returns cached value.
186
+ * Otherwise, computes value using provided function and caches it.
187
+ *
188
+ * @param key - Cache key
189
+ * @param compute - Function to compute value if not in cache
190
+ * @param ttl - Optional custom TTL for this entry
191
+ * @returns Cached or computed value
192
+ */
193
+ getOrCompute(key: K, compute: () => Promise<V>, ttl?: number): Promise<V>;
194
+ /**
195
+ * Get or compute value with Result wrapper
196
+ */
197
+ getOrComputeResult(key: K, compute: () => Promise<Result<V, SDKError>>, ttl?: number): Promise<Result<V, SDKError>>;
56
198
  }
57
199
  /**
58
- * Cache Manager
59
- *
60
- * Factory for creating named caches with specific configurations
200
+ * Generic cache interface for type safety
201
+ */
202
+ export interface Cache<T> {
203
+ get(key: string): T | null | undefined;
204
+ set(key: string, value: T): void;
205
+ delete(key: string): boolean;
206
+ clear(): void;
207
+ has(key: string): boolean;
208
+ size(): number;
209
+ getStats(): CacheStats;
210
+ }
211
+ /**
212
+ * Cache Manager - Factory for creating specialized caches
61
213
  */
62
214
  export declare class CacheManager {
63
215
  private caches;
64
- private readonly debug;
65
- constructor(config?: {
66
- debug?: boolean;
67
- });
216
+ private readonly globalConfig;
217
+ constructor(globalConfig?: CacheConfig);
68
218
  /**
69
- * Get or create a cache instance
219
+ * Create or get a named cache
220
+ *
221
+ * @param name - Unique cache name
222
+ * @param config - Optional cache-specific configuration
223
+ * @returns LRU cache instance
70
224
  */
71
- getCache<T = any>(name: string, config: CacheConfig): Cache<T>;
225
+ getCache<K, V>(name: string, config?: CacheConfig): LRUCache<K, V>;
72
226
  /**
73
227
  * Clear all caches
74
228
  */
@@ -80,13 +234,18 @@ export declare class CacheManager {
80
234
  /**
81
235
  * Get statistics for all caches
82
236
  */
83
- getAllStats(): Record<string, ReturnType<Cache["getStats"]>>;
237
+ getAllStats(): Record<string, CacheStats>;
238
+ /**
239
+ * Get list of all cache names
240
+ */
241
+ getCacheNames(): string[];
84
242
  /**
85
- * Destroy cache manager
243
+ * Delete a named cache
86
244
  */
87
- destroy(): void;
245
+ deleteCache(name: string): boolean;
88
246
  }
89
- export { Cache as LRUCache };
90
- export declare function createCacheManager(config?: {
91
- debug?: boolean;
92
- }): CacheManager;
247
+ /**
248
+ * Factory function to create a CacheManager instance
249
+ */
250
+ export declare function createCacheManager(config?: CacheConfig): CacheManager;
251
+ export {};
@@ -143,6 +143,7 @@ export declare class DiamondHandsSDK {
143
143
  /**
144
144
  * Check if SDK is ready for operations
145
145
  */
146
+ private _relayNotification;
146
147
  private checkInitialized;
147
148
  private toSDKError;
148
149
  /**
@@ -427,7 +428,7 @@ export declare class DiamondHandsSDK {
427
428
  getLoansByBorrower(borrower: string, pagination?: {
428
429
  page: number;
429
430
  pageSize: number;
430
- }): Promise<Result<import("../interfaces/chunks/loan-operations.i").PaginatedLoansResponse, SDKError>>;
431
+ }): Promise<Result<import("..").PaginatedLoansResponse, SDKError>>;
431
432
  /**
432
433
  * Get all active loans
433
434
  *
@@ -437,7 +438,7 @@ export declare class DiamondHandsSDK {
437
438
  getActiveLoans(pagination?: {
438
439
  page: number;
439
440
  pageSize: number;
440
- }): Promise<Result<import("../interfaces/chunks/loan-operations.i").PaginatedLoansResponse, SDKError>>;
441
+ }): Promise<Result<import("..").PaginatedLoansResponse, SDKError>>;
441
442
  /**
442
443
  * Get loans by state/status
443
444
  *
@@ -448,7 +449,7 @@ export declare class DiamondHandsSDK {
448
449
  getLoansByState(state: string, pagination?: {
449
450
  page: number;
450
451
  pageSize: number;
451
- }): Promise<Result<import("../interfaces/chunks/loan-operations.i").PaginatedLoansResponse, SDKError>>;
452
+ }): Promise<Result<import("..").PaginatedLoansResponse, SDKError>>;
452
453
  /**
453
454
  * Get all loans with pagination
454
455
  *
@@ -462,11 +463,11 @@ export declare class DiamondHandsSDK {
462
463
  maxRows?: number;
463
464
  orderBy?: "createdAt" | "lastUpdatedAt" | "ucdDebt";
464
465
  orderDirection?: "asc" | "desc";
465
- }, source?: "subgraph" | "contract"): Promise<Result<import("../interfaces/chunks/loan-operations.i").PaginatedLoansResponse, SDKError>>;
466
+ }, source?: "subgraph" | "contract"): Promise<Result<import("..").PaginatedLoansResponse, SDKError>>;
466
467
  /**
467
468
  * Get all events for a loan position from the subgraph
468
469
  */
469
- getLoanEvents(positionId: string, filter?: import("../types/event-types").LoanEventsFilter): Promise<Result<import("../types/event-types").LoanEvents, SDKError>>;
470
+ getLoanEvents(positionId: string, filter?: import("../types/event-types").LoanEventsFilter): Promise<Result<import("..").LoanEvents, SDKError>>;
470
471
  /**
471
472
  * Wait for the subgraph to index up to (and including) the given block number.
472
473
  * Call after on-chain actions (createLoan, mintUCD, etc.) before querying the subgraph.
@@ -481,7 +482,7 @@ export declare class DiamondHandsSDK {
481
482
  * @param address - Bitcoin address
482
483
  * @returns Balance in satoshis
483
484
  */
484
- getBitcoinBalance(address: string): Promise<Result<import("./bitcoin/bitcoin-operations.module").EnrichedBitcoinBalance, SDKError>>;
485
+ getBitcoinBalance(address: string): Promise<Result<import("..").EnrichedBitcoinBalance, SDKError>>;
485
486
  /**
486
487
  * Get the current Bitcoin price
487
488
  *
@@ -501,7 +502,7 @@ export declare class DiamondHandsSDK {
501
502
  * @param publicKey - PKP public key
502
503
  * @returns Bitcoin addresses for all networks
503
504
  */
504
- deriveBitcoinAddresses(publicKey: string): Promise<Result<import("../interfaces/chunks/loan-operations.i").BitcoinAddresses, SDKError>>;
505
+ deriveBitcoinAddresses(publicKey: string): Promise<Result<import("..").BitcoinAddresses, SDKError>>;
505
506
  /**
506
507
  * Get PKP data by token ID
507
508
  *
@@ -542,7 +543,7 @@ export declare class DiamondHandsSDK {
542
543
  * @param recipient - Recipient address
543
544
  * @returns Transaction result
544
545
  */
545
- mintMockBTC(amount: Satoshis, recipient: string): Promise<Result<import("./mock/mock-token-manager.module").MockTokenTransactionResult, SDKError>>;
546
+ mintMockBTC(amount: Satoshis, recipient: string): Promise<Result<import("..").MockTokenTransactionResult, SDKError>>;
546
547
  /**
547
548
  * Approve mock BTC spending (test networks only)
548
549
  *
@@ -550,7 +551,7 @@ export declare class DiamondHandsSDK {
550
551
  * @param amount - Amount in satoshis
551
552
  * @returns Transaction result
552
553
  */
553
- approveMockBTC(spender: string, amount: Satoshis): Promise<Result<import("./mock/mock-token-manager.module").MockTokenTransactionResult, SDKError>>;
554
+ approveMockBTC(spender: string, amount: Satoshis): Promise<Result<import("..").MockTokenTransactionResult, SDKError>>;
554
555
  /**
555
556
  * Get SDK configuration
556
557
  */
@@ -562,11 +563,7 @@ export declare class DiamondHandsSDK {
562
563
  /**
563
564
  * Get cache statistics
564
565
  */
565
- getCacheStats(): Record<string, {
566
- size: number;
567
- maxSize: number;
568
- ttlMs: number;
569
- }>;
566
+ getCacheStats(): Record<string, import("..").CacheStats>;
570
567
  /**
571
568
  * Get contract manager (for advanced usage)
572
569
  */
@@ -53,6 +53,8 @@ export interface LoanQueryConfig {
53
53
  bitcoinOperations: BitcoinOperations;
54
54
  /** Ethereum provider for PKP public key retrieval */
55
55
  provider?: providers.Provider;
56
+ /** PositionManagerCoreModule address — used as fallback vault address source for Chipotle loans */
57
+ positionManagerCoreAddress?: string;
56
58
  /** Cache for loan query results (keyed by PKP ID) */
57
59
  cache?: Cache<LoanData>;
58
60
  /** Enable debug logging */
@@ -194,11 +196,7 @@ export declare class LoanQuery {
194
196
  /**
195
197
  * Get cache statistics
196
198
  */
197
- getCacheStats(): {
198
- size: number;
199
- maxSize: number;
200
- ttlMs: number;
201
- } | null;
199
+ getCacheStats(): import("../..").CacheStats | null;
202
200
  }
203
201
  /**
204
202
  * Factory function to create a LoanQuery instance
@@ -124,11 +124,7 @@ export declare class PKPManager {
124
124
  /**
125
125
  * Get cache statistics
126
126
  */
127
- getCacheStats(): {
128
- size: number;
129
- maxSize: number;
130
- ttlMs: number;
131
- } | null;
127
+ getCacheStats(): import("../..").CacheStats | null;
132
128
  }
133
129
  /**
134
130
  * Factory function to create a PKPManager instance
@@ -133,13 +133,20 @@ export declare function generatePaymentAuthorization(positionId: string, amount:
133
133
  */
134
134
  export declare function generateExtendAuthorization(positionId: string, selectedTerm: number, chainId: number, signer: ethers5.Signer): Promise<ExtendOwnerAuthorization>;
135
135
  /**
136
- * Get PKP public key from PKP token ID
136
+ * Get PKP public key from PKP token ID.
137
137
  *
138
- * Queries the PKP NFT contract on the Chipotle LIT chain (Chronicle Yellowstone, chainId 175188).
138
+ * Only valid for datil/naga-era PKPs minted as NFTs on Chronicle Yellowstone.
139
+ * The caller must supply both the provider (connected to the PKP NFT's chain)
140
+ * and the PKP NFT contract address for that chain.
141
+ *
142
+ * Chipotle PKPs are wallet addresses returned by the Chipotle REST API — they
143
+ * are not NFTs and cannot be looked up via this function. Passing a Chipotle
144
+ * pkpId (ABI-encoded ETH address, e.g. 0x000...00<20-byte-addr>) throws an
145
+ * explicit error so callers surface a clear diagnostic.
139
146
  *
140
147
  * @param pkpTokenId - PKP token ID (bytes32 hex string)
141
- * @param provider - Ethereum provider (optional; reused if already on the correct LIT chain)
142
- * @param pkpNftContractAddress - PKP NFT contract address (required)
148
+ * @param provider - Ethereum provider connected to the PKP NFT chain
149
+ * @param pkpNftContractAddress - PKP NFT contract address on that chain (required)
143
150
  * @returns PKP public key as hex string with '0x' prefix
144
151
  */
145
152
  export declare function getPKPPublicKeyFromTokenId(pkpTokenId: string, provider?: ethers5.providers.Provider, pkpNftContractAddress?: string): Promise<string>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gvnrdao/dh-sdk",
3
- "version": "0.0.205",
3
+ "version": "0.0.206",
4
4
  "description": "TypeScript SDK for Diamond Hands Protocol - Bitcoin-backed lending with LIT Protocol PKPs",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/sdk/src/index.d.ts",
@@ -37,7 +37,7 @@
37
37
  "typecheck": "tsc --noEmit",
38
38
  "typecheck:strict": "tsc --noEmit -p tsconfig.strict.json",
39
39
  "test:types": "tsc --noEmit -p tsconfig.types.json",
40
- "prepublishOnly": "npm run sync:deployments && npm run validate:contracts && npm run build:node && npm run build:browser",
40
+ "prepublishOnly": "npm run sync:deployments && npm run validate:contracts && npm run build:node",
41
41
  "test": "jest",
42
42
  "test:unit": "jest tests/shared/unit",
43
43
  "test:integration": "jest tests/shared/integration",