@lerna-labs/hydra-sdk 1.0.0-beta.27 → 1.0.0-beta.29

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.
@@ -30,6 +30,7 @@ export declare class HydraMonitor extends EventEmitter {
30
30
  readonly ws: HydraWebSocket;
31
31
  private _headStatus;
32
32
  private _previousStatus;
33
+ private _headId;
33
34
  private _events;
34
35
  private _stopped;
35
36
  private _reconnecting;
@@ -54,7 +55,14 @@ export declare class HydraMonitor extends EventEmitter {
54
55
  /** The full Greetings message from the most recent connection. */
55
56
  get greetings(): GreetingsMessage | null;
56
57
  /**
57
- * Summary of Hydra head info extracted from the last Greetings.
58
+ * Summary of Hydra head info derived from live state plus the last Greetings.
59
+ *
60
+ * `headStatus` and `headId` reflect the current state tracked from transition
61
+ * messages (`HeadIsInitializing`, `HeadIsOpen`, etc.), not the snapshot taken
62
+ * at connection time. The remaining fields (node version, participants,
63
+ * contestation period, network info) come from the cached Greetings since
64
+ * they are static for the life of the head.
65
+ *
58
66
  * Excludes the full UTxO snapshot to keep payloads small.
59
67
  * Returns `null` if no Greetings has been received yet.
60
68
  */
@@ -37,6 +37,7 @@ export class HydraMonitor extends EventEmitter {
37
37
  ws;
38
38
  _headStatus = 'IDLE';
39
39
  _previousStatus = 'IDLE';
40
+ _headId = null;
40
41
  _events = [];
41
42
  _stopped = true;
42
43
  _reconnecting = false;
@@ -93,7 +94,14 @@ export class HydraMonitor extends EventEmitter {
93
94
  return this.ws.lastGreetings;
94
95
  }
95
96
  /**
96
- * Summary of Hydra head info extracted from the last Greetings.
97
+ * Summary of Hydra head info derived from live state plus the last Greetings.
98
+ *
99
+ * `headStatus` and `headId` reflect the current state tracked from transition
100
+ * messages (`HeadIsInitializing`, `HeadIsOpen`, etc.), not the snapshot taken
101
+ * at connection time. The remaining fields (node version, participants,
102
+ * contestation period, network info) come from the cached Greetings since
103
+ * they are static for the life of the head.
104
+ *
97
105
  * Excludes the full UTxO snapshot to keep payloads small.
98
106
  * Returns `null` if no Greetings has been received yet.
99
107
  */
@@ -104,8 +112,8 @@ export class HydraMonitor extends EventEmitter {
104
112
  const peers = g.env?.configuredPeers;
105
113
  const peerCount = peers ? peers.split(',').filter(Boolean).length : 0;
106
114
  return {
107
- headStatus: g.headStatus,
108
- headId: g.hydraHeadId ?? null,
115
+ headStatus: HYDRA_TO_HEAD_STATUS[this._headStatus],
116
+ headId: this._headId,
109
117
  nodeVersion: g.hydraNodeVersion ?? null,
110
118
  me: g.me.vkey,
111
119
  contestationPeriod: g.env?.contestationPeriod ?? null,
@@ -178,14 +186,25 @@ export class HydraMonitor extends EventEmitter {
178
186
  const mapped = HEAD_STATUS_TO_HYDRA[msg.headStatus];
179
187
  if (mapped)
180
188
  this.updateStatus(mapped);
189
+ const greetingHeadId = msg.hydraHeadId;
190
+ if (greetingHeadId)
191
+ this._headId = greetingHeadId;
181
192
  }
182
193
  else if (msg.tag === 'HeadIsAborted') {
183
194
  this.updateStatus('IDLE');
195
+ this._headId = null;
184
196
  }
185
197
  else {
186
198
  const mapped = TAG_TO_HYDRA[msg.tag];
187
199
  if (mapped)
188
200
  this.updateStatus(mapped);
201
+ // Track headId from transition messages (Greetings may not include
202
+ // it for a fresh node — HeadIsInitializing is the first place it
203
+ // reliably appears). Skipped for HeadIsAborted, which clears it above.
204
+ const msgHeadId = msg.headId;
205
+ if (typeof msgHeadId === 'string' && msgHeadId) {
206
+ this._headId = msgHeadId;
207
+ }
189
208
  }
190
209
  // Error routing
191
210
  if (msg.tag === 'PostTxOnChainFailed' || msg.tag === 'TxInvalid') {
@@ -70,11 +70,22 @@ export declare class Wrangler {
70
70
  shutdownHead(): Promise<void>;
71
71
  /**
72
72
  * Wait for the Hydra head to fully close and finalize.
73
+ *
74
+ * Resolves on the `HeadIsClosed` / `HeadIsFinalized` transition events, **and**
75
+ * on the initial `Greetings` replay if the head is already at `Closed` or
76
+ * `Final`. Rejects fast if the head is `Idle` (no head exists to close).
77
+ *
73
78
  * @param timeoutMs - Maximum time to wait in milliseconds.
74
79
  */
75
80
  waitForHeadClose(timeoutMs?: number): Promise<void>;
76
81
  /**
77
82
  * Wait for the Hydra head to reach the `Open` state.
83
+ *
84
+ * Resolves on the `HeadIsOpen` transition event, **and** on the initial
85
+ * `Greetings` replay if the head is already `Open`. Rejects fast if the
86
+ * head is in a terminal or shutting-down state (`Closed`, `FanoutPossible`,
87
+ * `Final`) — a new head must be started from a fresh node.
88
+ *
78
89
  * @param commitArgs - UTxO to commit into the head during initialization.
79
90
  * @param timeoutMs - Maximum time to wait in milliseconds.
80
91
  */
package/dist/wrangler.js CHANGED
@@ -140,6 +140,11 @@ export class Wrangler {
140
140
  }
141
141
  /**
142
142
  * Wait for the Hydra head to fully close and finalize.
143
+ *
144
+ * Resolves on the `HeadIsClosed` / `HeadIsFinalized` transition events, **and**
145
+ * on the initial `Greetings` replay if the head is already at `Closed` or
146
+ * `Final`. Rejects fast if the head is `Idle` (no head exists to close).
147
+ *
143
148
  * @param timeoutMs - Maximum time to wait in milliseconds.
144
149
  */
145
150
  async waitForHeadClose(timeoutMs = 180000) {
@@ -153,14 +158,30 @@ export class Wrangler {
153
158
  case 'ReadyToFanout':
154
159
  this.ws.send({ tag: 'Fanout' });
155
160
  break;
156
- case 'Greetings':
157
- this.onGreetings(message.headStatus).catch((err) => reject(new Error(`Greetings handler failed: ${String(err)}`)));
161
+ case 'Greetings': {
162
+ const status = message.headStatus;
163
+ if (status === 'Closed' || status === 'Final') {
164
+ resolve();
165
+ return;
166
+ }
167
+ if (status === 'Idle') {
168
+ reject(new Error(`Cannot wait for head to close: head is "Idle" — no head exists to close`));
169
+ return;
170
+ }
171
+ this.onGreetings(status).catch((err) => reject(new Error(`Greetings handler failed: ${String(err)}`)));
158
172
  break;
173
+ }
159
174
  }
160
175
  }, timeoutMs, 'Timeout waiting for head to close!');
161
176
  }
162
177
  /**
163
178
  * Wait for the Hydra head to reach the `Open` state.
179
+ *
180
+ * Resolves on the `HeadIsOpen` transition event, **and** on the initial
181
+ * `Greetings` replay if the head is already `Open`. Rejects fast if the
182
+ * head is in a terminal or shutting-down state (`Closed`, `FanoutPossible`,
183
+ * `Final`) — a new head must be started from a fresh node.
184
+ *
164
185
  * @param commitArgs - UTxO to commit into the head during initialization.
165
186
  * @param timeoutMs - Maximum time to wait in milliseconds.
166
187
  */
@@ -176,7 +197,16 @@ export class Wrangler {
176
197
  this.doCommit(commitArgs).catch((err) => reject(new Error(`Commit failed: ${String(err)}`)));
177
198
  }
178
199
  else if (message.tag === 'Greetings') {
179
- this.onGreetings(message.headStatus, commitArgs).catch((err) => reject(new Error(`Greetings handler failed: ${String(err)}`)));
200
+ const status = message.headStatus;
201
+ if (status === 'Open') {
202
+ resolve();
203
+ return;
204
+ }
205
+ if (status === 'Closed' || status === 'FanoutPossible' || status === 'Final') {
206
+ reject(new Error(`Cannot wait for head to open: head is "${status}" (terminal or shutting down)`));
207
+ return;
208
+ }
209
+ this.onGreetings(status, commitArgs).catch((err) => reject(new Error(`Greetings handler failed: ${String(err)}`)));
180
210
  }
181
211
  }, timeoutMs, 'Timeout waiting for head to open');
182
212
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lerna-labs/hydra-sdk",
3
- "version": "1.0.0-beta.27",
3
+ "version": "1.0.0-beta.29",
4
4
  "description": "TypeScript SDK for managing Cardano Hydra Heads — lifecycle, UTxO queries, wallet management, transaction submission, and signature verification",
5
5
  "keywords": [
6
6
  "cardano",