@mem-cash/types 0.0.1

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,12 @@
1
+ # @mem-cash/types
2
+
3
+ Shared primitives, data types, and interfaces for the mem-cash monorepo.
4
+
5
+ ## Contents
6
+
7
+ - **Primitives** -- `ScriptHash`, `Txid`, `BlockHash`, `OutpointKey` type aliases; `parseOutpointKey` validates vout as an integer in `[0, 0xFFFFFFFF]`
8
+ - **Data types** -- `BlockHeader`, `UtxoEntry`, `HistoryEntry`, `MempoolTx`, `TransactionRecord`, `Balance`, `TokenData`
9
+ - **Storage interfaces** -- `StorageReader`, `StorageWriter`, `Storage` for pluggable backends
10
+ - **Merkle utilities** -- `computeTxMerkleBranch`, `computeHeaderMerkleBranch` for SPV proofs; input validation rejects empty hash lists, out-of-bounds indices, and non-32-byte hashes
11
+ - **MTP** -- `computeMedianTimePast` (BIP113)
12
+ - **Reject codes** -- BCHN-compatible `REJECT_INVALID`, `REJECT_NONSTANDARD`, etc.
@@ -0,0 +1,38 @@
1
+ import type { BlockHeader, Outpoint, UtxoEntry } from "./data.js";
2
+ import type { BlockHash, BlockHeight, OutpointKey, ScriptHash, Txid } from "./primitives.js";
3
+ /** A single input in a processed block transaction. */
4
+ export interface ProcessedBlockInput {
5
+ readonly prevOutpoint: Outpoint;
6
+ }
7
+ /** A single output in a processed block transaction. */
8
+ export interface ProcessedBlockOutput {
9
+ readonly outpointKey: OutpointKey;
10
+ readonly utxo: UtxoEntry;
11
+ }
12
+ /** A transaction within a processed block. */
13
+ export interface ProcessedBlockTx {
14
+ readonly txid: Txid;
15
+ readonly inputs: readonly ProcessedBlockInput[];
16
+ readonly outputs: readonly ProcessedBlockOutput[];
17
+ readonly rawHex?: string;
18
+ readonly fee?: bigint;
19
+ }
20
+ /** A fully processed block ready to be applied to storage. */
21
+ export interface ProcessedBlock {
22
+ readonly height: BlockHeight;
23
+ readonly hash: BlockHash;
24
+ readonly header: BlockHeader;
25
+ readonly transactions: readonly ProcessedBlockTx[];
26
+ }
27
+ /** Info needed to undo (revert) a block. */
28
+ export interface UndoInfo {
29
+ readonly height: BlockHeight;
30
+ readonly hash: BlockHash;
31
+ /** UTXOs that were created by this block (to remove on undo). */
32
+ readonly addedUtxos: readonly OutpointKey[];
33
+ /** UTXOs that were spent by this block (to restore on undo). */
34
+ readonly removedUtxos: readonly UtxoEntry[];
35
+ /** All scripthashes affected by this block. */
36
+ readonly affectedScriptHashes: ReadonlySet<ScriptHash>;
37
+ }
38
+ //# sourceMappingURL=block.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.d.ts","sourceRoot":"","sources":["../src/block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE7F,uDAAuD;AACvD,MAAM,WAAW,mBAAmB;IACnC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC;CAChC;AAED,wDAAwD;AACxD,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CACzB;AAED,8CAA8C;AAC9C,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAChD,QAAQ,CAAC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAClD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,8DAA8D;AAC9D,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACnD;AAED,4CAA4C;AAC5C,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,iEAAiE;IACjE,QAAQ,CAAC,UAAU,EAAE,SAAS,WAAW,EAAE,CAAC;IAC5C,gEAAgE;IAChE,QAAQ,CAAC,YAAY,EAAE,SAAS,SAAS,EAAE,CAAC;IAC5C,+CAA+C;IAC/C,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CACvD"}
package/dist/block.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=block.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block.js","sourceRoot":"","sources":["../src/block.ts"],"names":[],"mappings":""}
package/dist/data.d.ts ADDED
@@ -0,0 +1,88 @@
1
+ import type { BlockHash, BlockHeight, OutpointKey, ScriptHash, Txid } from "./primitives.js";
2
+ /** A specific transaction output (txid + index). */
3
+ export interface Outpoint {
4
+ readonly txid: Txid;
5
+ readonly vout: number;
6
+ }
7
+ /** CashToken data attached to a UTXO. */
8
+ export interface TokenData {
9
+ /** Token category (32-byte hex token id). */
10
+ readonly category: string;
11
+ /** Fungible token amount. */
12
+ readonly amount: bigint;
13
+ /** Non-fungible token data, if present. */
14
+ readonly nft?: {
15
+ readonly commitment: string;
16
+ readonly capability: "none" | "mutable" | "minting";
17
+ };
18
+ }
19
+ /** A confirmed or unconfirmed UTXO. */
20
+ export interface UtxoEntry {
21
+ readonly outpoint: Outpoint;
22
+ readonly satoshis: bigint;
23
+ readonly scriptHash: ScriptHash;
24
+ /** Block height where this UTXO was created. 0 = mempool/unconfirmed. */
25
+ readonly height: BlockHeight;
26
+ /** The full locking script (scriptPubKey) for VM evaluation. */
27
+ readonly lockingBytecode: Uint8Array;
28
+ /** Whether this UTXO was created by a coinbase transaction. */
29
+ readonly isCoinbase?: boolean;
30
+ readonly tokenData?: TokenData;
31
+ }
32
+ /** An entry in a scripthash's transaction history. */
33
+ export interface HistoryEntry {
34
+ /** Transaction hash (hex). */
35
+ readonly txHash: Txid;
36
+ /** Block height. 0 = mempool, -1 = mempool with unconfirmed parents. */
37
+ readonly height: number;
38
+ /** Fee in satoshis (only present for mempool entries). */
39
+ readonly fee?: bigint;
40
+ }
41
+ /** Confirmed + unconfirmed balance for a scripthash. */
42
+ export interface Balance {
43
+ readonly confirmed: bigint;
44
+ readonly unconfirmed: bigint;
45
+ }
46
+ /** Stored transaction record. */
47
+ export interface TransactionRecord {
48
+ readonly txid: Txid;
49
+ /** Block height. 0 = unconfirmed. */
50
+ readonly height: BlockHeight;
51
+ readonly rawHex?: string;
52
+ readonly fee?: bigint;
53
+ }
54
+ /** A block header with all standard fields. */
55
+ export interface BlockHeader {
56
+ readonly hash: BlockHash;
57
+ readonly height: BlockHeight;
58
+ readonly version: number;
59
+ readonly prevHash: BlockHash;
60
+ readonly merkleRoot: string;
61
+ readonly timestamp: number;
62
+ readonly bits: number;
63
+ readonly nonce: number;
64
+ /** Raw 80-byte header as hex. */
65
+ readonly hex: string;
66
+ }
67
+ /** Per-scripthash bookkeeping within a mempool transaction. */
68
+ export interface MempoolTxScriptHashEntry {
69
+ /** Outpoints spent from confirmed UTXOs. */
70
+ readonly confirmedSpends: readonly OutpointKey[];
71
+ /** Outpoints spent from other mempool UTXOs. */
72
+ readonly unconfirmedSpends: readonly OutpointKey[];
73
+ /** Outpoint keys for new outputs to this scripthash. */
74
+ readonly outputs: readonly OutpointKey[];
75
+ }
76
+ /** A transaction currently in the mempool. */
77
+ export interface MempoolTx {
78
+ readonly txid: Txid;
79
+ readonly fee: bigint;
80
+ readonly size: number;
81
+ /** Scripthash → spend/output info for this tx. */
82
+ readonly entries: ReadonlyMap<ScriptHash, MempoolTxScriptHashEntry>;
83
+ /** Txids of mempool parents (unconfirmed inputs). */
84
+ readonly parents: ReadonlySet<Txid>;
85
+ /** Txids of mempool children (txs that spend our outputs). */
86
+ readonly children: ReadonlySet<Txid>;
87
+ }
88
+ //# sourceMappingURL=data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":"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"}
package/dist/data.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../src/data.ts"],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ export type { ProcessedBlock, ProcessedBlockInput, ProcessedBlockOutput, ProcessedBlockTx, UndoInfo, } from "./block.js";
2
+ export type { Balance, BlockHeader, HistoryEntry, MempoolTx, MempoolTxScriptHashEntry, Outpoint, TokenData, TransactionRecord, UtxoEntry, } from "./data.js";
3
+ export { computeHeaderMerkleBranch, computeMerkleBranchAndRoot, computeTxMerkleBranch, } from "./merkle.js";
4
+ export { computeMedianTimePast } from "./mtp.js";
5
+ export { type BlockHash, type BlockHeight, makeOutpointKey, type OutpointKey, parseOutpointKey, type ScriptHash, type Txid, } from "./primitives.js";
6
+ export { REJECT_CHECKPOINT, REJECT_DUPLICATE, REJECT_HIGHFEE, REJECT_INSUFFICIENTFEE, REJECT_INVALID, REJECT_MALFORMED, REJECT_NONSTANDARD, REJECT_OBSOLETE, } from "./rejectCodes.js";
7
+ export type { Storage, StorageReader, StorageWriter } from "./storageInterface.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,cAAc,EACd,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,QAAQ,GACR,MAAM,YAAY,CAAC;AAEpB,YAAY,EACX,OAAO,EACP,WAAW,EACX,YAAY,EACZ,SAAS,EACT,wBAAwB,EACxB,QAAQ,EACR,SAAS,EACT,iBAAiB,EACjB,SAAS,GACT,MAAM,WAAW,CAAC;AAEnB,OAAO,EACN,yBAAyB,EACzB,0BAA0B,EAC1B,qBAAqB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EACN,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,eAAe,EACf,KAAK,WAAW,EAChB,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,IAAI,GACT,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACN,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,GACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { computeHeaderMerkleBranch, computeMerkleBranchAndRoot, computeTxMerkleBranch, } from "./merkle.js";
2
+ export { computeMedianTimePast } from "./mtp.js";
3
+ export { makeOutpointKey, parseOutpointKey, } from "./primitives.js";
4
+ export { REJECT_CHECKPOINT, REJECT_DUPLICATE, REJECT_HIGHFEE, REJECT_INSUFFICIENTFEE, REJECT_INVALID, REJECT_MALFORMED, REJECT_NONSTANDARD, REJECT_OBSOLETE, } from "./rejectCodes.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAoBA,OAAO,EACN,yBAAyB,EACzB,0BAA0B,EAC1B,qBAAqB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,EAGN,eAAe,EAEf,gBAAgB,GAGhB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACN,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,GACf,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Compute the merkle branch and root for a given index in a list of hashes.
3
+ *
4
+ * Hashes should be in internal byte order (little-endian, as used in Bitcoin's
5
+ * merkle tree computation). The returned branch and root are also in internal order.
6
+ *
7
+ * @param hashes - Array of 32-byte hashes in internal byte order
8
+ * @param index - Position of the target hash
9
+ * @returns branch (sibling hashes) and root
10
+ */
11
+ export declare function computeMerkleBranchAndRoot(hashes: Uint8Array[], index: number): {
12
+ branch: Uint8Array[];
13
+ root: Uint8Array;
14
+ };
15
+ /**
16
+ * Compute the merkle branch for a transaction in a block.
17
+ *
18
+ * Takes txid hex strings in display order (big-endian, as shown in block explorers),
19
+ * converts to internal byte order for tree computation, then converts the branch
20
+ * back to display order hex strings for the protocol response.
21
+ *
22
+ * @param txids - Ordered txid hex strings (display order)
23
+ * @param targetTxid - The txid to compute the branch for
24
+ * @returns branch hashes in display-order hex and the position, or null if txid not found
25
+ */
26
+ export declare function computeTxMerkleBranch(txids: string[], targetTxid: string): {
27
+ merkle: string[];
28
+ pos: number;
29
+ } | null;
30
+ /**
31
+ * Compute a merkle branch for a block header within a checkpoint range.
32
+ *
33
+ * Used by `blockchain.block.header` with cp_height parameter.
34
+ * Computes a merkle tree over block hashes from height 0 to cp_height (inclusive),
35
+ * then returns the branch proving the header at `height` is included.
36
+ *
37
+ * @param headerHashes - Block hashes (display-order hex) for heights 0..cp_height
38
+ * @param height - The height of the header to prove
39
+ * @returns branch hashes in display-order hex and the merkle root
40
+ */
41
+ export declare function computeHeaderMerkleBranch(headerHashes: string[], height: number): {
42
+ branch: string[];
43
+ root: string;
44
+ };
45
+ //# sourceMappingURL=merkle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merkle.d.ts","sourceRoot":"","sources":["../src/merkle.ts"],"names":[],"mappings":"AAuBA;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACzC,MAAM,EAAE,UAAU,EAAE,EACpB,KAAK,EAAE,MAAM,GACX;IAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,CA+C5C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACpC,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,GAChB;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAa1C;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACxC,YAAY,EAAE,MAAM,EAAE,EACtB,MAAM,EAAE,MAAM,GACZ;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAUpC"}
package/dist/merkle.js ADDED
@@ -0,0 +1,114 @@
1
+ import { binToHex, hexToBin, sha256 } from "@bitauth/libauth";
2
+ /** Reverse a Uint8Array (returns new array). */
3
+ function reverseBytes(bytes) {
4
+ const reversed = new Uint8Array(bytes.length);
5
+ reversed.set(bytes);
6
+ reversed.reverse();
7
+ return reversed;
8
+ }
9
+ /** Double-SHA256 of a Uint8Array. */
10
+ function hash256(data) {
11
+ return sha256.hash(sha256.hash(data));
12
+ }
13
+ /** Hash a pair of 32-byte values for the merkle tree (double-SHA256 of concatenation). */
14
+ function hashPair(a, b) {
15
+ const combined = new Uint8Array(64);
16
+ combined.set(a, 0);
17
+ combined.set(b, 32);
18
+ return hash256(combined);
19
+ }
20
+ /**
21
+ * Compute the merkle branch and root for a given index in a list of hashes.
22
+ *
23
+ * Hashes should be in internal byte order (little-endian, as used in Bitcoin's
24
+ * merkle tree computation). The returned branch and root are also in internal order.
25
+ *
26
+ * @param hashes - Array of 32-byte hashes in internal byte order
27
+ * @param index - Position of the target hash
28
+ * @returns branch (sibling hashes) and root
29
+ */
30
+ export function computeMerkleBranchAndRoot(hashes, index) {
31
+ if (hashes.length === 0) {
32
+ throw new Error("Cannot compute merkle root for empty hash list");
33
+ }
34
+ if (index < 0 || index >= hashes.length) {
35
+ throw new Error(`Merkle index ${index} out of bounds for ${hashes.length} hashes`);
36
+ }
37
+ for (const hash of hashes) {
38
+ if (hash.length !== 32) {
39
+ throw new Error(`Invalid hash length: ${hash.length}, expected 32`);
40
+ }
41
+ }
42
+ const branch = [];
43
+ let level = [...hashes];
44
+ let idx = index;
45
+ while (level.length > 1) {
46
+ // If odd number of elements, duplicate the last one
47
+ if (level.length % 2 !== 0) {
48
+ const last = level[level.length - 1];
49
+ if (last)
50
+ level.push(last);
51
+ }
52
+ // Record the sibling of the target
53
+ const siblingIdx = idx ^ 1;
54
+ const sibling = level[siblingIdx];
55
+ if (sibling && siblingIdx < level.length) {
56
+ branch.push(sibling);
57
+ }
58
+ // Build next level
59
+ const nextLevel = [];
60
+ for (let i = 0; i < level.length; i += 2) {
61
+ const left = level[i];
62
+ const right = level[i + 1];
63
+ if (left && right) {
64
+ nextLevel.push(hashPair(left, right));
65
+ }
66
+ }
67
+ idx = Math.floor(idx / 2);
68
+ level = nextLevel;
69
+ }
70
+ return { branch, root: level[0] ?? new Uint8Array(32) };
71
+ }
72
+ /**
73
+ * Compute the merkle branch for a transaction in a block.
74
+ *
75
+ * Takes txid hex strings in display order (big-endian, as shown in block explorers),
76
+ * converts to internal byte order for tree computation, then converts the branch
77
+ * back to display order hex strings for the protocol response.
78
+ *
79
+ * @param txids - Ordered txid hex strings (display order)
80
+ * @param targetTxid - The txid to compute the branch for
81
+ * @returns branch hashes in display-order hex and the position, or null if txid not found
82
+ */
83
+ export function computeTxMerkleBranch(txids, targetTxid) {
84
+ const index = txids.indexOf(targetTxid);
85
+ if (index === -1)
86
+ return null;
87
+ // Convert display-order txids to internal byte order
88
+ const internalHashes = txids.map((txid) => reverseBytes(hexToBin(txid)));
89
+ const { branch } = computeMerkleBranchAndRoot(internalHashes, index);
90
+ // Convert branch back to display order hex
91
+ const merkle = branch.map((h) => binToHex(reverseBytes(h)));
92
+ return { merkle, pos: index };
93
+ }
94
+ /**
95
+ * Compute a merkle branch for a block header within a checkpoint range.
96
+ *
97
+ * Used by `blockchain.block.header` with cp_height parameter.
98
+ * Computes a merkle tree over block hashes from height 0 to cp_height (inclusive),
99
+ * then returns the branch proving the header at `height` is included.
100
+ *
101
+ * @param headerHashes - Block hashes (display-order hex) for heights 0..cp_height
102
+ * @param height - The height of the header to prove
103
+ * @returns branch hashes in display-order hex and the merkle root
104
+ */
105
+ export function computeHeaderMerkleBranch(headerHashes, height) {
106
+ // Convert display-order hashes to internal byte order
107
+ const internalHashes = headerHashes.map((h) => reverseBytes(hexToBin(h)));
108
+ const { branch, root } = computeMerkleBranchAndRoot(internalHashes, height);
109
+ return {
110
+ branch: branch.map((h) => binToHex(reverseBytes(h))),
111
+ root: binToHex(reverseBytes(root)),
112
+ };
113
+ }
114
+ //# sourceMappingURL=merkle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merkle.js","sourceRoot":"","sources":["../src/merkle.ts"],"names":[],"mappings":"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"}
package/dist/mtp.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { StorageReader } from "./storageInterface.js";
2
+ /**
3
+ * Compute BIP113 Median Time Past for a given height.
4
+ * Returns the median of up to 11 block timestamps ending at `height`.
5
+ * Returns 0 if no headers are available.
6
+ */
7
+ export declare function computeMedianTimePast(storage: StorageReader, height: number): number;
8
+ //# sourceMappingURL=mtp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mtp.d.ts","sourceRoot":"","sources":["../src/mtp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAK3D;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAWpF"}
package/dist/mtp.js ADDED
@@ -0,0 +1,21 @@
1
+ /** BIP113: number of previous blocks used to compute Median Time Past. */
2
+ const MTP_BLOCK_COUNT = 11;
3
+ /**
4
+ * Compute BIP113 Median Time Past for a given height.
5
+ * Returns the median of up to 11 block timestamps ending at `height`.
6
+ * Returns 0 if no headers are available.
7
+ */
8
+ export function computeMedianTimePast(storage, height) {
9
+ const timestamps = [];
10
+ for (let i = 0; i < MTP_BLOCK_COUNT && height - i >= 0; i++) {
11
+ const header = storage.getHeader(height - i);
12
+ if (header) {
13
+ timestamps.push(header.timestamp);
14
+ }
15
+ }
16
+ if (timestamps.length === 0)
17
+ return 0;
18
+ timestamps.sort((a, b) => a - b);
19
+ return timestamps[Math.floor(timestamps.length / 2)] ?? 0;
20
+ }
21
+ //# sourceMappingURL=mtp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mtp.js","sourceRoot":"","sources":["../src/mtp.ts"],"names":[],"mappings":"AAEA,0EAA0E;AAC1E,MAAM,eAAe,GAAG,EAAE,CAAC;AAE3B;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAsB,EAAE,MAAc;IAC3E,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,IAAI,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,MAAM,EAAE,CAAC;YACZ,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACtC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,18 @@
1
+ /** 64-char lowercase hex scripthash (SHA256 of output script). */
2
+ export type ScriptHash = string;
3
+ /** 64-char lowercase hex transaction id. */
4
+ export type Txid = string;
5
+ /** 64-char lowercase hex block hash. */
6
+ export type BlockHash = string;
7
+ /** Block height (non-negative integer). */
8
+ export type BlockHeight = number;
9
+ /** Canonical outpoint key: `"${txid}:${vout}"`. */
10
+ export type OutpointKey = `${string}:${number}`;
11
+ /** Build a canonical outpoint key from txid and output index. */
12
+ export declare function makeOutpointKey(txid: Txid, vout: number): OutpointKey;
13
+ /** Parse a canonical outpoint key back into txid and vout. */
14
+ export declare function parseOutpointKey(key: OutpointKey): {
15
+ txid: Txid;
16
+ vout: number;
17
+ };
18
+ //# sourceMappingURL=primitives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../src/primitives.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAEhC,4CAA4C;AAC5C,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC;AAE1B,wCAAwC;AACxC,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAE/B,2CAA2C;AAC3C,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC;AAEjC,mDAAmD;AACnD,MAAM,MAAM,WAAW,GAAG,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AAEhD,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAErE;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAW/E"}
@@ -0,0 +1,18 @@
1
+ /** Build a canonical outpoint key from txid and output index. */
2
+ export function makeOutpointKey(txid, vout) {
3
+ return `${txid}:${vout}`;
4
+ }
5
+ /** Parse a canonical outpoint key back into txid and vout. */
6
+ export function parseOutpointKey(key) {
7
+ const lastColon = key.lastIndexOf(":");
8
+ const voutStr = key.slice(lastColon + 1);
9
+ const vout = Number(voutStr);
10
+ if (!Number.isInteger(vout) || vout < 0 || vout > 0xffffffff) {
11
+ throw new Error(`Invalid vout in outpoint key: ${voutStr}`);
12
+ }
13
+ return {
14
+ txid: key.slice(0, lastColon),
15
+ vout,
16
+ };
17
+ }
18
+ //# sourceMappingURL=primitives.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.js","sourceRoot":"","sources":["../src/primitives.ts"],"names":[],"mappings":"AAeA,iEAAiE;AACjE,MAAM,UAAU,eAAe,CAAC,IAAU,EAAE,IAAY;IACvD,OAAO,GAAG,IAAI,IAAI,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAAC,GAAgB;IAChD,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,UAAU,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,iCAAiC,OAAO,EAAE,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO;QACN,IAAI,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC;QAC7B,IAAI;KACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * BCHN P2P reject codes (consensus/validation.h).
3
+ * Used to classify validation failures by severity and category.
4
+ */
5
+ /** Malformed data structure. */
6
+ export declare const REJECT_MALFORMED = 1;
7
+ /** Network rule violation (consensus failure). */
8
+ export declare const REJECT_INVALID = 16;
9
+ /** Obsolete version. */
10
+ export declare const REJECT_OBSOLETE = 17;
11
+ /** Already known (duplicate tx/block). */
12
+ export declare const REJECT_DUPLICATE = 18;
13
+ /** Standard policy violation. */
14
+ export declare const REJECT_NONSTANDARD = 64;
15
+ /** Fee too low for relay. */
16
+ export declare const REJECT_INSUFFICIENTFEE = 66;
17
+ /** Conflicts with checkpoint. */
18
+ export declare const REJECT_CHECKPOINT = 67;
19
+ /** Absurdly high fee (internal-only, not sent over P2P). */
20
+ export declare const REJECT_HIGHFEE = 256;
21
+ //# sourceMappingURL=rejectCodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rejectCodes.d.ts","sourceRoot":"","sources":["../src/rejectCodes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,gCAAgC;AAChC,eAAO,MAAM,gBAAgB,IAAO,CAAC;AAErC,kDAAkD;AAClD,eAAO,MAAM,cAAc,KAAO,CAAC;AAEnC,wBAAwB;AACxB,eAAO,MAAM,eAAe,KAAO,CAAC;AAEpC,0CAA0C;AAC1C,eAAO,MAAM,gBAAgB,KAAO,CAAC;AAErC,iCAAiC;AACjC,eAAO,MAAM,kBAAkB,KAAO,CAAC;AAEvC,6BAA6B;AAC7B,eAAO,MAAM,sBAAsB,KAAO,CAAC;AAE3C,iCAAiC;AACjC,eAAO,MAAM,iBAAiB,KAAO,CAAC;AAEtC,4DAA4D;AAC5D,eAAO,MAAM,cAAc,MAAQ,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * BCHN P2P reject codes (consensus/validation.h).
3
+ * Used to classify validation failures by severity and category.
4
+ */
5
+ /** Malformed data structure. */
6
+ export const REJECT_MALFORMED = 0x01;
7
+ /** Network rule violation (consensus failure). */
8
+ export const REJECT_INVALID = 0x10;
9
+ /** Obsolete version. */
10
+ export const REJECT_OBSOLETE = 0x11;
11
+ /** Already known (duplicate tx/block). */
12
+ export const REJECT_DUPLICATE = 0x12;
13
+ /** Standard policy violation. */
14
+ export const REJECT_NONSTANDARD = 0x40;
15
+ /** Fee too low for relay. */
16
+ export const REJECT_INSUFFICIENTFEE = 0x42;
17
+ /** Conflicts with checkpoint. */
18
+ export const REJECT_CHECKPOINT = 0x43;
19
+ /** Absurdly high fee (internal-only, not sent over P2P). */
20
+ export const REJECT_HIGHFEE = 0x100;
21
+ //# sourceMappingURL=rejectCodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rejectCodes.js","sourceRoot":"","sources":["../src/rejectCodes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,gCAAgC;AAChC,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC,kDAAkD;AAClD,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,CAAC;AAEnC,wBAAwB;AACxB,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;AAEpC,0CAA0C;AAC1C,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAErC,iCAAiC;AACjC,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEvC,6BAA6B;AAC7B,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC;AAE3C,iCAAiC;AACjC,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAEtC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC"}
@@ -0,0 +1,56 @@
1
+ import type { ProcessedBlock } from "./block.js";
2
+ import type { Balance, BlockHeader, HistoryEntry, MempoolTx, TransactionRecord, UtxoEntry } from "./data.js";
3
+ import type { OutpointKey, ScriptHash, Txid } from "./primitives.js";
4
+ /** Read-only view into the chain + mempool state. */
5
+ export interface StorageReader {
6
+ /** Get the block header at a given height. */
7
+ getHeader(height: number): BlockHeader | undefined;
8
+ /** Get the block header by block hash. */
9
+ getHeaderByHash(hash: string): BlockHeader | undefined;
10
+ /** Get the current chain tip (highest header), or undefined if empty. */
11
+ getTip(): BlockHeader | undefined;
12
+ /** Get confirmed transaction history for a scripthash. */
13
+ getHistory(scriptHash: ScriptHash, fromHeight?: number, toHeight?: number): HistoryEntry[];
14
+ /** Get mempool history entries for a scripthash. */
15
+ getMempoolHistory(scriptHash: ScriptHash): HistoryEntry[];
16
+ /** Get confirmed + unconfirmed balance for a scripthash. */
17
+ getBalance(scriptHash: ScriptHash): Balance;
18
+ /** Get unspent outputs for a scripthash (confirmed minus mempool-spent, plus mempool outputs). */
19
+ getUtxos(scriptHash: ScriptHash): UtxoEntry[];
20
+ /** Get a transaction record by txid. */
21
+ getTx(txid: Txid): TransactionRecord | undefined;
22
+ /** Get raw transaction hex by txid. */
23
+ getRawTx(txid: Txid): string | undefined;
24
+ /** Compute the Electrum status hash for a scripthash. Null if no history. */
25
+ getScriptHashStatus(scriptHash: ScriptHash): string | null;
26
+ /** Get a mempool transaction entry. */
27
+ getMempoolTx(txid: Txid): MempoolTx | undefined;
28
+ /** Get the ordered list of txids in a block at the given height. */
29
+ getTxidsAtHeight(height: number): Txid[] | undefined;
30
+ /** Get a single UTXO by outpoint key (confirmed or mempool, undefined if spent in mempool). */
31
+ getUtxoByOutpoint(key: OutpointKey): UtxoEntry | undefined;
32
+ /** Get all mempool transaction IDs. */
33
+ getMempoolTxids(): Txid[];
34
+ /** Get a mempool UTXO by outpoint key. */
35
+ getMempoolUtxo(key: OutpointKey): UtxoEntry | undefined;
36
+ }
37
+ /** Mutating operations on the chain + mempool state. */
38
+ export interface StorageWriter {
39
+ /** Apply a processed block to the confirmed state. Returns affected scripthashes. */
40
+ applyBlock(block: ProcessedBlock): Set<ScriptHash>;
41
+ /** Undo (revert) the block at the given height. Returns affected scripthashes. */
42
+ undoBlock(height: number): Set<ScriptHash>;
43
+ /** Add a transaction to the mempool. Returns affected scripthashes. */
44
+ addMempoolTx(tx: MempoolTx): Set<ScriptHash>;
45
+ /** Remove a mempool transaction (cascading to descendants). Returns affected scripthashes. */
46
+ removeMempoolTx(txid: Txid): Set<ScriptHash>;
47
+ /** Clear all mempool state. Returns all scripthashes that had mempool activity. */
48
+ clearMempool(): Set<ScriptHash>;
49
+ /** Pre-register a mempool UTXO before calling addMempoolTx. */
50
+ addMempoolUtxo(key: OutpointKey, utxo: UtxoEntry): void;
51
+ /** Store raw transaction hex so getRawTx works for mempool txs. */
52
+ storeRawTx(txid: Txid, rawHex: string): void;
53
+ }
54
+ /** Combined read + write storage. */
55
+ export type Storage = StorageReader & StorageWriter;
56
+ //# sourceMappingURL=storageInterface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storageInterface.d.ts","sourceRoot":"","sources":["../src/storageInterface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EACX,OAAO,EACP,WAAW,EACX,YAAY,EACZ,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAErE,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC7B,8CAA8C;IAC9C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAEnD,0CAA0C;IAC1C,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAEvD,yEAAyE;IACzE,MAAM,IAAI,WAAW,GAAG,SAAS,CAAC;IAElC,0DAA0D;IAC1D,UAAU,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;IAE3F,oDAAoD;IACpD,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,YAAY,EAAE,CAAC;IAE1D,4DAA4D;IAC5D,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC;IAE5C,kGAAkG;IAClG,QAAQ,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,EAAE,CAAC;IAE9C,wCAAwC;IACxC,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG,iBAAiB,GAAG,SAAS,CAAC;IAEjD,uCAAuC;IACvC,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IAEzC,6EAA6E;IAC7E,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;IAE3D,uCAAuC;IACvC,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,GAAG,SAAS,CAAC;IAEhD,oEAAoE;IACpE,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,SAAS,CAAC;IAErD,+FAA+F;IAC/F,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;IAE3D,uCAAuC;IACvC,eAAe,IAAI,IAAI,EAAE,CAAC;IAE1B,0CAA0C;IAC1C,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;CACxD;AAED,wDAAwD;AACxD,MAAM,WAAW,aAAa;IAC7B,qFAAqF;IACrF,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;IAEnD,kFAAkF;IAClF,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;IAE3C,uEAAuE;IACvE,YAAY,CAAC,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;IAE7C,8FAA8F;IAC9F,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;IAE7C,mFAAmF;IACnF,YAAY,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC;IAEhC,+DAA+D;IAC/D,cAAc,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAExD,mEAAmE;IACnE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7C;AAED,qCAAqC;AACrC,MAAM,MAAM,OAAO,GAAG,aAAa,GAAG,aAAa,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=storageInterface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storageInterface.js","sourceRoot":"","sources":["../src/storageInterface.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@mem-cash/types",
3
+ "version": "0.0.1",
4
+ "description": "Shared primitives, data types, and storage interfaces for mem-cash",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist/",
17
+ "README.md",
18
+ "LICENSE"
19
+ ],
20
+ "license": "MIT",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "https://github.com/mainnet-pat/mem-cash.git",
24
+ "directory": "packages/types"
25
+ },
26
+ "keywords": [
27
+ "bitcoin-cash",
28
+ "electrum",
29
+ "types",
30
+ "utxo",
31
+ "scripthash"
32
+ ],
33
+ "engines": {
34
+ "node": ">=20"
35
+ },
36
+ "scripts": {
37
+ "prepublishOnly": "tsc -b"
38
+ },
39
+ "dependencies": {
40
+ "@bitauth/libauth": "^3.1.0-next.8"
41
+ }
42
+ }