@arcaresearch/sdk 0.0.2 → 0.0.4

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/dist/arca.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { OperationHandle, OrderHandle } from './operation-handle';
1
2
  import { ArcaConfig, ArcaObject, ArcaObjectBrowseResponse, ArcaObjectDetailResponse, ArcaObjectListResponse, ArcaObjectVersionsResponse, ArcaBalance, AggregationSourceDto, BrowseObjectsOptions, CreateArcaObjectResponse, CreateArcaOptions, CreateDenominatedArcaOptions, CreateWatchResponse, DeleteArcaObjectResponse, DepositOptions, EnsureDeletedOptions, WithdrawalOptions, InitiateWithdrawalResponse, EventCallback, EventDetailResponse, EventSubscription, EventSubscriptionOptions, ExplorerSummary, InitiateDepositResponse, ListObjectsOptions, ListEventsOptions, ListOperationsOptions, EventListResponse, NonceResponse, Operation, OperationDetailResponse, OperationListResponse, OrderOperationResponse, PathAggregation, PnlResponse, EquityHistoryResponse, ReconciliationStateListResponse, SnapshotBalancesResponse, StateDeltaListResponse, TransferOptions, TransferResponse, CancelOrderOptions, CreatePerpsExchangeOptions, PlaceOrderOptions, UpdateLeverageOptions, UpdateLeverageResponse, LeverageSetting, ExchangeState, SimOrder, SimOrderWithFills, SimPosition, SimMetaResponse, SimMidsResponse, SimBookResponse, InvariantCheckResponse, ActiveAssetData, CandleInterval, CandlesResponse, CreatePaymentLinkOptions, CreatePaymentLinkResponse, ListPaymentLinksOptions, PaymentLinkListResponse } from './types';
2
3
  import { WebSocketManager } from './websocket';
3
4
  /**
@@ -52,29 +53,28 @@ export declare class Arca {
52
53
  * If one already exists with matching type/denomination, it is returned.
53
54
  * Otherwise a new one is created.
54
55
  *
55
- * Pass `operationPath` (from the nonce API with separator ":") for
56
- * explicit operation-level idempotency, especially when delete+recreate
57
- * scenarios are expected.
56
+ * `await` waits for the object to be fully created (operation completed).
57
+ * Use `.submitted` to access the HTTP response before the operation settles.
58
58
  */
59
- createDenominatedArca(opts: CreateDenominatedArcaOptions): Promise<CreateArcaObjectResponse>;
59
+ createDenominatedArca(opts: CreateDenominatedArcaOptions): OperationHandle<CreateArcaObjectResponse>;
60
60
  /**
61
61
  * Create an Arca object of any type at the given path (idempotent).
62
62
  *
63
- * Pass `operationPath` (from the nonce API with separator ":") for
64
- * explicit operation-level idempotency.
63
+ * `await` waits for the object to be fully created (operation completed).
64
+ * Use `.submitted` to access the HTTP response before the operation settles.
65
65
  */
66
- createArca(opts: CreateArcaOptions): Promise<CreateArcaObjectResponse>;
66
+ createArca(opts: CreateArcaOptions): OperationHandle<CreateArcaObjectResponse>;
67
67
  /** @deprecated Use createDenominatedArca instead */
68
- ensureDenominatedArca(opts: CreateDenominatedArcaOptions): Promise<CreateArcaObjectResponse>;
68
+ ensureDenominatedArca(opts: CreateDenominatedArcaOptions): OperationHandle<CreateArcaObjectResponse>;
69
69
  /** @deprecated Use createArca instead */
70
- ensureArca(opts: CreateArcaOptions): Promise<CreateArcaObjectResponse>;
70
+ ensureArca(opts: CreateArcaOptions): OperationHandle<CreateArcaObjectResponse>;
71
71
  /**
72
72
  * Delete an Arca object by path. If sweepTo is provided, remaining funds
73
73
  * are transferred to that Arca before deletion.
74
74
  *
75
75
  * If the object is already deleted, returns the existing state.
76
76
  */
77
- ensureDeleted(opts: EnsureDeletedOptions): Promise<DeleteArcaObjectResponse>;
77
+ ensureDeleted(opts: EnsureDeletedOptions): OperationHandle<DeleteArcaObjectResponse>;
78
78
  /**
79
79
  * Get an Arca object by path.
80
80
  */
