solana-ts 0.1.0

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 (48) hide show
  1. package/README.md +139 -0
  2. package/dist/engine.d.ts +62 -0
  3. package/dist/engine.d.ts.map +1 -0
  4. package/dist/engine.js +302 -0
  5. package/dist/engine.js.map +1 -0
  6. package/dist/index.d.ts +3 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +51 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/persistence.d.ts +21 -0
  11. package/dist/persistence.d.ts.map +1 -0
  12. package/dist/persistence.js +141 -0
  13. package/dist/persistence.js.map +1 -0
  14. package/dist/rpc/dispatcher.d.ts +47 -0
  15. package/dist/rpc/dispatcher.d.ts.map +1 -0
  16. package/dist/rpc/dispatcher.js +63 -0
  17. package/dist/rpc/dispatcher.js.map +1 -0
  18. package/dist/rpc/methods.d.ts +4 -0
  19. package/dist/rpc/methods.d.ts.map +1 -0
  20. package/dist/rpc/methods.js +263 -0
  21. package/dist/rpc/methods.js.map +1 -0
  22. package/dist/rpc/subscriptions.d.ts +14 -0
  23. package/dist/rpc/subscriptions.d.ts.map +1 -0
  24. package/dist/rpc/subscriptions.js +111 -0
  25. package/dist/rpc/subscriptions.js.map +1 -0
  26. package/dist/server.d.ts +6 -0
  27. package/dist/server.d.ts.map +1 -0
  28. package/dist/server.js +104 -0
  29. package/dist/server.js.map +1 -0
  30. package/dist/test.d.ts +2 -0
  31. package/dist/test.d.ts.map +1 -0
  32. package/dist/test.js +518 -0
  33. package/dist/test.js.map +1 -0
  34. package/dist/types.d.ts +40 -0
  35. package/dist/types.d.ts.map +1 -0
  36. package/dist/types.js +29 -0
  37. package/dist/types.js.map +1 -0
  38. package/package.json +31 -0
  39. package/src/engine.ts +401 -0
  40. package/src/index.ts +72 -0
  41. package/src/persistence.ts +189 -0
  42. package/src/rpc/dispatcher.ts +94 -0
  43. package/src/rpc/methods.ts +312 -0
  44. package/src/rpc/subscriptions.ts +158 -0
  45. package/src/server.ts +127 -0
  46. package/src/test.ts +674 -0
  47. package/src/types.ts +68 -0
  48. package/tsconfig.json +19 -0
