@shieldedtech/moth-wallet 0.2.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 (230) hide show
  1. package/README.md +62 -0
  2. package/dist/contract/args-parser.d.ts +29 -0
  3. package/dist/contract/args-parser.d.ts.map +1 -0
  4. package/dist/contract/args-parser.js +123 -0
  5. package/dist/contract/args-parser.js.map +1 -0
  6. package/dist/contract/artifact-loader.d.ts +26 -0
  7. package/dist/contract/artifact-loader.d.ts.map +1 -0
  8. package/dist/contract/artifact-loader.js +129 -0
  9. package/dist/contract/artifact-loader.js.map +1 -0
  10. package/dist/contract/call.d.ts +32 -0
  11. package/dist/contract/call.d.ts.map +1 -0
  12. package/dist/contract/call.js +245 -0
  13. package/dist/contract/call.js.map +1 -0
  14. package/dist/contract/deploy.d.ts +36 -0
  15. package/dist/contract/deploy.d.ts.map +1 -0
  16. package/dist/contract/deploy.js +388 -0
  17. package/dist/contract/deploy.js.map +1 -0
  18. package/dist/contract/fungible-token.d.ts +40 -0
  19. package/dist/contract/fungible-token.d.ts.map +1 -0
  20. package/dist/contract/fungible-token.js +88 -0
  21. package/dist/contract/fungible-token.js.map +1 -0
  22. package/dist/contract/initial-private-state.d.ts +18 -0
  23. package/dist/contract/initial-private-state.d.ts.map +1 -0
  24. package/dist/contract/initial-private-state.js +44 -0
  25. package/dist/contract/initial-private-state.js.map +1 -0
  26. package/dist/contract/maintenance.d.ts +72 -0
  27. package/dist/contract/maintenance.d.ts.map +1 -0
  28. package/dist/contract/maintenance.js +430 -0
  29. package/dist/contract/maintenance.js.map +1 -0
  30. package/dist/contract/state.d.ts +16 -0
  31. package/dist/contract/state.d.ts.map +1 -0
  32. package/dist/contract/state.js +18 -0
  33. package/dist/contract/state.js.map +1 -0
  34. package/dist/contract/witness-loader.d.ts +3 -0
  35. package/dist/contract/witness-loader.d.ts.map +1 -0
  36. package/dist/contract/witness-loader.js +27 -0
  37. package/dist/contract/witness-loader.js.map +1 -0
  38. package/dist/daemon/api-keys.d.ts +66 -0
  39. package/dist/daemon/api-keys.d.ts.map +1 -0
  40. package/dist/daemon/api-keys.js +222 -0
  41. package/dist/daemon/api-keys.js.map +1 -0
  42. package/dist/daemon/audit-log.d.ts +65 -0
  43. package/dist/daemon/audit-log.d.ts.map +1 -0
  44. package/dist/daemon/audit-log.js +73 -0
  45. package/dist/daemon/audit-log.js.map +1 -0
  46. package/dist/daemon/client.d.ts +63 -0
  47. package/dist/daemon/client.d.ts.map +1 -0
  48. package/dist/daemon/client.js +214 -0
  49. package/dist/daemon/client.js.map +1 -0
  50. package/dist/daemon/confirmation-queue.d.ts +46 -0
  51. package/dist/daemon/confirmation-queue.d.ts.map +1 -0
  52. package/dist/daemon/confirmation-queue.js +92 -0
  53. package/dist/daemon/confirmation-queue.js.map +1 -0
  54. package/dist/daemon/index.d.ts +23 -0
  55. package/dist/daemon/index.d.ts.map +1 -0
  56. package/dist/daemon/index.js +26 -0
  57. package/dist/daemon/index.js.map +1 -0
  58. package/dist/daemon/protocol.d.ts +40 -0
  59. package/dist/daemon/protocol.d.ts.map +1 -0
  60. package/dist/daemon/protocol.js +104 -0
  61. package/dist/daemon/protocol.js.map +1 -0
  62. package/dist/daemon/server.d.ts +158 -0
  63. package/dist/daemon/server.d.ts.map +1 -0
  64. package/dist/daemon/server.js +297 -0
  65. package/dist/daemon/server.js.map +1 -0
  66. package/dist/daemon/wallet-handlers.d.ts +37 -0
  67. package/dist/daemon/wallet-handlers.d.ts.map +1 -0
  68. package/dist/daemon/wallet-handlers.js +533 -0
  69. package/dist/daemon/wallet-handlers.js.map +1 -0
  70. package/dist/daemon/wallet-rpc-parsers.d.ts +14 -0
  71. package/dist/daemon/wallet-rpc-parsers.d.ts.map +1 -0
  72. package/dist/daemon/wallet-rpc-parsers.js +259 -0
  73. package/dist/daemon/wallet-rpc-parsers.js.map +1 -0
  74. package/dist/daemon/wallet-rpc-types.d.ts +138 -0
  75. package/dist/daemon/wallet-rpc-types.d.ts.map +1 -0
  76. package/dist/daemon/wallet-rpc-types.js +11 -0
  77. package/dist/daemon/wallet-rpc-types.js.map +1 -0
  78. package/dist/diagnostics/fs-timing-store.d.ts +29 -0
  79. package/dist/diagnostics/fs-timing-store.d.ts.map +1 -0
  80. package/dist/diagnostics/fs-timing-store.js +81 -0
  81. package/dist/diagnostics/fs-timing-store.js.map +1 -0
  82. package/dist/diagnostics/timings.d.ts +64 -0
  83. package/dist/diagnostics/timings.d.ts.map +1 -0
  84. package/dist/diagnostics/timings.js +100 -0
  85. package/dist/diagnostics/timings.js.map +1 -0
  86. package/dist/index.d.ts +37 -0
  87. package/dist/index.d.ts.map +1 -0
  88. package/dist/index.js +47 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/network/indexer-client.d.ts +66 -0
  91. package/dist/network/indexer-client.d.ts.map +1 -0
  92. package/dist/network/indexer-client.js +112 -0
  93. package/dist/network/indexer-client.js.map +1 -0
  94. package/dist/network/node-client.d.ts +27 -0
  95. package/dist/network/node-client.d.ts.map +1 -0
  96. package/dist/network/node-client.js +94 -0
  97. package/dist/network/node-client.js.map +1 -0
  98. package/dist/proof/client.d.ts +15 -0
  99. package/dist/proof/client.d.ts.map +1 -0
  100. package/dist/proof/client.js +77 -0
  101. package/dist/proof/client.js.map +1 -0
  102. package/dist/proof/provider.d.ts +12 -0
  103. package/dist/proof/provider.d.ts.map +1 -0
  104. package/dist/proof/provider.js +96 -0
  105. package/dist/proof/provider.js.map +1 -0
  106. package/dist/providers/index.d.ts +2 -0
  107. package/dist/providers/index.d.ts.map +1 -0
  108. package/dist/providers/index.js +2 -0
  109. package/dist/providers/index.js.map +1 -0
  110. package/dist/providers/midnight-provider.d.ts +11 -0
  111. package/dist/providers/midnight-provider.d.ts.map +1 -0
  112. package/dist/providers/midnight-provider.js +30 -0
  113. package/dist/providers/midnight-provider.js.map +1 -0
  114. package/dist/storage/adapter.d.ts +8 -0
  115. package/dist/storage/adapter.d.ts.map +1 -0
  116. package/dist/storage/adapter.js +2 -0
  117. package/dist/storage/adapter.js.map +1 -0
  118. package/dist/storage/fs-adapter.d.ts +14 -0
  119. package/dist/storage/fs-adapter.d.ts.map +1 -0
  120. package/dist/storage/fs-adapter.js +126 -0
  121. package/dist/storage/fs-adapter.js.map +1 -0
  122. package/dist/storage/safe-path.d.ts +13 -0
  123. package/dist/storage/safe-path.d.ts.map +1 -0
  124. package/dist/storage/safe-path.js +35 -0
  125. package/dist/storage/safe-path.js.map +1 -0
  126. package/dist/sync/activity.d.ts +53 -0
  127. package/dist/sync/activity.d.ts.map +1 -0
  128. package/dist/sync/activity.js +92 -0
  129. package/dist/sync/activity.js.map +1 -0
  130. package/dist/sync/dust-registration-estimate.d.ts +54 -0
  131. package/dist/sync/dust-registration-estimate.d.ts.map +1 -0
  132. package/dist/sync/dust-registration-estimate.js +103 -0
  133. package/dist/sync/dust-registration-estimate.js.map +1 -0
  134. package/dist/sync/node-sync-store.d.ts +10 -0
  135. package/dist/sync/node-sync-store.d.ts.map +1 -0
  136. package/dist/sync/node-sync-store.js +42 -0
  137. package/dist/sync/node-sync-store.js.map +1 -0
  138. package/dist/sync/operations.d.ts +138 -0
  139. package/dist/sync/operations.d.ts.map +1 -0
  140. package/dist/sync/operations.js +395 -0
  141. package/dist/sync/operations.js.map +1 -0
  142. package/dist/sync/preseed-parts.d.ts +18 -0
  143. package/dist/sync/preseed-parts.d.ts.map +1 -0
  144. package/dist/sync/preseed-parts.js +33 -0
  145. package/dist/sync/preseed-parts.js.map +1 -0
  146. package/dist/sync/preseed.d.ts +95 -0
  147. package/dist/sync/preseed.d.ts.map +1 -0
  148. package/dist/sync/preseed.js +365 -0
  149. package/dist/sync/preseed.js.map +1 -0
  150. package/dist/sync/progress.d.ts +45 -0
  151. package/dist/sync/progress.d.ts.map +1 -0
  152. package/dist/sync/progress.js +51 -0
  153. package/dist/sync/progress.js.map +1 -0
  154. package/dist/sync/sdk-dedup.d.ts +53 -0
  155. package/dist/sync/sdk-dedup.d.ts.map +1 -0
  156. package/dist/sync/sdk-dedup.js +134 -0
  157. package/dist/sync/sdk-dedup.js.map +1 -0
  158. package/dist/sync/sync-store.d.ts +33 -0
  159. package/dist/sync/sync-store.d.ts.map +1 -0
  160. package/dist/sync/sync-store.js +45 -0
  161. package/dist/sync/sync-store.js.map +1 -0
  162. package/dist/sync/wallet-sync.d.ts +153 -0
  163. package/dist/sync/wallet-sync.d.ts.map +1 -0
  164. package/dist/sync/wallet-sync.js +943 -0
  165. package/dist/sync/wallet-sync.js.map +1 -0
  166. package/dist/types/errors.d.ts +18 -0
  167. package/dist/types/errors.d.ts.map +1 -0
  168. package/dist/types/errors.js +33 -0
  169. package/dist/types/errors.js.map +1 -0
  170. package/dist/types/exit-codes.d.ts +8 -0
  171. package/dist/types/exit-codes.d.ts.map +1 -0
  172. package/dist/types/exit-codes.js +7 -0
  173. package/dist/types/exit-codes.js.map +1 -0
  174. package/dist/types/index.d.ts +6 -0
  175. package/dist/types/index.d.ts.map +1 -0
  176. package/dist/types/index.js +3 -0
  177. package/dist/types/index.js.map +1 -0
  178. package/dist/types/network.d.ts +65 -0
  179. package/dist/types/network.d.ts.map +1 -0
  180. package/dist/types/network.js +108 -0
  181. package/dist/types/network.js.map +1 -0
  182. package/dist/types/tokens.d.ts +3 -0
  183. package/dist/types/tokens.d.ts.map +1 -0
  184. package/dist/types/tokens.js +11 -0
  185. package/dist/types/tokens.js.map +1 -0
  186. package/dist/types/transaction.d.ts +13 -0
  187. package/dist/types/transaction.d.ts.map +1 -0
  188. package/dist/types/transaction.js +2 -0
  189. package/dist/types/transaction.js.map +1 -0
  190. package/dist/types/wallet.d.ts +82 -0
  191. package/dist/types/wallet.d.ts.map +1 -0
  192. package/dist/types/wallet.js +2 -0
  193. package/dist/types/wallet.js.map +1 -0
  194. package/dist/wallet/address-validate.d.ts +7 -0
  195. package/dist/wallet/address-validate.d.ts.map +1 -0
  196. package/dist/wallet/address-validate.js +28 -0
  197. package/dist/wallet/address-validate.js.map +1 -0
  198. package/dist/wallet/address.d.ts +32 -0
  199. package/dist/wallet/address.d.ts.map +1 -0
  200. package/dist/wallet/address.js +107 -0
  201. package/dist/wallet/address.js.map +1 -0
  202. package/dist/wallet/app-secret.d.ts +15 -0
  203. package/dist/wallet/app-secret.d.ts.map +1 -0
  204. package/dist/wallet/app-secret.js +45 -0
  205. package/dist/wallet/app-secret.js.map +1 -0
  206. package/dist/wallet/balance-format.d.ts +12 -0
  207. package/dist/wallet/balance-format.d.ts.map +1 -0
  208. package/dist/wallet/balance-format.js +51 -0
  209. package/dist/wallet/balance-format.js.map +1 -0
  210. package/dist/wallet/batch-transfer.d.ts +36 -0
  211. package/dist/wallet/batch-transfer.d.ts.map +1 -0
  212. package/dist/wallet/batch-transfer.js +93 -0
  213. package/dist/wallet/batch-transfer.js.map +1 -0
  214. package/dist/wallet/keystore.d.ts +16 -0
  215. package/dist/wallet/keystore.d.ts.map +1 -0
  216. package/dist/wallet/keystore.js +76 -0
  217. package/dist/wallet/keystore.js.map +1 -0
  218. package/dist/wallet/manager.d.ts +77 -0
  219. package/dist/wallet/manager.d.ts.map +1 -0
  220. package/dist/wallet/manager.js +474 -0
  221. package/dist/wallet/manager.js.map +1 -0
  222. package/dist/wallet/mnemonic.d.ts +5 -0
  223. package/dist/wallet/mnemonic.d.ts.map +1 -0
  224. package/dist/wallet/mnemonic.js +28 -0
  225. package/dist/wallet/mnemonic.js.map +1 -0
  226. package/dist/wallet/sign-message.d.ts +20 -0
  227. package/dist/wallet/sign-message.d.ts.map +1 -0
  228. package/dist/wallet/sign-message.js +58 -0
  229. package/dist/wallet/sign-message.js.map +1 -0
  230. package/package.json +55 -0