@@ -111,22 +111,25 @@ export declare class Arca {
111
111
  getSnapshotBalances(objectId: string, asOf: string): Promise<SnapshotBalancesResponse>;
112
112
  /**
113
113
  * Execute a transfer between two Arca objects.
114
- * Settlement is immediate for denominated targets, or async for
115
- * targets that require a receiver workflow (e.g. exchange objects).
114
+ * Settlement is immediate for denominated targets (await resolves instantly),
115
+ * or async for exchange targets (await waits for settlement).
116
116
  * The operation path serves as the idempotency key.
117
117
  */
118
- transfer(opts: TransferOptions): Promise<TransferResponse>;
118
+ transfer(opts: TransferOptions): OperationHandle<TransferResponse>;
119
119
  /**
120
120
  * Initiate a deposit to a denominated Arca object.
121
121
  * In demo realms, deposits are simulated with a configurable delay.
122
+ *
123
+ * `await` waits for deposit settlement. Use `.submitted` to access
124
+ * the poolAddress and other response data before settlement.
122
125
  */
123
- deposit(opts: DepositOptions): Promise<InitiateDepositResponse>;
126
+ deposit(opts: DepositOptions): OperationHandle<InitiateDepositResponse>;
124
127
  /**
125
128
  * Initiate a withdrawal from a denominated Arca object to an on-chain address.
126
129
  * Requires custody service (on-chain mode) to be active.
127
130
  */
128
- withdrawal(opts: WithdrawalOptions): Promise<InitiateWithdrawalResponse>;
129
- createPaymentLink(opts: CreatePaymentLinkOptions): Promise<CreatePaymentLinkResponse>;
131
+ withdrawal(opts: WithdrawalOptions): OperationHandle<InitiateWithdrawalResponse>;
132
+ createPaymentLink(opts: CreatePaymentLinkOptions): OperationHandle<CreatePaymentLinkResponse>;
130
133
  listPaymentLinks(opts?: ListPaymentLinksOptions): Promise<PaymentLinkListResponse>;
131
134
  /**
132
135
  * Get operation detail by ID (includes correlated events and deltas).
@@ -208,7 +211,7 @@ export declare class Arca {
208
211
  * Create a Perps Exchange Arca object.
209
212
  * Automatically sets type=exchange, denomination=USD, and exchangeType metadata.
210
213
  */
211
- createPerpsExchange(opts: CreatePerpsExchangeOptions): Promise<CreateArcaObjectResponse>;
214
+ createPerpsExchange(opts: CreatePerpsExchangeOptions): OperationHandle<CreateArcaObjectResponse>;
212
215
  /**
213
216
  * Get exchange account state (equity, margin, positions, orders).
214
217
  */
@@ -238,8 +241,11 @@ export declare class Arca {
238
241
  /**
239
242
  * Place an order on an exchange Arca object.
240
243
  * The operation path serves as the idempotency key.
244
+ *
245
+ * Returns an OrderHandle: `await` waits for placement. Use `.filled()`,
246
+ * `.onFill()`, `.fills()` for fill lifecycle, and `.cancel()` to cancel.
241
247
  */
242
- placeOrder(opts: PlaceOrderOptions): Promise<OrderOperationResponse>;
248
+ placeOrder(opts: PlaceOrderOptions): OrderHandle;
243
249
  /**
244
250
  * List orders for an exchange Arca object.
245
251
  */
@@ -252,7 +258,7 @@ export declare class Arca {
252
258
  * Cancel an order on an exchange Arca object.
253
259
  * The operation path serves as the idempotency key.
254
260
  */
255
- cancelOrder(opts: CancelOrderOptions): Promise<OrderOperationResponse>;
261
+ cancelOrder(opts: CancelOrderOptions): OperationHandle<OrderOperationResponse>;
256
262
  /**
257
263
  * List positions for an exchange Arca object.
258
264
  */
@@ -282,11 +288,11 @@ export declare class Arca {
282
288
  */
283
289
  checkInvariants(limit?: number): Promise<InvariantCheckResponse>;
284
290
  /**
285
- * Poll until all operations in the realm have reached a terminal state.
286
- * Useful after a batch of async operations (deposits, exchange transfers)
287
- * to wait for settlement before running invariant checks.
291
+ * Wait until all operations in the realm have reached a terminal state.
292
+ * Uses WebSocket events to react to completions instantly, with periodic
293
+ * HTTP polls as a safety net.
288
294
  *
289
- * @param opts.intervalMs - Polling interval in ms (default: 1000)
295
+ * @param opts.intervalMs - Safety-net poll interval in ms (default: 5000)
290
296
  * @param opts.timeoutMs - Max wait time in ms (default: 120000)
291
297
  * @param opts.onPoll - Optional callback with the current pending count
292
298
  * @returns The number of polls performed
@@ -298,11 +304,17 @@ export declare class Arca {
298
304
  }): Promise<number>;
299
305
  /**
300
306
  * Wait for a specific operation to reach a terminal state.
301
- * Uses WebSocket events to resolve immediately when the operation updates.
307
+ * Auto-connects the WebSocket and subscribes to the operations channel
308
+ * so callers don't need to manage the connection manually.
302
309
  * If the WS event arrives without embedded operation data (enrichment failure),
303
310
  * fetches the operation via HTTP as a fallback.
304
311
  */
305
312
  waitForOperation(operationId: string, timeoutMs?: number): Promise<Operation>;
313
+ /**
314
+ * Wrap a mutation HTTP call in an OperationHandle.
315
+ * Defers ready() + throwIfOperationFailed into the promise chain.
316
+ */
317
+ private op;
306
318
  private realmId;
307
319
  private throwIfOperationFailed;
308
320
  private resolveRealm;
@@ -1 +1 @@
1
- {"version":3,"file":"arca.d.ts","sourceRoot":"","sources":["../src/arca.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"arca.d.ts","sourceRoot":"","sources":["../src/arca.ts"],"names":[],"mappings":"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"}
package/dist/arca.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Arca = void 0;
4
4
  const client_1 = require("./client");
5
5
  const errors_1 = require("./errors");
6
+ const operation_handle_1 = require("./operation-handle");
6
7
  const types_1 = require("./types");
7
8
  const websocket_1 = require("./websocket");
8
9
  const DEFAULT_BASE_URL = 'https://api.arcaos.io';
@@ -146,44 +147,41 @@ class Arca {
146
147
  * If one already exists with matching type/denomination, it is returned.
147
148
  * Otherwise a new one is created.
148
149
  *
149
- * Pass `operationPath` (from the nonce API with separator ":") for
150
- * explicit operation-level idempotency, especially when delete+recreate
151
- * scenarios are expected.
150
+ * `await` waits for the object to be fully created (operation completed).
151
+ * Use `.submitted` to access the HTTP response before the operation settles.
152
152
  */
153
- async createDenominatedArca(opts) {
154
- await this.ready();
155
- return this.client.post('/objects', {
153
+ createDenominatedArca(opts) {
154
+ return this.op(() => this.client.post('/objects', {
156
155
  realmId: this.realmId(),
157
156
  path: opts.ref,
158
157
  type: 'denominated',
159
158
  denomination: opts.denomination,
160
159
  metadata: opts.metadata ?? null,
161
160
  operationPath: opts.operationPath ?? null,
162
- });
161
+ }));
163
162
  }
164
163
  /**
165
164
  * Create an Arca object of any type at the given path (idempotent).
166
165
  *
167
- * Pass `operationPath` (from the nonce API with separator ":") for
168
- * explicit operation-level idempotency.
166
+ * `await` waits for the object to be fully created (operation completed).
167
+ * Use `.submitted` to access the HTTP response before the operation settles.
169
168
  */
170
- async createArca(opts) {
171
- await this.ready();
172
- return this.client.post('/objects', {
169
+ createArca(opts) {
170
+ return this.op(() => this.client.post('/objects', {
173
171
  realmId: this.realmId(),
174
172
  path: opts.ref,
175
173
  type: opts.type,
176
174
  denomination: opts.denomination ?? null,
177
175
  metadata: opts.metadata ?? null,
178
176
  operationPath: opts.operationPath ?? null,
179
- });
177
+ }));
180
178
  }
181
179
  /** @deprecated Use createDenominatedArca instead */
182
- async ensureDenominatedArca(opts) {
180
+ ensureDenominatedArca(opts) {
183
181
  return this.createDenominatedArca(opts);
184
182
  }
185
183
  /** @deprecated Use createArca instead */
186
- async ensureArca(opts) {
184
+ ensureArca(opts) {
187
185
  return this.createArca(opts);
188
186
  }
189
187
  /**
@@ -192,15 +190,14 @@ class Arca {
192
190
  *
193
191
  * If the object is already deleted, returns the existing state.
194
192
  */
195
- async ensureDeleted(opts) {
196
- await this.ready();
197
- return this.client.post('/objects/delete', {
193
+ ensureDeleted(opts) {
194
+ return this.op(() => this.client.post('/objects/delete', {
198
195
  realmId: this.realmId(),
199
196
  path: opts.ref,
200
197
  sweepToPath: opts.sweepTo ?? null,
201
198
  liquidatePositions: opts.liquidatePositions ?? false,
202
199
  operationPath: opts.operationPath ?? null,
203
- });
200
+ }));
204
201
  }
205
202
  /**
206
203
  * Get an Arca object by path.
@@ -281,60 +278,55 @@ class Arca {
281
278
  // ---- Transfers ----
282
279
  /**
283
280
  * Execute a transfer between two Arca objects.
284
- * Settlement is immediate for denominated targets, or async for
285
- * targets that require a receiver workflow (e.g. exchange objects).
281
+ * Settlement is immediate for denominated targets (await resolves instantly),
282
+ * or async for exchange targets (await waits for settlement).
286
283
  * The operation path serves as the idempotency key.
287
284
  */
288
- async transfer(opts) {
289
- await this.ready();
290
- const response = await this.client.post('/transfer', {
285
+ transfer(opts) {
286
+ return this.op(() => this.client.post('/transfer', {
291
287
  realmId: this.realmId(),
292
288
  path: opts.path,
293
289
  sourceArcaPath: opts.from,
294
290
  targetArcaPath: opts.to,
295
291
  amount: opts.amount,
296
- });
297
- this.throwIfOperationFailed(response.operation);
298
- return response;
292
+ }));
299
293
  }
300
294
  // ---- Deposits ----
301
295
  /**
302
296
  * Initiate a deposit to a denominated Arca object.
303
297
  * In demo realms, deposits are simulated with a configurable delay.
298
+ *
299
+ * `await` waits for deposit settlement. Use `.submitted` to access
300
+ * the poolAddress and other response data before settlement.
304
301
  */
305
- async deposit(opts) {
306
- await this.ready();
307
- const response = await this.client.post('/deposit', {
302
+ deposit(opts) {
303
+ return this.op(() => this.client.post('/deposit', {
308
304
  realmId: this.realmId(),
309
305
  arcaPath: opts.arcaRef,
310
306
  amount: opts.amount,
311
307
  path: opts.path ?? null,
312
308
  senderAddress: opts.senderAddress ?? null,
313
- });
314
- this.throwIfOperationFailed(response.operation);
315
- return response;
309
+ durationSeconds: opts.durationSeconds ?? null,
310
+ willSucceed: opts.willSucceed ?? null,
311
+ }));
316
312
  }
317
313
  // ---- Withdrawals ----
318
314
  /**
319
315
  * Initiate a withdrawal from a denominated Arca object to an on-chain address.
320
316
  * Requires custody service (on-chain mode) to be active.
321
317
  */
322
- async withdrawal(opts) {
323
- await this.ready();
324
- const response = await this.client.post('/withdrawal', {
318
+ withdrawal(opts) {
319
+ return this.op(() => this.client.post('/withdrawal', {
325
320
  realmId: this.realmId(),
326
321
  arcaPath: opts.arcaPath,
327
322
  amount: opts.amount,
328
323
  destinationAddress: opts.destinationAddress ?? '',
329
324
  path: opts.path ?? null,
330
- });
331
- this.throwIfOperationFailed(response.operation);
332
- return response;
325
+ }));
333
326
  }
334
327
  // ---- Payment Links ----
335
- async createPaymentLink(opts) {
336
- await this.ready();
337
- return this.client.post('/payment-links', {
328
+ createPaymentLink(opts) {
329
+ return this.op(() => this.client.post('/payment-links', {
338
330
  realmId: this.realmId(),
339
331
  type: opts.type,
340
332
  arcaPath: opts.arcaRef,
@@ -342,7 +334,7 @@ class Arca {
342
334
  returnUrl: opts.returnUrl ?? null,
343
335
  expiresInMinutes: opts.expiresInMinutes ?? null,
344
336
  metadata: opts.metadata ? JSON.stringify(opts.metadata) : null,
345
- });
337
+ }));
346
338
  }
347
339
  async listPaymentLinks(opts) {
348
340
  await this.ready();
@@ -526,16 +518,15 @@ class Arca {
526
518
  * Create a Perps Exchange Arca object.
527
519
  * Automatically sets type=exchange, denomination=USD, and exchangeType metadata.
528
520
  */
529
- async createPerpsExchange(opts) {
530
- await this.ready();
531
- return this.client.post('/objects', {
521
+ createPerpsExchange(opts) {
522
+ return this.op(() => this.client.post('/objects', {
532
523
  realmId: this.realmId(),
533
524
  path: opts.ref,
534
525
  type: 'exchange',
535
526
  denomination: 'USD',
536
527
  metadata: JSON.stringify({ exchangeType: opts.exchangeType || 'hyperliquid' }),
537
528
  operationPath: opts.operationPath,
538
- });
529
+ }));
539
530
  }
540
531
  /**
541
532
  * Get exchange account state (equity, margin, positions, orders).
@@ -590,10 +581,12 @@ class Arca {
590
581
  /**
591
582
  * Place an order on an exchange Arca object.
592
583
  * The operation path serves as the idempotency key.
584
+ *
585
+ * Returns an OrderHandle: `await` waits for placement. Use `.filled()`,
586
+ * `.onFill()`, `.fills()` for fill lifecycle, and `.cancel()` to cancel.
593
587
  */
594
- async placeOrder(opts) {
595
- await this.ready();
596
- const response = await this.client.post(`/objects/${opts.objectId}/exchange/orders`, {
588
+ placeOrder(opts) {
589
+ const httpCall = this.ready().then(() => this.client.post(`/objects/${opts.objectId}/exchange/orders`, {
597
590
  realmId: this.realmId(),
598
591
  path: opts.path,
599
592
  coin: opts.coin,
@@ -607,9 +600,21 @@ class Arca {
607
600
  timeInForce: opts.timeInForce ?? 'GTC',
608
601
  ...(opts.builderFeeBps != null && { builderFeeBps: opts.builderFeeBps }),
609
602
  ...(opts.feeTargets != null && { feeTargets: opts.feeTargets }),
603
+ })).then(response => {
604
+ this.throwIfOperationFailed(response.operation);
605
+ return response;
610
606
  });
611
- this.throwIfOperationFailed(response.operation);
612
- return response;
607
+ const deps = {
608
+ getOrder: (objectId, orderId) => this.getOrder(objectId, orderId),
609
+ onFillEvent: (handler) => {
610
+ this.ws.ensureConnected();
611
+ this.ws.subscribe(['exchange']);
612
+ this.ws.on(types_1.EventType.ExchangeFill, handler);
613
+ return () => this.ws.off(types_1.EventType.ExchangeFill, handler);
614
+ },
615
+ cancelOrder: (cancelOpts) => this.cancelOrder(cancelOpts),
616
+ };
617
+ return new operation_handle_1.OrderHandle(httpCall, (id, timeout) => this.waitForOperation(id, timeout), opts.objectId, opts.path, deps);
613
618
  }
614
619
  /**
615
620
  * List orders for an exchange Arca object.
@@ -632,15 +637,14 @@ class Arca {
632
637
  * Cancel an order on an exchange Arca object.
633
638
  * The operation path serves as the idempotency key.
634
639
  */
635
- async cancelOrder(opts) {
636
- await this.ready();
637
- const params = new URLSearchParams({
638
- realmId: this.realmId(),
639
- path: opts.path,
640
+ cancelOrder(opts) {
641
+ return this.op(() => {
642
+ const params = new URLSearchParams({
643
+ realmId: this.realmId(),
644
+ path: opts.path,
645
+ });
646
+ return this.client.delete(`/objects/${opts.objectId}/exchange/orders/${opts.orderId}?${params.toString()}`);
640
647
  });
641
- const response = await this.client.delete(`/objects/${opts.objectId}/exchange/orders/${opts.orderId}?${params.toString()}`);
642
- this.throwIfOperationFailed(response.operation);
643
- return response;
644
648
  }
645
649
  /**
646
650
  * List positions for an exchange Arca object.
@@ -695,43 +699,89 @@ class Arca {
695
699
  return this.client.get('/internal/invariant-check', params);
696
700
  }
697
701
  /**
698
- * Poll until all operations in the realm have reached a terminal state.
699
- * Useful after a batch of async operations (deposits, exchange transfers)
700
- * to wait for settlement before running invariant checks.
702
+ * Wait until all operations in the realm have reached a terminal state.
703
+ * Uses WebSocket events to react to completions instantly, with periodic
704
+ * HTTP polls as a safety net.
701
705
  *
702
- * @param opts.intervalMs - Polling interval in ms (default: 1000)
706
+ * @param opts.intervalMs - Safety-net poll interval in ms (default: 5000)
703
707
  * @param opts.timeoutMs - Max wait time in ms (default: 120000)
704
708
  * @param opts.onPoll - Optional callback with the current pending count
705
709
  * @returns The number of polls performed
706
710
  */
707
711
  async waitForQuiescence(opts) {
708
712
  await this.ready();
709
- const interval = opts?.intervalMs ?? 1000;
713
+ const interval = opts?.intervalMs ?? 5000;
710
714
  const timeout = opts?.timeoutMs ?? 120_000;
711
715
  const start = Date.now();
712
716
  let polls = 0;
713
- while (true) {
717
+ this.ws.ensureConnected();
718
+ this.ws.subscribe(['operations']);
719
+ const checkPending = async () => {
714
720
  const res = await this.listOperations();
715
- const pending = res.operations.filter(op => op.state === 'pending');
716
721
  polls++;
722
+ const pending = res.operations.filter(op => op.state === 'pending');
717
723
  opts?.onPoll?.(pending.length);
718
- if (pending.length === 0)
719
- return polls;
724
+ return pending.length;
725
+ };
726
+ let pendingCount = await checkPending();
727
+ if (pendingCount === 0)
728
+ return polls;
729
+ return new Promise((resolve, reject) => {
730
+ let settled = false;
731
+ const timer = setTimeout(() => {
732
+ cleanup();
733
+ reject(new Error(`Timed out waiting for quiescence after ${timeout}ms. ` +
734
+ `${pendingCount} operations still pending.`));
735
+ }, timeout);
736
+ const safetyPoll = setInterval(async () => {
737
+ if (settled)
738
+ return;
739
+ try {
740
+ pendingCount = await checkPending();
741
+ if (pendingCount === 0) {
742
+ cleanup();
743
+ resolve(polls);
744
+ }
745
+ }
746
+ catch { /* ignore, will retry */ }
747
+ }, interval);
748
+ const cleanup = () => {
749
+ settled = true;
750
+ clearTimeout(timer);
751
+ clearInterval(safetyPoll);
752
+ this.ws.off(types_1.EventType.OperationUpdated, handler);
753
+ };
754
+ const handler = async () => {
755
+ if (settled)
756
+ return;
757
+ try {
758
+ pendingCount = await checkPending();
759
+ if (pendingCount === 0) {
760
+ cleanup();
761
+ resolve(polls);
762
+ }
763
+ }
764
+ catch { /* ignore */ }
765
+ };
766
+ this.ws.on(types_1.EventType.OperationUpdated, handler);
720
767
  if (Date.now() - start > timeout) {
721
- throw new Error(`Timed out waiting for quiescence after ${timeout}ms. ` +
722
- `${pending.length} operations still pending.`);
768
+ cleanup();
769
+ reject(new Error(`Timed out waiting for quiescence after ${timeout}ms. ` +
770
+ `${pendingCount} operations still pending.`));
723
771
  }
724
- await new Promise(r => setTimeout(r, interval));
725
- }
772
+ });
726
773
  }
727
774
  /**
728
775
  * Wait for a specific operation to reach a terminal state.
729
- * Uses WebSocket events to resolve immediately when the operation updates.
776
+ * Auto-connects the WebSocket and subscribes to the operations channel
777
+ * so callers don't need to manage the connection manually.
730
778
  * If the WS event arrives without embedded operation data (enrichment failure),
731
779
  * fetches the operation via HTTP as a fallback.
732
780
  */
733
781
  async waitForOperation(operationId, timeoutMs = 30000) {
734
782
  await this.ready();
783
+ this.ws.ensureConnected();
784
+ this.ws.subscribe(['operations']);
735
785
  return new Promise((resolve, reject) => {
736
786
  let settled = false;
737
787
  const timeout = setTimeout(() => {
@@ -785,6 +835,17 @@ class Arca {
785
835
  });
786
836
  }
787
837
  // ---- Internal ----
838
+ /**
839
+ * Wrap a mutation HTTP call in an OperationHandle.
840
+ * Defers ready() + throwIfOperationFailed into the promise chain.
841
+ */
842
+ op(httpCall) {
843
+ const call = this.ready().then(() => httpCall()).then(response => {
844
+ this.throwIfOperationFailed(response.operation);
845
+ return response;
846
+ });
847
+ return new operation_handle_1.OperationHandle(call, (id, timeout) => this.waitForOperation(id, timeout));
848
+ }
788
849
  realmId() {
789
850
  if (!this.resolvedRealmId) {
790
851
  throw new Error('Arca SDK not initialized. Call await arca.ready() first.');