package/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # solana-ts
2
+
3
+ A zero-idle-CPU local Solana RPC simulator powered by [LiteSVM](https://litesvm.com). Drop-in replacement for `solana-test-validator` that starts instantly, uses no CPU when idle, and persists state to a SQLite file.
4
+
5
+ ## Why
6
+
7
+ `solana-test-validator` ships a full validator binary — PoH, gossip, turbine, replay, leader schedule, voting — and burns CPU even when nothing is happening. This project strips all of that away and keeps only what matters for local app testing: an in-process SVM execution engine behind a Solana-compatible JSON-RPC server.
8
+
9
+ - Starts in under a second
10
+ - Zero CPU at idle (no slot ticking, no block production loop)
11
+ - Transactions execute synchronously and are immediately "confirmed"
12
+ - State persists to a single SQLite file across restarts
13
+ - Wire-compatible with `@solana/web3.js` v1 `Connection`
14
+
15
+ ## Quick start
16
+
17
+ ```bash
18
+ pnpm install
19
+ pnpm dev
20
+ ```
21
+
22
+ The server listens on `http://127.0.0.1:8899` (HTTP JSON-RPC) and `ws://127.0.0.1:8900` (WebSocket PubSub).
23
+
24
+ Connect from any Solana app:
25
+
26
+ ```typescript
27
+ import { Connection } from "@solana/web3.js";
28
+
29
+ const connection = new Connection("http://localhost:8899", "confirmed");
30
+ ```
31
+
32
+ ## CLI
33
+
34
+ ```
35
+ solana-ts [options]
36
+
37
+ Options:
38
+ -H, --host <address> Bind address (default: "127.0.0.1")
39
+ -p, --port <number> HTTP/WS port (default: 8899)
40
+ -l, --ledger <path> SQLite database path (default: ~/.solana-ts/ledger.db)
41
+ --reset Clear ledger on start
42
+ --transaction-history <n> Max transactions to retain (default: 5000)
43
+ --log-level <level> error | warn | info | debug (default: "info")
44
+ -q, --quiet Suppress all output except errors
45
+ -V, --version Output version number
46
+ -h, --help Display help
47
+ ```
48
+
49
+ Examples:
50
+
51
+ ```bash
52
+ # Start with default settings
53
+ pnpm dev
54
+
55
+ # Bind to all interfaces on port 9000, fresh ledger each time
56
+ pnpm dev -- --host 0.0.0.0 --port 9000 --reset
57
+
58
+ # Use a specific ledger file
59
+ pnpm dev -- --ledger ./my-ledger.db
60
+ ```
61
+
62
+ ## Supported RPC methods
63
+
64
+ | Method | Notes |
65
+ |---|---|
66
+ | `getVersion` | |
67
+ | `getHealth` | |
68
+ | `getSlot` | |
69
+ | `getBlockHeight` | |
70
+ | `getLatestBlockhash` | |
71
+ | `isBlockhashValid` | |
72
+ | `getBalance` | |
73
+ | `getAccountInfo` | base64 encoding |
74
+ | `getMultipleAccounts` | base64 encoding |
75
+ | `getMinimumBalanceForRentExemption` | |
76
+ | `requestAirdrop` | |
77
+ | `sendTransaction` | base58 and base64 encoding |
78
+ | `simulateTransaction` | |
79
+ | `getSignatureStatuses` | |
80
+ | `getTransaction` | JSON-decoded format |
81
+ | `getEpochInfo` | |
82
+ | `getGenesisHash` | Static value |
83
+ | `getRecentBlockhash` | Legacy compat |
84
+ | `getFeeForMessage` | Returns 5000 |
85
+ | `getIdentity` | |
86
+
87
+ **WebSocket subscriptions:**
88
+
89
+ | Method | Notes |
90
+ |---|---|
91
+ | `signatureSubscribe` / `signatureUnsubscribe` | Required by `confirmTransaction` |
92
+
93
+ ## Architecture
94
+
95
+ ```
96
+ @solana/web3.js ─── HTTP JSON-RPC ──→ RPC Dispatcher ──→ Method Handlers
97
+ ─── WebSocket ──────→ Subscription Mgr ─┘ │
98
+ SVM Engine
99
+ ┌────┴────┐
100
+ LiteSVM SQLite
101
+ ```
102
+
103
+ Transactions execute synchronously inside LiteSVM. After each transaction, modified account state is persisted to SQLite. On restart, accounts and slot counter are restored from the database.
104
+
105
+ WebSocket runs on port+1 (e.g. 8900) to match the convention used by `@solana/web3.js`, which derives the WS URL as `rpc_port + 1`.
106
+
107
+ ## Persistence
108
+
109
+ State is stored in a single SQLite file (default `~/.solana-ts/ledger.db`):
110
+
111
+ - **accounts** — address, lamports, data, owner, executable flag, rent epoch
112
+ - **transactions** — signature, slot, raw bytes, JSON metadata, block time
113
+ - **metadata** — key-value pairs (slot counter, etc.)
114
+
115
+ Use `--reset` to clear all state on startup.
116
+
117
+ ## Tests
118
+
119
+ ```bash
120
+ pnpm test
121
+ ```
122
+
123
+ Runs 36 tests covering basic RPC methods, airdrop/transfer flows, and persistence across server restarts (balance restore, slot resume, transaction history, `--reset` behavior, transacting on restored state).
124
+
125
+ ## Project structure
126
+
127
+ ```
128
+ src/
129
+ index.ts CLI entry point
130
+ server.ts HTTP + WebSocket server
131
+ engine.ts LiteSVM wrapper with persistence
132
+ persistence.ts SQLite storage layer
133
+ types.ts Shared types and logger
134
+ rpc/
135
+ dispatcher.ts JSON-RPC 2.0 routing
136
+ methods.ts RPC method handlers
137
+ subscriptions.ts WebSocket subscription manager
138
+ test.ts Integration tests
139
+ ```
@@ -0,0 +1,62 @@
1
+ import { type AccountInfo } from "@solana/web3.js";
2
+ import type { TransactionMeta, ServerConfig } from "./types.js";
3
+ type AccountInfoBytes = AccountInfo<Uint8Array>;
4
+ export interface SendTransactionResult {
5
+ signature: string;
6
+ slot: number;
7
+ meta: TransactionMeta;
8
+ }
9
+ export interface SimulateTransactionResult {
10
+ err: unknown | null;
11
+ logs: string[];
12
+ unitsConsumed: number;
13
+ }
14
+ export interface StoredTransaction {
15
+ signature: string;
16
+ slot: number;
17
+ blockTime: number;
18
+ meta: TransactionMeta;
19
+ data: Buffer;
20
+ }
21
+ type SignatureCallback = (err: unknown | null) => void;
22
+ export declare class SvmEngine {
23
+ private svm;
24
+ private persistence;
25
+ private slot;
26
+ private maxTxHistory;
27
+ private confirmedSignatures;
28
+ private signatureListeners;
29
+ private currentBlockhash;
30
+ private lastValidBlockHeight;
31
+ constructor(config: ServerConfig);
32
+ private restoreAccounts;
33
+ private refreshBlockhash;
34
+ private advanceSlot;
35
+ private persistAccounts;
36
+ private notifySignature;
37
+ getBalance(address: string): bigint | null;
38
+ getAccountInfo(address: string): AccountInfoBytes | null;
39
+ getLatestBlockhash(): {
40
+ blockhash: string;
41
+ lastValidBlockHeight: number;
42
+ };
43
+ getSlot(): number;
44
+ getBlockHeight(): number;
45
+ isBlockhashValid(blockhash: string): boolean;
46
+ getMinimumBalanceForRentExemption(dataLen: number): bigint;
47
+ requestAirdrop(address: string, lamports: bigint): SendTransactionResult;
48
+ sendTransaction(base64Tx: string): SendTransactionResult;
49
+ simulateTransaction(base64Tx: string): SimulateTransactionResult;
50
+ getSignatureStatuses(signatures: string[]): (null | {
51
+ slot: number;
52
+ confirmations: number | null;
53
+ err: unknown | null;
54
+ confirmationStatus: string;
55
+ })[];
56
+ getTransaction(signature: string): StoredTransaction | null;
57
+ onSignatureConfirmation(signature: string, callback: SignatureCallback): number;
58
+ removeSignatureListener(signature: string, index: number): void;
59
+ close(): void;
60
+ }
61
+ export {};
62
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,KAAK,EAAc,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG5E,KAAK,gBAAgB,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;AAEhD,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,yBAAyB;IACxC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,KAAK,iBAAiB,GAAG,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC;AAkCvD,qBAAa,SAAS;IACpB,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,mBAAmB,CAAqB;IAChD,OAAO,CAAC,kBAAkB,CAA0C;IACpE,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,oBAAoB,CAAa;gBAE7B,MAAM,EAAE,YAAY;IAwBhC,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,WAAW;IAKnB,OAAO,CAAC,eAAe;IAsBvB,OAAO,CAAC,eAAe;IAWvB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAI1C,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAIxD,kBAAkB,IAAI;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,oBAAoB,EAAE,MAAM,CAAC;KAC9B;IAOD,OAAO,IAAI,MAAM;IAIjB,cAAc,IAAI,MAAM;IAIxB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI5C,iCAAiC,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAI1D,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,qBAAqB;IAwCxE,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,qBAAqB;IA0DxD,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,yBAAyB;IAyBhE,oBAAoB,CAClB,UAAU,EAAE,MAAM,EAAE,GACnB,CAAC,IAAI,GAAG;QACT,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;QAC7B,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;QACpB,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAAC,EAAE;IA2BJ,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAa3D,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,MAAM;IAa/E,uBAAuB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAU/D,KAAK,IAAI,IAAI;CAKd"}
package/dist/engine.js ADDED
@@ -0,0 +1,302 @@
1
+ import { LiteSVM, } from "litesvm";
2
+ import { PublicKey, VersionedTransaction, Transaction, } from "@solana/web3.js";
3
+ import bs58 from "bs58";
4
+ import { Persistence } from "./persistence.js";
5
+ import { log } from "./types.js";
6
+ function isFailedMeta(result) {
7
+ return typeof result.err === "function";
8
+ }
9
+ function parseTransactionBytes(bytes) {
10
+ const isVersioned = (bytes[0] & 0x80) !== 0;
11
+ if (isVersioned) {
12
+ const tx = VersionedTransaction.deserialize(bytes);
13
+ return {
14
+ tx,
15
+ accountKeys: [...tx.message.staticAccountKeys],
16
+ numSignatures: tx.signatures.length,
17
+ isVersioned: true,
18
+ };
19
+ }
20
+ const tx = Transaction.from(Buffer.from(bytes));
21
+ const msg = tx.compileMessage();
22
+ return {
23
+ tx,
24
+ accountKeys: [...msg.accountKeys],
25
+ numSignatures: tx.signatures.length,
26
+ isVersioned: false,
27
+ };
28
+ }
29
+ export class SvmEngine {
30
+ svm;
31
+ persistence;
32
+ slot;
33
+ maxTxHistory;
34
+ confirmedSignatures = new Set();
35
+ signatureListeners = new Map();
36
+ currentBlockhash = "";
37
+ lastValidBlockHeight = 0;
38
+ constructor(config) {
39
+ this.persistence = new Persistence(config.ledgerPath);
40
+ this.maxTxHistory = config.transactionHistory;
41
+ if (config.reset) {
42
+ this.persistence.clear();
43
+ log.info("Ledger cleared");
44
+ }
45
+ this.svm = new LiteSVM();
46
+ this.svm.withTransactionHistory(BigInt(config.transactionHistory));
47
+ const savedSlot = this.persistence.getMeta("slot");
48
+ this.slot = savedSlot ? parseInt(savedSlot, 10) : 1;
49
+ if (this.slot > 1) {
50
+ this.svm.warpToSlot(BigInt(this.slot));
51
+ }
52
+ this.restoreAccounts();
53
+ this.refreshBlockhash();
54
+ log.info(`SVM engine initialized at slot ${this.slot}`);
55
+ }
56
+ restoreAccounts() {
57
+ const accounts = this.persistence.getAllAccounts();
58
+ if (accounts.length === 0)
59
+ return;
60
+ for (const row of accounts) {
61
+ const pubkey = new PublicKey(row.address);
62
+ const info = {
63
+ data: row.data ? new Uint8Array(row.data) : new Uint8Array(0),
64
+ executable: row.executable === 1,
65
+ lamports: Number(row.lamports),
66
+ owner: new PublicKey(row.owner),
67
+ rentEpoch: row.rent_epoch,
68
+ };
69
+ this.svm.setAccount(pubkey, info);
70
+ }
71
+ log.info(`Restored ${accounts.length} accounts from ledger`);
72
+ }
73
+ refreshBlockhash() {
74
+ this.currentBlockhash = this.svm.latestBlockhash();
75
+ this.lastValidBlockHeight = this.slot + 300;
76
+ }
77
+ advanceSlot() {
78
+ this.slot++;
79
+ this.persistence.setMeta("slot", String(this.slot));
80
+ }
81
+ persistAccounts(keys) {
82
+ const rows = [];
83
+ for (const key of keys) {
84
+ const info = this.svm.getAccount(key);
85
+ if (info) {
86
+ rows.push({
87
+ address: key.toBase58(),
88
+ lamports: BigInt(info.lamports),
89
+ data: info.data.length > 0 ? Buffer.from(info.data) : null,
90
+ owner: info.owner.toBase58(),
91
+ executable: info.executable ? 1 : 0,
92
+ rent_epoch: info.rentEpoch ?? 0,
93
+ });
94
+ }
95
+ else {
96
+ this.persistence.deleteAccount(key.toBase58());
97
+ }
98
+ }
99
+ if (rows.length > 0) {
100
+ this.persistence.upsertAccounts(rows);
101
+ }
102
+ }
103
+ notifySignature(signature, err) {
104
+ this.confirmedSignatures.add(signature);
105
+ const listeners = this.signatureListeners.get(signature);
106
+ if (listeners) {
107
+ for (const cb of listeners)
108
+ cb(err);
109
+ this.signatureListeners.delete(signature);
110
+ }
111
+ }
112
+ // --- Public API ---
113
+ getBalance(address) {
114
+ return this.svm.getBalance(new PublicKey(address));
115
+ }
116
+ getAccountInfo(address) {
117
+ return this.svm.getAccount(new PublicKey(address));
118
+ }
119
+ getLatestBlockhash() {
120
+ return {
121
+ blockhash: this.currentBlockhash,
122
+ lastValidBlockHeight: this.lastValidBlockHeight,
123
+ };
124
+ }
125
+ getSlot() {
126
+ return this.slot;
127
+ }
128
+ getBlockHeight() {
129
+ return this.slot;
130
+ }
131
+ isBlockhashValid(blockhash) {
132
+ return blockhash === this.currentBlockhash;
133
+ }
134
+ getMinimumBalanceForRentExemption(dataLen) {
135
+ return this.svm.minimumBalanceForRentExemption(BigInt(dataLen));
136
+ }
137
+ requestAirdrop(address, lamports) {
138
+ const pubkey = new PublicKey(address);
139
+ const result = this.svm.airdrop(pubkey, lamports);
140
+ if (!result) {
141
+ throw new Error("Airdrop returned null");
142
+ }
143
+ const txErr = isFailedMeta(result) ? result.err().toString() : null;
144
+ const meta = isFailedMeta(result) ? result.meta() : result;
145
+ const sigBytes = meta.signature();
146
+ const signature = bs58.encode(sigBytes);
147
+ this.advanceSlot();
148
+ this.persistAccounts([pubkey]);
149
+ const txMeta = {
150
+ fee: 0,
151
+ err: txErr,
152
+ logs: meta.logs(),
153
+ computeUnitsConsumed: Number(meta.computeUnitsConsumed()),
154
+ preBalances: [],
155
+ postBalances: [],
156
+ };
157
+ this.persistence.upsertTransaction({
158
+ signature,
159
+ slot: this.slot,
160
+ data: Buffer.alloc(0),
161
+ meta: JSON.stringify(txMeta),
162
+ block_time: Math.floor(Date.now() / 1000),
163
+ });
164
+ this.notifySignature(signature, txErr);
165
+ this.refreshBlockhash();
166
+ log.info(`Airdrop ${lamports} lamports to ${address} -> ${signature}`);
167
+ return { signature, slot: this.slot, meta: txMeta };
168
+ }
169
+ sendTransaction(base64Tx) {
170
+ const bytes = Buffer.from(base64Tx, "base64");
171
+ const { tx, accountKeys, numSignatures } = parseTransactionBytes(bytes);
172
+ const preBalances = accountKeys.map((k) => {
173
+ const bal = this.svm.getBalance(k);
174
+ return bal !== null ? Number(bal) : 0;
175
+ });
176
+ const result = this.svm.sendTransaction(tx);
177
+ const failed = isFailedMeta(result);
178
+ const txErr = failed ? result.err().toString() : null;
179
+ const meta = failed ? result.meta() : result;
180
+ const sigBytes = meta.signature();
181
+ const signature = bs58.encode(sigBytes);
182
+ const postBalances = accountKeys.map((k) => {
183
+ const bal = this.svm.getBalance(k);
184
+ return bal !== null ? Number(bal) : 0;
185
+ });
186
+ const fee = failed
187
+ ? 0
188
+ : numSignatures * 5000;
189
+ this.advanceSlot();
190
+ this.persistAccounts(accountKeys);
191
+ const txMeta = {
192
+ fee,
193
+ err: txErr,
194
+ logs: meta.logs(),
195
+ computeUnitsConsumed: Number(meta.computeUnitsConsumed()),
196
+ preBalances,
197
+ postBalances,
198
+ };
199
+ this.persistence.upsertTransaction({
200
+ signature,
201
+ slot: this.slot,
202
+ data: Buffer.from(bytes),
203
+ meta: JSON.stringify(txMeta),
204
+ block_time: Math.floor(Date.now() / 1000),
205
+ });
206
+ this.persistence.pruneTransactions(this.maxTxHistory);
207
+ this.notifySignature(signature, txErr);
208
+ this.refreshBlockhash();
209
+ if (failed) {
210
+ log.warn(`Transaction failed: ${signature} - ${txErr}`);
211
+ throw new Error(`Transaction simulation failed: ${txErr}`);
212
+ }
213
+ log.info(`Transaction confirmed: ${signature}`);
214
+ return { signature, slot: this.slot, meta: txMeta };
215
+ }
216
+ simulateTransaction(base64Tx) {
217
+ const bytes = Buffer.from(base64Tx, "base64");
218
+ const { tx } = parseTransactionBytes(bytes);
219
+ const result = this.svm.simulateTransaction(tx);
220
+ if ("err" in result && typeof result.err === "function") {
221
+ const failed = result;
222
+ const meta = failed.meta();
223
+ return {
224
+ err: failed.err().toString(),
225
+ logs: meta.logs(),
226
+ unitsConsumed: Number(meta.computeUnitsConsumed()),
227
+ };
228
+ }
229
+ const simInfo = result;
230
+ const meta = simInfo.meta();
231
+ return {
232
+ err: null,
233
+ logs: meta.logs(),
234
+ unitsConsumed: Number(meta.computeUnitsConsumed()),
235
+ };
236
+ }
237
+ getSignatureStatuses(signatures) {
238
+ return signatures.map((sig) => {
239
+ if (this.confirmedSignatures.has(sig)) {
240
+ const stored = this.persistence.getTransaction(sig);
241
+ const meta = stored?.meta ? JSON.parse(stored.meta) : null;
242
+ return {
243
+ slot: stored?.slot ?? this.slot,
244
+ confirmations: null,
245
+ err: meta?.err ?? null,
246
+ confirmationStatus: "confirmed",
247
+ };
248
+ }
249
+ const stored = this.persistence.getTransaction(sig);
250
+ if (stored) {
251
+ this.confirmedSignatures.add(sig);
252
+ const meta = stored.meta ? JSON.parse(stored.meta) : null;
253
+ return {
254
+ slot: stored.slot,
255
+ confirmations: null,
256
+ err: meta?.err ?? null,
257
+ confirmationStatus: "confirmed",
258
+ };
259
+ }
260
+ return null;
261
+ });
262
+ }
263
+ getTransaction(signature) {
264
+ const stored = this.persistence.getTransaction(signature);
265
+ if (!stored)
266
+ return null;
267
+ return {
268
+ signature: stored.signature,
269
+ slot: stored.slot,
270
+ blockTime: stored.block_time,
271
+ meta: stored.meta ? JSON.parse(stored.meta) : null,
272
+ data: stored.data,
273
+ };
274
+ }
275
+ onSignatureConfirmation(signature, callback) {
276
+ if (this.confirmedSignatures.has(signature)) {
277
+ const stored = this.persistence.getTransaction(signature);
278
+ const meta = stored?.meta ? JSON.parse(stored.meta) : null;
279
+ process.nextTick(() => callback(meta?.err ?? null));
280
+ return -1;
281
+ }
282
+ const listeners = this.signatureListeners.get(signature) ?? [];
283
+ listeners.push(callback);
284
+ this.signatureListeners.set(signature, listeners);
285
+ return listeners.length - 1;
286
+ }
287
+ removeSignatureListener(signature, index) {
288
+ const listeners = this.signatureListeners.get(signature);
289
+ if (listeners && index >= 0 && index < listeners.length) {
290
+ listeners.splice(index, 1);
291
+ if (listeners.length === 0) {
292
+ this.signatureListeners.delete(signature);
293
+ }
294
+ }
295
+ }
296
+ close() {
297
+ this.persistence.setMeta("slot", String(this.slot));
298
+ this.persistence.close();
299
+ log.info("SVM engine shut down");
300
+ }
301
+ }
302
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ import path from "node:path";
3
+ import os from "node:os";
4
+ import fs from "node:fs";
5
+ import { Command } from "commander";
6
+ import { createServer } from "./server.js";
7
+ import { setLogLevel } from "./types.js";
8
+ const DEFAULT_LEDGER_DIR = path.join(os.homedir(), ".solana-ts");
9
+ const DEFAULT_LEDGER_PATH = path.join(DEFAULT_LEDGER_DIR, "ledger.db");
10
+ const program = new Command();
11
+ program
12
+ .name("solana-ts")
13
+ .description("Zero-idle-CPU local Solana RPC simulator powered by LiteSVM")
14
+ .version("0.1.0")
15
+ .option("-H, --host <address>", "Bind address", "127.0.0.1")
16
+ .option("-p, --port <number>", "HTTP/WS port", "8899")
17
+ .option("-l, --ledger <path>", "SQLite database path", DEFAULT_LEDGER_PATH)
18
+ .option("--reset", "Clear ledger on start", false)
19
+ .option("--transaction-history <number>", "Max transactions to retain", "5000")
20
+ .option("--log-level <level>", "Log level: error | warn | info | debug", "info")
21
+ .option("-q, --quiet", "Suppress all output except errors", false)
22
+ .action(async (opts) => {
23
+ const logLevel = opts.quiet
24
+ ? "error"
25
+ : opts.logLevel;
26
+ setLogLevel(logLevel);
27
+ const ledgerPath = path.resolve(opts.ledger);
28
+ const ledgerDir = path.dirname(ledgerPath);
29
+ if (!fs.existsSync(ledgerDir)) {
30
+ fs.mkdirSync(ledgerDir, { recursive: true });
31
+ }
32
+ const config = {
33
+ host: opts.host,
34
+ port: parseInt(opts.port, 10),
35
+ ledgerPath,
36
+ reset: opts.reset,
37
+ transactionHistory: parseInt(opts.transactionHistory, 10),
38
+ logLevel,
39
+ };
40
+ const server = createServer(config);
41
+ const shutdown = async () => {
42
+ console.log("\nShutting down...");
43
+ await server.stop();
44
+ process.exit(0);
45
+ };
46
+ process.on("SIGINT", shutdown);
47
+ process.on("SIGTERM", shutdown);
48
+ await server.start();
49
+ });
50
+ program.parse();
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AACjE,MAAM,mBAAmB,GAAG,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;AAEvE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,6DAA6D,CAAC;KAC1E,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,sBAAsB,EAAE,cAAc,EAAE,WAAW,CAAC;KAC3D,MAAM,CAAC,qBAAqB,EAAE,cAAc,EAAE,MAAM,CAAC;KACrD,MAAM,CACL,qBAAqB,EACrB,sBAAsB,EACtB,mBAAmB,CACpB;KACA,MAAM,CAAC,SAAS,EAAE,uBAAuB,EAAE,KAAK,CAAC;KACjD,MAAM,CACL,gCAAgC,EAChC,4BAA4B,EAC5B,MAAM,CACP;KACA,MAAM,CACL,qBAAqB,EACrB,wCAAwC,EACxC,MAAM,CACP;KACA,MAAM,CAAC,aAAa,EAAE,mCAAmC,EAAE,KAAK,CAAC;KACjE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK;QACzB,CAAC,CAAC,OAAO;QACT,CAAC,CAAE,IAAI,CAAC,QAAqC,CAAC;IAChD,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEtB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,MAAM,MAAM,GAAiB;QAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7B,UAAU;QACV,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,kBAAkB,EAAE,QAAQ,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;QACzD,QAAQ;KACT,CAAC;IAEF,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAEpC,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAEhC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { AccountRow, TransactionRow } from "./types.js";
2
+ export declare class Persistence {
3
+ private db;
4
+ private stmts;
5
+ constructor(dbPath: string);
6
+ private migrate;
7
+ private prepareStatements;
8
+ upsertAccount(account: AccountRow): void;
9
+ upsertAccounts(accounts: AccountRow[]): void;
10
+ getAccount(address: string): AccountRow | undefined;
11
+ getAllAccounts(): AccountRow[];
12
+ deleteAccount(address: string): void;
13
+ upsertTransaction(tx: TransactionRow): void;
14
+ getTransaction(signature: string): TransactionRow | undefined;
15
+ pruneTransactions(maxCount: number): void;
16
+ setMeta(key: string, value: string): void;
17
+ getMeta(key: string): string | undefined;
18
+ clear(): void;
19
+ close(): void;
20
+ }
21
+ //# sourceMappingURL=persistence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../src/persistence.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7D,qBAAa,WAAW;IACtB,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,KAAK,CAWX;gBAEU,MAAM,EAAE,MAAM;IAQ1B,OAAO,CAAC,OAAO;IA0Bf,OAAO,CAAC,iBAAiB;IAmDzB,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAWxC,cAAc,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;IAO5C,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAQnD,cAAc,IAAI,UAAU,EAAE;IAU9B,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMpC,iBAAiB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI;IAU3C,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI7D,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IASzC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAOxC,KAAK,IAAI,IAAI;IAMb,KAAK,IAAI,IAAI;CAGd"}