openttt 0.1.1 → 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/LICENSE +48 -0
- package/README.md +16 -14
- 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 +24 -5
- package/vendor/helm-crypto/golay.d.ts +6 -0
- package/vendor/helm-crypto/golay.js +167 -0
- package/vendor/helm-crypto/golay.js.map +1 -0
- package/vendor/helm-crypto/grg_forward.d.ts +22 -0
- package/vendor/helm-crypto/grg_forward.js +89 -0
- package/vendor/helm-crypto/grg_forward.js.map +1 -0
- package/vendor/helm-crypto/grg_inverse.d.ts +16 -0
- package/vendor/helm-crypto/grg_inverse.js +118 -0
- package/vendor/helm-crypto/grg_inverse.js.map +1 -0
- package/vendor/helm-crypto/grg_pipeline.d.ts +13 -0
- package/vendor/helm-crypto/grg_pipeline.js +66 -0
- package/vendor/helm-crypto/grg_pipeline.js.map +1 -0
- package/vendor/helm-crypto/index.d.ts +5 -0
- package/vendor/helm-crypto/index.js +17 -0
- package/vendor/helm-crypto/index.js.map +1 -0
- package/vendor/helm-crypto/logger.d.ts +6 -0
- package/vendor/helm-crypto/logger.js +11 -0
- package/vendor/helm-crypto/logger.js.map +1 -0
- package/vendor/helm-crypto/reed_solomon.d.ts +37 -0
- package/vendor/helm-crypto/reed_solomon.js +210 -0
- package/vendor/helm-crypto/reed_solomon.js.map +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
Parameters
|
|
4
|
+
|
|
5
|
+
Licensor: Helm Protocol Foundation
|
|
6
|
+
Licensed Work: TikitakaTime SDK v0.1.0 (OpenTTT)
|
|
7
|
+
Additional Use
|
|
8
|
+
Grant: Non-production evaluation and testing.
|
|
9
|
+
Change Date: March 14, 2030
|
|
10
|
+
Change License: Apache License, Version 2.0
|
|
11
|
+
|
|
12
|
+
1. Grant of License. Licensor hereby grants you a world-wide, royalty-free,
|
|
13
|
+
non-exclusive, non-sublicensable, non-transferable license to use the
|
|
14
|
+
Licensed Work, subject to the conditions set forth in this License.
|
|
15
|
+
|
|
16
|
+
2. Conditions. You may use the Licensed Work for any purpose, except for
|
|
17
|
+
Commercial Use.
|
|
18
|
+
|
|
19
|
+
3. Commercial Use. Commercial Use means any use of the Licensed Work that is
|
|
20
|
+
intended for or directed toward commercial advantage or monetary
|
|
21
|
+
compensation.
|
|
22
|
+
|
|
23
|
+
4. Change. On the Change Date, this License shall terminate and the Licensor
|
|
24
|
+
hereby grants you a license to the Licensed Work under the Change License.
|
|
25
|
+
|
|
26
|
+
5. Intellectual Property. This License does not grant you any rights in the
|
|
27
|
+
Intellectual Property of the Licensor, except for the license to use the
|
|
28
|
+
Licensed Work as set forth in Section 1.
|
|
29
|
+
|
|
30
|
+
6. Termination. This License shall terminate automatically if you fail to
|
|
31
|
+
comply with any of its terms and conditions.
|
|
32
|
+
|
|
33
|
+
7. Disclaimer of Warranty. THE LICENSED WORK IS PROVIDED "AS IS", WITHOUT
|
|
34
|
+
WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
35
|
+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
36
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
37
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
|
38
|
+
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
39
|
+
LICENSED WORK OR THE USE OR OTHER DEALINGS IN THE LICENSED WORK.
|
|
40
|
+
|
|
41
|
+
8. Limitation of Liability. IN NO EVENT SHALL THE LICENSOR BE LIABLE FOR ANY
|
|
42
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
43
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
44
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
45
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
46
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
47
|
+
OUT OF THE USE OF THE LICENSED WORK, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
48
|
+
SUCH DAMAGE.
|
package/README.md
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
# OpenTTT
|
|
2
2
|
|
|
3
|
+
> **Reference implementation of [draft-helmprotocol-tttps-00](https://datatracker.ietf.org/doc/draft-helmprotocol-tttps/)**
|
|
4
|
+
|
|
3
5
|
**OpenSSL for Transaction Ordering** -- TLS-grade Proof of Time for DeFi.
|
|
4
6
|
|
|
5
7
|
OpenTTT brings cryptographic time verification to blockchain transaction ordering. Where TLS made HTTP trustworthy, OpenTTT makes transaction sequencing verifiable. No trust assumptions. No gentleman's agreements. Physics.
|
|
6
8
|
|
|
7
9
|
[](https://www.npmjs.com/package/openttt)
|
|
8
10
|
[](LICENSE)
|
|
9
|
-
[](https://github.com/Helm-Protocol/OpenTTT/actions/workflows/ci.yml)
|
|
12
|
+
[](https://codecov.io/gh/Helm-Protocol/OpenTTT)
|
|
13
|
+
[]()
|
|
10
14
|
|
|
11
15
|
```
|
|
12
16
|
npm install openttt
|
|
@@ -23,7 +27,7 @@ Current MEV protection relies on **trust**: builders promise fair ordering, prot
|
|
|
23
27
|
| **Mechanism** | Social contract (request) | Physical verification (proof) |
|
|
24
28
|
| **Enforcement** | Reputation, exclusion | Economic natural selection |
|
|
25
29
|
| **Bad actors** | Must be identified and removed | Naturally unprofitable, self-selecting out |
|
|
26
|
-
| **Time source** | Block timestamp (miner-controlled) | Multi-source NTP synthesis (NIST,
|
|
30
|
+
| **Time source** | Block timestamp (miner-controlled) | Multi-source NTP synthesis (NIST, Google, Apple) |
|
|
27
31
|
|
|
28
32
|
**The core insight**: Rollups generate precise timestamps and deliver them to builders with a receipt. The Adaptive GRG pipeline then verifies whether the builder respected that ordering:
|
|
29
33
|
|
|
@@ -41,14 +45,14 @@ Three lines to start minting TimeTokens:
|
|
|
41
45
|
```typescript
|
|
42
46
|
import { TTTClient } from "openttt";
|
|
43
47
|
|
|
44
|
-
const ttt = await TTTClient.forBase({
|
|
45
|
-
signer: { type: "privateKey", envVar: "OPERATOR_PK" },
|
|
46
|
-
});
|
|
48
|
+
const ttt = await TTTClient.forBase({ privateKey: process.env.OPERATOR_PK! });
|
|
47
49
|
ttt.startAutoMint();
|
|
48
50
|
```
|
|
49
51
|
|
|
50
52
|
That is it. The SDK connects to Base Mainnet, synthesizes time from three atomic clock sources, and begins minting Proof-of-Time tokens at your configured tier interval.
|
|
51
53
|
|
|
54
|
+
> **Shorthand**: Pass `privateKey` directly as a string instead of the full `signer` config object. The verbose form `{ signer: { type: "privateKey", key: "0x..." } }` still works for when you need other signer types (Turnkey, KMS, Privy).
|
|
55
|
+
|
|
52
56
|
---
|
|
53
57
|
|
|
54
58
|
## Progressive Disclosure
|
|
@@ -60,9 +64,7 @@ OpenTTT is designed around progressive disclosure. Start simple, add control as
|
|
|
60
64
|
```typescript
|
|
61
65
|
import { TTTClient } from "openttt";
|
|
62
66
|
|
|
63
|
-
const ttt = await TTTClient.forBase({
|
|
64
|
-
signer: { type: "privateKey", envVar: "OPERATOR_PK" },
|
|
65
|
-
});
|
|
67
|
+
const ttt = await TTTClient.forBase({ privateKey: process.env.OPERATOR_PK! });
|
|
66
68
|
ttt.startAutoMint();
|
|
67
69
|
```
|
|
68
70
|
|
|
@@ -70,7 +72,7 @@ ttt.startAutoMint();
|
|
|
70
72
|
|
|
71
73
|
```typescript
|
|
72
74
|
const ttt = await TTTClient.forSepolia({
|
|
73
|
-
|
|
75
|
+
privateKey: process.env.OPERATOR_PK!,
|
|
74
76
|
rpcUrl: "https://my-rpc.example.com",
|
|
75
77
|
tier: "T2_slot",
|
|
76
78
|
});
|
|
@@ -93,7 +95,7 @@ const ttt = await TTTClient.create({
|
|
|
93
95
|
tier: "T1_block",
|
|
94
96
|
contractAddress: "0x...",
|
|
95
97
|
poolAddress: "0x...",
|
|
96
|
-
timeSources: ["nist", "
|
|
98
|
+
timeSources: ["nist", "google", "cloudflare", "apple"],
|
|
97
99
|
protocolFeeRate: 0.05,
|
|
98
100
|
enableGracefulShutdown: true,
|
|
99
101
|
});
|
|
@@ -111,7 +113,7 @@ OpenTTT abstracts away signer complexity. Use a raw private key for development,
|
|
|
111
113
|
|---|---|---|
|
|
112
114
|
| `privateKey` | Development, small operators | `{ type: "privateKey", key: "0x..." }` or `{ type: "privateKey", envVar: "OPERATOR_PK" }` |
|
|
113
115
|
| `turnkey` | Production, TEE-backed institutional custody | `{ type: "turnkey", apiBaseUrl, organizationId, privateKeyId, apiPublicKey, apiPrivateKey }` |
|
|
114
|
-
| `privy` | Embedded wallets, consumer-facing apps | `{ type: "privy", appId, appSecret }` |
|
|
116
|
+
| `privy` | Embedded wallets, consumer-facing apps (coming soon) | `{ type: "privy", appId, appSecret }` |
|
|
115
117
|
| `kms` | Cloud HSM (AWS KMS or GCP Cloud KMS) | `{ type: "kms", provider: "aws"\|"gcp", keyId, ... }` |
|
|
116
118
|
|
|
117
119
|
**AWS KMS** requires `@aws-sdk/client-kms`. **GCP KMS** requires `@google-cloud/kms`. Both are optional peer dependencies -- install only what you use.
|
|
@@ -262,7 +264,7 @@ const ttt = await TTTClient.create({
|
|
|
262
264
|
```
|
|
263
265
|
TTTClient (entry point)
|
|
264
266
|
|-- AutoMintEngine Periodic minting loop
|
|
265
|
-
| |-- TimeSynthesis NTP multi-source median synthesis (NIST,
|
|
267
|
+
| |-- TimeSynthesis NTP multi-source median synthesis (NIST, Google, Apple)
|
|
266
268
|
| |-- DynamicFeeEngine Oracle-based pricing
|
|
267
269
|
| |-- EVMConnector On-chain mint/burn/events (ethers v6)
|
|
268
270
|
| '-- ProtocolFee EIP-712 signed fee collection
|
|
@@ -309,10 +311,10 @@ This asymmetry is deliberate: it is hard to earn trust and easy to lose it.
|
|
|
309
311
|
OpenTTT queries multiple atomic clock-synchronized NTP sources in parallel and produces a median-synthesized timestamp with confidence scoring:
|
|
310
312
|
|
|
311
313
|
- **NIST** (time.nist.gov) -- US national standard
|
|
312
|
-
- **
|
|
314
|
+
- **Apple** (time.apple.com) -- Apple global time service
|
|
313
315
|
- **Google** (time.google.com) -- Leap-smeared public NTP
|
|
314
316
|
|
|
315
|
-
All readings must fall within
|
|
317
|
+
All readings must fall within a stratum-dependent tolerance of the synthesized median (10ms for stratum 1, 25ms for stratum 2, 50ms for stratum 3+), or the Proof of Time is rejected. Single-source operation triggers a degraded-confidence warning.
|
|
316
318
|
|
|
317
319
|
---
|
|
318
320
|
|
|
@@ -12,6 +12,8 @@ export interface Block {
|
|
|
12
12
|
txs: string[];
|
|
13
13
|
data: Uint8Array;
|
|
14
14
|
}
|
|
15
|
+
/** Tier-based dynamic tolerance (ms) — auditor-requested upgrade */
|
|
16
|
+
export declare const TIER_TOLERANCE_MS: Record<string, number>;
|
|
15
17
|
export declare class AdaptiveSwitch {
|
|
16
18
|
private windowSize;
|
|
17
19
|
private threshold;
|
|
@@ -22,23 +24,36 @@ export declare class AdaptiveSwitch {
|
|
|
22
24
|
private consecutiveFailures;
|
|
23
25
|
private turboEntryThreshold;
|
|
24
26
|
private turboMaintainThreshold;
|
|
27
|
+
private tolerance;
|
|
28
|
+
constructor(options?: {
|
|
29
|
+
tolerance?: number;
|
|
30
|
+
});
|
|
25
31
|
/**
|
|
26
|
-
* TTT
|
|
32
|
+
* Core TTT mechanism: switches between Turbo/Full mode based on timestamp ordering match rate.
|
|
27
33
|
*/
|
|
28
|
-
verifyBlock(block: Block, tttRecord: TTTRecord): AdaptiveMode;
|
|
34
|
+
verifyBlock(block: Block, tttRecord: TTTRecord, chainId: number, poolAddress: string, tier?: string): AdaptiveMode;
|
|
29
35
|
/**
|
|
30
|
-
*
|
|
31
|
-
* TURBO: 20%
|
|
32
|
-
* FULL:
|
|
36
|
+
* Return fee discount rate based on current mode.
|
|
37
|
+
* TURBO: 20% discount (incentivizes profitability).
|
|
38
|
+
* FULL: No discount.
|
|
33
39
|
*/
|
|
34
40
|
getFeeDiscount(): number;
|
|
35
41
|
/**
|
|
36
|
-
*
|
|
42
|
+
* Get current adaptive mode.
|
|
37
43
|
*/
|
|
38
44
|
getCurrentMode(): AdaptiveMode;
|
|
39
45
|
/**
|
|
40
|
-
*
|
|
46
|
+
* Reset history (for testing).
|
|
41
47
|
*/
|
|
42
48
|
reset(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Serialize internal state to JSON for persistence across restarts.
|
|
51
|
+
* Allows operators to avoid re-learning over 20 blocks after a restart.
|
|
52
|
+
*/
|
|
53
|
+
serialize(): string;
|
|
54
|
+
/**
|
|
55
|
+
* Reconstruct an AdaptiveSwitch from previously serialized JSON state.
|
|
56
|
+
*/
|
|
57
|
+
static deserialize(json: string): AdaptiveSwitch;
|
|
43
58
|
private compareTransactionOrder;
|
|
44
59
|
}
|
package/dist/adaptive_switch.js
CHANGED
|
@@ -2,15 +2,22 @@
|
|
|
2
2
|
// sdk/src/adaptive_switch.ts — Adaptive Mode Switcher
|
|
3
3
|
// Turbo (50ms) vs Full (127ms)
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.AdaptiveSwitch = exports.AdaptiveMode = void 0;
|
|
6
|
-
const
|
|
5
|
+
exports.AdaptiveSwitch = exports.TIER_TOLERANCE_MS = exports.AdaptiveMode = void 0;
|
|
6
|
+
const helm_crypto_1 = require("../vendor/helm-crypto");
|
|
7
7
|
const logger_1 = require("./logger");
|
|
8
8
|
var AdaptiveMode;
|
|
9
9
|
(function (AdaptiveMode) {
|
|
10
10
|
AdaptiveMode["TURBO"] = "TURBO";
|
|
11
11
|
AdaptiveMode["FULL"] = "FULL";
|
|
12
12
|
})(AdaptiveMode || (exports.AdaptiveMode = AdaptiveMode = {}));
|
|
13
|
-
const TOLERANCE = 100; // 100ms tolerance for KTSat sync
|
|
13
|
+
// const TOLERANCE = 100; // 100ms tolerance for KTSat sync (now configurable via constructor)
|
|
14
|
+
/** Tier-based dynamic tolerance (ms) — auditor-requested upgrade */
|
|
15
|
+
exports.TIER_TOLERANCE_MS = {
|
|
16
|
+
T0_epoch: 2000, // 6.4min tick → 2s tolerance
|
|
17
|
+
T1_block: 200, // 2s tick → 200ms
|
|
18
|
+
T2_slot: 500, // 12s tick → 500ms
|
|
19
|
+
T3_micro: 10, // 100ms tick → 10ms (10%)
|
|
20
|
+
};
|
|
14
21
|
class AdaptiveSwitch {
|
|
15
22
|
windowSize = 20; // B1-9: Updated from 10 to 20
|
|
16
23
|
threshold = 0.9; // B1-9: Updated from 0.8 to 0.9
|
|
@@ -21,17 +28,22 @@ class AdaptiveSwitch {
|
|
|
21
28
|
consecutiveFailures = 0; // P2-1: Track consecutive failures for exponential backoff
|
|
22
29
|
turboEntryThreshold = 0.95; // P2-2: Hysteresis — stricter entry
|
|
23
30
|
turboMaintainThreshold = 0.85; // P2-2: Hysteresis — relaxed maintenance
|
|
31
|
+
tolerance;
|
|
32
|
+
constructor(options) {
|
|
33
|
+
this.tolerance = options?.tolerance ?? 100;
|
|
34
|
+
}
|
|
24
35
|
/**
|
|
25
|
-
* TTT
|
|
36
|
+
* Core TTT mechanism: switches between Turbo/Full mode based on timestamp ordering match rate.
|
|
26
37
|
*/
|
|
27
|
-
verifyBlock(block, tttRecord) {
|
|
28
|
-
// 1.
|
|
38
|
+
verifyBlock(block, tttRecord, chainId, poolAddress, tier) {
|
|
39
|
+
// 1. Check timestamp ordering and time match
|
|
29
40
|
const orderMatch = this.compareTransactionOrder(block.txs, tttRecord.txOrder);
|
|
30
|
-
const
|
|
41
|
+
const tolerance = tier ? (exports.TIER_TOLERANCE_MS[tier] ?? this.tolerance) : this.tolerance;
|
|
42
|
+
const timeMatch = Math.abs(block.timestamp - tttRecord.time) < tolerance;
|
|
31
43
|
let sequenceOk = orderMatch && timeMatch;
|
|
32
44
|
// B1-1: Do not skip GrgInverse.verify() in TURBO mode
|
|
33
45
|
// We check integrity regardless of mode
|
|
34
|
-
const integrityOk =
|
|
46
|
+
const integrityOk = helm_crypto_1.GrgInverse.verify(block.data, tttRecord.grgPayload, chainId, poolAddress);
|
|
35
47
|
if (!integrityOk) {
|
|
36
48
|
logger_1.logger.error(`[AdaptiveSwitch] GRG integrity check FAILED`);
|
|
37
49
|
sequenceOk = false; // Mark as false if integrity fails
|
|
@@ -42,7 +54,7 @@ class AdaptiveSwitch {
|
|
|
42
54
|
this.penaltyCooldown = 20 * Math.pow(2, this.consecutiveFailures - 1); // 20, 40, 80, 160, 320
|
|
43
55
|
}
|
|
44
56
|
}
|
|
45
|
-
// 2.
|
|
57
|
+
// 2. Update history (Sliding Window)
|
|
46
58
|
this.history.push(sequenceOk);
|
|
47
59
|
if (this.history.length > this.windowSize) {
|
|
48
60
|
this.history.shift();
|
|
@@ -50,7 +62,7 @@ class AdaptiveSwitch {
|
|
|
50
62
|
if (this.penaltyCooldown > 0) {
|
|
51
63
|
this.penaltyCooldown--;
|
|
52
64
|
}
|
|
53
|
-
// 3.
|
|
65
|
+
// 3. Calculate match rate and switch mode
|
|
54
66
|
const matchCount = this.history.filter(h => h).length;
|
|
55
67
|
const matchRate = this.history.length > 0 ? matchCount / this.history.length : 0;
|
|
56
68
|
// P2-2: Hysteresis — different thresholds for entering vs maintaining TURBO
|
|
@@ -73,21 +85,21 @@ class AdaptiveSwitch {
|
|
|
73
85
|
return this.currentMode;
|
|
74
86
|
}
|
|
75
87
|
/**
|
|
76
|
-
*
|
|
77
|
-
* TURBO: 20%
|
|
78
|
-
* FULL:
|
|
88
|
+
* Return fee discount rate based on current mode.
|
|
89
|
+
* TURBO: 20% discount (incentivizes profitability).
|
|
90
|
+
* FULL: No discount.
|
|
79
91
|
*/
|
|
80
92
|
getFeeDiscount() {
|
|
81
93
|
return this.currentMode === AdaptiveMode.TURBO ? 0.2 : 0.0;
|
|
82
94
|
}
|
|
83
95
|
/**
|
|
84
|
-
*
|
|
96
|
+
* Get current adaptive mode.
|
|
85
97
|
*/
|
|
86
98
|
getCurrentMode() {
|
|
87
99
|
return this.currentMode;
|
|
88
100
|
}
|
|
89
101
|
/**
|
|
90
|
-
*
|
|
102
|
+
* Reset history (for testing).
|
|
91
103
|
*/
|
|
92
104
|
reset() {
|
|
93
105
|
this.history = [];
|
|
@@ -95,6 +107,31 @@ class AdaptiveSwitch {
|
|
|
95
107
|
this.penaltyCooldown = 0;
|
|
96
108
|
this.consecutiveFailures = 0;
|
|
97
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Serialize internal state to JSON for persistence across restarts.
|
|
112
|
+
* Allows operators to avoid re-learning over 20 blocks after a restart.
|
|
113
|
+
*/
|
|
114
|
+
serialize() {
|
|
115
|
+
return JSON.stringify({
|
|
116
|
+
history: this.history,
|
|
117
|
+
currentMode: this.currentMode,
|
|
118
|
+
consecutiveFailures: this.consecutiveFailures,
|
|
119
|
+
penaltyCooldown: this.penaltyCooldown,
|
|
120
|
+
tolerance: this.tolerance,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Reconstruct an AdaptiveSwitch from previously serialized JSON state.
|
|
125
|
+
*/
|
|
126
|
+
static deserialize(json) {
|
|
127
|
+
const data = JSON.parse(json);
|
|
128
|
+
const instance = new AdaptiveSwitch({ tolerance: data.tolerance ?? 100 });
|
|
129
|
+
instance.history = data.history;
|
|
130
|
+
instance.currentMode = data.currentMode;
|
|
131
|
+
instance.consecutiveFailures = data.consecutiveFailures;
|
|
132
|
+
instance.penaltyCooldown = data.penaltyCooldown;
|
|
133
|
+
return instance;
|
|
134
|
+
}
|
|
98
135
|
compareTransactionOrder(blockTxs, expectedOrder) {
|
|
99
136
|
if (blockTxs.length !== expectedOrder.length)
|
|
100
137
|
return false;
|
package/dist/auto_mint.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { TimeSynthesis } from "./time_synthesis";
|
|
1
2
|
import { EVMConnector } from "./evm_connector";
|
|
2
3
|
import { AutoMintConfig, MintResult } from "./types";
|
|
3
4
|
/**
|
|
4
|
-
* AutoMintEngine - TTT
|
|
5
|
-
*
|
|
5
|
+
* AutoMintEngine - Automatic TTT minting engine.
|
|
6
|
+
* Combines time synthesis, dynamic fee calculation, and EVM minting into a single loop.
|
|
6
7
|
*/
|
|
7
8
|
export declare class AutoMintEngine {
|
|
8
9
|
private config;
|
|
@@ -20,26 +21,40 @@ export declare class AutoMintEngine {
|
|
|
20
21
|
private consecutiveFailures;
|
|
21
22
|
private maxConsecutiveFailures;
|
|
22
23
|
private potSigner;
|
|
24
|
+
/** Monotonic counter appended to tokenId hash to prevent collision when two mints share the same nanosecond timestamp. */
|
|
25
|
+
private mintNonce;
|
|
26
|
+
/** Fire the GRG >50ms performance warning at most once per engine session. */
|
|
27
|
+
private warnedGrgSlow;
|
|
23
28
|
constructor(config: AutoMintConfig);
|
|
24
29
|
getEvmConnector(): EVMConnector;
|
|
30
|
+
getTimeSynthesis(): TimeSynthesis;
|
|
25
31
|
setOnMint(callback: (result: MintResult) => void): void;
|
|
26
32
|
setOnFailure(callback: (error: Error) => void): void;
|
|
27
33
|
setOnLatency(callback: (ms: number) => void): void;
|
|
28
34
|
/**
|
|
29
|
-
*
|
|
35
|
+
* Initialize the engine (RPC connection and contract setup).
|
|
30
36
|
*/
|
|
31
37
|
initialize(): Promise<void>;
|
|
32
38
|
/**
|
|
33
|
-
*
|
|
39
|
+
* Start the automatic minting loop.
|
|
34
40
|
*/
|
|
35
41
|
start(): void;
|
|
36
42
|
/**
|
|
37
|
-
*
|
|
43
|
+
* Stop the automatic minting loop.
|
|
38
44
|
*/
|
|
39
45
|
stop(): void;
|
|
40
46
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
47
|
+
* Resume the minting loop after a circuit breaker trip.
|
|
48
|
+
* Resets the consecutive failure counter and restarts the loop.
|
|
49
|
+
*/
|
|
50
|
+
resume(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Sleep helper for retry backoff.
|
|
53
|
+
*/
|
|
54
|
+
private sleep;
|
|
55
|
+
/**
|
|
56
|
+
* Execute a single mint tick.
|
|
57
|
+
* Time synthesis -> tokenId generation -> EVM mint call -> fee calculation/deduction.
|
|
43
58
|
*/
|
|
44
59
|
mintTick(): Promise<void>;
|
|
45
60
|
private signFeeMessage;
|