@mem-cash/electrum 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.
Files changed (70) hide show
  1. package/README.md +143 -0
  2. package/dist/address.d.ts +20 -0
  3. package/dist/address.d.ts.map +1 -0
  4. package/dist/address.js +51 -0
  5. package/dist/address.js.map +1 -0
  6. package/dist/dispatch.d.ts +18 -0
  7. package/dist/dispatch.d.ts.map +1 -0
  8. package/dist/dispatch.js +108 -0
  9. package/dist/dispatch.js.map +1 -0
  10. package/dist/headers.d.ts +14 -0
  11. package/dist/headers.d.ts.map +1 -0
  12. package/dist/headers.js +156 -0
  13. package/dist/headers.js.map +1 -0
  14. package/dist/index.d.ts +16 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +11 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/indexer.d.ts +42 -0
  19. package/dist/indexer.d.ts.map +1 -0
  20. package/dist/indexer.js +216 -0
  21. package/dist/indexer.js.map +1 -0
  22. package/dist/memCash.d.ts +40 -0
  23. package/dist/memCash.d.ts.map +1 -0
  24. package/dist/memCash.js +212 -0
  25. package/dist/memCash.js.map +1 -0
  26. package/dist/mempool.d.ts +6 -0
  27. package/dist/mempool.d.ts.map +1 -0
  28. package/dist/mempool.js +46 -0
  29. package/dist/mempool.js.map +1 -0
  30. package/dist/schema.d.ts +638 -0
  31. package/dist/schema.d.ts.map +1 -0
  32. package/dist/schema.js +3 -0
  33. package/dist/schema.js.map +1 -0
  34. package/dist/scripthash.d.ts +18 -0
  35. package/dist/scripthash.d.ts.map +1 -0
  36. package/dist/scripthash.js +164 -0
  37. package/dist/scripthash.js.map +1 -0
  38. package/dist/server.d.ts +20 -0
  39. package/dist/server.d.ts.map +1 -0
  40. package/dist/server.js +120 -0
  41. package/dist/server.js.map +1 -0
  42. package/dist/stubs.d.ts +12 -0
  43. package/dist/stubs.d.ts.map +1 -0
  44. package/dist/stubs.js +16 -0
  45. package/dist/stubs.js.map +1 -0
  46. package/dist/test.d.ts +8 -0
  47. package/dist/test.d.ts.map +1 -0
  48. package/dist/test.js +240 -0
  49. package/dist/test.js.map +1 -0
  50. package/dist/testUtils.d.ts +20 -0
  51. package/dist/testUtils.d.ts.map +1 -0
  52. package/dist/testUtils.js +29 -0
  53. package/dist/testUtils.js.map +1 -0
  54. package/dist/transaction.d.ts +28 -0
  55. package/dist/transaction.d.ts.map +1 -0
  56. package/dist/transaction.js +318 -0
  57. package/dist/transaction.js.map +1 -0
  58. package/dist/transport.d.ts +24 -0
  59. package/dist/transport.d.ts.map +1 -0
  60. package/dist/transport.js +16 -0
  61. package/dist/transport.js.map +1 -0
  62. package/dist/types.d.ts +85 -0
  63. package/dist/types.d.ts.map +1 -0
  64. package/dist/types.js +58 -0
  65. package/dist/types.js.map +1 -0
  66. package/dist/utxo.d.ts +4 -0
  67. package/dist/utxo.d.ts.map +1 -0
  68. package/dist/utxo.js +39 -0
  69. package/dist/utxo.js.map +1 -0
  70. package/package.json +53 -0
