openttt 0.1.2 → 0.2.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.
Files changed (78) hide show
  1. package/README.md +52 -30
  2. package/dist/adaptive_switch.d.ts +22 -7
  3. package/dist/adaptive_switch.js +52 -15
  4. package/dist/auto_mint.d.ts +22 -7
  5. package/dist/auto_mint.js +107 -30
  6. package/dist/ct_log.d.ts +47 -0
  7. package/dist/ct_log.js +107 -0
  8. package/dist/dynamic_fee.d.ts +13 -2
  9. package/dist/dynamic_fee.js +62 -11
  10. package/dist/errors.d.ts +44 -25
  11. package/dist/errors.js +58 -42
  12. package/dist/evm_connector.d.ts +28 -1
  13. package/dist/evm_connector.js +124 -32
  14. package/dist/grg_api_client.d.ts +41 -0
  15. package/dist/grg_api_client.js +116 -0
  16. package/dist/http_client.d.ts +98 -0
  17. package/dist/http_client.js +252 -0
  18. package/dist/index.d.ts +5 -5
  19. package/dist/index.js +5 -5
  20. package/dist/logger.d.ts +36 -4
  21. package/dist/logger.js +70 -11
  22. package/dist/networks.d.ts +21 -0
  23. package/dist/networks.js +30 -4
  24. package/dist/pool_registry.d.ts +9 -0
  25. package/dist/pool_registry.js +37 -0
  26. package/dist/pot_signer.d.ts +15 -0
  27. package/dist/pot_signer.js +28 -0
  28. package/dist/protocol_fee.d.ts +42 -26
  29. package/dist/protocol_fee.js +77 -54
  30. package/dist/revenue_tiers.d.ts +36 -0
  31. package/dist/revenue_tiers.js +83 -0
  32. package/dist/signer.d.ts +1 -2
  33. package/dist/signer.js +72 -14
  34. package/dist/time_synthesis.d.ts +38 -0
  35. package/dist/time_synthesis.js +131 -21
  36. package/dist/trust_store.d.ts +49 -0
  37. package/dist/trust_store.js +89 -0
  38. package/dist/ttt_builder.d.ts +1 -1
  39. package/dist/ttt_builder.js +2 -2
  40. package/dist/ttt_client.d.ts +42 -29
  41. package/dist/ttt_client.js +117 -28
  42. package/dist/types.d.ts +46 -3
  43. package/dist/v4_hook.d.ts +10 -2
  44. package/dist/v4_hook.js +10 -2
  45. package/dist/x402_enforcer.d.ts +17 -2
  46. package/dist/x402_enforcer.js +27 -2
  47. package/package.json +6 -2
  48. package/dist/golay.d.ts +0 -6
  49. package/dist/golay.js +0 -166
  50. package/dist/grg_forward.d.ts +0 -11
  51. package/dist/grg_forward.js +0 -74
  52. package/dist/grg_inverse.d.ts +0 -7
  53. package/dist/grg_inverse.js +0 -100
  54. package/dist/grg_pipeline.d.ts +0 -13
  55. package/dist/grg_pipeline.js +0 -64
  56. package/dist/reed_solomon.d.ts +0 -12
  57. package/dist/reed_solomon.js +0 -179
  58. package/vendor/helm-crypto/golay.d.ts +0 -6
  59. package/vendor/helm-crypto/golay.js +0 -167
  60. package/vendor/helm-crypto/golay.js.map +0 -1
  61. package/vendor/helm-crypto/grg_forward.d.ts +0 -22
  62. package/vendor/helm-crypto/grg_forward.js +0 -89
  63. package/vendor/helm-crypto/grg_forward.js.map +0 -1
  64. package/vendor/helm-crypto/grg_inverse.d.ts +0 -16
  65. package/vendor/helm-crypto/grg_inverse.js +0 -118
  66. package/vendor/helm-crypto/grg_inverse.js.map +0 -1
  67. package/vendor/helm-crypto/grg_pipeline.d.ts +0 -13
  68. package/vendor/helm-crypto/grg_pipeline.js +0 -66
  69. package/vendor/helm-crypto/grg_pipeline.js.map +0 -1
  70. package/vendor/helm-crypto/index.d.ts +0 -5
  71. package/vendor/helm-crypto/index.js +0 -17
  72. package/vendor/helm-crypto/index.js.map +0 -1
  73. package/vendor/helm-crypto/logger.d.ts +0 -6
  74. package/vendor/helm-crypto/logger.js +0 -11
  75. package/vendor/helm-crypto/logger.js.map +0 -1
  76. package/vendor/helm-crypto/reed_solomon.d.ts +0 -37
  77. package/vendor/helm-crypto/reed_solomon.js +0 -210
  78. package/vendor/helm-crypto/reed_solomon.js.map +0 -1
