@gvnrdao/dh-sdk 0.0.295 → 0.0.297
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/browser/dist/browser.js +1 -1
- package/dist/deployments.d.ts +2 -0
- package/dist/deployments.js +64 -64
- package/dist/deployments.mjs +64 -64
- package/dist/graphs/diamond-hands.d.ts +15 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.js +4955 -108222
- package/dist/index.mjs +4826 -108087
- package/dist/modules/diamond-hands-sdk.d.ts +2 -2
- package/dist/modules/withdrawal-address/withdrawal-address.module.d.ts +14 -2
- package/dist/server.js +235 -3
- package/dist/server.mjs +235 -3
- package/dist/utils/chunks/eip1559-broadcast.utils.d.ts +74 -1
- package/package.json +7 -11
- package/browser/dist/833.browser.js +0 -2
- package/browser/dist/833.browser.js.LICENSE.txt +0 -1
- package/browser/dist/index.d.ts +0 -8
- package/browser/dist/index.d.ts.map +0 -1
- package/browser/dist/index.js +0 -25
|
@@ -952,9 +952,9 @@ export declare class DiamondHandsSDK {
|
|
|
952
952
|
*/
|
|
953
953
|
loanOps(): {
|
|
954
954
|
getProtocolConfig(): Promise<{
|
|
955
|
-
liquidationThreshold:
|
|
955
|
+
liquidationThreshold: string;
|
|
956
956
|
minimumLoanValueUcd: string;
|
|
957
|
-
minimumLoanValueWei:
|
|
957
|
+
minimumLoanValueWei: string;
|
|
958
958
|
maxSingleLoanValueUcd: string;
|
|
959
959
|
maxSingleLoanValueWei: string;
|
|
960
960
|
}>;
|
|
@@ -11,17 +11,19 @@
|
|
|
11
11
|
* Display lists (with the original address strings) come from the subgraph —
|
|
12
12
|
* the contract stores only keccak256(address). This module exposes the
|
|
13
13
|
* authoritative contract reads (isApproved / hashes / timestamps) and the
|
|
14
|
-
* mutating txs.
|
|
14
|
+
* mutating txs. `getEntries` also enriches with the raw address via
|
|
15
|
+
* `setGraphClient` (late-injected — see diamond-hands-sdk.ts), best-effort.
|
|
15
16
|
*/
|
|
16
17
|
import { type TransactionResponse } from "ethers";
|
|
17
18
|
import type { ContractManager } from "../contract/contract-manager.module";
|
|
19
|
+
import type { DiamondHandsGraph } from "../../graphs/diamond-hands";
|
|
18
20
|
import { Result } from "../../types/result";
|
|
19
21
|
import { SDKError } from "../../utils/error-handler";
|
|
20
22
|
export interface WithdrawalAddressModuleConfig {
|
|
21
23
|
contractManager: ContractManager;
|
|
22
24
|
debug?: boolean;
|
|
23
25
|
}
|
|
24
|
-
/** A single approved-address entry as read from the contract
|
|
26
|
+
/** A single approved-address entry as read from the contract, enriched with the raw address from the subgraph when available. */
|
|
25
27
|
export interface WithdrawalAddressEntry {
|
|
26
28
|
/** keccak256(bytes(normalizedAddress)). */
|
|
27
29
|
addrHash: string;
|
|
@@ -36,10 +38,20 @@ export interface WithdrawalAddressEntry {
|
|
|
36
38
|
* delay after this entry was added.
|
|
37
39
|
*/
|
|
38
40
|
approved: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Raw BTC address string, resolved from the subgraph's WithdrawalAddressBook
|
|
43
|
+
* (indexed from the contract's AddressAdded event log — never on-chain
|
|
44
|
+
* readable directly). `null` if not yet indexed, the lookup failed, or no
|
|
45
|
+
* graph client was wired via `setGraphClient`.
|
|
46
|
+
*/
|
|
47
|
+
address: string | null;
|
|
39
48
|
}
|
|
40
49
|
export declare class WithdrawalAddressModule {
|
|
41
50
|
private readonly config;
|
|
51
|
+
private graphClient?;
|
|
42
52
|
constructor(config: WithdrawalAddressModuleConfig);
|
|
53
|
+
/** Late-inject the graph client (constructed after this module in the SDK's constructor). */
|
|
54
|
+
setGraphClient(graphClient: DiamondHandsGraph): void;
|
|
43
55
|
/** Resolve the registry contract, or fail if it isn't configured for this network. */
|
|
44
56
|
private getRegistry;
|
|
45
57
|
/** True iff the registry is wired for this network (enforcement is active). */
|
package/dist/server.js
CHANGED
|
@@ -54,6 +54,238 @@ var VALID_LIT_NETWORKS = [
|
|
|
54
54
|
DEFAULT_LIT_NETWORKS.CHIPOTLE
|
|
55
55
|
];
|
|
56
56
|
|
|
57
|
+
// src/utils/logger.utils.ts
|
|
58
|
+
var Logger = class _Logger {
|
|
59
|
+
config;
|
|
60
|
+
static instance = null;
|
|
61
|
+
constructor(config2 = {}) {
|
|
62
|
+
this.config = {
|
|
63
|
+
enabled: config2.enabled ?? true,
|
|
64
|
+
level: config2.level ?? "info",
|
|
65
|
+
includeTimestamp: config2.includeTimestamp ?? false,
|
|
66
|
+
includeContext: config2.includeContext ?? true,
|
|
67
|
+
maxContextKeys: config2.maxContextKeys ?? 5,
|
|
68
|
+
verboseInProduction: config2.verboseInProduction ?? false,
|
|
69
|
+
isProduction: config2.isProduction ?? false
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Get or create singleton logger instance
|
|
74
|
+
*/
|
|
75
|
+
static getInstance(config2) {
|
|
76
|
+
if (!_Logger.instance) {
|
|
77
|
+
_Logger.instance = new _Logger(config2);
|
|
78
|
+
}
|
|
79
|
+
return _Logger.instance;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Update logger configuration
|
|
83
|
+
*/
|
|
84
|
+
updateConfig(config2) {
|
|
85
|
+
this.config = { ...this.config, ...config2 };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if a log level should be output
|
|
89
|
+
*/
|
|
90
|
+
shouldLog(level) {
|
|
91
|
+
if (!this.config.enabled)
|
|
92
|
+
return false;
|
|
93
|
+
if (this.config.isProduction && !this.config.verboseInProduction) {
|
|
94
|
+
if (level === "debug" || level === "info") {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const levels = {
|
|
99
|
+
debug: 0,
|
|
100
|
+
info: 1,
|
|
101
|
+
warn: 2,
|
|
102
|
+
error: 3
|
|
103
|
+
};
|
|
104
|
+
return levels[level] >= levels[this.config.level];
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Format context object for output
|
|
108
|
+
*/
|
|
109
|
+
formatContext(context) {
|
|
110
|
+
if (!this.config.includeContext || !context)
|
|
111
|
+
return "";
|
|
112
|
+
const keys = Object.keys(context).slice(0, this.config.maxContextKeys);
|
|
113
|
+
const pairs = keys.map((key) => `${key}=${context[key]}`).join(" ");
|
|
114
|
+
return pairs ? ` [${pairs}]` : "";
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Format timestamp for output
|
|
118
|
+
*/
|
|
119
|
+
formatTimestamp() {
|
|
120
|
+
if (!this.config.includeTimestamp)
|
|
121
|
+
return "";
|
|
122
|
+
return `[${(/* @__PURE__ */ new Date()).toISOString()}] `;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Core logging method
|
|
126
|
+
*/
|
|
127
|
+
log(level, message, context) {
|
|
128
|
+
if (!this.shouldLog(level))
|
|
129
|
+
return;
|
|
130
|
+
const timestamp = this.formatTimestamp();
|
|
131
|
+
const contextStr = this.formatContext(context);
|
|
132
|
+
const prefix = this.getLevelPrefix(level);
|
|
133
|
+
const fullMessage = `${timestamp}${prefix}${message}${contextStr}`;
|
|
134
|
+
switch (level) {
|
|
135
|
+
case "debug":
|
|
136
|
+
console.debug(fullMessage);
|
|
137
|
+
break;
|
|
138
|
+
case "info":
|
|
139
|
+
console.info(fullMessage);
|
|
140
|
+
break;
|
|
141
|
+
case "warn":
|
|
142
|
+
console.warn(fullMessage);
|
|
143
|
+
break;
|
|
144
|
+
case "error":
|
|
145
|
+
console.error(fullMessage);
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get prefix for log level
|
|
151
|
+
*/
|
|
152
|
+
getLevelPrefix(level) {
|
|
153
|
+
const prefixes = {
|
|
154
|
+
debug: "\u{1F50D} [DEBUG]",
|
|
155
|
+
info: "\u2139\uFE0F [INFO] ",
|
|
156
|
+
warn: "\u26A0\uFE0F [WARN] ",
|
|
157
|
+
error: "\u274C [ERROR]"
|
|
158
|
+
};
|
|
159
|
+
return prefixes[level];
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Debug level logging
|
|
163
|
+
*/
|
|
164
|
+
debug(message, context) {
|
|
165
|
+
this.log("debug", message, context);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Info level logging
|
|
169
|
+
*/
|
|
170
|
+
info(message, context) {
|
|
171
|
+
this.log("info", message, context);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Warning level logging
|
|
175
|
+
*/
|
|
176
|
+
warn(message, context) {
|
|
177
|
+
this.log("warn", message, context);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Error level logging
|
|
181
|
+
*/
|
|
182
|
+
error(message, context) {
|
|
183
|
+
this.log("error", message, context);
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Log operation start
|
|
187
|
+
*/
|
|
188
|
+
startOperation(operation, context) {
|
|
189
|
+
this.info(`Starting ${operation}`, { operation, ...context });
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Log operation completion
|
|
193
|
+
*/
|
|
194
|
+
completeOperation(operation, context) {
|
|
195
|
+
this.info(`Completed ${operation}`, { operation, ...context });
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Log operation failure
|
|
199
|
+
*/
|
|
200
|
+
failOperation(operation, error, context) {
|
|
201
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
202
|
+
this.error(`Failed ${operation}: ${errorMessage}`, { operation, error: errorMessage, ...context });
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Log retry attempt
|
|
206
|
+
*/
|
|
207
|
+
retry(operation, attempt, maxAttempts, error, context) {
|
|
208
|
+
const errorMessage = error ? `: ${error.message}` : "";
|
|
209
|
+
this.warn(`Retrying ${operation} (${attempt}/${maxAttempts})${errorMessage}`, {
|
|
210
|
+
operation,
|
|
211
|
+
attempt,
|
|
212
|
+
maxAttempts,
|
|
213
|
+
...context
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Log cache operations
|
|
218
|
+
*/
|
|
219
|
+
cacheHit(key, context) {
|
|
220
|
+
this.debug(`Cache HIT for ${key}`, { operation: "cache", key, ...context });
|
|
221
|
+
}
|
|
222
|
+
cacheMiss(key, context) {
|
|
223
|
+
this.debug(`Cache MISS for ${key}`, { operation: "cache", key, ...context });
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Log network operations
|
|
227
|
+
*/
|
|
228
|
+
networkRequest(url, method, context) {
|
|
229
|
+
this.debug(`${method} ${url}`, { operation: "network", url, method, ...context });
|
|
230
|
+
}
|
|
231
|
+
networkResponse(url, status, duration, context) {
|
|
232
|
+
this.debug(`Response ${status} from ${url}${duration ? ` (${duration}ms)` : ""}`, {
|
|
233
|
+
operation: "network",
|
|
234
|
+
url,
|
|
235
|
+
status,
|
|
236
|
+
duration,
|
|
237
|
+
...context
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Log Bitcoin operations
|
|
242
|
+
*/
|
|
243
|
+
bitcoinOperation(operation, address, context) {
|
|
244
|
+
this.debug(`Bitcoin ${operation}${address ? ` for ${address}` : ""}`, {
|
|
245
|
+
operation: "bitcoin",
|
|
246
|
+
bitcoinOp: operation,
|
|
247
|
+
address,
|
|
248
|
+
...context
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Log contract operations
|
|
253
|
+
*/
|
|
254
|
+
contractOperation(operation, contract, context) {
|
|
255
|
+
this.debug(`Contract ${operation}${contract ? ` on ${contract}` : ""}`, {
|
|
256
|
+
operation: "contract",
|
|
257
|
+
contractOp: operation,
|
|
258
|
+
contract,
|
|
259
|
+
...context
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
function getLogger() {
|
|
264
|
+
return Logger.getInstance();
|
|
265
|
+
}
|
|
266
|
+
var log = {
|
|
267
|
+
debug: (message, context) => getLogger().debug(message, context),
|
|
268
|
+
info: (message, context) => getLogger().info(message, context),
|
|
269
|
+
warn: (message, context) => getLogger().warn(message, context),
|
|
270
|
+
error: (message, context) => getLogger().error(message, context),
|
|
271
|
+
// Operation helpers
|
|
272
|
+
start: (operation, context) => getLogger().startOperation(operation, context),
|
|
273
|
+
complete: (operation, context) => getLogger().completeOperation(operation, context),
|
|
274
|
+
fail: (operation, error, context) => getLogger().failOperation(operation, error, context),
|
|
275
|
+
retry: (operation, attempt, maxAttempts, error, context) => getLogger().retry(operation, attempt, maxAttempts, error, context),
|
|
276
|
+
// Specialized helpers
|
|
277
|
+
cache: {
|
|
278
|
+
hit: (key, context) => getLogger().cacheHit(key, context),
|
|
279
|
+
miss: (key, context) => getLogger().cacheMiss(key, context)
|
|
280
|
+
},
|
|
281
|
+
network: {
|
|
282
|
+
request: (url, method, context) => getLogger().networkRequest(url, method, context),
|
|
283
|
+
response: (url, status, duration, context) => getLogger().networkResponse(url, status, duration, context)
|
|
284
|
+
},
|
|
285
|
+
bitcoin: (operation, address, context) => getLogger().bitcoinOperation(operation, address, context),
|
|
286
|
+
contract: (operation, contract, context) => getLogger().contractOperation(operation, contract, context)
|
|
287
|
+
};
|
|
288
|
+
|
|
57
289
|
// src/constants/chunks/environment.ts
|
|
58
290
|
var possibleEnvPaths = [
|
|
59
291
|
".env",
|
|
@@ -85,7 +317,7 @@ function logEnvDiscoveryOnce() {
|
|
|
85
317
|
if (process.env.DEBUG_SDK !== "true") {
|
|
86
318
|
return;
|
|
87
319
|
}
|
|
88
|
-
|
|
320
|
+
log.info("[SDK] .env multi-path load", {
|
|
89
321
|
attempted: envPathsAttemptedAbs,
|
|
90
322
|
mergedFromExistingFiles: envPathsMergedAbs,
|
|
91
323
|
note: "later paths override earlier (dotenv)"
|
|
@@ -153,9 +385,9 @@ function loadSDKConfig() {
|
|
|
153
385
|
function envLog(message, ...args) {
|
|
154
386
|
const config2 = loadSDKConfig();
|
|
155
387
|
if (config2.debugMode) {
|
|
156
|
-
|
|
388
|
+
log.info(
|
|
157
389
|
`[SDK:${config2.environment.toUpperCase()}] ${message}`,
|
|
158
|
-
|
|
390
|
+
args.length > 0 ? { args } : void 0
|
|
159
391
|
);
|
|
160
392
|
}
|
|
161
393
|
}
|
package/dist/server.mjs
CHANGED
|
@@ -12,6 +12,238 @@ var VALID_LIT_NETWORKS = [
|
|
|
12
12
|
DEFAULT_LIT_NETWORKS.CHIPOTLE
|
|
13
13
|
];
|
|
14
14
|
|
|
15
|
+
// src/utils/logger.utils.ts
|
|
16
|
+
var Logger = class _Logger {
|
|
17
|
+
config;
|
|
18
|
+
static instance = null;
|
|
19
|
+
constructor(config2 = {}) {
|
|
20
|
+
this.config = {
|
|
21
|
+
enabled: config2.enabled ?? true,
|
|
22
|
+
level: config2.level ?? "info",
|
|
23
|
+
includeTimestamp: config2.includeTimestamp ?? false,
|
|
24
|
+
includeContext: config2.includeContext ?? true,
|
|
25
|
+
maxContextKeys: config2.maxContextKeys ?? 5,
|
|
26
|
+
verboseInProduction: config2.verboseInProduction ?? false,
|
|
27
|
+
isProduction: config2.isProduction ?? false
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get or create singleton logger instance
|
|
32
|
+
*/
|
|
33
|
+
static getInstance(config2) {
|
|
34
|
+
if (!_Logger.instance) {
|
|
35
|
+
_Logger.instance = new _Logger(config2);
|
|
36
|
+
}
|
|
37
|
+
return _Logger.instance;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Update logger configuration
|
|
41
|
+
*/
|
|
42
|
+
updateConfig(config2) {
|
|
43
|
+
this.config = { ...this.config, ...config2 };
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Check if a log level should be output
|
|
47
|
+
*/
|
|
48
|
+
shouldLog(level) {
|
|
49
|
+
if (!this.config.enabled)
|
|
50
|
+
return false;
|
|
51
|
+
if (this.config.isProduction && !this.config.verboseInProduction) {
|
|
52
|
+
if (level === "debug" || level === "info") {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const levels = {
|
|
57
|
+
debug: 0,
|
|
58
|
+
info: 1,
|
|
59
|
+
warn: 2,
|
|
60
|
+
error: 3
|
|
61
|
+
};
|
|
62
|
+
return levels[level] >= levels[this.config.level];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Format context object for output
|
|
66
|
+
*/
|
|
67
|
+
formatContext(context) {
|
|
68
|
+
if (!this.config.includeContext || !context)
|
|
69
|
+
return "";
|
|
70
|
+
const keys = Object.keys(context).slice(0, this.config.maxContextKeys);
|
|
71
|
+
const pairs = keys.map((key) => `${key}=${context[key]}`).join(" ");
|
|
72
|
+
return pairs ? ` [${pairs}]` : "";
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Format timestamp for output
|
|
76
|
+
*/
|
|
77
|
+
formatTimestamp() {
|
|
78
|
+
if (!this.config.includeTimestamp)
|
|
79
|
+
return "";
|
|
80
|
+
return `[${(/* @__PURE__ */ new Date()).toISOString()}] `;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Core logging method
|
|
84
|
+
*/
|
|
85
|
+
log(level, message, context) {
|
|
86
|
+
if (!this.shouldLog(level))
|
|
87
|
+
return;
|
|
88
|
+
const timestamp = this.formatTimestamp();
|
|
89
|
+
const contextStr = this.formatContext(context);
|
|
90
|
+
const prefix = this.getLevelPrefix(level);
|
|
91
|
+
const fullMessage = `${timestamp}${prefix}${message}${contextStr}`;
|
|
92
|
+
switch (level) {
|
|
93
|
+
case "debug":
|
|
94
|
+
console.debug(fullMessage);
|
|
95
|
+
break;
|
|
96
|
+
case "info":
|
|
97
|
+
console.info(fullMessage);
|
|
98
|
+
break;
|
|
99
|
+
case "warn":
|
|
100
|
+
console.warn(fullMessage);
|
|
101
|
+
break;
|
|
102
|
+
case "error":
|
|
103
|
+
console.error(fullMessage);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Get prefix for log level
|
|
109
|
+
*/
|
|
110
|
+
getLevelPrefix(level) {
|
|
111
|
+
const prefixes = {
|
|
112
|
+
debug: "\u{1F50D} [DEBUG]",
|
|
113
|
+
info: "\u2139\uFE0F [INFO] ",
|
|
114
|
+
warn: "\u26A0\uFE0F [WARN] ",
|
|
115
|
+
error: "\u274C [ERROR]"
|
|
116
|
+
};
|
|
117
|
+
return prefixes[level];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Debug level logging
|
|
121
|
+
*/
|
|
122
|
+
debug(message, context) {
|
|
123
|
+
this.log("debug", message, context);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Info level logging
|
|
127
|
+
*/
|
|
128
|
+
info(message, context) {
|
|
129
|
+
this.log("info", message, context);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Warning level logging
|
|
133
|
+
*/
|
|
134
|
+
warn(message, context) {
|
|
135
|
+
this.log("warn", message, context);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Error level logging
|
|
139
|
+
*/
|
|
140
|
+
error(message, context) {
|
|
141
|
+
this.log("error", message, context);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Log operation start
|
|
145
|
+
*/
|
|
146
|
+
startOperation(operation, context) {
|
|
147
|
+
this.info(`Starting ${operation}`, { operation, ...context });
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Log operation completion
|
|
151
|
+
*/
|
|
152
|
+
completeOperation(operation, context) {
|
|
153
|
+
this.info(`Completed ${operation}`, { operation, ...context });
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Log operation failure
|
|
157
|
+
*/
|
|
158
|
+
failOperation(operation, error, context) {
|
|
159
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
160
|
+
this.error(`Failed ${operation}: ${errorMessage}`, { operation, error: errorMessage, ...context });
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Log retry attempt
|
|
164
|
+
*/
|
|
165
|
+
retry(operation, attempt, maxAttempts, error, context) {
|
|
166
|
+
const errorMessage = error ? `: ${error.message}` : "";
|
|
167
|
+
this.warn(`Retrying ${operation} (${attempt}/${maxAttempts})${errorMessage}`, {
|
|
168
|
+
operation,
|
|
169
|
+
attempt,
|
|
170
|
+
maxAttempts,
|
|
171
|
+
...context
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Log cache operations
|
|
176
|
+
*/
|
|
177
|
+
cacheHit(key, context) {
|
|
178
|
+
this.debug(`Cache HIT for ${key}`, { operation: "cache", key, ...context });
|
|
179
|
+
}
|
|
180
|
+
cacheMiss(key, context) {
|
|
181
|
+
this.debug(`Cache MISS for ${key}`, { operation: "cache", key, ...context });
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Log network operations
|
|
185
|
+
*/
|
|
186
|
+
networkRequest(url, method, context) {
|
|
187
|
+
this.debug(`${method} ${url}`, { operation: "network", url, method, ...context });
|
|
188
|
+
}
|
|
189
|
+
networkResponse(url, status, duration, context) {
|
|
190
|
+
this.debug(`Response ${status} from ${url}${duration ? ` (${duration}ms)` : ""}`, {
|
|
191
|
+
operation: "network",
|
|
192
|
+
url,
|
|
193
|
+
status,
|
|
194
|
+
duration,
|
|
195
|
+
...context
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Log Bitcoin operations
|
|
200
|
+
*/
|
|
201
|
+
bitcoinOperation(operation, address, context) {
|
|
202
|
+
this.debug(`Bitcoin ${operation}${address ? ` for ${address}` : ""}`, {
|
|
203
|
+
operation: "bitcoin",
|
|
204
|
+
bitcoinOp: operation,
|
|
205
|
+
address,
|
|
206
|
+
...context
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Log contract operations
|
|
211
|
+
*/
|
|
212
|
+
contractOperation(operation, contract, context) {
|
|
213
|
+
this.debug(`Contract ${operation}${contract ? ` on ${contract}` : ""}`, {
|
|
214
|
+
operation: "contract",
|
|
215
|
+
contractOp: operation,
|
|
216
|
+
contract,
|
|
217
|
+
...context
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
function getLogger() {
|
|
222
|
+
return Logger.getInstance();
|
|
223
|
+
}
|
|
224
|
+
var log = {
|
|
225
|
+
debug: (message, context) => getLogger().debug(message, context),
|
|
226
|
+
info: (message, context) => getLogger().info(message, context),
|
|
227
|
+
warn: (message, context) => getLogger().warn(message, context),
|
|
228
|
+
error: (message, context) => getLogger().error(message, context),
|
|
229
|
+
// Operation helpers
|
|
230
|
+
start: (operation, context) => getLogger().startOperation(operation, context),
|
|
231
|
+
complete: (operation, context) => getLogger().completeOperation(operation, context),
|
|
232
|
+
fail: (operation, error, context) => getLogger().failOperation(operation, error, context),
|
|
233
|
+
retry: (operation, attempt, maxAttempts, error, context) => getLogger().retry(operation, attempt, maxAttempts, error, context),
|
|
234
|
+
// Specialized helpers
|
|
235
|
+
cache: {
|
|
236
|
+
hit: (key, context) => getLogger().cacheHit(key, context),
|
|
237
|
+
miss: (key, context) => getLogger().cacheMiss(key, context)
|
|
238
|
+
},
|
|
239
|
+
network: {
|
|
240
|
+
request: (url, method, context) => getLogger().networkRequest(url, method, context),
|
|
241
|
+
response: (url, status, duration, context) => getLogger().networkResponse(url, status, duration, context)
|
|
242
|
+
},
|
|
243
|
+
bitcoin: (operation, address, context) => getLogger().bitcoinOperation(operation, address, context),
|
|
244
|
+
contract: (operation, contract, context) => getLogger().contractOperation(operation, contract, context)
|
|
245
|
+
};
|
|
246
|
+
|
|
15
247
|
// src/constants/chunks/environment.ts
|
|
16
248
|
var possibleEnvPaths = [
|
|
17
249
|
".env",
|
|
@@ -43,7 +275,7 @@ function logEnvDiscoveryOnce() {
|
|
|
43
275
|
if (process.env.DEBUG_SDK !== "true") {
|
|
44
276
|
return;
|
|
45
277
|
}
|
|
46
|
-
|
|
278
|
+
log.info("[SDK] .env multi-path load", {
|
|
47
279
|
attempted: envPathsAttemptedAbs,
|
|
48
280
|
mergedFromExistingFiles: envPathsMergedAbs,
|
|
49
281
|
note: "later paths override earlier (dotenv)"
|
|
@@ -111,9 +343,9 @@ function loadSDKConfig() {
|
|
|
111
343
|
function envLog(message, ...args) {
|
|
112
344
|
const config2 = loadSDKConfig();
|
|
113
345
|
if (config2.debugMode) {
|
|
114
|
-
|
|
346
|
+
log.info(
|
|
115
347
|
`[SDK:${config2.environment.toUpperCase()}] ${message}`,
|
|
116
|
-
|
|
348
|
+
args.length > 0 ? { args } : void 0
|
|
117
349
|
);
|
|
118
350
|
}
|
|
119
351
|
}
|
|
@@ -3,7 +3,23 @@
|
|
|
3
3
|
* (e.g. large mintUCD) without manual signDigest / eth_sendRawTransaction.
|
|
4
4
|
*/
|
|
5
5
|
import { type Provider, type Signer, type TransactionResponse } from "ethers";
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Cap on mintUCD's gasLimit. mintUCD dynamically sizes gasLimit via
|
|
8
|
+
* estimateContractCallGasWithMargin() (real eth_estimateGas + 25% margin) on
|
|
9
|
+
* mainnet, so this value is NOT normally what gets submitted -- it only
|
|
10
|
+
* becomes the literal gasLimit if (a) the estimate comes back anomalously
|
|
11
|
+
* high, or (b) eth_estimateGas itself fails, which is a hard error on
|
|
12
|
+
* mainnet and only falls back to this raw value on Sepolia/localhost.
|
|
13
|
+
* Previously 10,000,000 with a comment claiming "mintUCD + LIT validation
|
|
14
|
+
* can exceed 7M gas" -- no evidence of that was found across 16 real mint
|
|
15
|
+
* transactions checked (1 mainnet, 15 recent Sepolia, 2026-07-02): the
|
|
16
|
+
* dynamically-computed gasLimit actually submitted ranged 388,620-886,988.
|
|
17
|
+
* Lowered to 2,000,000 (~2.25x headroom over the highest real value seen)
|
|
18
|
+
* for consistency with MAKE_PAYMENT_GAS_CEILING/EXTEND_POSITION_GAS_CEILING's
|
|
19
|
+
* ~1.5-2x-headroom convention -- a smaller margin than those because this
|
|
20
|
+
* ceiling is a rarely-hit fallback/cap, not the everyday operating value, so
|
|
21
|
+
* a little extra buffer for cold-storage variance is cheap insurance.
|
|
22
|
+
*/
|
|
7
23
|
export declare const MINT_UCD_GAS_CEILING: bigint;
|
|
8
24
|
/**
|
|
9
25
|
* Fixed-gas ceiling for the withdrawBTC raw-tx fallback (used when estimateGas
|
|
@@ -15,6 +31,63 @@ export declare const MINT_UCD_GAS_CEILING: bigint;
|
|
|
15
31
|
* while staying well under the block gas limit.
|
|
16
32
|
*/
|
|
17
33
|
export declare const WITHDRAW_BTC_GAS_CEILING: bigint;
|
|
34
|
+
/**
|
|
35
|
+
* Fixed-gas ceiling for makePayment's broadcast (no estimateGas — see the call
|
|
36
|
+
* site's comment on why). The prior 500,000 limit silently doomed the call: the
|
|
37
|
+
* full chain (PositionManager -> LoanOperationsManager -> OperationAuthorization-
|
|
38
|
+
* Registry auth/quantum checks -> UCDController -> UCDToken's reentrancy-guarded
|
|
39
|
+
* burn(), 9+ nested call frames) needs a measured minimum of 573,821 gas once
|
|
40
|
+
* EIP-150's 63/64 forwarding rule is accounted for at each hop -- MORE than the
|
|
41
|
+
* ~481,100 gas a successful run actually consumes, because a tight overall limit
|
|
42
|
+
* starves the innermost calls of forwarded gas even when the total would
|
|
43
|
+
* technically fit. Under-gassing surfaced as UCDController's generic
|
|
44
|
+
* BurnCallFailed() (the real out-of-gas failure deep in UCDToken.burn()'s
|
|
45
|
+
* reentrancy sentry gets swallowed by the low-level call), which looked
|
|
46
|
+
* unrelated to gas. Verified live via debug_traceCall + binary search against a
|
|
47
|
+
* real mainnet revert (2026-07-02). 1M gives ~1.74x headroom over the measured
|
|
48
|
+
* floor, matching WITHDRAW_BTC_GAS_CEILING's ~2x-headroom convention above.
|
|
49
|
+
*/
|
|
50
|
+
export declare const MAKE_PAYMENT_GAS_CEILING: bigint;
|
|
51
|
+
/**
|
|
52
|
+
* Fixed-gas ceiling for extendPosition's broadcast. Previously had NO explicit
|
|
53
|
+
* gasLimit at all -- the only timing-sensitive call in this file that fell
|
|
54
|
+
* through to ethers' implicit estimateGas, which is exactly the RPC-latency
|
|
55
|
+
* risk every other call here (makePayment, mintUCD, withdrawBTC, liquidation
|
|
56
|
+
* commit/reveal) was deliberately hardened against, despite extendPosition
|
|
57
|
+
* ALSO calling awaitSafeSubmissionWindow just before broadcasting. Grounded in
|
|
58
|
+
* 10 real recent Sepolia PositionRenewed transactions: gasUsed ranged
|
|
59
|
+
* 388,150-430,705 (2026-07-02). Not binary-search-verified against a live
|
|
60
|
+
* revert like MAKE_PAYMENT_GAS_CEILING was -- replaying those specific txs
|
|
61
|
+
* hits a Gnosis Safe "GS026" (invalid owner) error unrelated to gas, because
|
|
62
|
+
* eth_call can't faithfully reproduce the embedded Safe-owner signature
|
|
63
|
+
* context. 1M gives >2x headroom over the observed max.
|
|
64
|
+
*/
|
|
65
|
+
export declare const EXTEND_POSITION_GAS_CEILING: bigint;
|
|
66
|
+
/**
|
|
67
|
+
* Fixed-gas ceiling for commitLiquidation's broadcast. No liquidation has ever
|
|
68
|
+
* executed on mainnet OR Sepolia yet (both networks are too new / no position
|
|
69
|
+
* has needed it), so unlike MAKE_PAYMENT_GAS_CEILING this is NOT verified
|
|
70
|
+
* against any real transaction -- it is a reasoned estimate only. The commit
|
|
71
|
+
* phase's on-chain work (auth + quantum checks, no burn/collateral movement)
|
|
72
|
+
* is similar in shape to makePayment's, so this matches MAKE_PAYMENT_GAS_CEILING.
|
|
73
|
+
* The prior hardcoded 500,000 followed the exact same "round unverified guess"
|
|
74
|
+
* pattern that caused MAKE_PAYMENT_GAS_CEILING's real production failure, so
|
|
75
|
+
* treat this as provisional until a real mainnet liquidation exists to
|
|
76
|
+
* measure against (see the debug_traceCall + binary-search method used for
|
|
77
|
+
* makePayment/withdrawBTC).
|
|
78
|
+
*/
|
|
79
|
+
export declare const LIQUIDATION_COMMIT_GAS_CEILING: bigint;
|
|
80
|
+
/**
|
|
81
|
+
* Fixed-gas ceiling for revealAndLiquidate's broadcast. Same "no real
|
|
82
|
+
* transaction exists yet to verify against" caveat as
|
|
83
|
+
* LIQUIDATION_COMMIT_GAS_CEILING. The reveal phase does substantially more
|
|
84
|
+
* on-chain work than commit or makePayment -- position lookup, liquidation-
|
|
85
|
+
* eligibility calculation, debt burn, AND collateral/vault handling -- closer
|
|
86
|
+
* in shape to WITHDRAW_BTC_GAS_CEILING's flow than to MAKE_PAYMENT_GAS_CEILING's.
|
|
87
|
+
* The prior hardcoded 700,000 was likewise an unverified guess. Treat as
|
|
88
|
+
* provisional until re-measured against a real liquidation.
|
|
89
|
+
*/
|
|
90
|
+
export declare const LIQUIDATION_REVEAL_GAS_CEILING: bigint;
|
|
18
91
|
/** Headroom on eth_estimateGas (25%). */
|
|
19
92
|
export declare const MINT_UCD_ESTIMATE_MARGIN_BPS = 2500;
|
|
20
93
|
/**
|