openttt 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/adaptive_switch.d.ts +22 -7
- package/dist/adaptive_switch.js +52 -15
- package/dist/auto_mint.d.ts +22 -7
- package/dist/auto_mint.js +107 -30
- package/dist/ct_log.d.ts +47 -0
- package/dist/ct_log.js +107 -0
- package/dist/dynamic_fee.d.ts +13 -2
- package/dist/dynamic_fee.js +62 -11
- package/dist/errors.d.ts +44 -25
- package/dist/errors.js +58 -42
- package/dist/evm_connector.d.ts +28 -1
- package/dist/evm_connector.js +124 -32
- package/dist/index.d.ts +4 -5
- package/dist/index.js +4 -5
- package/dist/logger.d.ts +36 -4
- package/dist/logger.js +70 -11
- package/dist/networks.d.ts +21 -0
- package/dist/networks.js +30 -4
- package/dist/pool_registry.d.ts +9 -0
- package/dist/pool_registry.js +37 -0
- package/dist/pot_signer.d.ts +15 -0
- package/dist/pot_signer.js +28 -0
- package/dist/protocol_fee.d.ts +42 -26
- package/dist/protocol_fee.js +77 -54
- package/dist/revenue_tiers.d.ts +36 -0
- package/dist/revenue_tiers.js +83 -0
- package/dist/signer.d.ts +1 -2
- package/dist/signer.js +72 -14
- package/dist/time_synthesis.d.ts +38 -0
- package/dist/time_synthesis.js +134 -20
- package/dist/trust_store.d.ts +49 -0
- package/dist/trust_store.js +89 -0
- package/dist/ttt_builder.d.ts +1 -1
- package/dist/ttt_builder.js +2 -2
- package/dist/ttt_client.d.ts +24 -29
- package/dist/ttt_client.js +97 -28
- package/dist/types.d.ts +46 -3
- package/dist/v4_hook.d.ts +10 -2
- package/dist/v4_hook.js +10 -2
- package/dist/x402_enforcer.d.ts +17 -2
- package/dist/x402_enforcer.js +27 -2
- package/package.json +1 -1
package/dist/ttt_client.d.ts
CHANGED
|
@@ -1,32 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EventEmitter } from "events";
|
|
2
|
+
import { AutoMintConfig, TTTClientConfig, MintResult, HealthStatus } from "./types";
|
|
3
|
+
export { HealthStatus } from "./types";
|
|
2
4
|
/**
|
|
3
|
-
*
|
|
5
|
+
* Typed event map for TTTClient EventEmitter.
|
|
4
6
|
*/
|
|
5
|
-
export interface
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
balanceSufficient: boolean;
|
|
12
|
-
ntpSourcesOk: boolean;
|
|
13
|
-
};
|
|
14
|
-
metrics: {
|
|
15
|
-
mintCount: number;
|
|
16
|
-
mintFailures: number;
|
|
17
|
-
successRate: number;
|
|
18
|
-
totalFeesPaid: string;
|
|
19
|
-
avgMintLatencyMs: number;
|
|
20
|
-
lastMintAt: string | null;
|
|
21
|
-
uptimeMs: number;
|
|
22
|
-
};
|
|
23
|
-
alerts: string[];
|
|
7
|
+
export interface TTTClientEvents {
|
|
8
|
+
mint: [result: MintResult];
|
|
9
|
+
error: [error: Error];
|
|
10
|
+
alert: [alert: string];
|
|
11
|
+
latency: [ms: number];
|
|
12
|
+
modeSwitch: [mode: string];
|
|
24
13
|
}
|
|
25
14
|
/**
|
|
26
|
-
* TTTClient -
|
|
27
|
-
*
|
|
15
|
+
* TTTClient - SDK entry point for DEX operators.
|
|
16
|
+
* Initializes all internal modules and manages the auto-minting process.
|
|
28
17
|
*/
|
|
29
|
-
export declare class TTTClient {
|
|
18
|
+
export declare class TTTClient extends EventEmitter {
|
|
30
19
|
private config;
|
|
31
20
|
private autoMintEngine;
|
|
32
21
|
private poolRegistry;
|
|
@@ -37,10 +26,10 @@ export declare class TTTClient {
|
|
|
37
26
|
private signer;
|
|
38
27
|
private lastTokenId;
|
|
39
28
|
private mintLatencies;
|
|
29
|
+
private maxLatencyHistory;
|
|
40
30
|
private lastMintAt;
|
|
41
31
|
private startedAt;
|
|
42
32
|
private minBalanceWei;
|
|
43
|
-
private onAlertCallback?;
|
|
44
33
|
constructor(config: AutoMintConfig);
|
|
45
34
|
/**
|
|
46
35
|
* Static factory for Base Mainnet
|
|
@@ -59,17 +48,22 @@ export declare class TTTClient {
|
|
|
59
48
|
*/
|
|
60
49
|
destroy(): Promise<void>;
|
|
61
50
|
/**
|
|
62
|
-
* SDK
|
|
51
|
+
* Initialize the SDK: RPC connection, time sources, fee engine wiring.
|
|
63
52
|
*/
|
|
64
53
|
initialize(): Promise<void>;
|
|
65
54
|
/**
|
|
66
|
-
*
|
|
55
|
+
* Start the auto-minting process.
|
|
67
56
|
*/
|
|
68
57
|
startAutoMint(): void;
|
|
69
58
|
/**
|
|
70
|
-
*
|
|
59
|
+
* Stop the auto-minting process.
|
|
71
60
|
*/
|
|
72
61
|
stopAutoMint(): void;
|
|
62
|
+
/**
|
|
63
|
+
* Resume auto-minting after a circuit breaker trip.
|
|
64
|
+
* Resets consecutive failure count and restarts the engine.
|
|
65
|
+
*/
|
|
66
|
+
resume(): void;
|
|
73
67
|
/**
|
|
74
68
|
* List registered pools.
|
|
75
69
|
*/
|
|
@@ -87,6 +81,7 @@ export declare class TTTClient {
|
|
|
87
81
|
setMinBalance(weiAmount: bigint): void;
|
|
88
82
|
/**
|
|
89
83
|
* Register alert callback for real-time notifications.
|
|
84
|
+
* Backward compatible: delegates to EventEmitter 'alert' event.
|
|
90
85
|
*/
|
|
91
86
|
onAlert(callback: (alert: string) => void): void;
|
|
92
87
|
private emitAlert;
|
|
@@ -104,7 +99,7 @@ export declare class TTTClient {
|
|
|
104
99
|
*/
|
|
105
100
|
getHealth(): Promise<HealthStatus>;
|
|
106
101
|
/**
|
|
107
|
-
*
|
|
102
|
+
* Return current SDK status and statistics (balance, mint count, fees, etc.)
|
|
108
103
|
*/
|
|
109
104
|
getStatus(): Promise<{
|
|
110
105
|
isInitialized: boolean;
|
package/dist/ttt_client.js
CHANGED
|
@@ -2,16 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TTTClient = void 0;
|
|
4
4
|
const ethers_1 = require("ethers");
|
|
5
|
+
const events_1 = require("events");
|
|
5
6
|
const auto_mint_1 = require("./auto_mint");
|
|
7
|
+
const types_1 = require("./types");
|
|
6
8
|
const logger_1 = require("./logger");
|
|
7
9
|
const pool_registry_1 = require("./pool_registry");
|
|
8
10
|
const networks_1 = require("./networks");
|
|
9
11
|
const signer_1 = require("./signer");
|
|
10
12
|
/**
|
|
11
|
-
* TTTClient -
|
|
12
|
-
*
|
|
13
|
+
* TTTClient - SDK entry point for DEX operators.
|
|
14
|
+
* Initializes all internal modules and manages the auto-minting process.
|
|
13
15
|
*/
|
|
14
|
-
class TTTClient {
|
|
16
|
+
class TTTClient extends events_1.EventEmitter {
|
|
15
17
|
config;
|
|
16
18
|
autoMintEngine;
|
|
17
19
|
poolRegistry;
|
|
@@ -22,15 +24,17 @@ class TTTClient {
|
|
|
22
24
|
signer = null;
|
|
23
25
|
lastTokenId = null;
|
|
24
26
|
mintLatencies = [];
|
|
27
|
+
maxLatencyHistory;
|
|
25
28
|
lastMintAt = null;
|
|
26
29
|
startedAt = new Date();
|
|
27
30
|
minBalanceWei = ethers_1.ethers.parseEther("0.01"); // 0.01 ETH alert threshold
|
|
28
|
-
onAlertCallback;
|
|
29
31
|
constructor(config) {
|
|
32
|
+
super();
|
|
30
33
|
this.config = config;
|
|
34
|
+
this.maxLatencyHistory = config.maxLatencyHistory ?? 100;
|
|
31
35
|
this.autoMintEngine = new auto_mint_1.AutoMintEngine(config);
|
|
32
36
|
this.poolRegistry = new pool_registry_1.PoolRegistry();
|
|
33
|
-
//
|
|
37
|
+
// Wire callbacks to update stats + emit events
|
|
34
38
|
this.autoMintEngine.setOnMint((result) => {
|
|
35
39
|
this.mintCount++;
|
|
36
40
|
this.totalFeesPaid += result.protocolFeePaid;
|
|
@@ -38,16 +42,20 @@ class TTTClient {
|
|
|
38
42
|
this.lastMintAt = new Date();
|
|
39
43
|
// Record in registry
|
|
40
44
|
this.poolRegistry.recordMint(this.config.poolAddress, 1n);
|
|
45
|
+
// Emit typed 'mint' event
|
|
46
|
+
this.emit('mint', result);
|
|
41
47
|
});
|
|
42
|
-
//
|
|
43
|
-
this.autoMintEngine.setOnFailure((
|
|
48
|
+
// Wire failure/latency metrics from AutoMint loop to TTTClient
|
|
49
|
+
this.autoMintEngine.setOnFailure((error) => {
|
|
44
50
|
this.mintFailures++;
|
|
51
|
+
this.emit('error', error);
|
|
45
52
|
});
|
|
46
53
|
this.autoMintEngine.setOnLatency((ms) => {
|
|
47
54
|
this.mintLatencies.push(ms);
|
|
48
|
-
if (this.mintLatencies.length >
|
|
55
|
+
if (this.mintLatencies.length > this.maxLatencyHistory) {
|
|
49
56
|
this.mintLatencies.shift();
|
|
50
57
|
}
|
|
58
|
+
this.emit('latency', ms);
|
|
51
59
|
});
|
|
52
60
|
}
|
|
53
61
|
/**
|
|
@@ -66,10 +74,36 @@ class TTTClient {
|
|
|
66
74
|
* Universal factory to create and initialize a client
|
|
67
75
|
*/
|
|
68
76
|
static async create(config) {
|
|
77
|
+
// 0. Shorthand: privateKey string -> SignerConfig
|
|
78
|
+
if (config.privateKey && !config.signer) {
|
|
79
|
+
const key = config.privateKey.startsWith('0x') ? config.privateKey : '0x' + config.privateKey;
|
|
80
|
+
config = { ...config, signer: { type: 'privateKey', key } };
|
|
81
|
+
}
|
|
82
|
+
// 0.5. Validation: require either signer or privateKey
|
|
83
|
+
if (!config.signer) {
|
|
84
|
+
throw new Error('TTTClient requires either `signer` or `privateKey`. Simplest: TTTClient.forBase({ privateKey: process.env.OPERATOR_PK! })');
|
|
85
|
+
}
|
|
86
|
+
// 0.7. Validate tier — CRITICAL: invalid tier causes setInterval(fn, undefined) = 1ms loop = wallet drain
|
|
87
|
+
const tier = config.tier || "T1_block";
|
|
88
|
+
if (!types_1.TierIntervals[tier]) {
|
|
89
|
+
const validTiers = Object.keys(types_1.TierIntervals).join(', ');
|
|
90
|
+
throw new Error(`[TTTClient] Invalid tier "${tier}". Valid tiers: ${validTiers}`);
|
|
91
|
+
}
|
|
92
|
+
// 0.8. Validate fee rate bounds
|
|
93
|
+
if (config.protocolFeeRate !== undefined) {
|
|
94
|
+
if (config.protocolFeeRate < 0 || config.protocolFeeRate > 1) {
|
|
95
|
+
throw new Error(`[TTTClient] protocolFeeRate must be 0-1 (got ${config.protocolFeeRate}). Example: 0.05 = 5%`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// 0.9. Validate network string
|
|
99
|
+
if (typeof config.network === 'string' && !networks_1.NETWORKS[config.network]) {
|
|
100
|
+
const validNets = Object.keys(networks_1.NETWORKS).join(', ');
|
|
101
|
+
throw new Error(`[TTTClient] Unknown network "${config.network}". Valid: ${validNets}. Or pass a custom NetworkConfig object.`);
|
|
102
|
+
}
|
|
69
103
|
// 1. Resolve network defaults
|
|
70
104
|
let net;
|
|
71
105
|
if (typeof config.network === 'string') {
|
|
72
|
-
net = networks_1.NETWORKS[config.network]
|
|
106
|
+
net = networks_1.NETWORKS[config.network];
|
|
73
107
|
}
|
|
74
108
|
else if (config.network) {
|
|
75
109
|
net = config.network;
|
|
@@ -92,12 +126,25 @@ class TTTClient {
|
|
|
92
126
|
signer: signer,
|
|
93
127
|
contractAddress: config.contractAddress || net.tttAddress,
|
|
94
128
|
feeCollectorAddress: net.protocolFeeAddress,
|
|
95
|
-
poolAddress:
|
|
129
|
+
poolAddress: (() => {
|
|
130
|
+
const addr = config.poolAddress;
|
|
131
|
+
if (!addr || addr === "0x0000000000000000000000000000000000000000") {
|
|
132
|
+
throw new Error("[TTTClient] poolAddress is required. Provide a valid DEX pool address.");
|
|
133
|
+
}
|
|
134
|
+
return addr;
|
|
135
|
+
})(),
|
|
96
136
|
tier: config.tier || "T1_block",
|
|
97
|
-
timeSources: config.timeSources || ["nist", "
|
|
137
|
+
timeSources: config.timeSources || ["nist", "google", "cloudflare", "apple"],
|
|
98
138
|
protocolFeeRate: config.protocolFeeRate || 0.05,
|
|
99
|
-
protocolFeeRecipient:
|
|
139
|
+
protocolFeeRecipient: (() => {
|
|
140
|
+
const addr = config.protocolFeeRecipient;
|
|
141
|
+
if (!addr || addr === "0x0000000000000000000000000000000000000000") {
|
|
142
|
+
throw new Error("[TTTClient] protocolFeeRecipient is required. Provide a valid fee recipient address.");
|
|
143
|
+
}
|
|
144
|
+
return addr;
|
|
145
|
+
})(),
|
|
100
146
|
fallbackPriceUsd: config.fallbackPriceUsd || 10000n,
|
|
147
|
+
maxLatencyHistory: config.maxLatencyHistory,
|
|
101
148
|
};
|
|
102
149
|
// 4. Instantiate and initialize
|
|
103
150
|
const client = new TTTClient(autoMintConfig);
|
|
@@ -128,7 +175,7 @@ class TTTClient {
|
|
|
128
175
|
logger_1.logger.info("[TTTClient] Client destroyed successfully.");
|
|
129
176
|
}
|
|
130
177
|
/**
|
|
131
|
-
* SDK
|
|
178
|
+
* Initialize the SDK: RPC connection, time sources, fee engine wiring.
|
|
132
179
|
*/
|
|
133
180
|
async initialize() {
|
|
134
181
|
if (this.isInitialized)
|
|
@@ -140,7 +187,7 @@ class TTTClient {
|
|
|
140
187
|
this.signer = connector.getSigner();
|
|
141
188
|
// Register initial pool
|
|
142
189
|
await this.poolRegistry.registerPool(this.config.chainId, this.config.poolAddress);
|
|
143
|
-
//
|
|
190
|
+
// Validate feeCollectorAddress early before use
|
|
144
191
|
if (this.config.feeCollectorAddress && !ethers_1.ethers.isAddress(this.config.feeCollectorAddress)) {
|
|
145
192
|
throw new Error(`[TTTClient] Invalid feeCollectorAddress: ${this.config.feeCollectorAddress}`);
|
|
146
193
|
}
|
|
@@ -179,7 +226,7 @@ class TTTClient {
|
|
|
179
226
|
}
|
|
180
227
|
}
|
|
181
228
|
/**
|
|
182
|
-
*
|
|
229
|
+
* Start the auto-minting process.
|
|
183
230
|
*/
|
|
184
231
|
startAutoMint() {
|
|
185
232
|
if (!this.isInitialized) {
|
|
@@ -189,11 +236,20 @@ class TTTClient {
|
|
|
189
236
|
logger_1.logger.info(`[TTTClient] Auto-minting started for tier ${this.config.tier}`);
|
|
190
237
|
}
|
|
191
238
|
/**
|
|
192
|
-
*
|
|
239
|
+
* Stop the auto-minting process.
|
|
193
240
|
*/
|
|
194
241
|
stopAutoMint() {
|
|
195
242
|
this.autoMintEngine.stop();
|
|
196
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* Resume auto-minting after a circuit breaker trip.
|
|
246
|
+
* Resets consecutive failure count and restarts the engine.
|
|
247
|
+
*/
|
|
248
|
+
resume() {
|
|
249
|
+
this.autoMintEngine.resume();
|
|
250
|
+
this.emit('modeSwitch', 'resumed');
|
|
251
|
+
logger_1.logger.info(`[TTTClient] Auto-minting resumed`);
|
|
252
|
+
}
|
|
197
253
|
/**
|
|
198
254
|
* List registered pools.
|
|
199
255
|
*/
|
|
@@ -214,18 +270,14 @@ class TTTClient {
|
|
|
214
270
|
}
|
|
215
271
|
/**
|
|
216
272
|
* Register alert callback for real-time notifications.
|
|
273
|
+
* Backward compatible: delegates to EventEmitter 'alert' event.
|
|
217
274
|
*/
|
|
218
275
|
onAlert(callback) {
|
|
219
|
-
this.
|
|
276
|
+
this.on('alert', callback);
|
|
220
277
|
}
|
|
221
278
|
emitAlert(alert) {
|
|
222
279
|
logger_1.logger.warn(`[TTTClient] ALERT: ${alert}`);
|
|
223
|
-
|
|
224
|
-
try {
|
|
225
|
-
this.onAlertCallback(alert);
|
|
226
|
-
}
|
|
227
|
-
catch (_) { /* swallow */ }
|
|
228
|
-
}
|
|
280
|
+
this.emit('alert', alert);
|
|
229
281
|
}
|
|
230
282
|
/**
|
|
231
283
|
* Record a mint failure (called internally or externally).
|
|
@@ -238,8 +290,7 @@ class TTTClient {
|
|
|
238
290
|
*/
|
|
239
291
|
recordMintLatency(ms) {
|
|
240
292
|
this.mintLatencies.push(ms);
|
|
241
|
-
|
|
242
|
-
if (this.mintLatencies.length > 100) {
|
|
293
|
+
if (this.mintLatencies.length > this.maxLatencyHistory) {
|
|
243
294
|
this.mintLatencies.shift();
|
|
244
295
|
}
|
|
245
296
|
}
|
|
@@ -251,7 +302,7 @@ class TTTClient {
|
|
|
251
302
|
const alerts = [];
|
|
252
303
|
let rpcConnected = false;
|
|
253
304
|
let balanceSufficient = false;
|
|
254
|
-
let ntpSourcesOk =
|
|
305
|
+
let ntpSourcesOk = false;
|
|
255
306
|
// 1. RPC connectivity check
|
|
256
307
|
if (this.isInitialized && this.signer?.provider) {
|
|
257
308
|
try {
|
|
@@ -277,7 +328,25 @@ class TTTClient {
|
|
|
277
328
|
alerts.push("Balance check failed");
|
|
278
329
|
}
|
|
279
330
|
}
|
|
280
|
-
// 3.
|
|
331
|
+
// 3. NTP/time source health check via quick synthesis with timeout
|
|
332
|
+
try {
|
|
333
|
+
const synthResult = await Promise.race([
|
|
334
|
+
this.autoMintEngine.getTimeSynthesis().synthesize(),
|
|
335
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error("Time synthesis health check timed out")), 3000)),
|
|
336
|
+
]);
|
|
337
|
+
if (synthResult && synthResult.sources >= 2 && synthResult.confidence >= 0.5) {
|
|
338
|
+
ntpSourcesOk = true;
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
ntpSourcesOk = false;
|
|
342
|
+
alerts.push(`Time sources degraded: ${synthResult?.sources ?? 0} source(s), confidence ${synthResult?.confidence?.toFixed(2) ?? "N/A"}`);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
ntpSourcesOk = false;
|
|
347
|
+
alerts.push("Time source health check failed");
|
|
348
|
+
}
|
|
349
|
+
// 4. Consecutive failure check
|
|
281
350
|
const total = this.mintCount + this.mintFailures;
|
|
282
351
|
const successRate = total > 0 ? this.mintCount / total : 1;
|
|
283
352
|
if (this.mintFailures > 5 && successRate < 0.8) {
|
|
@@ -316,7 +385,7 @@ class TTTClient {
|
|
|
316
385
|
};
|
|
317
386
|
}
|
|
318
387
|
/**
|
|
319
|
-
*
|
|
388
|
+
* Return current SDK status and statistics (balance, mint count, fees, etc.)
|
|
320
389
|
*/
|
|
321
390
|
async getStatus() {
|
|
322
391
|
if (!this.isInitialized || !this.signer) {
|
package/dist/types.d.ts
CHANGED
|
@@ -9,9 +9,19 @@ export declare const TierIntervals: Record<TierType, number>;
|
|
|
9
9
|
*/
|
|
10
10
|
export interface TTTClientConfig {
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Signer configuration (PrivateKey, Turnkey, Privy, KMS).
|
|
13
|
+
* Required unless `privateKey` shorthand is provided.
|
|
13
14
|
*/
|
|
14
|
-
signer
|
|
15
|
+
signer?: SignerConfig;
|
|
16
|
+
/**
|
|
17
|
+
* Shorthand: pass a raw private key string directly.
|
|
18
|
+
* If provided (and `signer` is not), auto-converts to { type: 'privateKey', key: ... }.
|
|
19
|
+
* Accepts with or without '0x' prefix.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* TTTClient.forBase({ privateKey: process.env.OPERATOR_PK! })
|
|
23
|
+
*/
|
|
24
|
+
privateKey?: string;
|
|
15
25
|
/**
|
|
16
26
|
* Optional: Network selection (preset "base", "sepolia" or custom NetworkConfig)
|
|
17
27
|
* Default: "base" (Base Mainnet)
|
|
@@ -28,7 +38,7 @@ export interface TTTClientConfig {
|
|
|
28
38
|
rpcUrl?: string;
|
|
29
39
|
/**
|
|
30
40
|
* Optional: Overwrite default NTP/KTSat sources
|
|
31
|
-
* Default: ["nist", "
|
|
41
|
+
* Default: ["nist", "google", "cloudflare", "apple"]
|
|
32
42
|
*/
|
|
33
43
|
timeSources?: string[];
|
|
34
44
|
/**
|
|
@@ -57,6 +67,12 @@ export interface TTTClientConfig {
|
|
|
57
67
|
* Optional: Automatically register SIGINT handler for graceful shutdown
|
|
58
68
|
*/
|
|
59
69
|
enableGracefulShutdown?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Optional: Maximum number of mint latency samples to keep in the ring buffer.
|
|
72
|
+
* Used for avgMintLatencyMs calculation in health checks.
|
|
73
|
+
* Default: 100
|
|
74
|
+
*/
|
|
75
|
+
maxLatencyHistory?: number;
|
|
60
76
|
}
|
|
61
77
|
/**
|
|
62
78
|
* Internal configuration used by engines.
|
|
@@ -75,6 +91,8 @@ export interface AutoMintConfig {
|
|
|
75
91
|
protocolFeeRate: number;
|
|
76
92
|
protocolFeeRecipient: string;
|
|
77
93
|
fallbackPriceUsd?: bigint;
|
|
94
|
+
maxLatencyHistory?: number;
|
|
95
|
+
potSignerKeyPath?: string;
|
|
78
96
|
}
|
|
79
97
|
export interface MintResult {
|
|
80
98
|
tokenId: string;
|
|
@@ -138,9 +156,34 @@ export interface ProofOfTime {
|
|
|
138
156
|
source: string;
|
|
139
157
|
timestamp: bigint;
|
|
140
158
|
uncertainty: number;
|
|
159
|
+
stratum?: number;
|
|
141
160
|
}[];
|
|
142
161
|
nonce: string;
|
|
143
162
|
expiresAt: bigint;
|
|
144
163
|
issuerSignature?: PotSignature;
|
|
145
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Health status returned by TTTClient.getHealth().
|
|
167
|
+
* Provides liveness, readiness, and operational metrics.
|
|
168
|
+
*/
|
|
169
|
+
export interface HealthStatus {
|
|
170
|
+
healthy: boolean;
|
|
171
|
+
checks: {
|
|
172
|
+
initialized: boolean;
|
|
173
|
+
rpcConnected: boolean;
|
|
174
|
+
signerAvailable: boolean;
|
|
175
|
+
balanceSufficient: boolean;
|
|
176
|
+
ntpSourcesOk: boolean;
|
|
177
|
+
};
|
|
178
|
+
metrics: {
|
|
179
|
+
mintCount: number;
|
|
180
|
+
mintFailures: number;
|
|
181
|
+
successRate: number;
|
|
182
|
+
totalFeesPaid: string;
|
|
183
|
+
avgMintLatencyMs: number;
|
|
184
|
+
lastMintAt: string | null;
|
|
185
|
+
uptimeMs: number;
|
|
186
|
+
};
|
|
187
|
+
alerts: string[];
|
|
188
|
+
}
|
|
146
189
|
export type { PotSignature } from "./pot_signer";
|
package/dist/v4_hook.d.ts
CHANGED
|
@@ -3,8 +3,16 @@ import { ProtocolFeeCollector } from "./protocol_fee";
|
|
|
3
3
|
import { FeeCalculation } from "./dynamic_fee";
|
|
4
4
|
import { BeforeSwapParams, AfterSwapParams } from "./types";
|
|
5
5
|
/**
|
|
6
|
-
* UniswapV4Hook - TTT-based Uniswap V4 Hook Simulation
|
|
7
|
-
*
|
|
6
|
+
* UniswapV4Hook - TTT-based Uniswap V4 Hook Simulation (SDK-side)
|
|
7
|
+
*
|
|
8
|
+
* This is a simulation/SDK-side hook that mirrors the logic of a Uniswap V4 hook
|
|
9
|
+
* for off-chain validation and testing. It is NOT the actual Solidity on-chain hook.
|
|
10
|
+
*
|
|
11
|
+
* The actual V4 hook contract should implement IHooks from @uniswap/v4-core
|
|
12
|
+
* (see: https://github.com/Uniswap/v4-core/blob/main/src/interfaces/IHooks.sol).
|
|
13
|
+
*
|
|
14
|
+
* Provides TTT balance verification and fee management logic that can be used
|
|
15
|
+
* to validate swap eligibility before submitting on-chain transactions.
|
|
8
16
|
*/
|
|
9
17
|
export declare class UniswapV4Hook {
|
|
10
18
|
private evmConnector;
|
package/dist/v4_hook.js
CHANGED
|
@@ -4,8 +4,16 @@ exports.UniswapV4Hook = void 0;
|
|
|
4
4
|
const ethers_1 = require("ethers");
|
|
5
5
|
const logger_1 = require("./logger");
|
|
6
6
|
/**
|
|
7
|
-
* UniswapV4Hook - TTT-based Uniswap V4 Hook Simulation
|
|
8
|
-
*
|
|
7
|
+
* UniswapV4Hook - TTT-based Uniswap V4 Hook Simulation (SDK-side)
|
|
8
|
+
*
|
|
9
|
+
* This is a simulation/SDK-side hook that mirrors the logic of a Uniswap V4 hook
|
|
10
|
+
* for off-chain validation and testing. It is NOT the actual Solidity on-chain hook.
|
|
11
|
+
*
|
|
12
|
+
* The actual V4 hook contract should implement IHooks from @uniswap/v4-core
|
|
13
|
+
* (see: https://github.com/Uniswap/v4-core/blob/main/src/interfaces/IHooks.sol).
|
|
14
|
+
*
|
|
15
|
+
* Provides TTT balance verification and fee management logic that can be used
|
|
16
|
+
* to validate swap eligibility before submitting on-chain transactions.
|
|
9
17
|
*/
|
|
10
18
|
class UniswapV4Hook {
|
|
11
19
|
evmConnector;
|
package/dist/x402_enforcer.d.ts
CHANGED
|
@@ -11,9 +11,24 @@ export interface SwapDetails {
|
|
|
11
11
|
export declare class X402Enforcer {
|
|
12
12
|
private static getCost;
|
|
13
13
|
/**
|
|
14
|
-
* Deducts TTT ticks from
|
|
14
|
+
* Deducts TTT ticks from the provided balance and determines Adaptive Mode.
|
|
15
|
+
*
|
|
16
|
+
* **Important:** By default, the `balance` parameter is an SDK-local value
|
|
17
|
+
* (tracked in-memory by the caller). It is NOT verified against the on-chain
|
|
18
|
+
* TTT token balance. This is sufficient for hot-path tick accounting where
|
|
19
|
+
* on-chain settlement happens separately via `deductOnChain()`.
|
|
20
|
+
*
|
|
21
|
+
* @param feeEngine - Dynamic fee engine for cost calculation
|
|
22
|
+
* @param swap - Swap details (user, tokens, amount)
|
|
23
|
+
* @param balance - SDK-local TTT balance (not on-chain unless verifyOnChain=true)
|
|
24
|
+
* @param tier - Stratum tier (0-3)
|
|
25
|
+
* @param mode - Current adaptive mode (Turbo/Full)
|
|
26
|
+
* @param verifyOnChain - If true, checks on-chain TTT balance via EVMConnector
|
|
27
|
+
* before deducting. Requires `connector` and `tokenId`. Default: false.
|
|
28
|
+
* @param connector - EVMConnector instance (required when verifyOnChain=true)
|
|
29
|
+
* @param tokenId - Token ID for on-chain balance lookup (required when verifyOnChain=true)
|
|
15
30
|
*/
|
|
16
|
-
static deductTick(feeEngine: DynamicFeeEngine, swap: SwapDetails, balance: bigint, tier: number, mode: AdaptiveMode): Promise<{
|
|
31
|
+
static deductTick(feeEngine: DynamicFeeEngine, swap: SwapDetails, balance: bigint, tier: number, mode: AdaptiveMode, verifyOnChain?: boolean, connector?: EVMConnector, tokenId?: bigint): Promise<{
|
|
17
32
|
success: boolean;
|
|
18
33
|
remaining: bigint;
|
|
19
34
|
mode: AdaptiveMode;
|
package/dist/x402_enforcer.js
CHANGED
|
@@ -17,10 +17,35 @@ class X402Enforcer {
|
|
|
17
17
|
return feeCalc.tttAmount;
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
20
|
-
* Deducts TTT ticks from
|
|
20
|
+
* Deducts TTT ticks from the provided balance and determines Adaptive Mode.
|
|
21
|
+
*
|
|
22
|
+
* **Important:** By default, the `balance` parameter is an SDK-local value
|
|
23
|
+
* (tracked in-memory by the caller). It is NOT verified against the on-chain
|
|
24
|
+
* TTT token balance. This is sufficient for hot-path tick accounting where
|
|
25
|
+
* on-chain settlement happens separately via `deductOnChain()`.
|
|
26
|
+
*
|
|
27
|
+
* @param feeEngine - Dynamic fee engine for cost calculation
|
|
28
|
+
* @param swap - Swap details (user, tokens, amount)
|
|
29
|
+
* @param balance - SDK-local TTT balance (not on-chain unless verifyOnChain=true)
|
|
30
|
+
* @param tier - Stratum tier (0-3)
|
|
31
|
+
* @param mode - Current adaptive mode (Turbo/Full)
|
|
32
|
+
* @param verifyOnChain - If true, checks on-chain TTT balance via EVMConnector
|
|
33
|
+
* before deducting. Requires `connector` and `tokenId`. Default: false.
|
|
34
|
+
* @param connector - EVMConnector instance (required when verifyOnChain=true)
|
|
35
|
+
* @param tokenId - Token ID for on-chain balance lookup (required when verifyOnChain=true)
|
|
21
36
|
*/
|
|
22
|
-
static async deductTick(feeEngine, swap, balance, tier, mode) {
|
|
37
|
+
static async deductTick(feeEngine, swap, balance, tier, mode, verifyOnChain = false, connector, tokenId) {
|
|
23
38
|
const cost = await this.getCost(feeEngine, tier);
|
|
39
|
+
// Optional on-chain balance verification before deducting
|
|
40
|
+
if (verifyOnChain) {
|
|
41
|
+
if (!connector || tokenId === undefined) {
|
|
42
|
+
throw new Error("[x402] verifyOnChain requires both connector and tokenId parameters");
|
|
43
|
+
}
|
|
44
|
+
const onChainBalance = await connector.getTTTBalance(swap.user, tokenId);
|
|
45
|
+
if (onChainBalance < cost) {
|
|
46
|
+
throw new Error(`[x402] On-chain balance insufficient for user ${swap.user}. Required: ${cost}, On-chain: ${onChainBalance}.`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
24
49
|
if (balance < cost) {
|
|
25
50
|
throw new Error(`[x402] Insufficient TTT ticks for user ${swap.user}. Required: ${cost}, Have: ${balance}.`);
|
|
26
51
|
}
|