@mem-cash/core 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,45 @@
1
+ # @mem-cash/core
2
+
3
+ Node engine, subscription manager, and mempool acceptance for mem-cash.
4
+
5
+ ## Node
6
+
7
+ `createNode()` wires together in-memory storage with an optional transaction verifier:
8
+
9
+ ```typescript
10
+ import { createNode } from "@mem-cash/core";
11
+ import { createTxVerifier } from "@mem-cash/validation";
12
+
13
+ const verifier = await createTxVerifier({ standard: false });
14
+ const node = createNode({ verifier });
15
+
16
+ node.setChainTip(200, 1700000000);
17
+ node.addUtxo({ txid, vout: 0, satoshis: 10_000n, scriptHash, height: 100 });
18
+
19
+ const result = node.submitTransaction(rawHex);
20
+ // { success: true, txid, fee, size, affectedScriptHashes }
21
+
22
+ // Debug without accepting to mempool (per-input VM traces)
23
+ const debug = node.debugTransaction(rawHex);
24
+ // { success: true, txid, fee, size, inputResults: [...] }
25
+ ```
26
+
27
+ ## Subscription Manager
28
+
29
+ Tracks scripthash and header subscriptions, detects status changes, and dispatches notifications:
30
+
31
+ ```typescript
32
+ const consumerId = node.subscriptions.addConsumer((notification) => {
33
+ if (notification.type === "scripthash") {
34
+ console.log(notification.scriptHash, notification.status);
35
+ } else {
36
+ console.log("new tip:", notification.header.height);
37
+ }
38
+ });
39
+ ```
40
+
41
+ Subscriber callbacks are isolated with try-catch -- a throwing callback is logged via `console.error` but does not prevent other subscribers from receiving their notifications.
42
+
43
+ ## Mempool Acceptance
44
+
45
+ Two-phase pattern: the verifier validates (read-only), then `acceptToMempool` performs storage mutations and returns affected scripthashes for notification dispatch.
@@ -0,0 +1,16 @@
1
+ import type { ScriptHash, Storage } from "@mem-cash/types";
2
+ import type { ValidatedTransaction } from "@mem-cash/validation";
3
+ /** Result of accepting a validated transaction into the mempool. */
4
+ export interface AcceptResult {
5
+ readonly affectedScriptHashes: ReadonlySet<ScriptHash>;
6
+ }
7
+ /**
8
+ * Accept a validated transaction into the mempool.
9
+ *
10
+ * This is the write side of the evaluate+accept two-phase pattern.
11
+ * The evaluator validates and returns a ValidatedTransaction (read-only);
12
+ * this function computes scripthashes from the decoded transaction and
13
+ * performs the storage mutations.
14
+ */
15
+ export declare function acceptToMempool(storage: Storage, validatedTx: ValidatedTransaction): AcceptResult;
16
+ //# sourceMappingURL=accept.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept.d.ts","sourceRoot":"","sources":["../src/accept.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAIX,UAAU,EACV,OAAO,EAGP,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,oEAAoE;AACpE,MAAM,WAAW,YAAY;IAC5B,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CACvD;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,oBAAoB,GAAG,YAAY,CAwFjG"}
package/dist/accept.js ADDED
@@ -0,0 +1,103 @@
1
+ import { binToHex, sha256 } from "@bitauth/libauth";
2
+ import { makeOutpointKey } from "@mem-cash/types";
3
+ /**
4
+ * Accept a validated transaction into the mempool.
5
+ *
6
+ * This is the write side of the evaluate+accept two-phase pattern.
7
+ * The evaluator validates and returns a ValidatedTransaction (read-only);
8
+ * this function computes scripthashes from the decoded transaction and
9
+ * performs the storage mutations.
10
+ */
11
+ export function acceptToMempool(storage, validatedTx) {
12
+ const { txid, rawHex, fee, size, transaction, sourceOutputs } = validatedTx;
13
+ // Compute scripthashes for each output
14
+ const outputScriptHashes = [];
15
+ for (const output of transaction.outputs) {
16
+ const scriptHash = binToHex(sha256.hash(output.lockingBytecode));
17
+ outputScriptHashes.push(scriptHash);
18
+ }
19
+ // Create mempool UTXOs for each output
20
+ for (let vout = 0; vout < transaction.outputs.length; vout++) {
21
+ const output = transaction.outputs[vout];
22
+ const scriptHash = outputScriptHashes[vout];
23
+ if (!output || !scriptHash)
24
+ continue;
25
+ const key = makeOutpointKey(txid, vout);
26
+ const base = {
27
+ outpoint: { txid, vout },
28
+ satoshis: output.valueSatoshis,
29
+ scriptHash,
30
+ height: 0,
31
+ lockingBytecode: output.lockingBytecode,
32
+ };
33
+ const utxoEntry = output.token
34
+ ? {
35
+ ...base,
36
+ tokenData: {
37
+ category: binToHex(output.token.category),
38
+ amount: output.token.amount,
39
+ ...(output.token.nft
40
+ ? {
41
+ nft: {
42
+ capability: output.token.nft.capability,
43
+ commitment: binToHex(output.token.nft.commitment),
44
+ },
45
+ }
46
+ : {}),
47
+ },
48
+ }
49
+ : base;
50
+ storage.addMempoolUtxo(key, utxoEntry);
51
+ }
52
+ // Build MempoolTx entries map
53
+ const entriesMap = new Map();
54
+ const parents = new Set();
55
+ // Process inputs — derive scripthash and outpointKey from decoded tx + sourceOutputs
56
+ for (let i = 0; i < transaction.inputs.length; i++) {
57
+ const input = transaction.inputs[i];
58
+ const sourceOutput = sourceOutputs[i];
59
+ if (!input || !sourceOutput)
60
+ continue;
61
+ const parentTxid = binToHex(input.outpointTransactionHash);
62
+ const outpointKey = makeOutpointKey(parentTxid, input.outpointIndex);
63
+ const inputScriptHash = binToHex(sha256.hash(sourceOutput.lockingBytecode));
64
+ const entry = getOrCreateEntry(entriesMap, inputScriptHash);
65
+ if ((sourceOutput.height ?? 1) > 0) {
66
+ entry.confirmedSpends.push(outpointKey);
67
+ }
68
+ else {
69
+ entry.unconfirmedSpends.push(outpointKey);
70
+ parents.add(parentTxid);
71
+ }
72
+ }
73
+ // Process outputs
74
+ for (let vout = 0; vout < outputScriptHashes.length; vout++) {
75
+ const scriptHash = outputScriptHashes[vout];
76
+ if (!scriptHash)
77
+ continue;
78
+ const key = makeOutpointKey(txid, vout);
79
+ const entry = getOrCreateEntry(entriesMap, scriptHash);
80
+ entry.outputs.push(key);
81
+ }
82
+ const mempoolTx = {
83
+ txid,
84
+ fee,
85
+ size,
86
+ entries: entriesMap,
87
+ parents,
88
+ children: new Set(),
89
+ };
90
+ storage.storeRawTx(txid, rawHex);
91
+ const affectedScriptHashes = storage.addMempoolTx(mempoolTx);
92
+ return { affectedScriptHashes };
93
+ }
94
+ /** Get or create a MempoolTxScriptHashEntry in the map. */
95
+ function getOrCreateEntry(map, scriptHash) {
96
+ let entry = map.get(scriptHash);
97
+ if (!entry) {
98
+ entry = { confirmedSpends: [], unconfirmedSpends: [], outputs: [] };
99
+ map.set(scriptHash, entry);
100
+ }
101
+ return entry;
102
+ }
103
+ //# sourceMappingURL=accept.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept.js","sourceRoot":"","sources":["../src/accept.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export type { AcceptResult } from "./accept.js";
2
+ export { acceptToMempool } from "./accept.js";
3
+ export type { AddUtxoParams, MineResult, Node, NodeConfig, SubmitFailure, SubmitResult, SubmitSuccess, } from "./node.js";
4
+ export { createNode } from "./node.js";
5
+ export type { ConsumerHooks, ConsumerId, HeaderNotification, Notification, NotificationCallback, ScriptHashNotification, SubscriptionManager, SubscriptionManagerConfig, } from "./subscriptionManager.js";
6
+ export { createSubscriptionManager } from "./subscriptionManager.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACX,aAAa,EACb,UAAU,EACV,IAAI,EACJ,UAAU,EACV,aAAa,EACb,YAAY,EACZ,aAAa,GACb,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EACX,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,YAAY,EACZ,oBAAoB,EACpB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,GACzB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { acceptToMempool } from "./accept.js";
2
+ export { createNode } from "./node.js";
3
+ export { createSubscriptionManager } from "./subscriptionManager.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAU9C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAWvC,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,74 @@
1
+ import type { TestableStorage } from "@mem-cash/storage";
2
+ import type { ScriptHash, StorageReader } from "@mem-cash/types";
3
+ import type { DebugResult, TxVerifier } from "@mem-cash/validation";
4
+ import type { SubscriptionManager } from "./subscriptionManager.js";
5
+ /** Configuration for the Node. All fields optional. */
6
+ export interface NodeConfig {
7
+ /** Transaction verifier. When provided, submitTransaction runs full validation. */
8
+ readonly verifier?: TxVerifier;
9
+ }
10
+ /** Parameters for adding a UTXO. */
11
+ export interface AddUtxoParams {
12
+ readonly txid: string;
13
+ readonly vout: number;
14
+ readonly satoshis: bigint;
15
+ readonly scriptHash: string;
16
+ readonly height: number;
17
+ readonly lockingBytecode?: Uint8Array;
18
+ readonly isCoinbase?: boolean;
19
+ }
20
+ /** Successful transaction submission. */
21
+ export interface SubmitSuccess {
22
+ readonly success: true;
23
+ readonly txid: string;
24
+ readonly fee: bigint;
25
+ readonly size: number;
26
+ readonly affectedScriptHashes: ReadonlySet<ScriptHash>;
27
+ }
28
+ /** Failed transaction submission. */
29
+ export interface SubmitFailure {
30
+ readonly success: false;
31
+ /** BCHN reject code (e.g. REJECT_INVALID, REJECT_NONSTANDARD). */
32
+ readonly code: number;
33
+ /** BCHN strRejectReason. */
34
+ readonly error: string;
35
+ /** BCHN strDebugMessage — optional extra context. */
36
+ readonly debugMessage?: string;
37
+ }
38
+ /** Result of submitting a transaction. */
39
+ export type SubmitResult = SubmitSuccess | SubmitFailure;
40
+ /** Result of mining blocks. */
41
+ export interface MineResult {
42
+ /** New chain tip height after mining. */
43
+ readonly height: number;
44
+ /** All scripthashes affected by confirming mempool transactions. */
45
+ readonly affectedScriptHashes: ReadonlySet<ScriptHash>;
46
+ }
47
+ /** The core node engine with in-memory storage. */
48
+ export interface Node extends StorageReader {
49
+ /** Submit a raw transaction hex. */
50
+ readonly submitTransaction: (rawHex: string) => SubmitResult;
51
+ /** Debug a raw transaction: run full validation with per-input traces, without accepting to mempool. */
52
+ readonly debugTransaction: (rawHex: string) => DebugResult | SubmitFailure;
53
+ /** Mine a block: confirms all mempool transactions, advances chain tip. */
54
+ readonly mine: (timestamp?: number) => MineResult;
55
+ /** Set chain tip with 11 headers at the given timestamp (sets both height and MTP). */
56
+ readonly setChainTip: (height: number, timestamp: number) => void;
57
+ /** Add a UTXO to the confirmed set. */
58
+ readonly addUtxo: (params: AddUtxoParams) => void;
59
+ /** The underlying storage with test helpers for direct manipulation. */
60
+ readonly storage: TestableStorage;
61
+ /** The subscription manager. */
62
+ readonly subscriptions: SubscriptionManager;
63
+ }
64
+ /**
65
+ * Create a core node with in-memory storage.
66
+ *
67
+ * Wires together storage, optional transaction verifier, and subscription manager.
68
+ *
69
+ * When `config.verifier` is provided, `submitTransaction` runs full consensus
70
+ * and policy checks. Without a verifier, transactions are decoded and accepted
71
+ * directly (useful for testing or trusted-input scenarios).
72
+ */
73
+ export declare function createNode(config?: NodeConfig): Node;
74
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,KAAK,EAMX,UAAU,EACV,aAAa,EAEb,MAAM,iBAAiB,CAAC;AAOzB,OAAO,KAAK,EAEX,WAAW,EAEX,UAAU,EAEV,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAGpE,uDAAuD;AACvD,MAAM,WAAW,UAAU;IAC1B,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,CAAC,EAAE,UAAU,CAAC;CAC/B;AAED,oCAAoC;AACpC,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC;IACtC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CACvD;AAED,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;IACxB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,0CAA0C;AAC1C,MAAM,MAAM,YAAY,GAAG,aAAa,GAAG,aAAa,CAAC;AAEzD,+BAA+B;AAC/B,MAAM,WAAW,UAAU;IAC1B,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,oBAAoB,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CACvD;AAED,mDAAmD;AACnD,MAAM,WAAW,IAAK,SAAQ,aAAa;IAC1C,oCAAoC;IACpC,QAAQ,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,YAAY,CAAC;IAE7D,wGAAwG;IACxG,QAAQ,CAAC,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,WAAW,GAAG,aAAa,CAAC;IAE3E,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,MAAM,KAAK,UAAU,CAAC;IAElD,uFAAuF;IACvF,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAElE,uCAAuC;IACvC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IAElD,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAElC,gCAAgC;IAChC,QAAQ,CAAC,aAAa,EAAE,mBAAmB,CAAC;CAC5C;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG,IAAI,CAuPpD"}
package/dist/node.js ADDED
@@ -0,0 +1,251 @@
1
+ import { binToHex, decodeTransactionBch, hashTransactionUiOrder, hexToBin, sha256, utf8ToBin, } from "@bitauth/libauth";
2
+ import { createMemoryStorage } from "@mem-cash/storage";
3
+ import { computeMedianTimePast, makeOutpointKey, REJECT_INVALID, REJECT_MALFORMED, } from "@mem-cash/types";
4
+ import { acceptToMempool } from "./accept.js";
5
+ import { createSubscriptionManager } from "./subscriptionManager.js";
6
+ /**
7
+ * Create a core node with in-memory storage.
8
+ *
9
+ * Wires together storage, optional transaction verifier, and subscription manager.
10
+ *
11
+ * When `config.verifier` is provided, `submitTransaction` runs full consensus
12
+ * and policy checks. Without a verifier, transactions are decoded and accepted
13
+ * directly (useful for testing or trusted-input scenarios).
14
+ */
15
+ export function createNode(config) {
16
+ const storage = createMemoryStorage();
17
+ const verifier = config?.verifier;
18
+ const subscriptions = createSubscriptionManager(storage);
19
+ function deriveChainState() {
20
+ const tip = storage.getTip();
21
+ if (!tip)
22
+ return null;
23
+ return {
24
+ height: tip.height,
25
+ medianTimePast: computeMedianTimePast(storage, tip.height),
26
+ };
27
+ }
28
+ function resolveSourceOutputs(rawHex) {
29
+ const rawBytes = hexToBin(rawHex);
30
+ const decoded = decodeTransactionBch(rawBytes);
31
+ if (typeof decoded === "string")
32
+ return {
33
+ ok: false,
34
+ code: REJECT_MALFORMED,
35
+ error: "TX decode failed",
36
+ debugMessage: decoded,
37
+ };
38
+ const sourceOutputs = [];
39
+ for (const input of decoded.inputs) {
40
+ const parentTxid = binToHex(input.outpointTransactionHash);
41
+ const key = makeOutpointKey(parentTxid, input.outpointIndex);
42
+ const utxo = storage.getUtxoByOutpoint(key);
43
+ if (!utxo) {
44
+ return { ok: false, code: REJECT_INVALID, error: "bad-txns-inputs-missingorspent" };
45
+ }
46
+ sourceOutputs.push(utxoToSourceOutput(utxo));
47
+ }
48
+ return { ok: true, outputs: sourceOutputs };
49
+ }
50
+ /** Convert a reject failure to a SubmitFailure, avoiding undefined in optional fields. */
51
+ function toSubmitFailure(f) {
52
+ const result = { success: false, code: f.code, error: f.error };
53
+ if (f.debugMessage != null)
54
+ result.debugMessage = f.debugMessage;
55
+ return result;
56
+ }
57
+ function submitTransaction(rawHex) {
58
+ const resolved = resolveSourceOutputs(rawHex);
59
+ if (!resolved.ok)
60
+ return toSubmitFailure(resolved);
61
+ const sourceOutputs = resolved.outputs;
62
+ let validatedTx;
63
+ if (verifier) {
64
+ const chainState = deriveChainState();
65
+ if (!chainState) {
66
+ return { success: false, code: REJECT_INVALID, error: "No chain tip set" };
67
+ }
68
+ const result = verifier.verify(rawHex, sourceOutputs, chainState);
69
+ if (!result.success)
70
+ return toSubmitFailure(result);
71
+ validatedTx = result.validatedTx;
72
+ }
73
+ else {
74
+ const rawBytes = hexToBin(rawHex);
75
+ const decoded = decodeTransactionBch(rawBytes);
76
+ if (typeof decoded === "string") {
77
+ return {
78
+ success: false,
79
+ code: REJECT_MALFORMED,
80
+ error: "TX decode failed",
81
+ debugMessage: decoded,
82
+ };
83
+ }
84
+ const txid = binToHex(hashTransactionUiOrder(rawBytes));
85
+ const inputSum = sourceOutputs.reduce((sum, so) => sum + so.valueSatoshis, 0n);
86
+ const outputSum = decoded.outputs.reduce((sum, o) => sum + o.valueSatoshis, 0n);
87
+ validatedTx = {
88
+ txid,
89
+ rawHex,
90
+ fee: inputSum - outputSum,
91
+ size: rawBytes.length,
92
+ transaction: decoded,
93
+ sourceOutputs,
94
+ };
95
+ }
96
+ const { affectedScriptHashes } = acceptToMempool(storage, validatedTx);
97
+ subscriptions.notifyChanges(affectedScriptHashes);
98
+ return {
99
+ success: true,
100
+ txid: validatedTx.txid,
101
+ fee: validatedTx.fee,
102
+ size: validatedTx.size,
103
+ affectedScriptHashes,
104
+ };
105
+ }
106
+ function debugTransaction(rawHex) {
107
+ if (!verifier) {
108
+ return { success: false, code: REJECT_INVALID, error: "No verifier configured" };
109
+ }
110
+ const resolved = resolveSourceOutputs(rawHex);
111
+ if (!resolved.ok)
112
+ return toSubmitFailure(resolved);
113
+ const chainState = deriveChainState();
114
+ if (!chainState) {
115
+ return { success: false, code: REJECT_INVALID, error: "No chain tip set" };
116
+ }
117
+ return verifier.debug(rawHex, resolved.outputs, chainState);
118
+ }
119
+ function setChainTip(height, timestamp) {
120
+ const startHeight = Math.max(0, height - 10);
121
+ for (let h = startHeight; h <= height; h++) {
122
+ storage._test.header.add({
123
+ hash: h.toString(16).padStart(64, "0"),
124
+ height: h,
125
+ timestamp,
126
+ });
127
+ }
128
+ }
129
+ function addUtxo(params) {
130
+ storage._test.utxo.add(Object.assign({
131
+ txid: params.txid,
132
+ vout: params.vout,
133
+ satoshis: params.satoshis,
134
+ scriptHash: params.scriptHash,
135
+ height: params.height,
136
+ lockingBytecode: params.lockingBytecode ?? new Uint8Array(0),
137
+ }, params.isCoinbase ? { isCoinbase: true } : {}));
138
+ }
139
+ function mine(timestamp) {
140
+ const tip = storage.getTip();
141
+ const newHeight = (tip?.height ?? 0) + 1;
142
+ const ts = timestamp ?? 1700000000 + newHeight;
143
+ const txids = storage.getMempoolTxids();
144
+ const processedTxs = [];
145
+ for (const txid of txids) {
146
+ const mempoolTx = storage.getMempoolTx(txid);
147
+ if (!mempoolTx)
148
+ continue;
149
+ const rawHex = storage.getRawTx(txid);
150
+ const inputs = [];
151
+ const outputs = [];
152
+ for (const [, entry] of mempoolTx.entries) {
153
+ for (const key of entry.confirmedSpends) {
154
+ const [prevTxid, prevVout] = key.split(":");
155
+ inputs.push({ prevOutpoint: { txid: prevTxid, vout: Number(prevVout) } });
156
+ }
157
+ for (const key of entry.unconfirmedSpends) {
158
+ const [prevTxid, prevVout] = key.split(":");
159
+ inputs.push({ prevOutpoint: { txid: prevTxid, vout: Number(prevVout) } });
160
+ }
161
+ for (const key of entry.outputs) {
162
+ const utxo = storage.getMempoolUtxo(key);
163
+ if (utxo) {
164
+ outputs.push({ outpointKey: key, utxo: { ...utxo, height: newHeight } });
165
+ }
166
+ }
167
+ }
168
+ const ptx = { txid, inputs, outputs, fee: mempoolTx.fee };
169
+ if (rawHex)
170
+ ptx.rawHex = rawHex;
171
+ processedTxs.push(ptx);
172
+ }
173
+ storage.clearMempool();
174
+ const blockHash = binToHex(sha256.hash(utf8ToBin(`block-${newHeight}`)));
175
+ const header = {
176
+ hash: blockHash,
177
+ height: newHeight,
178
+ version: 1,
179
+ prevHash: tip?.hash ?? "0".repeat(64),
180
+ merkleRoot: "0".repeat(64),
181
+ timestamp: ts,
182
+ bits: 0x1d00ffff,
183
+ nonce: 0,
184
+ hex: "0".repeat(160),
185
+ };
186
+ const block = {
187
+ height: newHeight,
188
+ hash: blockHash,
189
+ header,
190
+ transactions: processedTxs,
191
+ };
192
+ const affectedScriptHashes = storage.applyBlock(block);
193
+ setChainTip(newHeight, ts);
194
+ subscriptions.notifyChanges(affectedScriptHashes);
195
+ subscriptions.notifyNewTip(header);
196
+ return { height: newHeight, affectedScriptHashes };
197
+ }
198
+ return {
199
+ // StorageReader delegation
200
+ getHeader: storage.getHeader,
201
+ getHeaderByHash: storage.getHeaderByHash,
202
+ getTip: storage.getTip,
203
+ getHistory: storage.getHistory,
204
+ getMempoolHistory: storage.getMempoolHistory,
205
+ getBalance: storage.getBalance,
206
+ getUtxos: storage.getUtxos,
207
+ getTx: storage.getTx,
208
+ getRawTx: storage.getRawTx,
209
+ getScriptHashStatus: storage.getScriptHashStatus,
210
+ getMempoolTx: storage.getMempoolTx,
211
+ getTxidsAtHeight: storage.getTxidsAtHeight,
212
+ getUtxoByOutpoint: storage.getUtxoByOutpoint,
213
+ getMempoolTxids: storage.getMempoolTxids,
214
+ getMempoolUtxo: storage.getMempoolUtxo,
215
+ // Node operations
216
+ submitTransaction,
217
+ debugTransaction,
218
+ mine,
219
+ setChainTip,
220
+ addUtxo,
221
+ storage,
222
+ subscriptions,
223
+ };
224
+ }
225
+ /** Map a storage UtxoEntry to a validation SourceOutput. */
226
+ function utxoToSourceOutput(utxo) {
227
+ const so = {
228
+ lockingBytecode: utxo.lockingBytecode,
229
+ valueSatoshis: utxo.satoshis,
230
+ };
231
+ if (utxo.height > 0) {
232
+ so.height = utxo.height;
233
+ }
234
+ if (utxo.isCoinbase) {
235
+ so.isCoinbase = true;
236
+ }
237
+ if (utxo.tokenData) {
238
+ so.token = {
239
+ category: hexToBin(utxo.tokenData.category),
240
+ amount: utxo.tokenData.amount,
241
+ nft: utxo.tokenData.nft
242
+ ? {
243
+ commitment: hexToBin(utxo.tokenData.nft.commitment),
244
+ capability: utxo.tokenData.nft.capability,
245
+ }
246
+ : undefined,
247
+ };
248
+ }
249
+ return so;
250
+ }
251
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import type { BlockHeader, ScriptHash, StorageReader } from "@mem-cash/types";
2
+ /** Opaque consumer identifier. */
3
+ export type ConsumerId = number;
4
+ /** Notification sent when a scripthash status changes. */
5
+ export interface ScriptHashNotification {
6
+ readonly type: "scripthash";
7
+ readonly scriptHash: ScriptHash;
8
+ readonly status: string | null;
9
+ }
10
+ /** Notification sent when a new block header arrives. */
11
+ export interface HeaderNotification {
12
+ readonly type: "header";
13
+ readonly header: BlockHeader;
14
+ }
15
+ /** Union of all notification types. */
16
+ export type Notification = ScriptHashNotification | HeaderNotification;
17
+ /** Callback invoked when a subscribed event fires. */
18
+ export type NotificationCallback = (notification: Notification) => void;
19
+ /** Subscription hooks bound to a single consumer. */
20
+ export interface ConsumerHooks {
21
+ readonly subscribeScriptHash: (scriptHash: ScriptHash) => void;
22
+ readonly unsubscribeScriptHash: (scriptHash: ScriptHash) => boolean;
23
+ readonly subscribeHeaders: () => void;
24
+ readonly unsubscribeHeaders: () => boolean;
25
+ }
26
+ /** Optional configuration for the subscription manager. */
27
+ export interface SubscriptionManagerConfig {
28
+ /** Maximum scripthash subscriptions per consumer. 0 = unlimited. */
29
+ readonly maxSubscriptionsPerConsumer?: number;
30
+ }
31
+ /** Manages scripthash and header subscriptions across multiple consumers. */
32
+ export interface SubscriptionManager {
33
+ /**
34
+ * Register a new consumer with the given notification callback.
35
+ * Returns the consumer's unique ID.
36
+ */
37
+ addConsumer(callback: NotificationCallback): ConsumerId;
38
+ /** Remove a consumer and all its subscriptions. */
39
+ removeConsumer(id: ConsumerId): void;
40
+ /**
41
+ * Subscribe a consumer to a scripthash.
42
+ * Records the current status as baseline so notifications only fire on changes.
43
+ */
44
+ subscribeScriptHash(consumerId: ConsumerId, scriptHash: ScriptHash): void;
45
+ /** Unsubscribe a consumer from a scripthash. Returns true if was subscribed. */
46
+ unsubscribeScriptHash(consumerId: ConsumerId, scriptHash: ScriptHash): boolean;
47
+ /** Subscribe a consumer to header notifications. */
48
+ subscribeHeaders(consumerId: ConsumerId): void;
49
+ /** Unsubscribe a consumer from headers. Returns true if was subscribed. */
50
+ unsubscribeHeaders(consumerId: ConsumerId): boolean;
51
+ /**
52
+ * Process a set of affected scripthashes (e.g. after a block or mempool change).
53
+ * Recomputes status for each affected scripthash, compares with last-notified
54
+ * status per subscriber, and dispatches notifications for changes.
55
+ * Returns the number of notifications dispatched.
56
+ */
57
+ notifyChanges(affectedScriptHashes: ReadonlySet<ScriptHash>): number;
58
+ /**
59
+ * Notify all header subscribers of a new chain tip.
60
+ * Returns the number of notifications dispatched.
61
+ */
62
+ notifyNewTip(header: BlockHeader): number;
63
+ /** Generate subscription hooks bound to a specific consumer. */
64
+ hooksForConsumer(consumerId: ConsumerId): ConsumerHooks;
65
+ /** Number of consumers subscribed to a specific scripthash. */
66
+ getScriptHashSubscriberCount(scriptHash: ScriptHash): number;
67
+ /** Number of consumers subscribed to header notifications. */
68
+ getHeaderSubscriberCount(): number;
69
+ /** Number of scripthash subscriptions for a consumer. */
70
+ getConsumerSubscriptionCount(consumerId: ConsumerId): number;
71
+ /** Total number of registered consumers. */
72
+ getConsumerCount(): number;
73
+ /** Total number of unique scripthash subscriptions across all consumers. */
74
+ getTotalSubscriptionCount(): number;
75
+ }
76
+ /**
77
+ * Create a new subscription manager.
78
+ *
79
+ * @param storage - Read-only storage for status hash computation
80
+ * @param config - Optional configuration
81
+ */
82
+ export declare function createSubscriptionManager(storage: StorageReader, config?: SubscriptionManagerConfig): SubscriptionManager;
83
+ //# sourceMappingURL=subscriptionManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriptionManager.d.ts","sourceRoot":"","sources":["../src/subscriptionManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE9E,kCAAkC;AAClC,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAIhC,0DAA0D;AAC1D,MAAM,WAAW,sBAAsB;IACtC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,yDAAyD;AACzD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;CAC7B;AAED,uCAAuC;AACvC,MAAM,MAAM,YAAY,GAAG,sBAAsB,GAAG,kBAAkB,CAAC;AAEvE,sDAAsD;AACtD,MAAM,MAAM,oBAAoB,GAAG,CAAC,YAAY,EAAE,YAAY,KAAK,IAAI,CAAC;AAIxE,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC/D,QAAQ,CAAC,qBAAqB,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,OAAO,CAAC;IACpE,QAAQ,CAAC,gBAAgB,EAAE,MAAM,IAAI,CAAC;IACtC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,OAAO,CAAC;CAC3C;AAID,2DAA2D;AAC3D,MAAM,WAAW,yBAAyB;IACzC,oEAAoE;IACpE,QAAQ,CAAC,2BAA2B,CAAC,EAAE,MAAM,CAAC;CAC9C;AAID,6EAA6E;AAC7E,MAAM,WAAW,mBAAmB;IACnC;;;OAGG;IACH,WAAW,CAAC,QAAQ,EAAE,oBAAoB,GAAG,UAAU,CAAC;IAExD,mDAAmD;IACnD,cAAc,CAAC,EAAE,EAAE,UAAU,GAAG,IAAI,CAAC;IAErC;;;OAGG;IACH,mBAAmB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAE1E,gFAAgF;IAChF,qBAAqB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC;IAE/E,oDAAoD;IACpD,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAE/C,2EAA2E;IAC3E,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC;IAEpD;;;;;OAKG;IACH,aAAa,CAAC,oBAAoB,EAAE,WAAW,CAAC,UAAU,CAAC,GAAG,MAAM,CAAC;IAErE;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC;IAE1C,gEAAgE;IAChE,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,aAAa,CAAC;IAIxD,+DAA+D;IAC/D,4BAA4B,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAAC;IAE7D,8DAA8D;IAC9D,wBAAwB,IAAI,MAAM,CAAC;IAEnC,yDAAyD;IACzD,4BAA4B,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAAC;IAE7D,4CAA4C;IAC5C,gBAAgB,IAAI,MAAM,CAAC;IAE3B,4EAA4E;IAC5E,yBAAyB,IAAI,MAAM,CAAC;CACpC;AAcD;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACxC,OAAO,EAAE,aAAa,EACtB,MAAM,CAAC,EAAE,yBAAyB,GAChC,mBAAmB,CAgNrB"}
@@ -0,0 +1,193 @@
1
+ // --- Factory ---
2
+ /**
3
+ * Create a new subscription manager.
4
+ *
5
+ * @param storage - Read-only storage for status hash computation
6
+ * @param config - Optional configuration
7
+ */
8
+ export function createSubscriptionManager(storage, config) {
9
+ let nextId = 1;
10
+ const consumers = new Map();
11
+ const scriptHashSubs = new Map();
12
+ const headerSubs = new Set();
13
+ const maxSubs = config?.maxSubscriptionsPerConsumer ?? 0;
14
+ function addConsumer(callback) {
15
+ const id = nextId++;
16
+ consumers.set(id, {
17
+ callback,
18
+ scriptHashes: new Set(),
19
+ headerSubscribed: false,
20
+ lastStatuses: new Map(),
21
+ });
22
+ return id;
23
+ }
24
+ function removeConsumer(id) {
25
+ const state = consumers.get(id);
26
+ if (!state)
27
+ return;
28
+ // Remove from all scripthash subscriber sets
29
+ for (const sh of state.scriptHashes) {
30
+ const subs = scriptHashSubs.get(sh);
31
+ if (subs) {
32
+ subs.delete(id);
33
+ if (subs.size === 0)
34
+ scriptHashSubs.delete(sh);
35
+ }
36
+ }
37
+ // Remove from header subscribers
38
+ headerSubs.delete(id);
39
+ consumers.delete(id);
40
+ }
41
+ function subscribeScriptHash(consumerId, scriptHash) {
42
+ const state = consumers.get(consumerId);
43
+ if (!state)
44
+ return;
45
+ // Already subscribed — idempotent
46
+ if (state.scriptHashes.has(scriptHash))
47
+ return;
48
+ // Check subscription limit
49
+ if (maxSubs > 0 && state.scriptHashes.size >= maxSubs)
50
+ return;
51
+ // Register
52
+ state.scriptHashes.add(scriptHash);
53
+ let subs = scriptHashSubs.get(scriptHash);
54
+ if (!subs) {
55
+ subs = new Set();
56
+ scriptHashSubs.set(scriptHash, subs);
57
+ }
58
+ subs.add(consumerId);
59
+ // Record baseline status so first notification only fires on actual change
60
+ const currentStatus = storage.getScriptHashStatus(scriptHash);
61
+ state.lastStatuses.set(scriptHash, currentStatus);
62
+ }
63
+ function unsubscribeScriptHash(consumerId, scriptHash) {
64
+ const state = consumers.get(consumerId);
65
+ if (!state)
66
+ return false;
67
+ if (!state.scriptHashes.has(scriptHash))
68
+ return false;
69
+ state.scriptHashes.delete(scriptHash);
70
+ state.lastStatuses.delete(scriptHash);
71
+ const subs = scriptHashSubs.get(scriptHash);
72
+ if (subs) {
73
+ subs.delete(consumerId);
74
+ if (subs.size === 0)
75
+ scriptHashSubs.delete(scriptHash);
76
+ }
77
+ return true;
78
+ }
79
+ function subscribeHeaders(consumerId) {
80
+ const state = consumers.get(consumerId);
81
+ if (!state)
82
+ return;
83
+ state.headerSubscribed = true;
84
+ headerSubs.add(consumerId);
85
+ }
86
+ function unsubscribeHeaders(consumerId) {
87
+ const state = consumers.get(consumerId);
88
+ if (!state)
89
+ return false;
90
+ if (!state.headerSubscribed)
91
+ return false;
92
+ state.headerSubscribed = false;
93
+ headerSubs.delete(consumerId);
94
+ return true;
95
+ }
96
+ function notifyChanges(affectedScriptHashes) {
97
+ let count = 0;
98
+ for (const scriptHash of affectedScriptHashes) {
99
+ const subs = scriptHashSubs.get(scriptHash);
100
+ if (!subs || subs.size === 0)
101
+ continue;
102
+ // Compute status once per scripthash
103
+ const newStatus = storage.getScriptHashStatus(scriptHash);
104
+ for (const consumerId of subs) {
105
+ const state = consumers.get(consumerId);
106
+ if (!state)
107
+ continue;
108
+ const lastStatus = state.lastStatuses.get(scriptHash);
109
+ // Only notify if status actually changed
110
+ // undefined means never subscribed (shouldn't happen), treat as changed
111
+ if (lastStatus !== undefined && lastStatus === newStatus)
112
+ continue;
113
+ state.lastStatuses.set(scriptHash, newStatus);
114
+ try {
115
+ state.callback({
116
+ type: "scripthash",
117
+ scriptHash,
118
+ status: newStatus,
119
+ });
120
+ }
121
+ catch (e) {
122
+ console.error("Subscriber callback threw during scripthash notification:", e);
123
+ }
124
+ count++;
125
+ }
126
+ }
127
+ return count;
128
+ }
129
+ function notifyNewTip(header) {
130
+ let count = 0;
131
+ const notification = {
132
+ type: "header",
133
+ header,
134
+ };
135
+ for (const consumerId of headerSubs) {
136
+ const state = consumers.get(consumerId);
137
+ if (!state)
138
+ continue;
139
+ try {
140
+ state.callback(notification);
141
+ }
142
+ catch (e) {
143
+ console.error("Subscriber callback threw during header notification:", e);
144
+ }
145
+ count++;
146
+ }
147
+ return count;
148
+ }
149
+ function hooksForConsumer(consumerId) {
150
+ return {
151
+ subscribeScriptHash: (scriptHash) => subscribeScriptHash(consumerId, scriptHash),
152
+ unsubscribeScriptHash: (scriptHash) => unsubscribeScriptHash(consumerId, scriptHash),
153
+ subscribeHeaders: () => subscribeHeaders(consumerId),
154
+ unsubscribeHeaders: () => unsubscribeHeaders(consumerId),
155
+ };
156
+ }
157
+ function getScriptHashSubscriberCount(scriptHash) {
158
+ return scriptHashSubs.get(scriptHash)?.size ?? 0;
159
+ }
160
+ function getHeaderSubscriberCount() {
161
+ return headerSubs.size;
162
+ }
163
+ function getConsumerSubscriptionCount(consumerId) {
164
+ return consumers.get(consumerId)?.scriptHashes.size ?? 0;
165
+ }
166
+ function getConsumerCount() {
167
+ return consumers.size;
168
+ }
169
+ function getTotalSubscriptionCount() {
170
+ let total = 0;
171
+ for (const subs of scriptHashSubs.values()) {
172
+ total += subs.size;
173
+ }
174
+ return total;
175
+ }
176
+ return {
177
+ addConsumer,
178
+ removeConsumer,
179
+ subscribeScriptHash,
180
+ unsubscribeScriptHash,
181
+ subscribeHeaders,
182
+ unsubscribeHeaders,
183
+ notifyChanges,
184
+ notifyNewTip,
185
+ hooksForConsumer,
186
+ getScriptHashSubscriberCount,
187
+ getHeaderSubscriberCount,
188
+ getConsumerSubscriptionCount,
189
+ getConsumerCount,
190
+ getTotalSubscriptionCount,
191
+ };
192
+ }
193
+ //# sourceMappingURL=subscriptionManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriptionManager.js","sourceRoot":"","sources":["../src/subscriptionManager.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@mem-cash/core",
3
+ "version": "0.0.1",
4
+ "description": "Node engine, subscription manager, and mempool acceptance 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/core"
25
+ },
26
+ "keywords": [
27
+ "bitcoin-cash",
28
+ "electrum",
29
+ "node",
30
+ "subscriptions",
31
+ "mempool"
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
+ "@mem-cash/storage": "0.0.1",
42
+ "@mem-cash/types": "0.0.1"
43
+ },
44
+ "peerDependencies": {
45
+ "@mem-cash/validation": "0.0.1"
46
+ },
47
+ "peerDependenciesMeta": {
48
+ "@mem-cash/validation": {
49
+ "optional": true
50
+ }
51
+ }
52
+ }