package/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # @mem-cash/electrum
2
+
3
+ Electrum Cash protocol handlers, dispatch, and the `Indexer` facade. Modelled after
4
+ [Fulcrum](https://github.com/cculianu/Fulcrum), the production C++ Electrum Cash indexer -- error messages, history sort order, status hash computation, and
5
+ protocol behavior are aligned with Fulcrum's implementation.
6
+
7
+ ## Protocol Coverage
8
+
9
+ All 53 Fulcrum client RPC methods are implemented:
10
+
11
+ | Category | Methods |
12
+ |---|---|
13
+ | `blockchain.scripthash.*` | get_balance, get_history, get_mempool, listunspent, subscribe, unsubscribe, get_status, get_first_use |
14
+ | `blockchain.address.*` | get_balance, get_history, get_mempool, listunspent, subscribe, unsubscribe, get_scripthash, get_status, get_first_use |
15
+ | `blockchain.transaction.*` | get, get_merkle, id_from_pos, broadcast, broadcast_package, get_height, get_confirmed_blockhash, subscribe, unsubscribe |
16
+ | `blockchain.transaction.dsproof.*` | get, list, subscribe, unsubscribe |
17
+ | `blockchain.block.*` / `blockchain.headers.*` | header, headers, header.get, headers.get_tip, headers.subscribe, headers.unsubscribe |
18
+ | `blockchain.utxo.*` | get_info |
19
+ | `mempool.*` | get_fee_histogram, get_info |
20
+ | `server.*` | version, ping, features, banner, donation_address, add_peer, peers.subscribe |
21
+ | `blockchain.estimatefee` / `blockchain.relayfee` | fee estimation |
22
+ | `blockchain.rpa.*` / `blockchain.reusable.*` / `daemon.passthrough` | stubs (not supported) |
23
+
24
+ ## Quick Start
25
+
26
+ `createIndexer()` wires together storage, validation, subscriptions, and protocol
27
+ dispatch into a single instance. All interaction goes through `request()`.
28
+
29
+ ```typescript
30
+ import { createIndexer } from "@mem-cash/electrum";
31
+ import { binToHex, sha256 } from "@bitauth/libauth";
32
+
33
+ const indexer = createIndexer({ standard: false });
34
+ indexer.setChainTip(200, 1700000000);
35
+
36
+ // OP_1 (always-true script) for simplicity
37
+ const lockingBytecode = Uint8Array.of(0x51);
38
+ const scriptHash = binToHex(sha256.hash(lockingBytecode));
39
+
40
+ indexer.addUtxo({
41
+ txid: "aa".repeat(32),
42
+ vout: 0,
43
+ satoshis: 10_000n,
44
+ scriptHash,
45
+ height: 100,
46
+ lockingBytecode,
47
+ });
48
+
49
+ // Query balance
50
+ const balance = await indexer.request("blockchain.scripthash.get_balance", [scriptHash]);
51
+
52
+ // Query unspent outputs
53
+ const utxos = await indexer.request("blockchain.scripthash.listunspent", [scriptHash]);
54
+
55
+ // Submit a transaction (verify + accept to mempool in one call)
56
+ const result = indexer.submitTransaction(rawHex);
57
+
58
+ // Or broadcast via the Electrum protocol method
59
+ const txid = await indexer.request("blockchain.transaction.broadcast", [rawHex]);
60
+ ```
61
+
62
+ ## Subscriptions
63
+
64
+ ```typescript
65
+ // Subscribe to scripthash status changes
66
+ const unsub = await indexer.subscribe(
67
+ "blockchain.scripthash.subscribe",
68
+ [scriptHash],
69
+ ([sh, status]) => console.log("status changed:", sh, status),
70
+ );
71
+
72
+ // Subscribe to new block headers
73
+ await indexer.subscribe(
74
+ "blockchain.headers.subscribe",
75
+ [],
76
+ ([header]) => console.log("new tip:", header.height),
77
+ );
78
+
79
+ // Unsubscribe
80
+ await unsub();
81
+ ```
82
+
83
+ ## Test Helpers
84
+
85
+ `test.*` RPC methods are available by default for setting up chain state.
86
+ To disable them (e.g. in production), pass `disableTestHandlers: true`:
87
+
88
+ ```typescript
89
+ const indexer = createIndexer({ disableTestHandlers: true });
90
+ ```
91
+
92
+ When enabled:
93
+
94
+ ```typescript
95
+ await indexer.request("test.set_chain_tip", [200, 1700000000]);
96
+ await indexer.request("test.add_utxo", [address, { satoshis: 10000, height: 100 }]);
97
+ await indexer.request("test.mine", [address, 1]); // max 1000 blocks per call
98
+
99
+ // Debug a transaction (per-input VM traces, without accepting to mempool)
100
+ const debug = await indexer.request("test.debugTransaction", [rawHex]);
101
+ // → { success: true, txid, fee, size, inputResults: [{ inputIndex: 0, success: true }, ...] }
102
+ // → { success: false, code, error, inputResults: [{ inputIndex: 0, success: false, error: "..." }] }
103
+
104
+ await indexer.request("test.reset", []);
105
+ ```
106
+
107
+ ## Resource Limits
108
+
109
+ - **`blockchain.block.header` / `blockchain.block.headers`** -- `cp_height` capped at 1,000,000 to prevent DoS via huge merkle tree allocations
110
+ - **`blockchain.transaction.broadcast_package`** -- max 1,000 transactions per call
111
+ - **`test.mine`** -- max 1,000 blocks per call
112
+ - Internal decoder errors are not exposed in RPC responses
113
+
114
+ ## Fulcrum Compatibility
115
+
116
+ - **Error strings** match BCHN's `strRejectReason` (e.g. `bad-txns-prevout-null`, `min relay fee not met`)
117
+ - **Reject codes** use BCHN values (`REJECT_INVALID`, `REJECT_NONSTANDARD`, etc.)
118
+ - **Broadcast errors** use Fulcrum's format: `"the transaction was rejected by network rules.\n\n<reason> (code <code>)\n"`
119
+ - **Mempool history sort** matches Fulcrum: height 0 (confirmed parents) before height -1 (unconfirmed parents), within each group sorted by txHash
120
+ - **Status hash** computation uses the same `txHash:height:` concatenation and single SHA-256
121
+ - **Two-pass script verification** distinguishes `mandatory-script-verify-flag-failed` from `non-mandatory-script-verify-flag`
122
+
123
+ ## Architecture
124
+
125
+ ```
126
+ +-----------------------------------------+
127
+ | Protocol Layer |
128
+ | dispatch() -> handler -> storage query |
129
+ | subscriptions -> notifyChanges() |
130
+ | acceptToMempool() -> storage mutations |
131
+ +-----------------------------------------+
132
+ | Validation Layer |
133
+ | createTxVerifier() -> verify()/debug() |
134
+ | consensus checks -> policy -> VM |
135
+ +-----------------------------------------+
136
+ | Storage Layer |
137
+ | createMemoryStorage() -> Storage |
138
+ | UTXO set, history, headers, mempool |
139
+ +-----------------------------------------+
140
+ | Core Layer |
141
+ | types, primitives, storage interfaces |
142
+ +-----------------------------------------+
143
+ ```
@@ -0,0 +1,20 @@
1
+ import type { HandlerResult, ProtocolContext } from "./types.js";
2
+ /** blockchain.address.get_balance */
3
+ export declare const addressGetBalance: (ctx: ProtocolContext, params: unknown[]) => HandlerResult;
4
+ /** blockchain.address.get_history */
5
+ export declare const addressGetHistory: (ctx: ProtocolContext, params: unknown[]) => HandlerResult;
6
+ /** blockchain.address.get_mempool */
7
+ export declare const addressGetMempool: (ctx: ProtocolContext, params: unknown[]) => HandlerResult;
8
+ /** blockchain.address.listunspent */
9
+ export declare const addressListUnspent: (ctx: ProtocolContext, params: unknown[]) => HandlerResult;
10
+ /** blockchain.address.subscribe — delegates to scripthash.subscribe. */
11
+ export declare const addressSubscribe: (ctx: ProtocolContext, params: unknown[]) => HandlerResult;
12
+ /** blockchain.address.unsubscribe */
13
+ export declare const addressUnsubscribe: (ctx: ProtocolContext, params: unknown[]) => HandlerResult;
14
+ /** blockchain.address.get_status */
15
+ export declare const addressGetStatus: (ctx: ProtocolContext, params: unknown[]) => HandlerResult;
16
+ /** blockchain.address.get_first_use */
17
+ export declare const addressGetFirstUse: (ctx: ProtocolContext, params: unknown[]) => HandlerResult;
18
+ /** blockchain.address.get_scripthash */
19
+ export declare function addressGetScripthash(_ctx: ProtocolContext, params: unknown[]): HandlerResult;
20
+ //# sourceMappingURL=address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA0BjE,qCAAqC;AACrC,eAAO,MAAM,iBAAiB,QAVrB,eAAe,UAAU,OAAO,EAAE,KAAK,aAU8B,CAAC;AAE/E,qCAAqC;AACrC,eAAO,MAAM,iBAAiB,QAbrB,eAAe,UAAU,OAAO,EAAE,KAAK,aAa8B,CAAC;AAE/E,qCAAqC;AACrC,eAAO,MAAM,iBAAiB,QAhBrB,eAAe,UAAU,OAAO,EAAE,KAAK,aAgB8B,CAAC;AAE/E,qCAAqC;AACrC,eAAO,MAAM,kBAAkB,QAnBtB,eAAe,UAAU,OAAO,EAAE,KAAK,aAmBgC,CAAC;AAEjF,wEAAwE;AACxE,eAAO,MAAM,gBAAgB,QAtBpB,eAAe,UAAU,OAAO,EAAE,KAAK,aAsB4B,CAAC;AAE7E,qCAAqC;AACrC,eAAO,MAAM,kBAAkB,QAzBtB,eAAe,UAAU,OAAO,EAAE,KAAK,aAyBgC,CAAC;AAEjF,oCAAoC;AACpC,eAAO,MAAM,gBAAgB,QA5BpB,eAAe,UAAU,OAAO,EAAE,KAAK,aA4B4B,CAAC;AAE7E,uCAAuC;AACvC,eAAO,MAAM,kBAAkB,QA/BtB,eAAe,UAAU,OAAO,EAAE,KAAK,aA+BgC,CAAC;AAEjF,wCAAwC;AACxC,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAK5F"}
@@ -0,0 +1,51 @@
1
+ import { binToHex, cashAddressToLockingBytecode, sha256 } from "@bitauth/libauth";
2
+ import * as scripthashHandlers from "./scripthash.js";
3
+ import { invalidParams } from "./types.js";
4
+ /** Decode a cash address to its scripthash. Returns null on failure. */
5
+ function addressToScriptHash(address) {
6
+ const result = cashAddressToLockingBytecode(address);
7
+ if (typeof result === "string")
8
+ return null;
9
+ return binToHex(sha256.hash(result.bytecode));
10
+ }
11
+ /**
12
+ * Rewrite params[0] from address to scripthash, then delegate to a
13
+ * scripthash handler. The response is identical — Fulcrum's address.*
14
+ * methods return the same shapes as scripthash.* methods.
15
+ */
16
+ function withScriptHash(handler) {
17
+ return (ctx, params) => {
18
+ if (typeof params[0] !== "string")
19
+ return invalidParams("Invalid address");
20
+ const scriptHash = addressToScriptHash(params[0]);
21
+ if (scriptHash === null)
22
+ return invalidParams("Invalid address");
23
+ return handler(ctx, [scriptHash, ...params.slice(1)]);
24
+ };
25
+ }
26
+ /** blockchain.address.get_balance */
27
+ export const addressGetBalance = withScriptHash(scripthashHandlers.getBalance);
28
+ /** blockchain.address.get_history */
29
+ export const addressGetHistory = withScriptHash(scripthashHandlers.getHistory);
30
+ /** blockchain.address.get_mempool */
31
+ export const addressGetMempool = withScriptHash(scripthashHandlers.getMempool);
32
+ /** blockchain.address.listunspent */
33
+ export const addressListUnspent = withScriptHash(scripthashHandlers.listUnspent);
34
+ /** blockchain.address.subscribe — delegates to scripthash.subscribe. */
35
+ export const addressSubscribe = withScriptHash(scripthashHandlers.subscribe);
36
+ /** blockchain.address.unsubscribe */
37
+ export const addressUnsubscribe = withScriptHash(scripthashHandlers.unsubscribe);
38
+ /** blockchain.address.get_status */
39
+ export const addressGetStatus = withScriptHash(scripthashHandlers.getStatus);
40
+ /** blockchain.address.get_first_use */
41
+ export const addressGetFirstUse = withScriptHash(scripthashHandlers.getFirstUse);
42
+ /** blockchain.address.get_scripthash */
43
+ export function addressGetScripthash(_ctx, params) {
44
+ if (typeof params[0] !== "string")
45
+ return invalidParams("Invalid address");
46
+ const scriptHash = addressToScriptHash(params[0]);
47
+ if (scriptHash === null)
48
+ return invalidParams("Invalid address");
49
+ return { result: scriptHash };
50
+ }
51
+ //# sourceMappingURL=address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.js","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,4BAA4B,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,KAAK,kBAAkB,MAAM,iBAAiB,CAAC;AAEtD,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,wEAAwE;AACxE,SAAS,mBAAmB,CAAC,OAAe;IAC3C,MAAM,MAAM,GAAG,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACrD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC5C,OAAO,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CACtB,OAAmE;IAEnE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE;QACtB,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ;YAAE,OAAO,aAAa,CAAC,iBAAiB,CAAC,CAAC;QAC3E,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,IAAI,UAAU,KAAK,IAAI;YAAE,OAAO,aAAa,CAAC,iBAAiB,CAAC,CAAC;QACjE,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC;AACH,CAAC;AAED,qCAAqC;AACrC,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;AAE/E,qCAAqC;AACrC,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;AAE/E,qCAAqC;AACrC,MAAM,CAAC,MAAM,iBAAiB,GAAG,cAAc,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC;AAE/E,qCAAqC;AACrC,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;AAEjF,wEAAwE;AACxE,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAE7E,qCAAqC;AACrC,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;AAEjF,oCAAoC;AACpC,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC;AAE7E,uCAAuC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;AAEjF,wCAAwC;AACxC,MAAM,UAAU,oBAAoB,CAAC,IAAqB,EAAE,MAAiB;IAC5E,IAAI,OAAO,MAAM,CAAC,CAAC,CAAC,KAAK,QAAQ;QAAE,OAAO,aAAa,CAAC,iBAAiB,CAAC,CAAC;IAC3E,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,aAAa,CAAC,iBAAiB,CAAC,CAAC;IACjE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Handler, HandlerResult, ProtocolContext } from "./types.js";
2
+ /**
3
+ * Dispatch a JSON-RPC method call to the appropriate handler.
4
+ *
5
+ * @param ctx - Protocol context with storage, server info, and hooks
6
+ * @param method - The JSON-RPC method name
7
+ * @param params - The method parameters
8
+ * @returns The handler result (success or error)
9
+ */
10
+ export declare function dispatch(ctx: ProtocolContext, method: string, params: unknown[]): Promise<HandlerResult>;
11
+ /** Get the list of all supported method names. */
12
+ export declare function getSupportedMethods(): string[];
13
+ /**
14
+ * Create a dispatch function with optional extra handlers merged on top of
15
+ * the built-in protocol handlers.
16
+ */
17
+ export declare function createDispatch(extraHandlers?: ReadonlyMap<string, Handler>): (ctx: ProtocolContext, method: string, params: unknown[]) => Promise<HandlerResult>;
18
+ //# sourceMappingURL=dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAgF1E;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAC7B,GAAG,EAAE,eAAe,EACpB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EAAE,GACf,OAAO,CAAC,aAAa,CAAC,CAMxB;AAED,kDAAkD;AAClD,wBAAgB,mBAAmB,IAAI,MAAM,EAAE,CAE9C;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC7B,aAAa,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,GAC1C,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,aAAa,CAAC,CAOrF"}
@@ -0,0 +1,108 @@
1
+ import * as addressHandlers from "./address.js";
2
+ import * as headersHandlers from "./headers.js";
3
+ import * as mempoolHandlers from "./mempool.js";
4
+ import * as scripthashHandlers from "./scripthash.js";
5
+ import * as serverHandlers from "./server.js";
6
+ import * as stubHandlers from "./stubs.js";
7
+ import * as transactionHandlers from "./transaction.js";
8
+ import { ERR_METHOD_NOT_FOUND, err } from "./types.js";
9
+ import * as utxoHandlers from "./utxo.js";
10
+ /** Registry of Electrum Cash protocol method handlers. */
11
+ const methodHandlers = new Map([
12
+ // blockchain.address.* (Fulcrum extension — delegates to scripthash handlers)
13
+ ["blockchain.address.get_balance", addressHandlers.addressGetBalance],
14
+ ["blockchain.address.get_first_use", addressHandlers.addressGetFirstUse],
15
+ ["blockchain.address.get_history", addressHandlers.addressGetHistory],
16
+ ["blockchain.address.get_mempool", addressHandlers.addressGetMempool],
17
+ ["blockchain.address.get_scripthash", addressHandlers.addressGetScripthash],
18
+ ["blockchain.address.get_status", addressHandlers.addressGetStatus],
19
+ ["blockchain.address.listunspent", addressHandlers.addressListUnspent],
20
+ ["blockchain.address.subscribe", addressHandlers.addressSubscribe],
21
+ ["blockchain.address.unsubscribe", addressHandlers.addressUnsubscribe],
22
+ // blockchain.scripthash.*
23
+ ["blockchain.scripthash.get_balance", scripthashHandlers.getBalance],
24
+ ["blockchain.scripthash.get_first_use", scripthashHandlers.getFirstUse],
25
+ ["blockchain.scripthash.get_history", scripthashHandlers.getHistory],
26
+ ["blockchain.scripthash.get_mempool", scripthashHandlers.getMempool],
27
+ ["blockchain.scripthash.listunspent", scripthashHandlers.listUnspent],
28
+ ["blockchain.scripthash.subscribe", scripthashHandlers.subscribe],
29
+ ["blockchain.scripthash.unsubscribe", scripthashHandlers.unsubscribe],
30
+ ["blockchain.scripthash.get_status", scripthashHandlers.getStatus],
31
+ // blockchain.headers.*
32
+ ["blockchain.header.get", headersHandlers.headerGet],
33
+ ["blockchain.headers.get_tip", headersHandlers.headersGetTip],
34
+ ["blockchain.headers.subscribe", headersHandlers.headersSubscribe],
35
+ ["blockchain.headers.unsubscribe", headersHandlers.headersUnsubscribe],
36
+ // blockchain.block.*
37
+ ["blockchain.block.header", headersHandlers.blockHeader],
38
+ ["blockchain.block.headers", headersHandlers.blockHeaders],
39
+ // blockchain.transaction.*
40
+ ["blockchain.transaction.broadcast", transactionHandlers.broadcast],
41
+ ["blockchain.transaction.broadcast_package", transactionHandlers.broadcastPackage],
42
+ ["blockchain.transaction.get", transactionHandlers.get],
43
+ ["blockchain.transaction.get_confirmed_blockhash", transactionHandlers.getConfirmedBlockhash],
44
+ ["blockchain.transaction.get_height", transactionHandlers.getHeight],
45
+ ["blockchain.transaction.get_merkle", transactionHandlers.getMerkle],
46
+ ["blockchain.transaction.id_from_pos", transactionHandlers.idFromPos],
47
+ ["blockchain.transaction.subscribe", transactionHandlers.txSubscribe],
48
+ ["blockchain.transaction.unsubscribe", transactionHandlers.txUnsubscribe],
49
+ ["blockchain.transaction.dsproof.get", transactionHandlers.dsproofGet],
50
+ ["blockchain.transaction.dsproof.list", transactionHandlers.dsproofList],
51
+ ["blockchain.transaction.dsproof.subscribe", transactionHandlers.dsproofSubscribe],
52
+ ["blockchain.transaction.dsproof.unsubscribe", transactionHandlers.dsproofUnsubscribe],
53
+ // blockchain.utxo.*
54
+ ["blockchain.utxo.get_info", utxoHandlers.getInfo],
55
+ // mempool.*
56
+ ["mempool.get_fee_histogram", mempoolHandlers.getFeeHistogram],
57
+ ["mempool.get_info", mempoolHandlers.getInfo],
58
+ // server.*
59
+ ["server.add_peer", serverHandlers.addPeer],
60
+ ["server.banner", serverHandlers.banner],
61
+ ["server.donation_address", serverHandlers.donationAddress],
62
+ ["server.features", serverHandlers.features],
63
+ ["server.peers.subscribe", serverHandlers.peersSubscribe],
64
+ ["server.ping", serverHandlers.ping],
65
+ ["server.version", serverHandlers.version],
66
+ // fee estimation
67
+ ["blockchain.estimatefee", serverHandlers.estimateFee],
68
+ ["blockchain.relayfee", serverHandlers.relayFee],
69
+ // stubs (not supported in Phase 1)
70
+ ["blockchain.rpa.get_history", stubHandlers.rpaGetHistory],
71
+ ["blockchain.rpa.get_mempool", stubHandlers.rpaGetMempool],
72
+ ["blockchain.reusable.get_history", stubHandlers.reusableGetHistory],
73
+ ["blockchain.reusable.get_mempool", stubHandlers.reusableGetMempool],
74
+ ["daemon.passthrough", stubHandlers.daemonPassthrough],
75
+ ]);
76
+ /**
77
+ * Dispatch a JSON-RPC method call to the appropriate handler.
78
+ *
79
+ * @param ctx - Protocol context with storage, server info, and hooks
80
+ * @param method - The JSON-RPC method name
81
+ * @param params - The method parameters
82
+ * @returns The handler result (success or error)
83
+ */
84
+ export async function dispatch(ctx, method, params) {
85
+ const handler = methodHandlers.get(method);
86
+ if (!handler) {
87
+ return err(ERR_METHOD_NOT_FOUND, `Unknown method: ${method}`);
88
+ }
89
+ return handler(ctx, params);
90
+ }
91
+ /** Get the list of all supported method names. */
92
+ export function getSupportedMethods() {
93
+ return [...methodHandlers.keys()];
94
+ }
95
+ /**
96
+ * Create a dispatch function with optional extra handlers merged on top of
97
+ * the built-in protocol handlers.
98
+ */
99
+ export function createDispatch(extraHandlers) {
100
+ const handlers = extraHandlers ? new Map([...methodHandlers, ...extraHandlers]) : methodHandlers;
101
+ return async (ctx, method, params) => {
102
+ const handler = handlers.get(method);
103
+ if (!handler)
104
+ return err(ERR_METHOD_NOT_FOUND, `Unknown method: ${method}`);
105
+ return handler(ctx, params);
106
+ };
107
+ }
108
+ //# sourceMappingURL=dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../src/dispatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type HandlerResult, type ProtocolContext } from "./types.js";
2
+ /** blockchain.block.header */
3
+ export declare function blockHeader(ctx: ProtocolContext, params: unknown[]): HandlerResult;
4
+ /** blockchain.block.headers (plural — returns a range of consecutive headers) */
5
+ export declare function blockHeaders(ctx: ProtocolContext, params: unknown[]): HandlerResult;
6
+ /** blockchain.header.get — retrieve a single header by height or hash. */
7
+ export declare function headerGet(ctx: ProtocolContext, params: unknown[]): HandlerResult;
8
+ /** blockchain.headers.get_tip — return the current chain tip. */
9
+ export declare function headersGetTip(ctx: ProtocolContext, _params: unknown[]): HandlerResult;
10
+ /** blockchain.headers.subscribe */
11
+ export declare function headersSubscribe(ctx: ProtocolContext, _params: unknown[]): HandlerResult;
12
+ /** blockchain.headers.unsubscribe */
13
+ export declare function headersUnsubscribe(ctx: ProtocolContext, _params: unknown[]): HandlerResult;
14
+ //# sourceMappingURL=headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.d.ts","sourceRoot":"","sources":["../src/headers.ts"],"names":[],"mappings":"AACA,OAAO,EAIN,KAAK,aAAa,EAGlB,KAAK,eAAe,EAEpB,MAAM,YAAY,CAAC;AAsBpB,8BAA8B;AAC9B,wBAAgB,WAAW,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CA2ClF;AAED,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CA2DnF;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAchF;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,aAAa,CAIrF;AAED,mCAAmC;AACnC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,aAAa,CAWxF;AAED,qCAAqC;AACrC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,aAAa,CAO1F"}
@@ -0,0 +1,156 @@
1
+ import { computeHeaderMerkleBranch } from "@mem-cash/types";
2
+ import { ERR_BAD_REQUEST, err, formatHeaderResponse, invalidParams, ok, validateNonNegativeInt, } from "./types.js";
3
+ /** Maximum number of headers returned in a single `blockchain.block.headers` request. */
4
+ const MAX_HEADERS_PER_REQUEST = 2016;
5
+ /** Maximum cp_height for merkle proof computation (prevents DoS via huge allocations). */
6
+ const MAX_CHECKPOINT_HEIGHT = 1_000_000;
7
+ /**
8
+ * Collect block hashes for heights 0..cpHeight (inclusive) from storage.
9
+ * Returns null if any header in the range is missing.
10
+ */
11
+ function collectHeaderHashes(ctx, cpHeight) {
12
+ const hashes = [];
13
+ for (let h = 0; h <= cpHeight; h++) {
14
+ const header = ctx.node.getHeader(h);
15
+ if (!header)
16
+ return null;
17
+ hashes.push(header.hash);
18
+ }
19
+ return hashes;
20
+ }
21
+ /** blockchain.block.header */
22
+ export function blockHeader(ctx, params) {
23
+ const height = validateNonNegativeInt(params[0]);
24
+ if (height === null)
25
+ return invalidParams("Invalid height");
26
+ const header = ctx.node.getHeader(height);
27
+ if (!header) {
28
+ return err(ERR_BAD_REQUEST, "Invalid height");
29
+ }
30
+ // Without checkpoint: return raw header hex
31
+ if (params[1] === undefined || params[1] === null) {
32
+ return ok(header.hex);
33
+ }
34
+ // With checkpoint height: return header + merkle proof
35
+ const cpHeight = validateNonNegativeInt(params[1]);
36
+ if (cpHeight === null)
37
+ return invalidParams("Invalid cp_height");
38
+ if (height > cpHeight) {
39
+ return invalidParams("height must be <= cp_height");
40
+ }
41
+ if (cpHeight > MAX_CHECKPOINT_HEIGHT) {
42
+ return invalidParams("cp_height exceeds maximum allowed value");
43
+ }
44
+ const tip = ctx.node.getTip();
45
+ if (!tip || cpHeight > tip.height) {
46
+ return invalidParams("cp_height exceeds chain tip");
47
+ }
48
+ const hashes = collectHeaderHashes(ctx, cpHeight);
49
+ if (!hashes) {
50
+ return err(ERR_BAD_REQUEST, "Missing headers in checkpoint range");
51
+ }
52
+ const { branch, root } = computeHeaderMerkleBranch(hashes, height);
53
+ return ok({
54
+ header: header.hex,
55
+ branch,
56
+ root,
57
+ });
58
+ }
59
+ /** blockchain.block.headers (plural — returns a range of consecutive headers) */
60
+ export function blockHeaders(ctx, params) {
61
+ const startHeight = validateNonNegativeInt(params[0]);
62
+ if (startHeight === null)
63
+ return invalidParams("Invalid start_height");
64
+ let count = validateNonNegativeInt(params[1]);
65
+ if (count === null)
66
+ return invalidParams("Invalid count");
67
+ // Clamp count to maximum
68
+ count = Math.min(count, MAX_HEADERS_PER_REQUEST);
69
+ // Clamp to available headers
70
+ const tip = ctx.node.getTip();
71
+ if (tip) {
72
+ count = Math.min(count, tip.height - startHeight + 1);
73
+ }
74
+ count = Math.max(count, 0);
75
+ // Collect headers
76
+ let hex = "";
77
+ let actual = 0;
78
+ for (let h = startHeight; h < startHeight + count; h++) {
79
+ const header = ctx.node.getHeader(h);
80
+ if (!header)
81
+ break;
82
+ hex += header.hex;
83
+ actual++;
84
+ }
85
+ const result = {
86
+ count: actual,
87
+ hex,
88
+ max: MAX_HEADERS_PER_REQUEST,
89
+ };
90
+ // Optional checkpoint proof
91
+ if (params[2] !== undefined && params[2] !== null) {
92
+ const cpHeight = validateNonNegativeInt(params[2]);
93
+ if (cpHeight === null)
94
+ return invalidParams("Invalid cp_height");
95
+ if (actual > 0 && cpHeight >= startHeight + actual - 1 && cpHeight <= MAX_CHECKPOINT_HEIGHT) {
96
+ if (tip && cpHeight <= tip.height) {
97
+ const hashes = collectHeaderHashes(ctx, cpHeight);
98
+ if (hashes) {
99
+ // Prove the last header in the returned range
100
+ const lastHeight = startHeight + actual - 1;
101
+ const proof = computeHeaderMerkleBranch(hashes, lastHeight);
102
+ result.branch = proof.branch;
103
+ result.root = proof.root;
104
+ }
105
+ }
106
+ }
107
+ }
108
+ return ok(result);
109
+ }
110
+ /** blockchain.header.get — retrieve a single header by height or hash. */
111
+ export function headerGet(ctx, params) {
112
+ const param = params[0];
113
+ let header;
114
+ if (typeof param === "number") {
115
+ const height = validateNonNegativeInt(param);
116
+ if (height === null)
117
+ return invalidParams("Invalid height");
118
+ header = ctx.node.getHeader(height);
119
+ }
120
+ else if (typeof param === "string" && param.length === 64) {
121
+ header = ctx.node.getHeaderByHash(param);
122
+ }
123
+ else {
124
+ return invalidParams("Expected block height (number) or hash (64-char hex)");
125
+ }
126
+ if (!header)
127
+ return err(ERR_BAD_REQUEST, "Invalid height");
128
+ return ok(formatHeaderResponse(header));
129
+ }
130
+ /** blockchain.headers.get_tip — return the current chain tip. */
131
+ export function headersGetTip(ctx, _params) {
132
+ const tip = ctx.node.getTip();
133
+ if (!tip)
134
+ return err(ERR_BAD_REQUEST, "No blocks available");
135
+ return ok(formatHeaderResponse(tip));
136
+ }
137
+ /** blockchain.headers.subscribe */
138
+ export function headersSubscribe(ctx, _params) {
139
+ const tip = ctx.node.getTip();
140
+ if (!tip) {
141
+ return err(ERR_BAD_REQUEST, "No blocks available");
142
+ }
143
+ if (ctx.subscribeHeaders) {
144
+ ctx.subscribeHeaders();
145
+ }
146
+ return ok(formatHeaderResponse(tip));
147
+ }
148
+ /** blockchain.headers.unsubscribe */
149
+ export function headersUnsubscribe(ctx, _params) {
150
+ if (!ctx.unsubscribeHeaders) {
151
+ return err(ERR_BAD_REQUEST, "Subscriptions not supported");
152
+ }
153
+ const wasSubscribed = ctx.unsubscribeHeaders();
154
+ return ok(wasSubscribed);
155
+ }
156
+ //# sourceMappingURL=headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers.js","sourceRoot":"","sources":["../src/headers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ export { createDispatch, dispatch, getSupportedMethods } from "./dispatch.js";
2
+ export { blockHeader, blockHeaders, headerGet, headersGetTip, headersSubscribe, headersUnsubscribe, } from "./headers.js";
3
+ export type { Indexer, IndexerConfig, Unsubscribe } from "./indexer.js";
4
+ export { createIndexer } from "./indexer.js";
5
+ export type { AnySchema, ElectrumCashSchema, ElectrumCashSchema_1_5_3, ElectrumCashSchema_1_6_0, ElectrumCashTestSchema, ExtractEntry, ExtractMethod, ExtractParams, ExtractRequestMethod, ExtractReturn, ExtractSubscriptionMethod, OverrideRequests, Schema, SchemaEntry, } from "./schema.js";
6
+ export { getBalance, getHistory, getMempool, getStatus, listUnspent, subscribe, unsubscribe, } from "./scripthash.js";
7
+ export { estimateFee, features, ping, relayFee, version, } from "./server.js";
8
+ export { createTestHandlers } from "./test.js";
9
+ export type { TokenDetails, Utxo } from "./testUtils.js";
10
+ export { randomNFT, randomToken, randomUtxo } from "./testUtils.js";
11
+ export { broadcast, dsproofSubscribe, dsproofUnsubscribe, get, getMerkle, idFromPos, txSubscribe, txUnsubscribe, } from "./transaction.js";
12
+ export type { IndexerTransport } from "./transport.js";
13
+ export { asTransport } from "./transport.js";
14
+ export type { DsproofData, Handler, HandlerResult, ProtocolContext, ProtocolError, } from "./types.js";
15
+ export { ERR_BAD_REQUEST, ERR_DAEMON_ERROR, ERR_INTERNAL, ERR_INVALID_PARAMS, ERR_INVALID_REQUEST, ERR_METHOD_NOT_FOUND, err, formatHeaderResponse, internalError, invalidParams, ok, validateNonNegativeInt, validateOptionalBool, validateScriptHash, validateTxid, } from "./types.js";
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EACN,WAAW,EACX,YAAY,EACZ,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,kBAAkB,GAClB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EACX,SAAS,EACT,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,yBAAyB,EACzB,gBAAgB,EAChB,MAAM,EACN,WAAW,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,UAAU,EACV,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,WAAW,GACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,WAAW,EACX,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,OAAO,GACP,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACN,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAClB,GAAG,EACH,SAAS,EACT,SAAS,EACT,WAAW,EACX,aAAa,GACb,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EACX,WAAW,EACX,OAAO,EACP,aAAa,EACb,eAAe,EACf,aAAa,GACb,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,GAAG,EACH,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,EAAE,EACF,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,GACZ,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ export { createDispatch, dispatch, getSupportedMethods } from "./dispatch.js";
2
+ export { blockHeader, blockHeaders, headerGet, headersGetTip, headersSubscribe, headersUnsubscribe, } from "./headers.js";
3
+ export { createIndexer } from "./indexer.js";
4
+ export { getBalance, getHistory, getMempool, getStatus, listUnspent, subscribe, unsubscribe, } from "./scripthash.js";
5
+ export { estimateFee, features, ping, relayFee, version, } from "./server.js";
6
+ export { createTestHandlers } from "./test.js";
7
+ export { randomNFT, randomToken, randomUtxo } from "./testUtils.js";
8
+ export { broadcast, dsproofSubscribe, dsproofUnsubscribe, get, getMerkle, idFromPos, txSubscribe, txUnsubscribe, } from "./transaction.js";
9
+ export { asTransport } from "./transport.js";
10
+ export { ERR_BAD_REQUEST, ERR_DAEMON_ERROR, ERR_INTERNAL, ERR_INVALID_PARAMS, ERR_INVALID_REQUEST, ERR_METHOD_NOT_FOUND, err, formatHeaderResponse, internalError, invalidParams, ok, validateNonNegativeInt, validateOptionalBool, validateScriptHash, validateTxid, } from "./types.js";
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC9E,OAAO,EACN,WAAW,EACX,YAAY,EACZ,SAAS,EACT,aAAa,EACb,gBAAgB,EAChB,kBAAkB,GAClB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAiB7C,OAAO,EACN,UAAU,EACV,UAAU,EACV,UAAU,EACV,SAAS,EACT,WAAW,EACX,SAAS,EACT,WAAW,GACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACN,WAAW,EACX,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,OAAO,GACP,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACpE,OAAO,EACN,SAAS,EACT,gBAAgB,EAChB,kBAAkB,EAClB,GAAG,EACH,SAAS,EACT,SAAS,EACT,WAAW,EACX,aAAa,GACb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAQ7C,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,GAAG,EACH,oBAAoB,EACpB,aAAa,EACb,aAAa,EACb,EAAE,EACF,sBAAsB,EACtB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,GACZ,MAAM,YAAY,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { Node, NodeConfig } from "@mem-cash/core";
2
+ import type { ElectrumCashTestSchema, ExtractParams, ExtractRequestMethod, ExtractReturn, ExtractSubscriptionMethod, Schema } from "./schema.js";
3
+ /** Function that tears down a subscription. */
4
+ export type Unsubscribe = () => Promise<void>;
5
+ /** Configuration for the Indexer Electrum instance. */
6
+ export interface IndexerConfig extends NodeConfig {
7
+ /** Server version string (default: "mem-cash/0.1"). */
8
+ readonly serverVersion?: string;
9
+ /** Genesis hash (default: BCH mainnet). */
10
+ readonly genesisHash?: string;
11
+ /** CashAddress prefix for address encoding (default: "bitcoincash"). */
12
+ readonly addressPrefix?: string;
13
+ /** Server banner text. */
14
+ readonly banner?: string;
15
+ /** Server donation address. */
16
+ readonly donationAddress?: string;
17
+ /** Disable test.* RPC handlers. Set to true to exclude them (e.g. in production). */
18
+ readonly disableTestHandlers?: boolean;
19
+ }
20
+ /** A core Node wrapped with Electrum RPC dispatch. */
21
+ export interface Indexer<S extends Schema = ElectrumCashTestSchema> extends Node {
22
+ /**
23
+ * Dispatch an Electrum RPC method.
24
+ * Params can be a positional array or a named-parameter object.
25
+ * Returns the unwrapped result; throws on RPC error.
26
+ */
27
+ readonly request: <M extends ExtractRequestMethod<S>>(method: M, params?: ExtractParams<S, M>) => Promise<ExtractReturn<S, M>>;
28
+ /**
29
+ * Subscribe to an Electrum method. The callback receives the initial
30
+ * result immediately and subsequent notifications as they occur.
31
+ * Returns an unsubscribe function.
32
+ */
33
+ readonly subscribe: <M extends ExtractSubscriptionMethod<S>>(method: M, params: ExtractParams<S, M>, callback: (data: ExtractReturn<S, M>) => void) => Promise<Unsubscribe>;
34
+ }
35
+ /**
36
+ * Create a Indexer instance: a core Node with Electrum RPC dispatch.
37
+ *
38
+ * All `test.*` RPC methods are available via `request()`.
39
+ * Core node methods (`submitTransaction`, `mine`, etc.) are available directly.
40
+ */
41
+ export declare function createIndexer(config?: IndexerConfig): Indexer;
42
+ //# sourceMappingURL=indexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.d.ts","sourceRoot":"","sources":["../src/indexer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,UAAU,EAAgB,MAAM,gBAAgB,CAAC;AAIrE,OAAO,KAAK,EACX,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,aAAa,EACb,yBAAyB,EACzB,MAAM,EACN,MAAM,aAAa,CAAC;AAQrB,+CAA+C;AAC/C,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9C,uDAAuD;AACvD,MAAM,WAAW,aAAc,SAAQ,UAAU;IAChD,uDAAuD;IACvD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,2CAA2C;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,wEAAwE;IACxE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,0BAA0B;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,+BAA+B;IAC/B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;IAClC,qFAAqF;IACrF,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACvC;AAED,sDAAsD;AACtD,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,sBAAsB,CAAE,SAAQ,IAAI;IAC/E;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,SAAS,oBAAoB,CAAC,CAAC,CAAC,EACnD,MAAM,EAAE,CAAC,EACT,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,KACxB,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAElC;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,yBAAyB,CAAC,CAAC,CAAC,EAC1D,MAAM,EAAE,CAAC,EACT,MAAM,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,EAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,KACzC,OAAO,CAAC,WAAW,CAAC,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CA8N7D"}