@@ -1,32 +1,22 @@
1
- import { AutoMintConfig, TTTClientConfig } from "./types";
1
+ import { EventEmitter } from "events";
2
+ import { AutoMintConfig, TTTClientConfig, MintResult, HealthStatus } from "./types";
3
+ import { HttpOnlyClient, HttpOnlyClientOptions } from "./http_client";
4
+ export { HealthStatus } from "./types";
2
5
  /**
3
- * Health status returned by getHealth()
6
+ * Typed event map for TTTClient EventEmitter.
4
7
  */
5
- export interface HealthStatus {
6
- healthy: boolean;
7
- checks: {
8
- initialized: boolean;
9
- rpcConnected: boolean;
10
- signerAvailable: boolean;
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[];
8
+ export interface TTTClientEvents {
9
+ mint: [result: MintResult];
10
+ error: [error: Error];
11
+ alert: [alert: string];
12
+ latency: [ms: number];
13
+ modeSwitch: [mode: string];
24
14
  }
25
15
  /**
26
- * TTTClient - DEX 운영자용 SDK 진입점
27
- * 모든 내부 모듈을 초기화하고 자동 민팅 프로세스를 관리
16
+ * TTTClient - SDK entry point for DEX operators.
17
+ * Initializes all internal modules and manages the auto-minting process.
28
18
  */
29
- export declare class TTTClient {
19
+ export declare class TTTClient extends EventEmitter {
30
20
  private config;
31
21
  private autoMintEngine;
32
22
  private poolRegistry;
@@ -37,10 +27,10 @@ export declare class TTTClient {
37
27
  private signer;
38
28
  private lastTokenId;
39
29
  private mintLatencies;
30
+ private maxLatencyHistory;
40
31
  private lastMintAt;
41
32
  private startedAt;
42
33
  private minBalanceWei;
43
- private onAlertCallback?;
44
34
  constructor(config: AutoMintConfig);
45
35
  /**
46
36
  * Static factory for Base Mainnet
@@ -50,6 +40,23 @@ export declare class TTTClient {
50
40
  * Static factory for Base Sepolia
51
41
  */
52
42
  static forSepolia(config: Omit<TTTClientConfig, 'network'>): Promise<TTTClient>;
43
+ /**
44
+ * Zero-friction sandbox mode — no ETH, no signer, no on-chain interaction.
45
+ *
46
+ * Returns an HttpOnlyClient that fetches verified time from NIST, Apple,
47
+ * Google, and Cloudflare HTTPS endpoints and produces HMAC-signed PoTs.
48
+ *
49
+ * @example
50
+ * // Zero-friction: no wallet, no RPC, no gas
51
+ * const client = TTTClient.httpOnly();
52
+ * const pot = await client.generatePoT();
53
+ * console.log(pot.timestamp, pot.confidence);
54
+ *
55
+ * // Verify locally (no on-chain check needed)
56
+ * const result = client.verifyPoT(pot);
57
+ * console.log(result.valid); // true
58
+ */
59
+ static httpOnly(options?: HttpOnlyClientOptions): HttpOnlyClient;
53
60
  /**
54
61
  * Universal factory to create and initialize a client
55
62
  */
@@ -59,17 +66,22 @@ export declare class TTTClient {
59
66
  */
60
67
  destroy(): Promise<void>;
61
68
  /**
62
- * SDK 초기화: RPC 연결, 시간 소스 설정, 수수료 엔진 연결
69
+ * Initialize the SDK: RPC connection, time sources, fee engine wiring.
63
70
  */
64
71
  initialize(): Promise<void>;
65
72
  /**
66
- * 자동 민팅 프로세스 시작
73
+ * Start the auto-minting process.
67
74
  */
68
75
  startAutoMint(): void;
69
76
  /**
70
- * 자동 민팅 프로세스 정지
77
+ * Stop the auto-minting process.
71
78
  */
72
79
  stopAutoMint(): void;
80
+ /**
81
+ * Resume auto-minting after a circuit breaker trip.
82
+ * Resets consecutive failure count and restarts the engine.
83
+ */
84
+ resume(): void;
73
85
  /**
74
86
  * List registered pools.
75
87
  */
@@ -87,6 +99,7 @@ export declare class TTTClient {
87
99
  setMinBalance(weiAmount: bigint): void;
88
100
  /**
89
101
  * Register alert callback for real-time notifications.
102
+ * Backward compatible: delegates to EventEmitter 'alert' event.
90
103
  */
91
104
  onAlert(callback: (alert: string) => void): void;
92
105
  private emitAlert;
@@ -104,7 +117,7 @@ export declare class TTTClient {
104
117
  */
105
118
  getHealth(): Promise<HealthStatus>;
106
119
  /**
107
- * 현재 SDK 상태 통계 반환 (잔고, 민팅 수, 수수료 )
120
+ * Return current SDK status and statistics (balance, mint count, fees, etc.)
108
121
  */
109
122
  getStatus(): Promise<{
110
123
  isInitialized: boolean;
@@ -2,16 +2,19 @@
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");
12
+ const http_client_1 = require("./http_client");
10
13
  /**
11
- * TTTClient - DEX 운영자용 SDK 진입점
12
- * 모든 내부 모듈을 초기화하고 자동 민팅 프로세스를 관리
14
+ * TTTClient - SDK entry point for DEX operators.
15
+ * Initializes all internal modules and manages the auto-minting process.
13
16
  */
14
- class TTTClient {
17
+ class TTTClient extends events_1.EventEmitter {
15
18
  config;
16
19
  autoMintEngine;
17
20
  poolRegistry;
@@ -22,15 +25,17 @@ class TTTClient {
22
25
  signer = null;
23
26
  lastTokenId = null;
24
27
  mintLatencies = [];
28
+ maxLatencyHistory;
25
29
  lastMintAt = null;
26
30
  startedAt = new Date();
27
31
  minBalanceWei = ethers_1.ethers.parseEther("0.01"); // 0.01 ETH alert threshold
28
- onAlertCallback;
29
32
  constructor(config) {
33
+ super();
30
34
  this.config = config;
35
+ this.maxLatencyHistory = config.maxLatencyHistory ?? 100;
31
36
  this.autoMintEngine = new auto_mint_1.AutoMintEngine(config);
32
37
  this.poolRegistry = new pool_registry_1.PoolRegistry();
33
- // Set up callback to update stats + metrics
38
+ // Wire callbacks to update stats + emit events
34
39
  this.autoMintEngine.setOnMint((result) => {
35
40
  this.mintCount++;
36
41
  this.totalFeesPaid += result.protocolFeePaid;
@@ -38,16 +43,20 @@ class TTTClient {
38
43
  this.lastMintAt = new Date();
39
44
  // Record in registry
40
45
  this.poolRegistry.recordMint(this.config.poolAddress, 1n);
46
+ // Emit typed 'mint' event
47
+ this.emit('mint', result);
41
48
  });
42
- // H2: Wire failure/latency metrics from AutoMint loop to TTTClient
43
- this.autoMintEngine.setOnFailure((_error) => {
49
+ // Wire failure/latency metrics from AutoMint loop to TTTClient
50
+ this.autoMintEngine.setOnFailure((error) => {
44
51
  this.mintFailures++;
52
+ this.emit('error', error);
45
53
  });
46
54
  this.autoMintEngine.setOnLatency((ms) => {
47
55
  this.mintLatencies.push(ms);
48
- if (this.mintLatencies.length > 100) {
56
+ if (this.mintLatencies.length > this.maxLatencyHistory) {
49
57
  this.mintLatencies.shift();
50
58
  }
59
+ this.emit('latency', ms);
51
60
  });
52
61
  }
53
62
  /**
@@ -62,14 +71,59 @@ class TTTClient {
62
71
  static async forSepolia(config) {
63
72
  return this.create({ ...config, network: 'sepolia' });
64
73
  }
74
+ /**
75
+ * Zero-friction sandbox mode — no ETH, no signer, no on-chain interaction.
76
+ *
77
+ * Returns an HttpOnlyClient that fetches verified time from NIST, Apple,
78
+ * Google, and Cloudflare HTTPS endpoints and produces HMAC-signed PoTs.
79
+ *
80
+ * @example
81
+ * // Zero-friction: no wallet, no RPC, no gas
82
+ * const client = TTTClient.httpOnly();
83
+ * const pot = await client.generatePoT();
84
+ * console.log(pot.timestamp, pot.confidence);
85
+ *
86
+ * // Verify locally (no on-chain check needed)
87
+ * const result = client.verifyPoT(pot);
88
+ * console.log(result.valid); // true
89
+ */
90
+ static httpOnly(options) {
91
+ return new http_client_1.HttpOnlyClient(options);
92
+ }
65
93
  /**
66
94
  * Universal factory to create and initialize a client
67
95
  */
68
96
  static async create(config) {
97
+ // 0. Shorthand: privateKey string -> SignerConfig
98
+ if (config.privateKey && !config.signer) {
99
+ const key = config.privateKey.startsWith('0x') ? config.privateKey : '0x' + config.privateKey;
100
+ config = { ...config, signer: { type: 'privateKey', key } };
101
+ }
102
+ // 0.5. Validation: require either signer or privateKey
103
+ if (!config.signer) {
104
+ throw new Error('TTTClient requires either `signer` or `privateKey`. Simplest: TTTClient.forBase({ privateKey: process.env.OPERATOR_PK! })');
105
+ }
106
+ // 0.7. Validate tier — CRITICAL: invalid tier causes setInterval(fn, undefined) = 1ms loop = wallet drain
107
+ const tier = config.tier || "T1_block";
108
+ if (!types_1.TierIntervals[tier]) {
109
+ const validTiers = Object.keys(types_1.TierIntervals).join(', ');
110
+ throw new Error(`[TTTClient] Invalid tier "${tier}". Valid tiers: ${validTiers}`);
111
+ }
112
+ // 0.8. Validate fee rate bounds
113
+ if (config.protocolFeeRate !== undefined) {
114
+ if (config.protocolFeeRate < 0 || config.protocolFeeRate > 1) {
115
+ throw new Error(`[TTTClient] protocolFeeRate must be 0-1 (got ${config.protocolFeeRate}). Example: 0.05 = 5%`);
116
+ }
117
+ }
118
+ // 0.9. Validate network string
119
+ if (typeof config.network === 'string' && !networks_1.NETWORKS[config.network]) {
120
+ const validNets = Object.keys(networks_1.NETWORKS).join(', ');
121
+ throw new Error(`[TTTClient] Unknown network "${config.network}". Valid: ${validNets}. Or pass a custom NetworkConfig object.`);
122
+ }
69
123
  // 1. Resolve network defaults
70
124
  let net;
71
125
  if (typeof config.network === 'string') {
72
- net = networks_1.NETWORKS[config.network] || networks_1.NETWORKS.base;
126
+ net = networks_1.NETWORKS[config.network];
73
127
  }
74
128
  else if (config.network) {
75
129
  net = config.network;
@@ -92,12 +146,25 @@ class TTTClient {
92
146
  signer: signer,
93
147
  contractAddress: config.contractAddress || net.tttAddress,
94
148
  feeCollectorAddress: net.protocolFeeAddress,
95
- poolAddress: config.poolAddress || "0x0000000000000000000000000000000000000000",
149
+ poolAddress: (() => {
150
+ const addr = config.poolAddress;
151
+ if (!addr || addr === "0x0000000000000000000000000000000000000000") {
152
+ throw new Error("[TTTClient] poolAddress is required. Provide a valid DEX pool address.");
153
+ }
154
+ return addr;
155
+ })(),
96
156
  tier: config.tier || "T1_block",
97
- timeSources: config.timeSources || ["nist", "kriss", "google"],
157
+ timeSources: config.timeSources || ["nist", "google", "cloudflare", "apple"],
98
158
  protocolFeeRate: config.protocolFeeRate || 0.05,
99
- protocolFeeRecipient: config.protocolFeeRecipient || "0x0000000000000000000000000000000000000000",
159
+ protocolFeeRecipient: (() => {
160
+ const addr = config.protocolFeeRecipient;
161
+ if (!addr || addr === "0x0000000000000000000000000000000000000000") {
162
+ throw new Error("[TTTClient] protocolFeeRecipient is required. Provide a valid fee recipient address.");
163
+ }
164
+ return addr;
165
+ })(),
100
166
  fallbackPriceUsd: config.fallbackPriceUsd || 10000n,
167
+ maxLatencyHistory: config.maxLatencyHistory,
101
168
  };
102
169
  // 4. Instantiate and initialize
103
170
  const client = new TTTClient(autoMintConfig);
@@ -128,7 +195,7 @@ class TTTClient {
128
195
  logger_1.logger.info("[TTTClient] Client destroyed successfully.");
129
196
  }
130
197
  /**
131
- * SDK 초기화: RPC 연결, 시간 소스 설정, 수수료 엔진 연결
198
+ * Initialize the SDK: RPC connection, time sources, fee engine wiring.
132
199
  */
133
200
  async initialize() {
134
201
  if (this.isInitialized)
@@ -140,7 +207,7 @@ class TTTClient {
140
207
  this.signer = connector.getSigner();
141
208
  // Register initial pool
142
209
  await this.poolRegistry.registerPool(this.config.chainId, this.config.poolAddress);
143
- // R2-P2-2: Validate feeCollectorAddress early before use
210
+ // Validate feeCollectorAddress early before use
144
211
  if (this.config.feeCollectorAddress && !ethers_1.ethers.isAddress(this.config.feeCollectorAddress)) {
145
212
  throw new Error(`[TTTClient] Invalid feeCollectorAddress: ${this.config.feeCollectorAddress}`);
146
213
  }
@@ -179,7 +246,7 @@ class TTTClient {
179
246
  }
180
247
  }
181
248
  /**
182
- * 자동 민팅 프로세스 시작
249
+ * Start the auto-minting process.
183
250
  */
184
251
  startAutoMint() {
185
252
  if (!this.isInitialized) {
@@ -189,11 +256,20 @@ class TTTClient {
189
256
  logger_1.logger.info(`[TTTClient] Auto-minting started for tier ${this.config.tier}`);
190
257
  }
191
258
  /**
192
- * 자동 민팅 프로세스 정지
259
+ * Stop the auto-minting process.
193
260
  */
194
261
  stopAutoMint() {
195
262
  this.autoMintEngine.stop();
196
263
  }
264
+ /**
265
+ * Resume auto-minting after a circuit breaker trip.
266
+ * Resets consecutive failure count and restarts the engine.
267
+ */
268
+ resume() {
269
+ this.autoMintEngine.resume();
270
+ this.emit('modeSwitch', 'resumed');
271
+ logger_1.logger.info(`[TTTClient] Auto-minting resumed`);
272
+ }
197
273
  /**
198
274
  * List registered pools.
199
275
  */
@@ -214,18 +290,14 @@ class TTTClient {
214
290
  }
215
291
  /**
216
292
  * Register alert callback for real-time notifications.
293
+ * Backward compatible: delegates to EventEmitter 'alert' event.
217
294
  */
218
295
  onAlert(callback) {
219
- this.onAlertCallback = callback;
296
+ this.on('alert', callback);
220
297
  }
221
298
  emitAlert(alert) {
222
299
  logger_1.logger.warn(`[TTTClient] ALERT: ${alert}`);
223
- if (this.onAlertCallback) {
224
- try {
225
- this.onAlertCallback(alert);
226
- }
227
- catch (_) { /* swallow */ }
228
- }
300
+ this.emit('alert', alert);
229
301
  }
230
302
  /**
231
303
  * Record a mint failure (called internally or externally).
@@ -238,8 +310,7 @@ class TTTClient {
238
310
  */
239
311
  recordMintLatency(ms) {
240
312
  this.mintLatencies.push(ms);
241
- // Keep last 100 entries
242
- if (this.mintLatencies.length > 100) {
313
+ if (this.mintLatencies.length > this.maxLatencyHistory) {
243
314
  this.mintLatencies.shift();
244
315
  }
245
316
  }
@@ -251,7 +322,7 @@ class TTTClient {
251
322
  const alerts = [];
252
323
  let rpcConnected = false;
253
324
  let balanceSufficient = false;
254
- let ntpSourcesOk = true; // Assume ok unless we can verify
325
+ let ntpSourcesOk = false;
255
326
  // 1. RPC connectivity check
256
327
  if (this.isInitialized && this.signer?.provider) {
257
328
  try {
@@ -277,7 +348,25 @@ class TTTClient {
277
348
  alerts.push("Balance check failed");
278
349
  }
279
350
  }
280
- // 3. Consecutive failure check
351
+ // 3. NTP/time source health check via quick synthesis with timeout
352
+ try {
353
+ const synthResult = await Promise.race([
354
+ this.autoMintEngine.getTimeSynthesis().synthesize(),
355
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Time synthesis health check timed out")), 3000)),
356
+ ]);
357
+ if (synthResult && synthResult.sources >= 2 && synthResult.confidence >= 0.5) {
358
+ ntpSourcesOk = true;
359
+ }
360
+ else {
361
+ ntpSourcesOk = false;
362
+ alerts.push(`Time sources degraded: ${synthResult?.sources ?? 0} source(s), confidence ${synthResult?.confidence?.toFixed(2) ?? "N/A"}`);
363
+ }
364
+ }
365
+ catch {
366
+ ntpSourcesOk = false;
367
+ alerts.push("Time source health check failed");
368
+ }
369
+ // 4. Consecutive failure check
281
370
  const total = this.mintCount + this.mintFailures;
282
371
  const successRate = total > 0 ? this.mintCount / total : 1;
283
372
  if (this.mintFailures > 5 && successRate < 0.8) {
@@ -316,7 +405,7 @@ class TTTClient {
316
405
  };
317
406
  }
318
407
  /**
319
- * 현재 SDK 상태 통계 반환 (잔고, 민팅 수, 수수료 )
408
+ * Return current SDK status and statistics (balance, mint count, fees, etc.)
320
409
  */
321
410
  async getStatus() {
322
411
  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
- * Required: Signer configuration (PrivateKey, Turnkey, Privy, KMS)
12
+ * Signer configuration (PrivateKey, Turnkey, Privy, KMS).
13
+ * Required unless `privateKey` shorthand is provided.
13
14
  */
14
- signer: SignerConfig;
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", "kriss", "google"]
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
- * Provides actual logic for TTT balance verification and fee management.
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
- * Provides actual logic for TTT balance verification and fee management.
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;
@@ -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 local balance and determines Adaptive Mode.
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;
@@ -17,10 +17,35 @@ class X402Enforcer {
17
17
  return feeCalc.tttAmount;
18
18
  }
19
19
  /**
20
- * Deducts TTT ticks from local balance and determines Adaptive Mode.
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
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openttt",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "OpenTTT — TLS-grade transaction ordering for DeFi. Time + Logic + Sync.",
5
5
  "license": "BSL-1.1",
6
6
  "repository": {
@@ -31,7 +31,11 @@
31
31
  },
32
32
  "files": [
33
33
  "dist",
34
- "vendor",
34
+ "!dist/golay.*",
35
+ "!dist/grg_forward.*",
36
+ "!dist/grg_inverse.*",
37
+ "!dist/grg_pipeline.*",
38
+ "!dist/reed_solomon.*",
35
39
  "README.md"
36
40
  ],
37
41
  "scripts": {
package/dist/golay.d.ts DELETED
@@ -1,6 +0,0 @@
1
- export declare function golayEncode(data: Uint8Array): Uint8Array;
2
- export declare function golayDecode(encoded: Uint8Array): {
3
- data: Uint8Array;
4
- corrected: number;
5
- uncorrectable: boolean;
6
- };