@mem-cash/validation 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/validation
2
+
3
+ Stateless transaction evaluator for Bitcoin Cash. Validates raw transaction hex against consensus rules, policy checks, and libauth VM script verification.
4
+
5
+ ## Usage
6
+
7
+ ```typescript
8
+ import { createTxVerifier } from "@mem-cash/validation";
9
+
10
+ const verifier = await createTxVerifier({
11
+ vmVersion: "BCH_2025_05",
12
+ standard: true,
13
+ });
14
+
15
+ const result = verifier.verify(rawHex, sourceOutputs, chainState);
16
+ if (result.success) {
17
+ console.log(result.txid, result.fee, result.validatedTx);
18
+ } else {
19
+ console.log(result.code, result.error); // BCHN reject code + reason
20
+ }
21
+ ```
22
+
23
+ ## Verification Pipeline
24
+
25
+ Matches BCHN's `AcceptToMemoryPool` order:
26
+
27
+ 1. Decode transaction hex
28
+ 2. Null prevout check (`bad-txns-prevout-null`)
29
+ 3. Validate sourceOutputs count matches inputs (`bad-txns-inputs-missingorspent`)
30
+ 4. Locktime finality (`bad-txns-nonfinal`)
31
+ 5. Coinbase maturity (`bad-txns-premature-spend-of-coinbase`)
32
+ 6. Unspendable inputs (`bad-txns-input-scriptpubkey-unspendable`)
33
+ 7. Input value ranges (`bad-txns-inputvalues-outofrange`)
34
+ 8. Output value ranges and fee computation (`bad-txns-outputvalues-outofrange`, `bad-txns-in-belowout`) -- per-output and cumulative sum checked against `MAX_MONEY`
35
+ 9. BIP68 sequence locks (`non-BIP68-final`)
36
+ 10. Min relay fee (`min relay fee not met`)
37
+ 11. Absurd fee guard (`absurdly-high-fee`)
38
+ 12. Dust check (`dust`)
39
+ 13. VM script verification (`mandatory-script-verify-flag-failed` / `non-mandatory-script-verify-flag`)
40
+
41
+ All error strings and reject codes match BCHN exactly. The verifier implements BCHN's two-pass script verification to distinguish mandatory from non-mandatory failures.
42
+
43
+ ## Config Validation
44
+
45
+ `createTxVerifier` rejects non-positive `minRelayFeePerKb` and `maxFee` values at construction time to prevent bypassing fee policy checks.
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Result of a consensus/policy check.
3
+ * On failure, `code` is the BCHN reject code, `error` is the BCHN
4
+ * strRejectReason, and `debugMessage` is optional extra context
5
+ * (matching BCHN's strDebugMessage).
6
+ */
7
+ export type CheckResult = {
8
+ ok: true;
9
+ } | {
10
+ ok: false;
11
+ code: number;
12
+ error: string;
13
+ debugMessage?: string;
14
+ };
15
+ /** Input descriptor for null prevout check. */
16
+ interface PrevoutInput {
17
+ readonly txid: string;
18
+ readonly vout: number;
19
+ }
20
+ /**
21
+ * Reject inputs referencing the null outpoint (all-zero txid + vout 0xFFFFFFFF).
22
+ * BCHN: CheckRegularTransaction → "bad-txns-prevout-null" (REJECT_INVALID, DoS 10).
23
+ */
24
+ export declare function checkNullPrevout(inputs: readonly PrevoutInput[]): CheckResult;
25
+ /**
26
+ * Validate each input value is within range and cumulative sum does not exceed MAX_MONEY.
27
+ * BCHN: CheckTxInputs → "bad-txns-inputvalues-outofrange" (REJECT_INVALID, DoS 100).
28
+ */
29
+ export declare function checkInputValueRanges(inputValues: readonly bigint[]): CheckResult;
30
+ /** Input descriptor for coinbase maturity check. */
31
+ interface MaturityInput {
32
+ readonly isCoinbase?: boolean | undefined;
33
+ readonly height: number;
34
+ }
35
+ /**
36
+ * Check that coinbase outputs have sufficient maturity (>= 100 blocks deep).
37
+ * BCHN: CheckTxInputs → "bad-txns-premature-spend-of-coinbase" (REJECT_INVALID).
38
+ */
39
+ export declare function checkCoinbaseMaturity(inputs: readonly MaturityInput[], spendHeight: number): CheckResult;
40
+ /** Input descriptor for unspendable check. */
41
+ interface ScriptInput {
42
+ readonly lockingBytecode: Uint8Array;
43
+ }
44
+ /**
45
+ * Reject inputs whose locking script starts with OP_RETURN or exceeds MAX_SCRIPT_SIZE.
46
+ * BCHN: CheckTxInputs → "bad-txns-input-scriptpubkey-unspendable" (REJECT_INVALID, DoS 100).
47
+ */
48
+ export declare function checkUnspendableInputs(inputs: readonly ScriptInput[]): CheckResult;
49
+ /** Input descriptor for locktime finality check. */
50
+ interface SequenceInput {
51
+ readonly sequenceNumber: number;
52
+ }
53
+ /**
54
+ * Check IsFinalTx logic from BCHN.
55
+ * BCHN: ContextualCheckTransaction → "bad-txns-nonfinal" (REJECT_INVALID, DoS 10).
56
+ */
57
+ export declare function checkLocktimeFinality(locktime: number, inputs: readonly SequenceInput[], blockHeight: number, mtp: number): CheckResult;
58
+ /** Input descriptor for BIP68 sequence lock check. */
59
+ interface SequenceLockInput {
60
+ readonly sequenceNumber: number;
61
+ readonly height: number;
62
+ /** MTP at height-1. Required for time-based locks. */
63
+ readonly medianTimePast?: number;
64
+ }
65
+ /**
66
+ * Check BIP68 relative sequence locks.
67
+ * Only applies when txVersion >= 2.
68
+ * BCHN: AcceptToMemoryPoolWorker → "non-BIP68-final" (REJECT_NONSTANDARD, DoS 0).
69
+ */
70
+ export declare function checkSequenceLocks(txVersion: number, inputs: readonly SequenceLockInput[], spendHeight: number, spendMtp: number): CheckResult;
71
+ /**
72
+ * Check that fee meets the minimum relay fee rate.
73
+ * BCHN: AcceptToMemoryPoolWorker → "min relay fee not met" (REJECT_INSUFFICIENTFEE, DoS 0).
74
+ */
75
+ export declare function checkMinRelayFee(fee: bigint, txSize: number, minFeePerKb: bigint): CheckResult;
76
+ /**
77
+ * Guard against absurdly high fees.
78
+ * BCHN: AcceptToMemoryPoolWorker → "absurdly-high-fee" (REJECT_HIGHFEE).
79
+ */
80
+ export declare function checkAbsurdFee(fee: bigint, maxFee: bigint): CheckResult;
81
+ /**
82
+ * Check that no non-OP_RETURN output is dust.
83
+ * BCHN: IsStandardTx → "dust" (REJECT_NONSTANDARD, DoS 0).
84
+ */
85
+ export declare function checkDustOutputs(outputs: readonly {
86
+ readonly lockingBytecode: Uint8Array;
87
+ readonly valueSatoshis: bigint;
88
+ }[], dustRelayFeePerKb: bigint): CheckResult;
89
+ export {};
90
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"AAmBA;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GACpB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAIrE,+CAA+C;AAC/C,UAAU,YAAY;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,WAAW,CAO7E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,WAAW,CAYjF;AAED,oDAAoD;AACpD,UAAU,aAAa;IACtB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACxB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACpC,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,WAAW,EAAE,MAAM,GACjB,WAAW,CAeb;AAED,8CAA8C;AAC9C,UAAU,WAAW;IACpB,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC;CACrC;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,GAAG,WAAW,CAqBlF;AAED,oDAAoD;AACpD,UAAU,aAAa;IACtB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CAChC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACpC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,aAAa,EAAE,EAChC,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,GACT,WAAW,CAkBb;AAED,sDAAsD;AACtD,UAAU,iBAAiB;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CACjC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,iBAAiB,EAAE,EACpC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACd,WAAW,CA2Bb;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,CAM9F;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,CAUvE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,OAAO,EAAE,SAAS;IAAE,QAAQ,CAAC,eAAe,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,EAAE,EAC5F,iBAAiB,EAAE,MAAM,GACvB,WAAW,CAwBb"}
package/dist/checks.js ADDED
@@ -0,0 +1,187 @@
1
+ import { REJECT_HIGHFEE, REJECT_INSUFFICIENTFEE, REJECT_INVALID, REJECT_NONSTANDARD, } from "@mem-cash/types";
2
+ import { COINBASE_MATURITY, LOCKTIME_THRESHOLD, MAX_MONEY, MAX_SCRIPT_SIZE, OP_RETURN, SEQUENCE_FINAL, SEQUENCE_LOCKTIME_DISABLE_FLAG, SEQUENCE_LOCKTIME_GRANULARITY, SEQUENCE_LOCKTIME_MASK, SEQUENCE_LOCKTIME_TYPE_FLAG, } from "./constants.js";
3
+ const CHECK_OK = { ok: true };
4
+ /**
5
+ * Reject inputs referencing the null outpoint (all-zero txid + vout 0xFFFFFFFF).
6
+ * BCHN: CheckRegularTransaction → "bad-txns-prevout-null" (REJECT_INVALID, DoS 10).
7
+ */
8
+ export function checkNullPrevout(inputs) {
9
+ for (const input of inputs) {
10
+ if (input.txid === "00".repeat(32) && input.vout === 0xffffffff) {
11
+ return { ok: false, code: REJECT_INVALID, error: "bad-txns-prevout-null" };
12
+ }
13
+ }
14
+ return CHECK_OK;
15
+ }
16
+ /**
17
+ * Validate each input value is within range and cumulative sum does not exceed MAX_MONEY.
18
+ * BCHN: CheckTxInputs → "bad-txns-inputvalues-outofrange" (REJECT_INVALID, DoS 100).
19
+ */
20
+ export function checkInputValueRanges(inputValues) {
21
+ let sum = 0n;
22
+ for (const value of inputValues) {
23
+ if (value > MAX_MONEY) {
24
+ return { ok: false, code: REJECT_INVALID, error: "bad-txns-inputvalues-outofrange" };
25
+ }
26
+ sum += value;
27
+ if (sum > MAX_MONEY) {
28
+ return { ok: false, code: REJECT_INVALID, error: "bad-txns-inputvalues-outofrange" };
29
+ }
30
+ }
31
+ return CHECK_OK;
32
+ }
33
+ /**
34
+ * Check that coinbase outputs have sufficient maturity (>= 100 blocks deep).
35
+ * BCHN: CheckTxInputs → "bad-txns-premature-spend-of-coinbase" (REJECT_INVALID).
36
+ */
37
+ export function checkCoinbaseMaturity(inputs, spendHeight) {
38
+ for (const input of inputs) {
39
+ if (input.isCoinbase) {
40
+ const depth = spendHeight - input.height;
41
+ if (depth < COINBASE_MATURITY) {
42
+ return {
43
+ ok: false,
44
+ code: REJECT_INVALID,
45
+ error: "bad-txns-premature-spend-of-coinbase",
46
+ debugMessage: `tried to spend coinbase at depth ${depth}`,
47
+ };
48
+ }
49
+ }
50
+ }
51
+ return CHECK_OK;
52
+ }
53
+ /**
54
+ * Reject inputs whose locking script starts with OP_RETURN or exceeds MAX_SCRIPT_SIZE.
55
+ * BCHN: CheckTxInputs → "bad-txns-input-scriptpubkey-unspendable" (REJECT_INVALID, DoS 100).
56
+ */
57
+ export function checkUnspendableInputs(inputs) {
58
+ for (const entry of inputs) {
59
+ const script = entry.lockingBytecode;
60
+ if (script.length > 0 && script[0] === OP_RETURN) {
61
+ return {
62
+ ok: false,
63
+ code: REJECT_INVALID,
64
+ error: "bad-txns-input-scriptpubkey-unspendable",
65
+ debugMessage: "input scriptPubKey is unspendable",
66
+ };
67
+ }
68
+ if (script.length > MAX_SCRIPT_SIZE) {
69
+ return {
70
+ ok: false,
71
+ code: REJECT_INVALID,
72
+ error: "bad-txns-input-scriptpubkey-unspendable",
73
+ debugMessage: "input scriptPubKey is unspendable",
74
+ };
75
+ }
76
+ }
77
+ return CHECK_OK;
78
+ }
79
+ /**
80
+ * Check IsFinalTx logic from BCHN.
81
+ * BCHN: ContextualCheckTransaction → "bad-txns-nonfinal" (REJECT_INVALID, DoS 10).
82
+ */
83
+ export function checkLocktimeFinality(locktime, inputs, blockHeight, mtp) {
84
+ if (locktime === 0)
85
+ return CHECK_OK;
86
+ const threshold = locktime < LOCKTIME_THRESHOLD ? blockHeight : mtp;
87
+ if (locktime < threshold)
88
+ return CHECK_OK;
89
+ // Locktime not satisfied by height/time — check if all inputs are final
90
+ for (const input of inputs) {
91
+ if (input.sequenceNumber !== SEQUENCE_FINAL) {
92
+ return {
93
+ ok: false,
94
+ code: REJECT_INVALID,
95
+ error: "bad-txns-nonfinal",
96
+ debugMessage: "non-final transaction",
97
+ };
98
+ }
99
+ }
100
+ return CHECK_OK;
101
+ }
102
+ /**
103
+ * Check BIP68 relative sequence locks.
104
+ * Only applies when txVersion >= 2.
105
+ * BCHN: AcceptToMemoryPoolWorker → "non-BIP68-final" (REJECT_NONSTANDARD, DoS 0).
106
+ */
107
+ export function checkSequenceLocks(txVersion, inputs, spendHeight, spendMtp) {
108
+ if (txVersion < 2)
109
+ return CHECK_OK;
110
+ for (const input of inputs) {
111
+ const seq = input.sequenceNumber;
112
+ // Bit 31 set → relative lock disabled for this input
113
+ if (seq & SEQUENCE_LOCKTIME_DISABLE_FLAG)
114
+ continue;
115
+ const maskedSeq = seq & SEQUENCE_LOCKTIME_MASK;
116
+ if (seq & SEQUENCE_LOCKTIME_TYPE_FLAG) {
117
+ // Time-based lock: compare MTP difference
118
+ const prevMtp = input.medianTimePast ?? 0;
119
+ const requiredTime = maskedSeq * SEQUENCE_LOCKTIME_GRANULARITY;
120
+ if (spendMtp - prevMtp < requiredTime) {
121
+ return { ok: false, code: REJECT_NONSTANDARD, error: "non-BIP68-final" };
122
+ }
123
+ }
124
+ else {
125
+ // Height-based lock
126
+ const requiredDepth = maskedSeq;
127
+ if (spendHeight - input.height < requiredDepth) {
128
+ return { ok: false, code: REJECT_NONSTANDARD, error: "non-BIP68-final" };
129
+ }
130
+ }
131
+ }
132
+ return CHECK_OK;
133
+ }
134
+ /**
135
+ * Check that fee meets the minimum relay fee rate.
136
+ * BCHN: AcceptToMemoryPoolWorker → "min relay fee not met" (REJECT_INSUFFICIENTFEE, DoS 0).
137
+ */
138
+ export function checkMinRelayFee(fee, txSize, minFeePerKb) {
139
+ const minFee = (minFeePerKb * BigInt(txSize) + 999n) / 1000n;
140
+ if (fee < minFee) {
141
+ return { ok: false, code: REJECT_INSUFFICIENTFEE, error: "min relay fee not met" };
142
+ }
143
+ return CHECK_OK;
144
+ }
145
+ /**
146
+ * Guard against absurdly high fees.
147
+ * BCHN: AcceptToMemoryPoolWorker → "absurdly-high-fee" (REJECT_HIGHFEE).
148
+ */
149
+ export function checkAbsurdFee(fee, maxFee) {
150
+ if (fee > maxFee) {
151
+ return {
152
+ ok: false,
153
+ code: REJECT_HIGHFEE,
154
+ error: "absurdly-high-fee",
155
+ debugMessage: `${fee} > ${maxFee}`,
156
+ };
157
+ }
158
+ return CHECK_OK;
159
+ }
160
+ /**
161
+ * Check that no non-OP_RETURN output is dust.
162
+ * BCHN: IsStandardTx → "dust" (REJECT_NONSTANDARD, DoS 0).
163
+ */
164
+ export function checkDustOutputs(outputs, dustRelayFeePerKb) {
165
+ for (const output of outputs) {
166
+ // OP_RETURN outputs are exempt from dust checks
167
+ if (output.lockingBytecode.length > 0 && output.lockingBytecode[0] === OP_RETURN) {
168
+ continue;
169
+ }
170
+ // Empty scripts are unspendable — also exempt
171
+ if (output.lockingBytecode.length === 0) {
172
+ continue;
173
+ }
174
+ // Serialize size of a CTxOut: 8 (value) + compactSize(scriptLen) + scriptLen
175
+ // For scripts < 253 bytes, compactSize is 1 byte
176
+ const scriptLen = output.lockingBytecode.length;
177
+ const outputSize = 8 + (scriptLen < 253 ? 1 : 3) + scriptLen;
178
+ // 148 = estimated input size to spend (32 prevhash + 4 previndex + 1 scriptLen + 107 sigScript + 4 sequence)
179
+ const spendSize = outputSize + 148;
180
+ const dustThreshold = (3n * dustRelayFeePerKb * BigInt(spendSize)) / 1000n;
181
+ if (output.valueSatoshis < dustThreshold) {
182
+ return { ok: false, code: REJECT_NONSTANDARD, error: "dust" };
183
+ }
184
+ }
185
+ return CHECK_OK;
186
+ }
187
+ //# sourceMappingURL=checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /** Maximum total supply of BCH in satoshis (21 million × 10^8). */
2
+ export declare const MAX_MONEY = 2100000000000000n;
3
+ /** Number of blocks before a coinbase output can be spent. */
4
+ export declare const COINBASE_MATURITY = 100;
5
+ /** Locktime values below this are interpreted as block heights; above as Unix timestamps. */
6
+ export declare const LOCKTIME_THRESHOLD = 500000000;
7
+ /** Sequence number indicating no relative lock-time or finality. */
8
+ export declare const SEQUENCE_FINAL = 4294967295;
9
+ /** BIP68: if bit 31 is set, sequence lock is disabled for this input. */
10
+ export declare const SEQUENCE_LOCKTIME_DISABLE_FLAG: number;
11
+ /** BIP68: if bit 22 is set, lock is time-based; otherwise height-based. */
12
+ export declare const SEQUENCE_LOCKTIME_TYPE_FLAG: number;
13
+ /** BIP68: mask for the 16-bit relative lock value. */
14
+ export declare const SEQUENCE_LOCKTIME_MASK = 65535;
15
+ /** BIP68: time-based granularity in seconds (2^9 = 512). */
16
+ export declare const SEQUENCE_LOCKTIME_GRANULARITY = 512;
17
+ /** Coinbase transaction prevout txid (all zeros). */
18
+ export declare const NULL_TXID: string;
19
+ /** Coinbase transaction prevout vout. */
20
+ export declare const NULL_VOUT = 4294967295;
21
+ /** OP_RETURN opcode — marks an output as provably unspendable. */
22
+ export declare const OP_RETURN = 106;
23
+ /** Maximum locking script size in bytes. */
24
+ export declare const MAX_SCRIPT_SIZE = 10000;
25
+ /** BIP113: number of previous blocks used to compute Median Time Past. */
26
+ export declare const MTP_BLOCK_COUNT = 11;
27
+ /** Default minimum relay fee in satoshis per kilobyte. */
28
+ export declare const DEFAULT_MIN_RELAY_FEE_PER_KB = 1000n;
29
+ /** Default maximum acceptable fee in satoshis (0.1 BCH). */
30
+ export declare const DEFAULT_MAX_FEE = 10000000n;
31
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,eAAO,MAAM,SAAS,oBAAyB,CAAC;AAEhD,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAErC,6FAA6F;AAC7F,eAAO,MAAM,kBAAkB,YAAc,CAAC;AAE9C,oEAAoE;AACpE,eAAO,MAAM,cAAc,aAAa,CAAC;AAEzC,yEAAyE;AACzE,eAAO,MAAM,8BAA8B,QAAU,CAAC;AAEtD,2EAA2E;AAC3E,eAAO,MAAM,2BAA2B,QAAU,CAAC;AAEnD,sDAAsD;AACtD,eAAO,MAAM,sBAAsB,QAAa,CAAC;AAEjD,4DAA4D;AAC5D,eAAO,MAAM,6BAA6B,MAAM,CAAC;AAEjD,qDAAqD;AACrD,eAAO,MAAM,SAAS,QAAkB,CAAC;AAEzC,yCAAyC;AACzC,eAAO,MAAM,SAAS,aAAa,CAAC;AAEpC,kEAAkE;AAClE,eAAO,MAAM,SAAS,MAAO,CAAC;AAE9B,4CAA4C;AAC5C,eAAO,MAAM,eAAe,QAAS,CAAC;AAEtC,0EAA0E;AAC1E,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC,0DAA0D;AAC1D,eAAO,MAAM,4BAA4B,QAAQ,CAAC;AAElD,4DAA4D;AAC5D,eAAO,MAAM,eAAe,YAAc,CAAC"}
@@ -0,0 +1,31 @@
1
+ /** Maximum total supply of BCH in satoshis (21 million × 10^8). */
2
+ export const MAX_MONEY = 2100000000000000n;
3
+ /** Number of blocks before a coinbase output can be spent. */
4
+ export const COINBASE_MATURITY = 100;
5
+ /** Locktime values below this are interpreted as block heights; above as Unix timestamps. */
6
+ export const LOCKTIME_THRESHOLD = 500_000_000;
7
+ /** Sequence number indicating no relative lock-time or finality. */
8
+ export const SEQUENCE_FINAL = 0xffffffff;
9
+ /** BIP68: if bit 31 is set, sequence lock is disabled for this input. */
10
+ export const SEQUENCE_LOCKTIME_DISABLE_FLAG = 1 << 31;
11
+ /** BIP68: if bit 22 is set, lock is time-based; otherwise height-based. */
12
+ export const SEQUENCE_LOCKTIME_TYPE_FLAG = 1 << 22;
13
+ /** BIP68: mask for the 16-bit relative lock value. */
14
+ export const SEQUENCE_LOCKTIME_MASK = 0x0000ffff;
15
+ /** BIP68: time-based granularity in seconds (2^9 = 512). */
16
+ export const SEQUENCE_LOCKTIME_GRANULARITY = 512;
17
+ /** Coinbase transaction prevout txid (all zeros). */
18
+ export const NULL_TXID = "00".repeat(32);
19
+ /** Coinbase transaction prevout vout. */
20
+ export const NULL_VOUT = 0xffffffff;
21
+ /** OP_RETURN opcode — marks an output as provably unspendable. */
22
+ export const OP_RETURN = 0x6a;
23
+ /** Maximum locking script size in bytes. */
24
+ export const MAX_SCRIPT_SIZE = 10_000;
25
+ /** BIP113: number of previous blocks used to compute Median Time Past. */
26
+ export const MTP_BLOCK_COUNT = 11;
27
+ /** Default minimum relay fee in satoshis per kilobyte. */
28
+ export const DEFAULT_MIN_RELAY_FEE_PER_KB = 1000n;
29
+ /** Default maximum acceptable fee in satoshis (0.1 BCH). */
30
+ export const DEFAULT_MAX_FEE = 10000000n;
31
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,mEAAmE;AACnE,MAAM,CAAC,MAAM,SAAS,GAAG,iBAAsB,CAAC;AAEhD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAErC,6FAA6F;AAC7F,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAE9C,oEAAoE;AACpE,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;AAEzC,yEAAyE;AACzE,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,IAAI,EAAE,CAAC;AAEtD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,IAAI,EAAE,CAAC;AAEnD,sDAAsD;AACtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,UAAU,CAAC;AAEjD,4DAA4D;AAC5D,MAAM,CAAC,MAAM,6BAA6B,GAAG,GAAG,CAAC;AAEjD,qDAAqD;AACrD,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAEzC,yCAAyC;AACzC,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CAAC;AAEpC,kEAAkE;AAClE,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC;AAE9B,4CAA4C;AAC5C,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AAEtC,0EAA0E;AAC1E,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAElC,0DAA0D;AAC1D,MAAM,CAAC,MAAM,4BAA4B,GAAG,KAAK,CAAC;AAElD,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAG,SAAW,CAAC"}
@@ -0,0 +1,6 @@
1
+ export type { CheckResult } from "./checks.js";
2
+ export { checkAbsurdFee, checkCoinbaseMaturity, checkDustOutputs, checkInputValueRanges, checkLocktimeFinality, checkMinRelayFee, checkNullPrevout, checkSequenceLocks, checkUnspendableInputs, } from "./checks.js";
3
+ export { COINBASE_MATURITY, DEFAULT_MAX_FEE, DEFAULT_MIN_RELAY_FEE_PER_KB, LOCKTIME_THRESHOLD, MAX_MONEY, MAX_SCRIPT_SIZE, MTP_BLOCK_COUNT, OP_RETURN, SEQUENCE_FINAL, SEQUENCE_LOCKTIME_DISABLE_FLAG, SEQUENCE_LOCKTIME_GRANULARITY, SEQUENCE_LOCKTIME_MASK, SEQUENCE_LOCKTIME_TYPE_FLAG, } from "./constants.js";
4
+ export type { ChainState, DebugFailure, DebugInputResult, DebugResult, DebugSuccess, SourceOutput, Transaction, TxVerifier, TxVerifierConfig, ValidatedTransaction, VerifyFailure, VerifyResult, VerifySuccess, VmVersion, } from "./types.js";
5
+ export { createTxVerifier } from "./verifier.js";
6
+ //# 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,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EACN,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,iBAAiB,EACjB,eAAe,EACf,4BAA4B,EAC5B,kBAAkB,EAClB,SAAS,EACT,eAAe,EACf,eAAe,EACf,SAAS,EACT,cAAc,EACd,8BAA8B,EAC9B,6BAA6B,EAC7B,sBAAsB,EACtB,2BAA2B,GAC3B,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACX,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,UAAU,EACV,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,YAAY,EACZ,aAAa,EACb,SAAS,GACT,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { checkAbsurdFee, checkCoinbaseMaturity, checkDustOutputs, checkInputValueRanges, checkLocktimeFinality, checkMinRelayFee, checkNullPrevout, checkSequenceLocks, checkUnspendableInputs, } from "./checks.js";
2
+ export { COINBASE_MATURITY, DEFAULT_MAX_FEE, DEFAULT_MIN_RELAY_FEE_PER_KB, LOCKTIME_THRESHOLD, MAX_MONEY, MAX_SCRIPT_SIZE, MTP_BLOCK_COUNT, OP_RETURN, SEQUENCE_FINAL, SEQUENCE_LOCKTIME_DISABLE_FLAG, SEQUENCE_LOCKTIME_GRANULARITY, SEQUENCE_LOCKTIME_MASK, SEQUENCE_LOCKTIME_TYPE_FLAG, } from "./constants.js";
3
+ export { createTxVerifier } from "./verifier.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,iBAAiB,EACjB,eAAe,EACf,4BAA4B,EAC5B,kBAAkB,EAClB,SAAS,EACT,eAAe,EACf,eAAe,EACf,SAAS,EACT,cAAc,EACd,8BAA8B,EAC9B,6BAA6B,EAC7B,sBAAsB,EACtB,2BAA2B,GAC3B,MAAM,gBAAgB,CAAC;AAiBxB,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,105 @@
1
+ import type { decodeTransactionBch, Output } from "@bitauth/libauth";
2
+ /** Supported BCH virtual machine versions (matches libauth identifiers). */
3
+ export type VmVersion = "BCH_2023_05" | "BCH_2025_05" | "BCH_2026_05" | "BCH_SPEC";
4
+ /** Configuration for the transaction verifier. */
5
+ export interface TxVerifierConfig {
6
+ /** VM version to use (default: "BCH_2025_05"). */
7
+ vmVersion?: VmVersion;
8
+ /** Whether to enforce standard transaction rules (default: true). */
9
+ standard?: boolean;
10
+ /** Minimum relay fee in satoshis per kilobyte (default: 1000). */
11
+ minRelayFeePerKb?: bigint;
12
+ /** Maximum acceptable fee in satoshis (default: 10_000_000 = 0.1 BCH). */
13
+ maxFee?: bigint;
14
+ }
15
+ /**
16
+ * Chain state required for consensus checks.
17
+ * The caller derives these from their storage/headers.
18
+ */
19
+ export interface ChainState {
20
+ /** Current chain tip height. */
21
+ readonly height: number;
22
+ /** BIP113 Median Time Past at the current tip. */
23
+ readonly medianTimePast: number;
24
+ }
25
+ /**
26
+ * Source output with consensus-relevant metadata.
27
+ * Extends libauth's Output with confirmation height and coinbase flag.
28
+ */
29
+ export interface SourceOutput extends Output {
30
+ /** Confirmation height. 0 = mempool/unconfirmed. Defaults to 1 if omitted. */
31
+ readonly height?: number;
32
+ /** Whether this output was created by a coinbase transaction. */
33
+ readonly isCoinbase?: boolean;
34
+ /** BIP113 MTP at height-1. Required for BIP68 time-based sequence locks. */
35
+ readonly medianTimePast?: number;
36
+ }
37
+ /** Decoded BCH transaction (non-error result from decodeTransactionBch). */
38
+ export type Transaction = Exclude<ReturnType<typeof decodeTransactionBch>, string>;
39
+ /** Validated transaction data returned by verify/debug. */
40
+ export interface ValidatedTransaction {
41
+ readonly txid: string;
42
+ readonly rawHex: string;
43
+ readonly fee: bigint;
44
+ readonly size: number;
45
+ /** The decoded libauth transaction. */
46
+ readonly transaction: Transaction;
47
+ /** The source outputs as provided by the caller. */
48
+ readonly sourceOutputs: readonly SourceOutput[];
49
+ }
50
+ /** Successful transaction verification result. */
51
+ export interface VerifySuccess {
52
+ readonly success: true;
53
+ readonly txid: string;
54
+ readonly fee: bigint;
55
+ readonly size: number;
56
+ readonly validatedTx: ValidatedTransaction;
57
+ }
58
+ /** Failed transaction verification result. */
59
+ export interface VerifyFailure {
60
+ readonly success: false;
61
+ /** BCHN reject code (e.g. REJECT_INVALID, REJECT_NONSTANDARD). */
62
+ readonly code: number;
63
+ /** BCHN strRejectReason (e.g. "bad-txns-prevout-null"). */
64
+ readonly error: string;
65
+ /** BCHN strDebugMessage — optional extra context. */
66
+ readonly debugMessage?: string;
67
+ }
68
+ /** Result of verifying a transaction. */
69
+ export type VerifyResult = VerifySuccess | VerifyFailure;
70
+ /** Per-input debug trace. */
71
+ export interface DebugInputResult {
72
+ readonly inputIndex: number;
73
+ readonly success: boolean;
74
+ readonly error?: string;
75
+ }
76
+ /** Successful debug result with per-input traces. */
77
+ export interface DebugSuccess {
78
+ readonly success: true;
79
+ readonly txid: string;
80
+ readonly fee: bigint;
81
+ readonly size: number;
82
+ readonly validatedTx: ValidatedTransaction;
83
+ readonly inputResults: readonly DebugInputResult[];
84
+ }
85
+ /** Failed debug result with optional partial traces. */
86
+ export interface DebugFailure {
87
+ readonly success: false;
88
+ /** BCHN reject code. */
89
+ readonly code: number;
90
+ /** BCHN strRejectReason. */
91
+ readonly error: string;
92
+ /** BCHN strDebugMessage — optional extra context. */
93
+ readonly debugMessage?: string;
94
+ readonly inputResults?: readonly DebugInputResult[];
95
+ }
96
+ /** Result of debugging a transaction. */
97
+ export type DebugResult = DebugSuccess | DebugFailure;
98
+ /** Transaction verifier interface. */
99
+ export interface TxVerifier {
100
+ /** Verify a raw transaction hex. Returns ValidatedTransaction on success. */
101
+ verify(rawHex: string, sourceOutputs: readonly SourceOutput[], chainState: ChainState): VerifyResult;
102
+ /** Debug a raw transaction hex with per-input traces. Returns ValidatedTransaction on success. */
103
+ debug(rawHex: string, sourceOutputs: readonly SourceOutput[], chainState: ChainState): DebugResult;
104
+ }
105
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import type { TxVerifier, TxVerifierConfig } from "./types.js";
2
+ /**
3
+ * Create a stateless transaction verifier.
4
+ * All context (source outputs, chain state) is provided per call.
5
+ *
6
+ * Pipeline order (matching BCHN AcceptToMemoryPool):
7
+ * 1. Decode tx hex
8
+ * 2. Null prevout check
9
+ * 3. Validate sourceOutputs length
10
+ * 4. Locktime finality check
11
+ * 5. Coinbase maturity check
12
+ * 6. Unspendable inputs check
13
+ * 7. Input value ranges check
14
+ * 8. Compute fee
15
+ * 9. BIP68 sequence locks check
16
+ * 10. Min relay fee check (policy, before VM)
17
+ * 11. Absurd fee guard (policy, before VM)
18
+ * 12. Dust output check (policy, standard only)
19
+ * 13. VM verify (most expensive — last)
20
+ * 14. Build ValidatedTransaction
21
+ */
22
+ export declare function createTxVerifier(config?: TxVerifierConfig): Promise<TxVerifier>;
23
+ //# sourceMappingURL=verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier.d.ts","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAMX,UAAU,EACV,gBAAgB,EAIhB,MAAM,YAAY,CAAC;AAqFpB;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CAqTrF"}
@@ -0,0 +1,333 @@
1
+ import { binToHex, decodeTransactionBch, encodeTransactionBch, hashTransactionUiOrder, hexToBin, } from "@bitauth/libauth";
2
+ import { REJECT_INVALID, REJECT_MALFORMED, REJECT_NONSTANDARD } from "@mem-cash/types";
3
+ import { checkAbsurdFee, checkCoinbaseMaturity, checkDustOutputs, checkInputValueRanges, checkLocktimeFinality, checkMinRelayFee, checkNullPrevout, checkSequenceLocks, checkUnspendableInputs, } from "./checks.js";
4
+ import { DEFAULT_MAX_FEE, DEFAULT_MIN_RELAY_FEE_PER_KB, MAX_MONEY } from "./constants.js";
5
+ /**
6
+ * Dynamically import and create a libauth VM for the given version.
7
+ * Only the requested VM version is loaded, keeping other versions tree-shakeable.
8
+ */
9
+ async function createVmFacade(version, standard) {
10
+ const lib = await import("@bitauth/libauth");
11
+ const createFn = (() => {
12
+ switch (version) {
13
+ case "BCH_2023_05":
14
+ return lib.createVirtualMachineBch2023;
15
+ case "BCH_2025_05":
16
+ return lib.createVirtualMachineBch2025;
17
+ case "BCH_2026_05":
18
+ return lib.createVirtualMachineBch2026;
19
+ case "BCH_SPEC":
20
+ return lib.createVirtualMachineBchSpec;
21
+ }
22
+ })();
23
+ const vm = createFn(standard);
24
+ return {
25
+ verify(resolved) {
26
+ return vm.verify(resolved);
27
+ },
28
+ debugInput(program) {
29
+ const debugTrace = vm.debug(program);
30
+ const keys = Object.keys(debugTrace);
31
+ const stateCount = keys.length;
32
+ if (stateCount === 0) {
33
+ return { success: false, error: "No execution states produced" };
34
+ }
35
+ const lastState = debugTrace[stateCount - 1];
36
+ const stateResult = vm.stateSuccess(lastState);
37
+ if (stateResult === true) {
38
+ return { success: true };
39
+ }
40
+ return { success: false, error: stateResult };
41
+ },
42
+ };
43
+ }
44
+ /** Strip consensus metadata from SourceOutput[], keeping only libauth Output fields. */
45
+ function toVmOutputs(sourceOutputs) {
46
+ return sourceOutputs.map((so) => {
47
+ const output = {
48
+ lockingBytecode: so.lockingBytecode,
49
+ valueSatoshis: so.valueSatoshis,
50
+ };
51
+ if (so.token) {
52
+ output.token = so.token;
53
+ }
54
+ return output;
55
+ });
56
+ }
57
+ /**
58
+ * Create a stateless transaction verifier.
59
+ * All context (source outputs, chain state) is provided per call.
60
+ *
61
+ * Pipeline order (matching BCHN AcceptToMemoryPool):
62
+ * 1. Decode tx hex
63
+ * 2. Null prevout check
64
+ * 3. Validate sourceOutputs length
65
+ * 4. Locktime finality check
66
+ * 5. Coinbase maturity check
67
+ * 6. Unspendable inputs check
68
+ * 7. Input value ranges check
69
+ * 8. Compute fee
70
+ * 9. BIP68 sequence locks check
71
+ * 10. Min relay fee check (policy, before VM)
72
+ * 11. Absurd fee guard (policy, before VM)
73
+ * 12. Dust output check (policy, standard only)
74
+ * 13. VM verify (most expensive — last)
75
+ * 14. Build ValidatedTransaction
76
+ */
77
+ export async function createTxVerifier(config) {
78
+ const version = config?.vmVersion ?? "BCH_2025_05";
79
+ const standard = config?.standard ?? true;
80
+ const minRelayFeePerKb = config?.minRelayFeePerKb ?? DEFAULT_MIN_RELAY_FEE_PER_KB;
81
+ const maxFee = config?.maxFee ?? DEFAULT_MAX_FEE;
82
+ if (minRelayFeePerKb <= 0n) {
83
+ throw new Error("minRelayFeePerKb must be positive");
84
+ }
85
+ if (maxFee <= 0n) {
86
+ throw new Error("maxFee must be positive");
87
+ }
88
+ const vm = await createVmFacade(version, standard);
89
+ // Consensus-only VM for two-pass script verification (BCHN CheckInputs pattern).
90
+ // When standard=true, a script failure is re-checked with consensus-only flags to
91
+ // distinguish mandatory vs non-mandatory violations.
92
+ const consensusVm = standard ? await createVmFacade(version, false) : null;
93
+ /** Run pre-VM pipeline steps 1-12. Returns validated data or error. */
94
+ function preVmPipeline(rawHex, sourceOutputs, chainState) {
95
+ const spendHeight = chainState.height + 1;
96
+ // 1. Decode tx hex
97
+ const rawBytes = hexToBin(rawHex);
98
+ const decoded = decodeTransactionBch(rawBytes);
99
+ if (typeof decoded === "string") {
100
+ return {
101
+ ok: false,
102
+ code: REJECT_MALFORMED,
103
+ error: "TX decode failed",
104
+ debugMessage: decoded,
105
+ };
106
+ }
107
+ // 2. Null prevout check
108
+ const prevoutInputs = decoded.inputs.map((inp) => ({
109
+ txid: binToHex(inp.outpointTransactionHash),
110
+ vout: inp.outpointIndex,
111
+ }));
112
+ const nullCheck = checkNullPrevout(prevoutInputs);
113
+ if (!nullCheck.ok)
114
+ return nullCheck;
115
+ // 3. Validate sourceOutputs count matches inputs
116
+ if (sourceOutputs.length !== decoded.inputs.length) {
117
+ return {
118
+ ok: false,
119
+ code: REJECT_INVALID,
120
+ error: "bad-txns-inputs-missingorspent",
121
+ debugMessage: `sourceOutputs length (${sourceOutputs.length}) does not match inputs length (${decoded.inputs.length})`,
122
+ };
123
+ }
124
+ // 4. Locktime finality check
125
+ const locktimeCheck = checkLocktimeFinality(decoded.locktime, decoded.inputs, spendHeight, chainState.medianTimePast);
126
+ if (!locktimeCheck.ok)
127
+ return locktimeCheck;
128
+ // Re-encode to get canonical bytes for size and txid
129
+ const encodedBytes = encodeTransactionBch(decoded);
130
+ const txid = binToHex(hashTransactionUiOrder(encodedBytes));
131
+ // 5. Coinbase maturity check
132
+ const maturityCheck = checkCoinbaseMaturity(sourceOutputs.map((so) => ({
133
+ isCoinbase: so.isCoinbase,
134
+ height: so.height ?? 1,
135
+ })), spendHeight);
136
+ if (!maturityCheck.ok)
137
+ return maturityCheck;
138
+ // 6. Unspendable inputs check
139
+ const unspendableCheck = checkUnspendableInputs(sourceOutputs);
140
+ if (!unspendableCheck.ok)
141
+ return unspendableCheck;
142
+ // 7. Input value ranges check
143
+ const valueCheck = checkInputValueRanges(sourceOutputs.map((so) => so.valueSatoshis));
144
+ if (!valueCheck.ok)
145
+ return valueCheck;
146
+ // 8. Compute fee (validate output values first)
147
+ let inputSum = 0n;
148
+ for (const so of sourceOutputs) {
149
+ inputSum += so.valueSatoshis;
150
+ }
151
+ let outputSum = 0n;
152
+ for (const output of decoded.outputs) {
153
+ if (output.valueSatoshis < 0n || output.valueSatoshis > MAX_MONEY) {
154
+ return {
155
+ ok: false,
156
+ code: REJECT_INVALID,
157
+ error: "bad-txns-outputvalues-outofrange",
158
+ };
159
+ }
160
+ outputSum += output.valueSatoshis;
161
+ if (outputSum > MAX_MONEY) {
162
+ return {
163
+ ok: false,
164
+ code: REJECT_INVALID,
165
+ error: "bad-txns-outputvalues-outofrange",
166
+ };
167
+ }
168
+ }
169
+ const fee = inputSum - outputSum;
170
+ if (fee < 0n) {
171
+ return {
172
+ ok: false,
173
+ code: REJECT_INVALID,
174
+ error: "bad-txns-in-belowout",
175
+ debugMessage: `value in (${inputSum}) < value out (${outputSum})`,
176
+ };
177
+ }
178
+ // 9. BIP68 sequence locks check
179
+ const seqCheck = checkSequenceLocks(decoded.version, sourceOutputs.map((so, idx) => {
180
+ const input = {
181
+ sequenceNumber: decoded.inputs[idx]?.sequenceNumber ?? 0xffffffff,
182
+ height: so.height ?? 1,
183
+ };
184
+ if (so.medianTimePast != null)
185
+ input.medianTimePast = so.medianTimePast;
186
+ return input;
187
+ }), spendHeight, chainState.medianTimePast);
188
+ if (!seqCheck.ok)
189
+ return seqCheck;
190
+ // 10. Min relay fee check (policy)
191
+ const size = encodedBytes.length;
192
+ const feeCheck = checkMinRelayFee(fee, size, minRelayFeePerKb);
193
+ if (!feeCheck.ok)
194
+ return feeCheck;
195
+ // 11. Absurd fee guard (policy)
196
+ const absurdCheck = checkAbsurdFee(fee, maxFee);
197
+ if (!absurdCheck.ok)
198
+ return absurdCheck;
199
+ // 12. Dust output check (policy, matches BCHN IsStandardTx)
200
+ if (standard) {
201
+ const dustCheck = checkDustOutputs(decoded.outputs, minRelayFeePerKb);
202
+ if (!dustCheck.ok)
203
+ return dustCheck;
204
+ }
205
+ return { ok: true, decoded, txid, encodedBytes, fee };
206
+ }
207
+ /**
208
+ * Classify a VM script error as mandatory or non-mandatory by re-checking
209
+ * with the consensus-only VM (BCHN CheckInputs two-pass pattern).
210
+ */
211
+ function classifyScriptError(primaryError, consensusCheck) {
212
+ if (consensusVm) {
213
+ const consensusResult = consensusCheck();
214
+ if (consensusResult === true) {
215
+ return {
216
+ code: REJECT_NONSTANDARD,
217
+ error: `non-mandatory-script-verify-flag (${primaryError})`,
218
+ };
219
+ }
220
+ return {
221
+ code: REJECT_INVALID,
222
+ error: `mandatory-script-verify-flag-failed (${consensusResult})`,
223
+ };
224
+ }
225
+ return {
226
+ code: REJECT_INVALID,
227
+ error: `mandatory-script-verify-flag-failed (${primaryError})`,
228
+ };
229
+ }
230
+ /** Convert a pipeline failure to a result failure, avoiding undefined in optional fields. */
231
+ function pipelineToFailure(f) {
232
+ const result = {
233
+ success: false,
234
+ code: f.code,
235
+ error: f.error,
236
+ };
237
+ if (f.debugMessage != null)
238
+ result.debugMessage = f.debugMessage;
239
+ return result;
240
+ }
241
+ function verify(rawHex, sourceOutputs, chainState) {
242
+ const pipeline = preVmPipeline(rawHex, sourceOutputs, chainState);
243
+ if (!pipeline.ok)
244
+ return pipelineToFailure(pipeline);
245
+ const { decoded, txid, encodedBytes, fee } = pipeline;
246
+ // 13. VM verify (most expensive — last)
247
+ const vmOutputs = toVmOutputs(sourceOutputs);
248
+ const verifyResult = vm.verify({ sourceOutputs: vmOutputs, transaction: decoded });
249
+ if (verifyResult !== true) {
250
+ const { code, error } = classifyScriptError(verifyResult, () => consensusVm
251
+ ? consensusVm.verify({ sourceOutputs: vmOutputs, transaction: decoded })
252
+ : verifyResult);
253
+ return { success: false, code, error };
254
+ }
255
+ // 14. Build ValidatedTransaction
256
+ const size = encodedBytes.length;
257
+ const validatedTx = {
258
+ txid,
259
+ rawHex,
260
+ fee,
261
+ size,
262
+ transaction: decoded,
263
+ sourceOutputs,
264
+ };
265
+ return { success: true, txid, fee, size, validatedTx };
266
+ }
267
+ function debug(rawHex, sourceOutputs, chainState) {
268
+ const pipeline = preVmPipeline(rawHex, sourceOutputs, chainState);
269
+ if (!pipeline.ok)
270
+ return pipelineToFailure(pipeline);
271
+ const { decoded, txid, encodedBytes, fee } = pipeline;
272
+ const vmOutputs = toVmOutputs(sourceOutputs);
273
+ // 13. Debug each input individually
274
+ const inputResults = [];
275
+ for (let i = 0; i < decoded.inputs.length; i++) {
276
+ try {
277
+ const result = vm.debugInput({
278
+ inputIndex: i,
279
+ sourceOutputs: vmOutputs,
280
+ transaction: decoded,
281
+ });
282
+ if (result.success) {
283
+ inputResults.push({ inputIndex: i, success: true });
284
+ }
285
+ else {
286
+ const scriptError = result.error ?? "Script evaluation failed";
287
+ inputResults.push({ inputIndex: i, success: false, error: scriptError });
288
+ const { code, error } = classifyScriptError(scriptError, () => consensusVm
289
+ ? (() => {
290
+ const r = consensusVm.debugInput({
291
+ inputIndex: i,
292
+ sourceOutputs: vmOutputs,
293
+ transaction: decoded,
294
+ });
295
+ return r.success ? true : (r.error ?? scriptError);
296
+ })()
297
+ : scriptError);
298
+ return { success: false, code, error, inputResults };
299
+ }
300
+ }
301
+ catch (e) {
302
+ const errorMsg = e instanceof Error ? e.message : "Unknown VM error";
303
+ inputResults.push({ inputIndex: i, success: false, error: errorMsg });
304
+ return {
305
+ success: false,
306
+ code: REJECT_INVALID,
307
+ error: `mandatory-script-verify-flag-failed (${errorMsg})`,
308
+ inputResults,
309
+ };
310
+ }
311
+ }
312
+ const verifyResult = vm.verify({ sourceOutputs: vmOutputs, transaction: decoded });
313
+ if (verifyResult !== true) {
314
+ const { code, error } = classifyScriptError(verifyResult, () => consensusVm
315
+ ? consensusVm.verify({ sourceOutputs: vmOutputs, transaction: decoded })
316
+ : verifyResult);
317
+ return { success: false, code, error, inputResults };
318
+ }
319
+ // 14. Build ValidatedTransaction
320
+ const size = encodedBytes.length;
321
+ const validatedTx = {
322
+ txid,
323
+ rawHex,
324
+ fee,
325
+ size,
326
+ transaction: decoded,
327
+ sourceOutputs,
328
+ };
329
+ return { success: true, txid, fee, size, validatedTx, inputResults };
330
+ }
331
+ return { verify, debug };
332
+ }
333
+ //# sourceMappingURL=verifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifier.js","sourceRoot":"","sources":["../src/verifier.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "@mem-cash/validation",
3
+ "version": "0.0.1",
4
+ "description": "Stateless BCH transaction evaluator with BCHN-compatible consensus and policy checks",
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/validation"
25
+ },
26
+ "keywords": [
27
+ "bitcoin-cash",
28
+ "electrum",
29
+ "validation",
30
+ "transaction",
31
+ "consensus"
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
+ }