@@ -0,0 +1,214 @@
1
+ // Daemon client: opens a Unix-domain socket connection, performs the
2
+ // version handshake, exposes a typed call() interface and clean shutdown.
3
+ //
4
+ // connectDaemon() is intentionally forgiving — if there's no socket file,
5
+ // or the connect is refused, it returns null instead of throwing. Callers
6
+ // (the CLI) treat null as "no daemon available, run standalone", which
7
+ // keeps the daemon optional rather than a hard dependency.
8
+ import { createConnection } from 'node:net';
9
+ import { randomUUID } from 'node:crypto';
10
+ import { encodeFrame, FrameDecoder, PROTOCOL_VERSION, DaemonProtocolError, } from './protocol.js';
11
+ /**
12
+ * Try to connect to the daemon at the given Unix-socket path. Stage-1
13
+ * entry point — kept for backwards compatibility. For TCP transports
14
+ * use `connectDaemonTcp(host, port)` or the unified
15
+ * `connectDaemonBind(bind)`.
16
+ *
17
+ * Returns:
18
+ * - DaemonClient on successful connect + handshake
19
+ * - null if the file doesn't exist, the connect is refused, or the
20
+ * handshake reports an incompatible protocol version
21
+ *
22
+ * Throws only on genuinely-unexpected conditions (filesystem error,
23
+ * malformed daemon response). Network-style failures are folded into
24
+ * null so the CLI can fall back to standalone without a try/catch.
25
+ */
26
+ export async function connectDaemon(socketPath, opts = {}) {
27
+ return connectDaemonBind({ transport: 'unix', socketPath }, opts);
28
+ }
29
+ /**
30
+ * Stage-2 entry point. Connect to a daemon listening on loopback TCP
31
+ * (or, at stage 3, a TLS-terminating reverse proxy in front of the
32
+ * daemon's loopback bind). Same fall-back-to-null semantics as
33
+ * `connectDaemon`.
34
+ */
35
+ export async function connectDaemonTcp(host, port, opts = {}) {
36
+ return connectDaemonBind({ transport: 'tcp', host, port }, opts);
37
+ }
38
+ /**
39
+ * Transport-agnostic entry point. Both `connectDaemon` and
40
+ * `connectDaemonTcp` route through here. The handshake + dispatcher
41
+ * setup is identical across transports — only the underlying socket
42
+ * factory differs.
43
+ */
44
+ export async function connectDaemonBind(bind, opts = {}) {
45
+ const log = opts.onLog ?? (() => { });
46
+ const defaultTimeoutMs = opts.defaultTimeoutMs ?? 10_000;
47
+ const sock = await openSocket(bind, log);
48
+ if (!sock)
49
+ return null;
50
+ const dispatcher = new ClientDispatcher(sock, defaultTimeoutMs, log);
51
+ let handshake;
52
+ try {
53
+ handshake = await dispatcher.call('version', undefined, {
54
+ timeoutMs: 2000,
55
+ });
56
+ }
57
+ catch (err) {
58
+ log('warn', `daemon handshake failed: ${err.message}`);
59
+ dispatcher.close();
60
+ return null;
61
+ }
62
+ if (handshake.protocol !== PROTOCOL_VERSION) {
63
+ log('warn', `daemon speaks protocol ${handshake.protocol}; client expects ${PROTOCOL_VERSION}`);
64
+ dispatcher.close();
65
+ return null;
66
+ }
67
+ // Stage-2 auth handshake. Only performed when the caller passes
68
+ // a token; daemons running without an auth handler (typical Unix
69
+ // case) will reject an `auth` call with METHOD_NOT_FOUND, so we
70
+ // gate on the token's presence rather than probing.
71
+ let apiKeyId;
72
+ if (opts.token) {
73
+ try {
74
+ const authResult = await dispatcher.call('auth', { token: opts.token }, { timeoutMs: 2000 });
75
+ apiKeyId = authResult.apiKeyId;
76
+ }
77
+ catch (err) {
78
+ const code = err instanceof DaemonProtocolError ? err.code : 'INTERNAL_ERROR';
79
+ log('warn', `daemon auth failed (${code}): ${err.message}`);
80
+ dispatcher.close();
81
+ return null;
82
+ }
83
+ }
84
+ return {
85
+ call: dispatcher.call.bind(dispatcher),
86
+ close: dispatcher.close.bind(dispatcher),
87
+ get closed() {
88
+ return dispatcher.closed;
89
+ },
90
+ daemonVersion: handshake.daemon,
91
+ apiKeyId,
92
+ };
93
+ }
94
+ function openSocket(bind, log) {
95
+ const target = bind.transport === 'unix'
96
+ ? bind.socketPath
97
+ : `${bind.host}:${bind.port}`;
98
+ return new Promise((resolve) => {
99
+ const sock = bind.transport === 'unix'
100
+ ? createConnection(bind.socketPath)
101
+ : createConnection({ host: bind.host, port: bind.port });
102
+ const onConnect = () => {
103
+ sock.off('error', onError);
104
+ resolve(sock);
105
+ };
106
+ const onError = (err) => {
107
+ sock.off('connect', onConnect);
108
+ sock.destroy();
109
+ // ENOENT (no socket file) and ECONNREFUSED (no listener) both
110
+ // mean "no daemon available" rather than a real error. Apply
111
+ // the same fall-back-to-null to both transports.
112
+ if (err.code === 'ENOENT' || err.code === 'ECONNREFUSED') {
113
+ log('info', `no daemon at ${target} (${err.code})`);
114
+ }
115
+ else {
116
+ log('warn', `daemon connect failed: ${err.message}`);
117
+ }
118
+ resolve(null);
119
+ };
120
+ sock.once('connect', onConnect);
121
+ sock.once('error', onError);
122
+ });
123
+ }
124
+ class ClientDispatcher {
125
+ closed = false;
126
+ sock;
127
+ defaultTimeoutMs;
128
+ decoder = new FrameDecoder();
129
+ pending = new Map();
130
+ log;
131
+ constructor(sock, defaultTimeoutMs, log) {
132
+ this.sock = sock;
133
+ this.defaultTimeoutMs = defaultTimeoutMs;
134
+ this.log = log;
135
+ sock.on('data', (chunk) => this.onData(chunk));
136
+ sock.on('close', () => this.failAllPending(new DaemonProtocolError('CLOSED', 'daemon connection closed')));
137
+ sock.on('error', (err) => {
138
+ this.log('warn', `daemon socket error: ${err.message}`);
139
+ this.failAllPending(new DaemonProtocolError('CLOSED', err.message));
140
+ });
141
+ }
142
+ call(method, params, opts = {}) {
143
+ if (this.closed) {
144
+ return Promise.reject(new DaemonProtocolError('CLOSED', 'daemon client is closed'));
145
+ }
146
+ const id = randomUUID();
147
+ const timeoutMs = opts.timeoutMs ?? this.defaultTimeoutMs;
148
+ return new Promise((resolve, reject) => {
149
+ const timer = setTimeout(() => {
150
+ this.pending.delete(id);
151
+ reject(new DaemonProtocolError('TIMEOUT', `call ${method} timed out after ${timeoutMs}ms`));
152
+ }, timeoutMs);
153
+ this.pending.set(id, {
154
+ resolve: resolve,
155
+ reject,
156
+ timer,
157
+ });
158
+ try {
159
+ this.sock.write(encodeFrame({ id, type: 'request', method, params }));
160
+ }
161
+ catch (err) {
162
+ clearTimeout(timer);
163
+ this.pending.delete(id);
164
+ reject(err);
165
+ }
166
+ });
167
+ }
168
+ close() {
169
+ if (this.closed)
170
+ return;
171
+ this.closed = true;
172
+ this.failAllPending(new DaemonProtocolError('CLOSED', 'client closed'));
173
+ this.sock.destroy();
174
+ }
175
+ onData(chunk) {
176
+ let frames;
177
+ try {
178
+ frames = this.decoder.push(chunk);
179
+ }
180
+ catch (err) {
181
+ this.log('warn', `daemon sent malformed frame: ${err.message}`);
182
+ this.close();
183
+ return;
184
+ }
185
+ for (const frame of frames) {
186
+ if (frame.type !== 'response') {
187
+ this.log('warn', `daemon sent unexpected frame type ${frame.type}`);
188
+ continue;
189
+ }
190
+ const waiter = this.pending.get(frame.id);
191
+ if (!waiter) {
192
+ // Unsolicited response — possible if a timeout already fired.
193
+ // Drop silently rather than warn; that's expected under timeout.
194
+ continue;
195
+ }
196
+ this.pending.delete(frame.id);
197
+ clearTimeout(waiter.timer);
198
+ if (frame.error) {
199
+ waiter.reject(new DaemonProtocolError(frame.error.code, frame.error.message));
200
+ }
201
+ else {
202
+ waiter.resolve(frame.result);
203
+ }
204
+ }
205
+ }
206
+ failAllPending(err) {
207
+ for (const [, waiter] of this.pending) {
208
+ clearTimeout(waiter.timer);
209
+ waiter.reject(err);
210
+ }
211
+ this.pending.clear();
212
+ }
213
+ }
214
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/daemon/client.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,0EAA0E;AAC1E,EAAE;AACF,0EAA0E;AAC1E,0EAA0E;AAC1E,uEAAuE;AACvE,2DAA2D;AAE3D,OAAO,EAAC,gBAAgB,EAAc,MAAM,UAAU,CAAC;AACvD,OAAO,EAAC,UAAU,EAAC,MAAM,aAAa,CAAC;AACvC,OAAO,EACL,WAAW,EACX,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,GAGpB,MAAM,eAAe,CAAC;AAkCvB;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAkB,EAClB,OAA6B,EAAE;IAE/B,OAAO,iBAAiB,CAAC,EAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAC,EAAE,IAAI,CAAC,CAAC;AAClE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,IAAY,EACZ,OAA6B,EAAE;IAE/B,OAAO,iBAAiB,CAAC,EAAC,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAC,EAAE,IAAI,CAAC,CAAC;AACjE,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,IAAgB,EAChB,OAA6B,EAAE;IAE/B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACrC,MAAM,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,IAAI,MAAM,CAAC;IAEzD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAEvB,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,CAAC,CAAC;IAErE,IAAI,SAA6C,CAAC;IAClD,IAAI,CAAC;QACH,SAAS,GAAG,MAAM,UAAU,CAAC,IAAI,CAAqC,SAAS,EAAE,SAAS,EAAE;YAC1F,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,MAAM,EAAE,4BAA6B,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAClE,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,SAAS,CAAC,QAAQ,KAAK,gBAAgB,EAAE,CAAC;QAC5C,GAAG,CACD,MAAM,EACN,0BAA0B,SAAS,CAAC,QAAQ,oBAAoB,gBAAgB,EAAE,CACnF,CAAC;QACF,UAAU,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gEAAgE;IAChE,iEAAiE;IACjE,gEAAgE;IAChE,oDAAoD;IACpD,IAAI,QAA4B,CAAC;IACjC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,MAAM,UAAU,CAAC,IAAI,CACtC,MAAM,EACN,EAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAC,EACnB,EAAC,SAAS,EAAE,IAAI,EAAC,CAClB,CAAC;YACF,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC;QACjC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,GAAG,GAAG,YAAY,mBAAmB,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,gBAAgB,CAAC;YAC9E,GAAG,CAAC,MAAM,EAAE,uBAAuB,IAAI,MAAO,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YACvE,UAAU,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;QACtC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;QACxC,IAAI,MAAM;YACR,OAAO,UAAU,CAAC,MAAM,CAAC;QAC3B,CAAC;QACD,aAAa,EAAE,SAAS,CAAC,MAAM;QAC/B,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CACjB,IAAgB,EAChB,GAA4D;IAE5D,MAAM,MAAM,GACV,IAAI,CAAC,SAAS,KAAK,MAAM;QACvB,CAAC,CAAC,IAAI,CAAC,UAAU;QACjB,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IAClC,OAAO,IAAI,OAAO,CAAgB,CAAC,OAAO,EAAE,EAAE;QAC5C,MAAM,IAAI,GACR,IAAI,CAAC,SAAS,KAAK,MAAM;YACvB,CAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC;YACnC,CAAC,CAAC,gBAAgB,CAAC,EAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAC,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,GAAG,EAAE;YACrB,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC;QACF,MAAM,OAAO,GAAG,CAAC,GAA0B,EAAE,EAAE;YAC7C,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,8DAA8D;YAC9D,6DAA6D;YAC7D,iDAAiD;YACjD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBACzD,GAAG,CAAC,MAAM,EAAE,gBAAgB,MAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,EAAE,0BAA0B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACvD,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,gBAAgB;IACpB,MAAM,GAAG,KAAK,CAAC;IAEE,IAAI,CAAS;IACb,gBAAgB,CAAS;IACzB,OAAO,GAAG,IAAI,YAAY,EAAE,CAAC;IAC7B,OAAO,GAAG,IAAI,GAAG,EAG/B,CAAC;IACa,GAAG,CAA0D;IAE9E,YACE,IAAY,EACZ,gBAAwB,EACxB,GAA4D;QAE5D,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QAEf,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,mBAAmB,CAAC,QAAQ,EAAE,0BAA0B,CAAC,CAAC,CAAC,CAAC;QAC3G,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACvB,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,wBAAwB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACxD,IAAI,CAAC,cAAc,CAAC,IAAI,mBAAmB,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QACtE,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAI,MAAc,EAAE,MAAe,EAAE,OAA6B,EAAE;QACtE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,mBAAmB,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAC,CAAC;QACtF,CAAC;QACD,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,gBAAgB,CAAC;QAE1D,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxB,MAAM,CAAC,IAAI,mBAAmB,CAAC,SAAS,EAAE,QAAQ,MAAM,oBAAoB,SAAS,IAAI,CAAC,CAAC,CAAC;YAC9F,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE;gBACnB,OAAO,EAAE,OAA+B;gBACxC,MAAM;gBACN,KAAK;aACN,CAAC,CAAC;YAEH,IAAI,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,EAAC,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAC,CAAC,CAAC,CAAC;YACtE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxB,MAAM,CAAC,GAAY,CAAC,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,cAAc,CAAC,IAAI,mBAAmB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC;QACxE,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACtB,CAAC;IAEO,MAAM,CAAC,KAAa;QAC1B,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,gCAAiC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3E,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC9B,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,qCAAqC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;gBACpE,SAAS;YACX,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,8DAA8D;gBAC9D,iEAAiE;gBACjE,SAAS;YACX,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC9B,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;gBAChB,MAAM,CAAC,MAAM,CAAC,IAAI,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,IAAoB,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAChG,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAEO,cAAc,CAAC,GAAU;QAC/B,KAAK,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACtC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF"}
@@ -0,0 +1,46 @@
1
+ export type ConfirmationRequest = {
2
+ readonly id: string;
3
+ readonly summary: string;
4
+ readonly details?: readonly string[];
5
+ };
6
+ export interface ConfirmationQueueOptions {
7
+ /**
8
+ * When true, every request() resolves immediately with true. Intended
9
+ * for non-interactive contexts (tests, server-mode daemons). The
10
+ * onAutoApprove callback, if provided, is invoked for each
11
+ * auto-approval so callers can log it.
12
+ */
13
+ readonly autoApprove?: boolean;
14
+ /** Hook called for every auto-approved request — useful for audit. */
15
+ readonly onAutoApprove?: (req: ConfirmationRequest) => void;
16
+ }
17
+ export declare class ConfirmationQueue {
18
+ private readonly items;
19
+ private readonly listeners;
20
+ private readonly autoApprove;
21
+ private readonly onAutoApprove?;
22
+ constructor(opts?: ConfirmationQueueOptions);
23
+ /** Push a request and resolve once the user answers (or immediately
24
+ * if autoApprove is enabled). */
25
+ request(summary: string, details?: readonly string[]): Promise<boolean>;
26
+ /** Head of the queue, or null when empty. The modal uses this to
27
+ * decide whether to render. */
28
+ peek(): ConfirmationRequest | null;
29
+ /** Resolve the head with the given verdict and advance. No-op when
30
+ * empty. */
31
+ resolve(approved: boolean): void;
32
+ /** Resolve every pending request as denied. Used on shutdown so any
33
+ * in-flight RPC calls fail cleanly instead of hanging the daemon. */
34
+ drainAsDenied(): void;
35
+ /** Subscribe to "queue changed" notifications. Returns an
36
+ * unsubscribe function. */
37
+ subscribe(listener: () => void): () => void;
38
+ /** Current depth; primarily for tests and logs. */
39
+ get size(): number;
40
+ /** Whether the queue is in auto-approve mode. The audit log uses
41
+ * this to record `auto-approve` vs `user-approve` decisions on
42
+ * the same code path. */
43
+ get isAutoApprove(): boolean;
44
+ private notify;
45
+ }
46
+ //# sourceMappingURL=confirmation-queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirmation-queue.d.ts","sourceRoot":"","sources":["../../src/daemon/confirmation-queue.ts"],"names":[],"mappings":"AAoBA,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC,CAAC;AAMF,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B,sEAAsE;IACtE,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,mBAAmB,KAAK,IAAI,CAAC;CAC7D;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAU;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAqC;gBAExD,IAAI,GAAE,wBAA6B;IAK/C;sCACkC;IAClC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAYvE;oCACgC;IAChC,IAAI,IAAI,mBAAmB,GAAG,IAAI;IAKlC;iBACa;IACb,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;IAOhC;0EACsE;IACtE,aAAa,IAAI,IAAI;IAMrB;gCAC4B;IAC5B,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAO3C,mDAAmD;IACnD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;8BAE0B;IAC1B,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED,OAAO,CAAC,MAAM;CASf"}
@@ -0,0 +1,92 @@
1
+ // FIFO queue of pending confirmation requests from the daemon's RPC
2
+ // handlers. A handler that needs human approval pushes an entry via
3
+ // request() and awaits the returned Promise. Two execution modes:
4
+ //
5
+ // - interactive (default): consumers like the TUI's ConfirmationModal
6
+ // subscribe to the queue, render the head entry, and resolve the
7
+ // promise once the user answers y/n.
8
+ //
9
+ // - auto-approve (test-only / Web2 service later): every request()
10
+ // resolves immediately with true. Used by `moth daemon serve
11
+ // --auto-approve` to run the daemon without a human in the loop.
12
+ // The summary + details are still emitted via the onAutoApprove
13
+ // callback so they can be logged for audit.
14
+ //
15
+ // Lives in @shieldedtech/moth-wallet so the TUI host and the
16
+ // headless serve command can both depend on it without crossing
17
+ // the TUI's React layer.
18
+ import { randomUUID } from 'node:crypto';
19
+ export class ConfirmationQueue {
20
+ items = [];
21
+ listeners = new Set();
22
+ autoApprove;
23
+ onAutoApprove;
24
+ constructor(opts = {}) {
25
+ this.autoApprove = opts.autoApprove ?? false;
26
+ this.onAutoApprove = opts.onAutoApprove;
27
+ }
28
+ /** Push a request and resolve once the user answers (or immediately
29
+ * if autoApprove is enabled). */
30
+ request(summary, details) {
31
+ if (this.autoApprove) {
32
+ const req = { id: randomUUID(), summary, details };
33
+ this.onAutoApprove?.(req);
34
+ return Promise.resolve(true);
35
+ }
36
+ return new Promise((resolve) => {
37
+ this.items.push({ id: randomUUID(), summary, details, resolve });
38
+ this.notify();
39
+ });
40
+ }
41
+ /** Head of the queue, or null when empty. The modal uses this to
42
+ * decide whether to render. */
43
+ peek() {
44
+ const head = this.items[0];
45
+ return head ? { id: head.id, summary: head.summary, details: head.details } : null;
46
+ }
47
+ /** Resolve the head with the given verdict and advance. No-op when
48
+ * empty. */
49
+ resolve(approved) {
50
+ const head = this.items.shift();
51
+ if (!head)
52
+ return;
53
+ head.resolve(approved);
54
+ this.notify();
55
+ }
56
+ /** Resolve every pending request as denied. Used on shutdown so any
57
+ * in-flight RPC calls fail cleanly instead of hanging the daemon. */
58
+ drainAsDenied() {
59
+ while (this.items.length > 0) {
60
+ this.resolve(false);
61
+ }
62
+ }
63
+ /** Subscribe to "queue changed" notifications. Returns an
64
+ * unsubscribe function. */
65
+ subscribe(listener) {
66
+ this.listeners.add(listener);
67
+ return () => {
68
+ this.listeners.delete(listener);
69
+ };
70
+ }
71
+ /** Current depth; primarily for tests and logs. */
72
+ get size() {
73
+ return this.items.length;
74
+ }
75
+ /** Whether the queue is in auto-approve mode. The audit log uses
76
+ * this to record `auto-approve` vs `user-approve` decisions on
77
+ * the same code path. */
78
+ get isAutoApprove() {
79
+ return this.autoApprove;
80
+ }
81
+ notify() {
82
+ for (const l of this.listeners) {
83
+ try {
84
+ l();
85
+ }
86
+ catch {
87
+ // listener errors must not affect other listeners or the queue
88
+ }
89
+ }
90
+ }
91
+ }
92
+ //# sourceMappingURL=confirmation-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirmation-queue.js","sourceRoot":"","sources":["../../src/daemon/confirmation-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export { PROTOCOL_VERSION, MAX_FRAME_BYTES, DaemonProtocolError, encodeFrame, FrameDecoder, } from './protocol.js';
2
+ export type { Frame, RequestFrame, ResponseFrame, RpcErrorCode } from './protocol.js';
3
+ export { startDaemon } from './server.js';
4
+ export type { DaemonHandle, DaemonOptions, RpcHandler, ConnectionContext, DaemonBind, AuthHandler, AuthResult, Scope } from './server.js';
5
+ export { ApiKeyStore } from './api-keys.js';
6
+ export type { ApiKeyRecord, ApiKeyGenerated, ApiKeyAuthResult } from './api-keys.js';
7
+ export { connectDaemon, connectDaemonTcp, connectDaemonBind } from './client.js';
8
+ export type { DaemonClient, ConnectDaemonOptions } from './client.js';
9
+ export { ConfirmationQueue } from './confirmation-queue.js';
10
+ export type { ConfirmationRequest, ConfirmationQueueOptions } from './confirmation-queue.js';
11
+ export { buildWalletHandlers } from './wallet-handlers.js';
12
+ export type { WalletHandlerDeps } from './wallet-handlers.js';
13
+ export { AuditLog } from './audit-log.js';
14
+ export type { AuditEntry, AuditRpcEntry, AuditLifecycleEntry, AuditDecision, AuditLogOptions, } from './audit-log.js';
15
+ export { parseSubmitTransactionParams, parseTransferTokensParams, parseCallCircuitParams, parseDeployContractParams, parseDustRegisterParams, parseDustDeregisterParams, parseInsertVerifierKeyParams, parseInsertVerifierKeysBatchParams, shortenHex, shortenAddress, } from './wallet-rpc-parsers.js';
16
+ export type { DaemonGetStateResult, DaemonSubmitTransactionParams, DaemonSubmitTransactionResult, DaemonTransferTokensParams, DaemonTransferTokensResult, DaemonCallCircuitParams, DaemonCallCircuitResult, DaemonDeployContractParams, DaemonDeployContractResult, DaemonDustRegisterParams, DaemonDustRegisterResult, DaemonDustDeregisterParams, DaemonDustDeregisterResult, DaemonInsertVerifierKeyParams, DaemonInsertVerifierKeyResult, DaemonInsertVerifierKeysBatchParams, DaemonInsertVerifierKeysBatchResult, } from './wallet-rpc-types.js';
17
+ /**
18
+ * Canonical socket path for a (network, wallet) pair. Sits inside the same
19
+ * `~/.moth/sync/<network>/` directory tree that the wallet sync cache uses,
20
+ * so the L1 0700 directory perms protect both atomically.
21
+ */
22
+ export declare function daemonSocketPath(networkId: string, walletName: string): string;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,YAAY,EAAC,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAC,MAAM,eAAe,CAAC;AAEpF,OAAO,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AACxC,YAAY,EAAC,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,iBAAiB,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAC,MAAM,aAAa,CAAC;AAExI,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,YAAY,EAAC,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAC,MAAM,eAAe,CAAC;AAEnF,OAAO,EAAC,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAC/E,YAAY,EAAC,YAAY,EAAE,oBAAoB,EAAC,MAAM,aAAa,CAAC;AAEpE,OAAO,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAC,mBAAmB,EAAE,wBAAwB,EAAC,MAAM,yBAAyB,CAAC;AAK3F,OAAO,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AACzD,YAAY,EAAC,iBAAiB,EAAC,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AACxC,YAAY,EACV,UAAU,EACV,aAAa,EACb,mBAAmB,EACnB,aAAa,EACb,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,sBAAsB,EACtB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,4BAA4B,EAC5B,kCAAkC,EAClC,UAAU,EACV,cAAc,GACf,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,oBAAoB,EACpB,6BAA6B,EAAE,6BAA6B,EAC5D,0BAA0B,EAAE,0BAA0B,EACtD,uBAAuB,EAAE,uBAAuB,EAChD,0BAA0B,EAAE,0BAA0B,EACtD,wBAAwB,EAAE,wBAAwB,EAClD,0BAA0B,EAAE,0BAA0B,EACtD,6BAA6B,EAAE,6BAA6B,EAC5D,mCAAmC,EAAE,mCAAmC,GACzE,MAAM,uBAAuB,CAAC;AAK/B;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAE9E"}
@@ -0,0 +1,26 @@
1
+ // Public surface of the wallet daemon module.
2
+ // L1 (filesystem perms) lives in server.ts; L3 (per-op confirmation) is the
3
+ // host application's responsibility — it composes its own modal-driven
4
+ // handlers and registers them with startDaemon().
5
+ export { PROTOCOL_VERSION, MAX_FRAME_BYTES, DaemonProtocolError, encodeFrame, FrameDecoder, } from './protocol.js';
6
+ export { startDaemon } from './server.js';
7
+ export { ApiKeyStore } from './api-keys.js';
8
+ export { connectDaemon, connectDaemonTcp, connectDaemonBind } from './client.js';
9
+ export { ConfirmationQueue } from './confirmation-queue.js';
10
+ // Shared RPC handler factory + wire types + parsers. Both the TUI
11
+ // host and the headless serve mode build their handler map by
12
+ // calling buildWalletHandlers(deps) with the same dependency bundle.
13
+ export { buildWalletHandlers } from './wallet-handlers.js';
14
+ export { AuditLog } from './audit-log.js';
15
+ export { parseSubmitTransactionParams, parseTransferTokensParams, parseCallCircuitParams, parseDeployContractParams, parseDustRegisterParams, parseDustDeregisterParams, parseInsertVerifierKeyParams, parseInsertVerifierKeysBatchParams, shortenHex, shortenAddress, } from './wallet-rpc-parsers.js';
16
+ import { join } from 'node:path';
17
+ import { homedir } from 'node:os';
18
+ /**
19
+ * Canonical socket path for a (network, wallet) pair. Sits inside the same
20
+ * `~/.moth/sync/<network>/` directory tree that the wallet sync cache uses,
21
+ * so the L1 0700 directory perms protect both atomically.
22
+ */
23
+ export function daemonSocketPath(networkId, walletName) {
24
+ return join(homedir(), '.moth', 'sync', networkId, `${walletName}.sock`);
25
+ }
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,4EAA4E;AAC5E,uEAAuE;AACvE,kDAAkD;AAElD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACnB,WAAW,EACX,YAAY,GACb,MAAM,eAAe,CAAC;AAIvB,OAAO,EAAC,WAAW,EAAC,MAAM,aAAa,CAAC;AAGxC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAG1C,OAAO,EAAC,aAAa,EAAE,gBAAgB,EAAE,iBAAiB,EAAC,MAAM,aAAa,CAAC;AAG/E,OAAO,EAAC,iBAAiB,EAAC,MAAM,yBAAyB,CAAC;AAG1D,kEAAkE;AAClE,8DAA8D;AAC9D,qEAAqE;AACrE,OAAO,EAAC,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AAGzD,OAAO,EAAC,QAAQ,EAAC,MAAM,gBAAgB,CAAC;AAQxC,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,sBAAsB,EACtB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,4BAA4B,EAC5B,kCAAkC,EAClC,UAAU,EACV,cAAc,GACf,MAAM,yBAAyB,CAAC;AAajC,OAAO,EAAC,IAAI,EAAC,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAC,OAAO,EAAC,MAAM,SAAS,CAAC;AAEhC;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,UAAkB;IACpE,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,UAAU,OAAO,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,40 @@
1
+ export declare const PROTOCOL_VERSION = "moth-wallet-daemon/1";
2
+ /** Bound on a single frame's payload size. Practical state snapshots are well
3
+ * under 1MB today; cap above lets the wire format grow without immediate
4
+ * ceiling changes. */
5
+ export declare const MAX_FRAME_BYTES: number;
6
+ export type RequestFrame = {
7
+ readonly id: string;
8
+ readonly type: 'request';
9
+ readonly method: string;
10
+ readonly params?: unknown;
11
+ };
12
+ export type ResponseFrame = {
13
+ readonly id: string;
14
+ readonly type: 'response';
15
+ readonly result?: unknown;
16
+ readonly error?: {
17
+ readonly code: string;
18
+ readonly message: string;
19
+ };
20
+ };
21
+ export type Frame = RequestFrame | ResponseFrame;
22
+ export type RpcErrorCode = 'METHOD_NOT_FOUND' | 'INVALID_REQUEST' | 'INVALID_PARAMS' | 'INTERNAL_ERROR' | 'CLOSED' | 'TIMEOUT' | 'UNAUTHORIZED';
23
+ export declare class DaemonProtocolError extends Error {
24
+ readonly code: RpcErrorCode;
25
+ constructor(code: RpcErrorCode, message: string);
26
+ }
27
+ export declare function encodeFrame(frame: Frame): Buffer;
28
+ /**
29
+ * Streaming decoder. push() accepts arbitrary chunks; complete frames come
30
+ * out in order, partial bytes stay buffered. Throws DaemonProtocolError on
31
+ * an over-large declared length so the caller can disconnect the peer
32
+ * before allocating.
33
+ */
34
+ export declare class FrameDecoder {
35
+ private buffer;
36
+ push(chunk: Buffer): Frame[];
37
+ /** Bytes still buffered (incomplete frame). Useful for diagnostics/tests. */
38
+ get pending(): number;
39
+ }
40
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/daemon/protocol.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,gBAAgB,yBAAyB,CAAC;AAEvD;;uBAEuB;AACvB,eAAO,MAAM,eAAe,QAAmB,CAAC;AAEhD,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,CAAC,EAAE;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;KAAC,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG,YAAY,GAAG,aAAa,CAAC;AAEjD,MAAM,MAAM,YAAY,GACpB,kBAAkB,GAClB,iBAAiB,GACjB,gBAAgB,GAChB,gBAAgB,GAChB,QAAQ,GACR,SAAS,GACT,cAAc,CAAC;AAEnB,qBAAa,mBAAoB,SAAQ,KAAK;IAE1C,QAAQ,CAAC,IAAI,EAAE,YAAY;gBAAlB,IAAI,EAAE,YAAY,EAC3B,OAAO,EAAE,MAAM;CAKlB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAWhD;AAED;;;;;GAKG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAA2B;IAEzC,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE;IAuB5B,6EAA6E;IAC7E,IAAI,OAAO,IAAI,MAAM,CAEpB;CACF"}
@@ -0,0 +1,104 @@
1
+ // Length-prefixed JSON-over-stream framing for the moth wallet daemon.
2
+ //
3
+ // Wire format: 4-byte big-endian uint32 payload length, then that many bytes
4
+ // of UTF-8 JSON. Streams are bidirectional and full-duplex; either side may
5
+ // emit Request or Response frames at any time, correlated by `id`. There is
6
+ // no built-in keepalive — the underlying Unix stream socket detects
7
+ // peer-close cleanly and that's enough.
8
+ //
9
+ // All sizes are bounded. A frame larger than MAX_FRAME_BYTES is rejected
10
+ // without buffering, so a misbehaving peer can't drive the daemon into an
11
+ // unbounded allocation.
12
+ export const PROTOCOL_VERSION = 'moth-wallet-daemon/1';
13
+ /** Bound on a single frame's payload size. Practical state snapshots are well
14
+ * under 1MB today; cap above lets the wire format grow without immediate
15
+ * ceiling changes. */
16
+ export const MAX_FRAME_BYTES = 16 * 1024 * 1024;
17
+ export class DaemonProtocolError extends Error {
18
+ code;
19
+ constructor(code, message) {
20
+ super(message);
21
+ this.code = code;
22
+ this.name = 'DaemonProtocolError';
23
+ }
24
+ }
25
+ export function encodeFrame(frame) {
26
+ const json = Buffer.from(JSON.stringify(frame), 'utf-8');
27
+ if (json.length > MAX_FRAME_BYTES) {
28
+ throw new DaemonProtocolError('INVALID_REQUEST', `frame too large: ${json.length} bytes (max ${MAX_FRAME_BYTES})`);
29
+ }
30
+ const lenHeader = Buffer.alloc(4);
31
+ lenHeader.writeUInt32BE(json.length, 0);
32
+ return Buffer.concat([lenHeader, json]);
33
+ }
34
+ /**
35
+ * Streaming decoder. push() accepts arbitrary chunks; complete frames come
36
+ * out in order, partial bytes stay buffered. Throws DaemonProtocolError on
37
+ * an over-large declared length so the caller can disconnect the peer
38
+ * before allocating.
39
+ */
40
+ export class FrameDecoder {
41
+ buffer = Buffer.alloc(0);
42
+ push(chunk) {
43
+ this.buffer = this.buffer.length === 0 ? chunk : Buffer.concat([this.buffer, chunk]);
44
+ const out = [];
45
+ while (this.buffer.length >= 4) {
46
+ const payloadLen = this.buffer.readUInt32BE(0);
47
+ if (payloadLen > MAX_FRAME_BYTES) {
48
+ throw new DaemonProtocolError('INVALID_REQUEST', `declared frame length ${payloadLen} exceeds max ${MAX_FRAME_BYTES}`);
49
+ }
50
+ if (this.buffer.length < 4 + payloadLen)
51
+ break;
52
+ const json = this.buffer.subarray(4, 4 + payloadLen).toString('utf-8');
53
+ this.buffer = this.buffer.subarray(4 + payloadLen);
54
+ const parsed = parseFrame(json);
55
+ out.push(parsed);
56
+ }
57
+ return out;
58
+ }
59
+ /** Bytes still buffered (incomplete frame). Useful for diagnostics/tests. */
60
+ get pending() {
61
+ return this.buffer.length;
62
+ }
63
+ }
64
+ function parseFrame(json) {
65
+ let raw;
66
+ try {
67
+ raw = JSON.parse(json);
68
+ }
69
+ catch (err) {
70
+ throw new DaemonProtocolError('INVALID_REQUEST', `frame is not valid JSON: ${err.message}`);
71
+ }
72
+ if (!raw || typeof raw !== 'object') {
73
+ throw new DaemonProtocolError('INVALID_REQUEST', 'frame is not a JSON object');
74
+ }
75
+ const f = raw;
76
+ if (typeof f.id !== 'string') {
77
+ throw new DaemonProtocolError('INVALID_REQUEST', 'frame.id must be a string');
78
+ }
79
+ if (f.type === 'request') {
80
+ if (typeof f.method !== 'string') {
81
+ throw new DaemonProtocolError('INVALID_REQUEST', 'request.method must be a string');
82
+ }
83
+ return { id: f.id, type: 'request', method: f.method, params: f.params };
84
+ }
85
+ if (f.type === 'response') {
86
+ if (f.error !== undefined && f.result !== undefined) {
87
+ throw new DaemonProtocolError('INVALID_REQUEST', 'response cannot carry both result and error');
88
+ }
89
+ if (f.error !== undefined) {
90
+ const e = f.error;
91
+ if (typeof e.code !== 'string' || typeof e.message !== 'string') {
92
+ throw new DaemonProtocolError('INVALID_REQUEST', 'response.error must have string code and message');
93
+ }
94
+ return {
95
+ id: f.id,
96
+ type: 'response',
97
+ error: { code: e.code, message: e.message },
98
+ };
99
+ }
100
+ return { id: f.id, type: 'response', result: f.result };
101
+ }
102
+ throw new DaemonProtocolError('INVALID_REQUEST', `frame.type must be "request" or "response", got ${String(f.type)}`);
103
+ }
104
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/daemon/protocol.ts"],"names":[],"mappings":"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"}