@totemsdk/txpow 0.1.0 → 0.1.2

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 ADDED
@@ -0,0 +1,76 @@
1
+ # @totemsdk/txpow
2
+
3
+ **TxPoW — Minima's spam-prevention proof-of-work on every transaction.**
4
+
5
+ Every Minima transaction must carry a proof-of-work envelope before it can be broadcast. This package handles the full TxPoW lifecycle: serialize, mine, verify, and calibrate.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @totemsdk/txpow
11
+ ```
12
+
13
+ ## What's inside
14
+
15
+ | Export | What it does |
16
+ |--------|-------------|
17
+ | `serializeTxHeader` / `serializeTxBody` / `serializeTxPoW` | Byte-identical TxPoW envelope assembly |
18
+ | `computeTxPoWId` | Derive the canonical TxPoW ID used for deduplication |
19
+ | `mineTxPoW(txBody, target)` | Local PoW mining loop — returns `{ minedHeaderBytes }` |
20
+ | `fetchTxPowTarget(axiaBaseUrl)` | Fetch current network difficulty from Axia |
21
+ | `verifyProofOfWork(txpowId, difficulty)` | Verify a received TxPoW (for relay nodes) |
22
+ | `calibrateHashRate()` | Benchmark local hardware hash rate |
23
+ | `estimateMiningCost(difficulty)` | Estimate mining time at current hash rate |
24
+ | `MAX_HASH`, `TX_POW_MIN_DIFFICULTY`, `CASCADE_LEVELS`, `MAIN_NET_CHAIN_ID` | Chain constants |
25
+
26
+ ## Usage
27
+
28
+ ### Mine and broadcast a transaction
29
+
30
+ ```typescript
31
+ import {
32
+ mineTxPoW,
33
+ fetchTxPowTarget,
34
+ serializeTxPoW,
35
+ computeTxPoWId,
36
+ } from '@totemsdk/txpow';
37
+
38
+ // 1. Fetch current difficulty
39
+ const target = await fetchTxPowTarget('https://api.axia.to');
40
+
41
+ // 2. Mine (this runs the PoW loop — may take seconds)
42
+ const { minedHeaderBytes } = await mineTxPoW(txBodyBytes, target);
43
+
44
+ // 3. Assemble the final TxPoW envelope
45
+ const txpowBytes = serializeTxPoW(minedHeaderBytes, txBodyBytes);
46
+ const txpowId = computeTxPoWId(txpowBytes);
47
+ console.log('TxPoW ID:', txpowId);
48
+
49
+ // 4. Broadcast
50
+ await provider.broadcastTxPoW(Buffer.from(txpowBytes).toString('hex'));
51
+ ```
52
+
53
+ ### Verify received TxPoW
54
+
55
+ ```typescript
56
+ import { verifyProofOfWork } from '@totemsdk/txpow';
57
+
58
+ const ok = verifyProofOfWork(txpowId, difficulty);
59
+ if (!ok) throw new Error('Invalid proof-of-work');
60
+ ```
61
+
62
+ ### Calibrate hardware
63
+
64
+ ```typescript
65
+ import { calibrateHashRate, estimateMiningCost } from '@totemsdk/txpow';
66
+
67
+ const hashesPerSecond = await calibrateHashRate();
68
+ const estimatedMs = estimateMiningCost(targetDifficulty, hashesPerSecond);
69
+ console.log(`Expected mining time: ${estimatedMs}ms`);
70
+ ```
71
+
72
+ ## See also
73
+
74
+ - [`@totemsdk/tx-builder`](../tx-builder) — construct `txBodyBytes` before mining
75
+ - [`@totemsdk/node`](../node) — Node.js wallet that uses txpow internally
76
+ - [`@totemsdk/chain-provider`](../chain-provider) — `broadcastTxPoW` endpoint
package/dist/index.d.ts CHANGED
@@ -22,5 +22,5 @@ export { MAX_HASH, ZERO_HASH, TX_POW_MIN_DIFFICULTY, CASCADE_LEVELS, MAIN_NET_CH
22
22
  export { serializeMagic } from './magic.js';
23
23
  export { mineTxPoW, isLessThan, type MineResult, type MineOptions, } from './mine.js';
24
24
  export { fetchTxPowTarget, type TxPowParams } from './difficulty.js';
25
- export { verifyProofOfWork, type VerifyResult } from './verify.js';
25
+ export { verifyProofOfWork, verifyTxPoWWork, type VerifyResult } from './verify.js';
26
26
  export { calibrateHashRate, estimateMiningCost, type MiningEstimate, } from './calibrate.js';
package/dist/index.js CHANGED
@@ -22,5 +22,5 @@ export { MAX_HASH, ZERO_HASH, TX_POW_MIN_DIFFICULTY, CASCADE_LEVELS, MAIN_NET_CH
22
22
  export { serializeMagic } from './magic.js';
23
23
  export { mineTxPoW, isLessThan, } from './mine.js';
24
24
  export { fetchTxPowTarget } from './difficulty.js';
25
- export { verifyProofOfWork } from './verify.js';
25
+ export { verifyProofOfWork, verifyTxPoWWork } from './verify.js';
26
26
  export { calibrateHashRate, estimateMiningCost, } from './calibrate.js';
package/dist/verify.d.ts CHANGED
@@ -3,6 +3,11 @@
3
3
  *
4
4
  * verifyProofOfWork checks that a given txpowId beats the difficulty target
5
5
  * without re-mining. Used by relay nodes to reject under-work submissions.
6
+ *
7
+ * verifyTxPoWWork is a convenience wrapper for relay nodes that receive raw
8
+ * TxPoW hex: it hashes the full bytes as a proxy txpowId and checks against
9
+ * the network minimum difficulty. PureMinima performs authoritative validation
10
+ * on submission; this is a first-pass spam filter.
6
11
  */
7
12
  export interface VerifyResult {
8
13
  valid: boolean;
@@ -19,3 +24,14 @@ export interface VerifyResult {
19
24
  * @param mTxnDifficulty The 32-byte difficulty target from the TxBody.
20
25
  */
21
26
  export declare function verifyProofOfWork(txpowId: Uint8Array, mTxnDifficulty: Uint8Array): VerifyResult;
27
+ /**
28
+ * Relay-side work verification from raw TxPoW hex.
29
+ *
30
+ * Validates hex format, minimum length (spam filter), then computes
31
+ * SHA3-256 of the serialized bytes as a proxy txpowId and checks it
32
+ * against TX_POW_MIN_DIFFICULTY.
33
+ *
34
+ * Note: full structural parsing of TxPoW headers is deferred to a future
35
+ * parser. PureMinima performs authoritative work verification on submission.
36
+ */
37
+ export declare function verifyTxPoWWork(txpowHex: string): VerifyResult;
package/dist/verify.js CHANGED
@@ -3,8 +3,15 @@
3
3
  *
4
4
  * verifyProofOfWork checks that a given txpowId beats the difficulty target
5
5
  * without re-mining. Used by relay nodes to reject under-work submissions.
6
+ *
7
+ * verifyTxPoWWork is a convenience wrapper for relay nodes that receive raw
8
+ * TxPoW hex: it hashes the full bytes as a proxy txpowId and checks against
9
+ * the network minimum difficulty. PureMinima performs authoritative validation
10
+ * on submission; this is a first-pass spam filter.
6
11
  */
7
12
  import { isLessThan } from './mine.js';
13
+ import { computeTxPoWId } from './serialization.js';
14
+ import { TX_POW_MIN_DIFFICULTY } from './constants.js';
8
15
  function toHex(bytes) {
9
16
  return '0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join('');
10
17
  }
@@ -41,3 +48,34 @@ export function verifyProofOfWork(txpowId, mTxnDifficulty) {
41
48
  reason: valid ? undefined : 'txpowId ≥ mTxnDifficulty',
42
49
  };
43
50
  }
51
+ /**
52
+ * Relay-side work verification from raw TxPoW hex.
53
+ *
54
+ * Validates hex format, minimum length (spam filter), then computes
55
+ * SHA3-256 of the serialized bytes as a proxy txpowId and checks it
56
+ * against TX_POW_MIN_DIFFICULTY.
57
+ *
58
+ * Note: full structural parsing of TxPoW headers is deferred to a future
59
+ * parser. PureMinima performs authoritative work verification on submission.
60
+ */
61
+ export function verifyTxPoWWork(txpowHex) {
62
+ if (typeof txpowHex !== 'string' || !/^[0-9a-fA-F]+$/.test(txpowHex)) {
63
+ return {
64
+ valid: false,
65
+ txpowId: '',
66
+ difficulty: toHex(TX_POW_MIN_DIFFICULTY),
67
+ reason: 'invalid hex encoding',
68
+ };
69
+ }
70
+ if (txpowHex.length < 200) {
71
+ return {
72
+ valid: false,
73
+ txpowId: '',
74
+ difficulty: toHex(TX_POW_MIN_DIFFICULTY),
75
+ reason: 'TxPoW too short (spam filter: minimum 100 bytes)',
76
+ };
77
+ }
78
+ const bytes = Uint8Array.from(Buffer.from(txpowHex, 'hex'));
79
+ const proxyId = computeTxPoWId(bytes);
80
+ return verifyProofOfWork(proxyId, TX_POW_MIN_DIFFICULTY);
81
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@totemsdk/txpow",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "TxPoW envelope serialization and proof-of-work mining for the Minima protocol",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -11,20 +11,15 @@
11
11
  "import": "./dist/index.js"
12
12
  }
13
13
  },
14
- "scripts": {
15
- "build": "tsc",
16
- "clean": "rm -rf dist",
17
- "test": "jest --passWithNoTests"
18
- },
19
14
  "files": [
20
15
  "dist",
21
16
  "src"
22
17
  ],
23
18
  "dependencies": {
24
- "@totemsdk/core": "^1.0.5"
19
+ "@totemsdk/core": "file:../core"
25
20
  },
26
21
  "peerDependencies": {
27
- "@noble/hashes": ">=1.3.0"
22
+ "@noble/hashes": ">=1.3.0 <2.0.0"
28
23
  },
29
24
  "peerDependenciesMeta": {
30
25
  "@noble/hashes": {
@@ -45,5 +40,10 @@
45
40
  "publishConfig": {
46
41
  "access": "public"
47
42
  },
48
- "license": "MIT"
49
- }
43
+ "license": "MIT",
44
+ "scripts": {
45
+ "build": "tsc",
46
+ "clean": "rm -rf dist",
47
+ "test": "jest --passWithNoTests"
48
+ }
49
+ }
package/src/index.ts CHANGED
@@ -47,7 +47,7 @@ export {
47
47
 
48
48
  export { fetchTxPowTarget, type TxPowParams } from './difficulty.js';
49
49
 
50
- export { verifyProofOfWork, type VerifyResult } from './verify.js';
50
+ export { verifyProofOfWork, verifyTxPoWWork, type VerifyResult } from './verify.js';
51
51
 
52
52
  export {
53
53
  calibrateHashRate,
package/src/verify.ts CHANGED
@@ -3,9 +3,16 @@
3
3
  *
4
4
  * verifyProofOfWork checks that a given txpowId beats the difficulty target
5
5
  * without re-mining. Used by relay nodes to reject under-work submissions.
6
+ *
7
+ * verifyTxPoWWork is a convenience wrapper for relay nodes that receive raw
8
+ * TxPoW hex: it hashes the full bytes as a proxy txpowId and checks against
9
+ * the network minimum difficulty. PureMinima performs authoritative validation
10
+ * on submission; this is a first-pass spam filter.
6
11
  */
7
12
 
8
13
  import { isLessThan } from './mine.js';
14
+ import { computeTxPoWId } from './serialization.js';
15
+ import { TX_POW_MIN_DIFFICULTY } from './constants.js';
9
16
 
10
17
  export interface VerifyResult {
11
18
  valid: boolean;
@@ -55,3 +62,35 @@ export function verifyProofOfWork(
55
62
  reason: valid ? undefined : 'txpowId ≥ mTxnDifficulty',
56
63
  };
57
64
  }
65
+
66
+ /**
67
+ * Relay-side work verification from raw TxPoW hex.
68
+ *
69
+ * Validates hex format, minimum length (spam filter), then computes
70
+ * SHA3-256 of the serialized bytes as a proxy txpowId and checks it
71
+ * against TX_POW_MIN_DIFFICULTY.
72
+ *
73
+ * Note: full structural parsing of TxPoW headers is deferred to a future
74
+ * parser. PureMinima performs authoritative work verification on submission.
75
+ */
76
+ export function verifyTxPoWWork(txpowHex: string): VerifyResult {
77
+ if (typeof txpowHex !== 'string' || !/^[0-9a-fA-F]+$/.test(txpowHex)) {
78
+ return {
79
+ valid: false,
80
+ txpowId: '',
81
+ difficulty: toHex(TX_POW_MIN_DIFFICULTY),
82
+ reason: 'invalid hex encoding',
83
+ };
84
+ }
85
+ if (txpowHex.length < 200) {
86
+ return {
87
+ valid: false,
88
+ txpowId: '',
89
+ difficulty: toHex(TX_POW_MIN_DIFFICULTY),
90
+ reason: 'TxPoW too short (spam filter: minimum 100 bytes)',
91
+ };
92
+ }
93
+ const bytes = Uint8Array.from(Buffer.from(txpowHex, 'hex'));
94
+ const proxyId = computeTxPoWId(bytes);
95
+ return verifyProofOfWork(proxyId, TX_POW_MIN_DIFFICULTY);
96
+ }