@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.
- package/README.md +143 -0
- package/dist/address.d.ts +20 -0
- package/dist/address.d.ts.map +1 -0
- package/dist/address.js +51 -0
- package/dist/address.js.map +1 -0
- package/dist/dispatch.d.ts +18 -0
- package/dist/dispatch.d.ts.map +1 -0
- package/dist/dispatch.js +108 -0
- package/dist/dispatch.js.map +1 -0
- package/dist/headers.d.ts +14 -0
- package/dist/headers.d.ts.map +1 -0
- package/dist/headers.js +156 -0
- package/dist/headers.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer.d.ts +42 -0
- package/dist/indexer.d.ts.map +1 -0
- package/dist/indexer.js +216 -0
- package/dist/indexer.js.map +1 -0
- package/dist/memCash.d.ts +40 -0
- package/dist/memCash.d.ts.map +1 -0
- package/dist/memCash.js +212 -0
- package/dist/memCash.js.map +1 -0
- package/dist/mempool.d.ts +6 -0
- package/dist/mempool.d.ts.map +1 -0
- package/dist/mempool.js +46 -0
- package/dist/mempool.js.map +1 -0
- package/dist/schema.d.ts +638 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +3 -0
- package/dist/schema.js.map +1 -0
- package/dist/scripthash.d.ts +18 -0
- package/dist/scripthash.d.ts.map +1 -0
- package/dist/scripthash.js +164 -0
- package/dist/scripthash.js.map +1 -0
- package/dist/server.d.ts +20 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +120 -0
- package/dist/server.js.map +1 -0
- package/dist/stubs.d.ts +12 -0
- package/dist/stubs.d.ts.map +1 -0
- package/dist/stubs.js +16 -0
- package/dist/stubs.js.map +1 -0
- package/dist/test.d.ts +8 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +240 -0
- package/dist/test.js.map +1 -0
- package/dist/testUtils.d.ts +20 -0
- package/dist/testUtils.d.ts.map +1 -0
- package/dist/testUtils.js +29 -0
- package/dist/testUtils.js.map +1 -0
- package/dist/transaction.d.ts +28 -0
- package/dist/transaction.d.ts.map +1 -0
- package/dist/transaction.js +318 -0
- package/dist/transaction.js.map +1 -0
- package/dist/transport.d.ts +24 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/transport.js +16 -0
- package/dist/transport.js.map +1 -0
- package/dist/types.d.ts +85 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +58 -0
- package/dist/types.js.map +1 -0
- package/dist/utxo.d.ts +4 -0
- package/dist/utxo.d.ts.map +1 -0
- package/dist/utxo.js +39 -0
- package/dist/utxo.js.map +1 -0
- 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"}
|
package/dist/address.js
ADDED
|
@@ -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"}
|
package/dist/dispatch.js
ADDED
|
@@ -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"}
|
package/dist/headers.js
ADDED
|
@@ -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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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|