@arkade-os/sdk 0.4.0-next.3 → 0.4.0-next.5

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.
@@ -289,6 +289,10 @@ class WalletMessageHandler {
289
289
  payload: { txid },
290
290
  });
291
291
  }
292
+ case "DELEGATE": {
293
+ const response = await this.handleDelegate(message);
294
+ return this.tagged({ id, ...response });
295
+ }
292
296
  default:
293
297
  console.error("Unknown message type", message);
294
298
  throw new Error("Unknown message");
@@ -502,6 +506,34 @@ class WalletMessageHandler {
502
506
  payload: { tx: signature },
503
507
  };
504
508
  }
509
+ async handleDelegate(message) {
510
+ const wallet = this.requireWallet();
511
+ if (!wallet.delegatorManager) {
512
+ throw new Error("Delegator not configured");
513
+ }
514
+ const { vtxoOutpoints, destination, delegateAt } = message.payload;
515
+ const allVtxos = await wallet.getVtxos();
516
+ const outpointSet = new Set(vtxoOutpoints.map((o) => `${o.txid}:${o.vout}`));
517
+ const filtered = allVtxos.filter((v) => outpointSet.has(`${v.txid}:${v.vout}`));
518
+ const result = await wallet.delegatorManager.delegate(filtered, destination, delegateAt !== undefined ? new Date(delegateAt) : undefined);
519
+ return {
520
+ tag: this.messageTag,
521
+ type: "DELEGATE_SUCCESS",
522
+ payload: {
523
+ delegated: result.delegated.map((o) => ({
524
+ txid: o.txid,
525
+ vout: o.vout,
526
+ })),
527
+ failed: result.failed.map((f) => ({
528
+ outpoints: f.outpoints.map((o) => ({
529
+ txid: o.txid,
530
+ vout: o.vout,
531
+ })),
532
+ error: String(f.error),
533
+ })),
534
+ },
535
+ };
536
+ }
505
537
  async handleGetVtxos(message) {
506
538
  if (!this.readonlyWallet) {
507
539
  throw new Error("Wallet handler not initialized");
@@ -124,6 +124,7 @@ class ServiceWorkerReadonlyWallet {
124
124
  url: initConfig.arkServerUrl,
125
125
  publicKey: initConfig.arkServerPublicKey,
126
126
  },
127
+ delegatorUrl: initConfig.delegatorUrl,
127
128
  timeoutMs: options.messageBusTimeoutMs,
128
129
  }, options.messageBusTimeoutMs);
129
130
  // Initialize the wallet handler
@@ -540,6 +541,7 @@ class ServiceWorkerWallet extends ServiceWorkerReadonlyWallet {
540
541
  url: initConfig.arkServerUrl,
541
542
  publicKey: initConfig.arkServerPublicKey,
542
543
  },
544
+ delegatorUrl: initConfig.delegatorUrl,
543
545
  timeoutMs: options.messageBusTimeoutMs,
544
546
  }, options.messageBusTimeoutMs);
545
547
  // Initialize the service worker with the config
@@ -654,5 +656,24 @@ class ServiceWorkerWallet extends ServiceWorkerReadonlyWallet {
654
656
  throw new Error(`Send failed: ${error}`);
655
657
  }
656
658
  }
659
+ async delegate(vtxoOutpoints, destination, delegateAt) {
660
+ const message = {
661
+ tag: this.messageTag,
662
+ type: "DELEGATE",
663
+ id: (0, utils_2.getRandomId)(),
664
+ payload: {
665
+ vtxoOutpoints,
666
+ destination,
667
+ delegateAt: delegateAt?.getTime(),
668
+ },
669
+ };
670
+ try {
671
+ const response = await this.sendMessage(message);
672
+ return response.payload;
673
+ }
674
+ catch (error) {
675
+ throw new Error(`Delegation failed: ${error}`);
676
+ }
677
+ }
657
678
  }
658
679
  exports.ServiceWorkerWallet = ServiceWorkerWallet;
@@ -4,15 +4,111 @@ exports.__resetServiceWorkerManager = void 0;
4
4
  exports.setupServiceWorkerOnce = setupServiceWorkerOnce;
5
5
  exports.getActiveServiceWorker = getActiveServiceWorker;
6
6
  const registrations = new Map();
7
+ let handshakes = new WeakSet();
7
8
  function ensureServiceWorkerSupport() {
8
9
  if (!("serviceWorker" in navigator)) {
9
10
  throw new Error("Service workers are not supported in this browser");
10
11
  }
11
12
  }
12
- function registerOnce(path) {
13
+ function debugLog(debug, ...args) {
14
+ if (debug) {
15
+ // eslint-disable-next-line no-console
16
+ console.debug(...args);
17
+ }
18
+ }
19
+ function normalizeOptions(pathOrOptions) {
20
+ if (typeof pathOrOptions === "string") {
21
+ return {
22
+ path: pathOrOptions,
23
+ updateViaCache: "none",
24
+ autoReload: true,
25
+ debug: false,
26
+ activationTimeoutMs: 10000,
27
+ };
28
+ }
29
+ return {
30
+ path: pathOrOptions.path,
31
+ updateViaCache: pathOrOptions.updateViaCache ?? "none",
32
+ autoReload: pathOrOptions.autoReload ?? true,
33
+ onNeedRefresh: pathOrOptions.onNeedRefresh,
34
+ onUpdated: pathOrOptions.onUpdated,
35
+ debug: pathOrOptions.debug ?? false,
36
+ activationTimeoutMs: pathOrOptions.activationTimeoutMs ?? 10000,
37
+ };
38
+ }
39
+ function sendSkipWaiting(worker, debug) {
40
+ if (!worker)
41
+ return;
42
+ try {
43
+ worker.postMessage({ type: "SKIP_WAITING" });
44
+ debugLog(debug, "Sent SKIP_WAITING to waiting service worker");
45
+ }
46
+ catch (error) {
47
+ console.warn("Failed to post SKIP_WAITING to service worker", error);
48
+ }
49
+ }
50
+ function attachUpdateHandlers(registration, options) {
51
+ // Guard: only the first caller per registration attaches handlers.
52
+ // Subsequent calls with different options are silently ignored.
53
+ if (handshakes.has(registration))
54
+ return;
55
+ handshakes.add(registration);
56
+ const { autoReload, onNeedRefresh, onUpdated, activationTimeoutMs, debug } = options;
57
+ let reloadTriggered = false;
58
+ const maybeReload = () => {
59
+ if (reloadTriggered)
60
+ return;
61
+ reloadTriggered = true;
62
+ debugLog(debug, "Service worker controller change detected");
63
+ onUpdated?.();
64
+ if (autoReload &&
65
+ typeof window !== "undefined" &&
66
+ typeof window.location?.reload === "function") {
67
+ window.location.reload();
68
+ }
69
+ };
70
+ const handleWaiting = (worker) => {
71
+ if (!worker)
72
+ return;
73
+ onNeedRefresh?.();
74
+ sendSkipWaiting(worker, debug);
75
+ if (activationTimeoutMs > 0 && typeof window !== "undefined") {
76
+ window.setTimeout(() => {
77
+ if (registration.waiting) {
78
+ debugLog(debug, "Waiting worker still pending; re-sending SKIP_WAITING");
79
+ sendSkipWaiting(registration.waiting, debug);
80
+ registration
81
+ .update()
82
+ .catch(() => debugLog(debug, "Service worker update retry failed (timeout path)"));
83
+ }
84
+ }, activationTimeoutMs);
85
+ }
86
+ };
87
+ // Handle an already waiting worker at startup.
88
+ if (registration.waiting) {
89
+ handleWaiting(registration.waiting);
90
+ }
91
+ // Listen for newly installed workers becoming waiting.
92
+ registration.addEventListener("updatefound", () => {
93
+ const installing = registration.installing;
94
+ if (!installing)
95
+ return;
96
+ installing.addEventListener("statechange", () => {
97
+ if (installing.state === "installed") {
98
+ handleWaiting(registration.waiting);
99
+ }
100
+ });
101
+ });
102
+ // Reload (or callback) once the new controller takes over.
103
+ navigator.serviceWorker.addEventListener("controllerchange", maybeReload, {
104
+ once: true,
105
+ });
106
+ }
107
+ function registerOnce(options) {
108
+ const { path, updateViaCache } = options;
13
109
  if (!registrations.has(path)) {
14
110
  const registrationPromise = navigator.serviceWorker
15
- .register(path)
111
+ .register(path, { updateViaCache })
16
112
  .then(async (registration) => {
17
113
  try {
18
114
  await registration.update();
@@ -29,18 +125,23 @@ function registerOnce(path) {
29
125
  });
30
126
  registrations.set(path, registrationPromise);
31
127
  }
32
- return registrations.get(path);
128
+ return registrations.get(path).then((registration) => {
129
+ attachUpdateHandlers(registration, options);
130
+ return registration;
131
+ });
33
132
  }
34
133
  /**
35
- * Registers a service worker for the given path only once and caches the
36
- * registration promise for subsequent calls.
134
+ * Registers a service worker for the given path only once, attaches an
135
+ * update/activation handshake (SKIP_WAITING + controllerchange reload), and
136
+ * caches the registration promise for subsequent calls.
37
137
  *
38
- * @param path - Service worker script path to register.
138
+ * @param pathOrOptions - Service worker script path or a configuration object.
39
139
  * @throws if service workers are not supported or registration fails.
40
140
  */
41
- async function setupServiceWorkerOnce(path) {
141
+ async function setupServiceWorkerOnce(pathOrOptions) {
42
142
  ensureServiceWorkerSupport();
43
- return registerOnce(path);
143
+ const options = normalizeOptions(pathOrOptions);
144
+ return registerOnce(options);
44
145
  }
45
146
  /**
46
147
  * Returns an active service worker instance, optionally ensuring a specific
@@ -51,9 +152,8 @@ async function setupServiceWorkerOnce(path) {
51
152
  */
52
153
  async function getActiveServiceWorker(path) {
53
154
  ensureServiceWorkerSupport();
54
- // Avoid mixing registrations when a specific script path is provided.
55
155
  const registration = path
56
- ? await registerOnce(path)
156
+ ? await registerOnce(normalizeOptions(path))
57
157
  : await navigator.serviceWorker.ready;
58
158
  let serviceWorker = registration.active ||
59
159
  registration.waiting ||
@@ -78,5 +178,6 @@ async function getActiveServiceWorker(path) {
78
178
  */
79
179
  const __resetServiceWorkerManager = () => {
80
180
  registrations.clear();
181
+ handshakes = new WeakSet();
81
182
  };
82
183
  exports.__resetServiceWorkerManager = __resetServiceWorkerManager;
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.MessageBus = void 0;
5
5
  const service_worker_manager_1 = require("./browser/service-worker-manager");
6
6
  const ark_1 = require("../providers/ark");
7
+ const delegator_1 = require("../providers/delegator");
7
8
  const identity_1 = require("../identity");
8
9
  const wallet_1 = require("../wallet/wallet");
9
10
  const base_1 = require("@scure/base");
@@ -139,6 +140,9 @@ class MessageBus {
139
140
  walletRepository: this.walletRepository,
140
141
  contractRepository: this.contractRepository,
141
142
  };
143
+ const delegatorProvider = config.delegatorUrl
144
+ ? new delegator_1.RestDelegatorProvider(config.delegatorUrl)
145
+ : undefined;
142
146
  if ("privateKey" in config.wallet) {
143
147
  const identity = identity_1.SingleKey.fromHex(config.wallet.privateKey);
144
148
  const wallet = await wallet_1.Wallet.create({
@@ -146,6 +150,7 @@ class MessageBus {
146
150
  arkServerUrl: config.arkServer.url,
147
151
  arkServerPublicKey: config.arkServer.publicKey,
148
152
  storage,
153
+ delegatorProvider,
149
154
  });
150
155
  return { wallet, arkProvider, readonlyWallet: wallet };
151
156
  }
@@ -156,6 +161,7 @@ class MessageBus {
156
161
  arkServerUrl: config.arkServer.url,
157
162
  arkServerPublicKey: config.arkServer.publicKey,
158
163
  storage,
164
+ delegatorProvider,
159
165
  });
160
166
  return { readonlyWallet, arkProvider };
161
167
  }
@@ -286,6 +286,10 @@ export class WalletMessageHandler {
286
286
  payload: { txid },
287
287
  });
288
288
  }
289
+ case "DELEGATE": {
290
+ const response = await this.handleDelegate(message);
291
+ return this.tagged({ id, ...response });
292
+ }
289
293
  default:
290
294
  console.error("Unknown message type", message);
291
295
  throw new Error("Unknown message");
@@ -499,6 +503,34 @@ export class WalletMessageHandler {
499
503
  payload: { tx: signature },
500
504
  };
501
505
  }
506
+ async handleDelegate(message) {
507
+ const wallet = this.requireWallet();
508
+ if (!wallet.delegatorManager) {
509
+ throw new Error("Delegator not configured");
510
+ }
511
+ const { vtxoOutpoints, destination, delegateAt } = message.payload;
512
+ const allVtxos = await wallet.getVtxos();
513
+ const outpointSet = new Set(vtxoOutpoints.map((o) => `${o.txid}:${o.vout}`));
514
+ const filtered = allVtxos.filter((v) => outpointSet.has(`${v.txid}:${v.vout}`));
515
+ const result = await wallet.delegatorManager.delegate(filtered, destination, delegateAt !== undefined ? new Date(delegateAt) : undefined);
516
+ return {
517
+ tag: this.messageTag,
518
+ type: "DELEGATE_SUCCESS",
519
+ payload: {
520
+ delegated: result.delegated.map((o) => ({
521
+ txid: o.txid,
522
+ vout: o.vout,
523
+ })),
524
+ failed: result.failed.map((f) => ({
525
+ outpoints: f.outpoints.map((o) => ({
526
+ txid: o.txid,
527
+ vout: o.vout,
528
+ })),
529
+ error: String(f.error),
530
+ })),
531
+ },
532
+ };
533
+ }
502
534
  async handleGetVtxos(message) {
503
535
  if (!this.readonlyWallet) {
504
536
  throw new Error("Wallet handler not initialized");
@@ -121,6 +121,7 @@ export class ServiceWorkerReadonlyWallet {
121
121
  url: initConfig.arkServerUrl,
122
122
  publicKey: initConfig.arkServerPublicKey,
123
123
  },
124
+ delegatorUrl: initConfig.delegatorUrl,
124
125
  timeoutMs: options.messageBusTimeoutMs,
125
126
  }, options.messageBusTimeoutMs);
126
127
  // Initialize the wallet handler
@@ -536,6 +537,7 @@ export class ServiceWorkerWallet extends ServiceWorkerReadonlyWallet {
536
537
  url: initConfig.arkServerUrl,
537
538
  publicKey: initConfig.arkServerPublicKey,
538
539
  },
540
+ delegatorUrl: initConfig.delegatorUrl,
539
541
  timeoutMs: options.messageBusTimeoutMs,
540
542
  }, options.messageBusTimeoutMs);
541
543
  // Initialize the service worker with the config
@@ -650,4 +652,23 @@ export class ServiceWorkerWallet extends ServiceWorkerReadonlyWallet {
650
652
  throw new Error(`Send failed: ${error}`);
651
653
  }
652
654
  }
655
+ async delegate(vtxoOutpoints, destination, delegateAt) {
656
+ const message = {
657
+ tag: this.messageTag,
658
+ type: "DELEGATE",
659
+ id: getRandomId(),
660
+ payload: {
661
+ vtxoOutpoints,
662
+ destination,
663
+ delegateAt: delegateAt?.getTime(),
664
+ },
665
+ };
666
+ try {
667
+ const response = await this.sendMessage(message);
668
+ return response.payload;
669
+ }
670
+ catch (error) {
671
+ throw new Error(`Delegation failed: ${error}`);
672
+ }
673
+ }
653
674
  }
@@ -1,13 +1,109 @@
1
1
  const registrations = new Map();
2
+ let handshakes = new WeakSet();
2
3
  function ensureServiceWorkerSupport() {
3
4
  if (!("serviceWorker" in navigator)) {
4
5
  throw new Error("Service workers are not supported in this browser");
5
6
  }
6
7
  }
7
- function registerOnce(path) {
8
+ function debugLog(debug, ...args) {
9
+ if (debug) {
10
+ // eslint-disable-next-line no-console
11
+ console.debug(...args);
12
+ }
13
+ }
14
+ function normalizeOptions(pathOrOptions) {
15
+ if (typeof pathOrOptions === "string") {
16
+ return {
17
+ path: pathOrOptions,
18
+ updateViaCache: "none",
19
+ autoReload: true,
20
+ debug: false,
21
+ activationTimeoutMs: 10000,
22
+ };
23
+ }
24
+ return {
25
+ path: pathOrOptions.path,
26
+ updateViaCache: pathOrOptions.updateViaCache ?? "none",
27
+ autoReload: pathOrOptions.autoReload ?? true,
28
+ onNeedRefresh: pathOrOptions.onNeedRefresh,
29
+ onUpdated: pathOrOptions.onUpdated,
30
+ debug: pathOrOptions.debug ?? false,
31
+ activationTimeoutMs: pathOrOptions.activationTimeoutMs ?? 10000,
32
+ };
33
+ }
34
+ function sendSkipWaiting(worker, debug) {
35
+ if (!worker)
36
+ return;
37
+ try {
38
+ worker.postMessage({ type: "SKIP_WAITING" });
39
+ debugLog(debug, "Sent SKIP_WAITING to waiting service worker");
40
+ }
41
+ catch (error) {
42
+ console.warn("Failed to post SKIP_WAITING to service worker", error);
43
+ }
44
+ }
45
+ function attachUpdateHandlers(registration, options) {
46
+ // Guard: only the first caller per registration attaches handlers.
47
+ // Subsequent calls with different options are silently ignored.
48
+ if (handshakes.has(registration))
49
+ return;
50
+ handshakes.add(registration);
51
+ const { autoReload, onNeedRefresh, onUpdated, activationTimeoutMs, debug } = options;
52
+ let reloadTriggered = false;
53
+ const maybeReload = () => {
54
+ if (reloadTriggered)
55
+ return;
56
+ reloadTriggered = true;
57
+ debugLog(debug, "Service worker controller change detected");
58
+ onUpdated?.();
59
+ if (autoReload &&
60
+ typeof window !== "undefined" &&
61
+ typeof window.location?.reload === "function") {
62
+ window.location.reload();
63
+ }
64
+ };
65
+ const handleWaiting = (worker) => {
66
+ if (!worker)
67
+ return;
68
+ onNeedRefresh?.();
69
+ sendSkipWaiting(worker, debug);
70
+ if (activationTimeoutMs > 0 && typeof window !== "undefined") {
71
+ window.setTimeout(() => {
72
+ if (registration.waiting) {
73
+ debugLog(debug, "Waiting worker still pending; re-sending SKIP_WAITING");
74
+ sendSkipWaiting(registration.waiting, debug);
75
+ registration
76
+ .update()
77
+ .catch(() => debugLog(debug, "Service worker update retry failed (timeout path)"));
78
+ }
79
+ }, activationTimeoutMs);
80
+ }
81
+ };
82
+ // Handle an already waiting worker at startup.
83
+ if (registration.waiting) {
84
+ handleWaiting(registration.waiting);
85
+ }
86
+ // Listen for newly installed workers becoming waiting.
87
+ registration.addEventListener("updatefound", () => {
88
+ const installing = registration.installing;
89
+ if (!installing)
90
+ return;
91
+ installing.addEventListener("statechange", () => {
92
+ if (installing.state === "installed") {
93
+ handleWaiting(registration.waiting);
94
+ }
95
+ });
96
+ });
97
+ // Reload (or callback) once the new controller takes over.
98
+ navigator.serviceWorker.addEventListener("controllerchange", maybeReload, {
99
+ once: true,
100
+ });
101
+ }
102
+ function registerOnce(options) {
103
+ const { path, updateViaCache } = options;
8
104
  if (!registrations.has(path)) {
9
105
  const registrationPromise = navigator.serviceWorker
10
- .register(path)
106
+ .register(path, { updateViaCache })
11
107
  .then(async (registration) => {
12
108
  try {
13
109
  await registration.update();
@@ -24,18 +120,23 @@ function registerOnce(path) {
24
120
  });
25
121
  registrations.set(path, registrationPromise);
26
122
  }
27
- return registrations.get(path);
123
+ return registrations.get(path).then((registration) => {
124
+ attachUpdateHandlers(registration, options);
125
+ return registration;
126
+ });
28
127
  }
29
128
  /**
30
- * Registers a service worker for the given path only once and caches the
31
- * registration promise for subsequent calls.
129
+ * Registers a service worker for the given path only once, attaches an
130
+ * update/activation handshake (SKIP_WAITING + controllerchange reload), and
131
+ * caches the registration promise for subsequent calls.
32
132
  *
33
- * @param path - Service worker script path to register.
133
+ * @param pathOrOptions - Service worker script path or a configuration object.
34
134
  * @throws if service workers are not supported or registration fails.
35
135
  */
36
- export async function setupServiceWorkerOnce(path) {
136
+ export async function setupServiceWorkerOnce(pathOrOptions) {
37
137
  ensureServiceWorkerSupport();
38
- return registerOnce(path);
138
+ const options = normalizeOptions(pathOrOptions);
139
+ return registerOnce(options);
39
140
  }
40
141
  /**
41
142
  * Returns an active service worker instance, optionally ensuring a specific
@@ -46,9 +147,8 @@ export async function setupServiceWorkerOnce(path) {
46
147
  */
47
148
  export async function getActiveServiceWorker(path) {
48
149
  ensureServiceWorkerSupport();
49
- // Avoid mixing registrations when a specific script path is provided.
50
150
  const registration = path
51
- ? await registerOnce(path)
151
+ ? await registerOnce(normalizeOptions(path))
52
152
  : await navigator.serviceWorker.ready;
53
153
  let serviceWorker = registration.active ||
54
154
  registration.waiting ||
@@ -73,4 +173,5 @@ export async function getActiveServiceWorker(path) {
73
173
  */
74
174
  export const __resetServiceWorkerManager = () => {
75
175
  registrations.clear();
176
+ handshakes = new WeakSet();
76
177
  };
@@ -1,6 +1,7 @@
1
1
  /// <reference lib="webworker" />
2
2
  import { getActiveServiceWorker, setupServiceWorkerOnce, } from './browser/service-worker-manager.js';
3
3
  import { RestArkProvider } from '../providers/ark.js';
4
+ import { RestDelegatorProvider } from '../providers/delegator.js';
4
5
  import { ReadonlySingleKey, SingleKey } from '../identity/index.js';
5
6
  import { ReadonlyWallet, Wallet } from '../wallet/wallet.js';
6
7
  import { hex } from "@scure/base";
@@ -136,6 +137,9 @@ export class MessageBus {
136
137
  walletRepository: this.walletRepository,
137
138
  contractRepository: this.contractRepository,
138
139
  };
140
+ const delegatorProvider = config.delegatorUrl
141
+ ? new RestDelegatorProvider(config.delegatorUrl)
142
+ : undefined;
139
143
  if ("privateKey" in config.wallet) {
140
144
  const identity = SingleKey.fromHex(config.wallet.privateKey);
141
145
  const wallet = await Wallet.create({
@@ -143,6 +147,7 @@ export class MessageBus {
143
147
  arkServerUrl: config.arkServer.url,
144
148
  arkServerPublicKey: config.arkServer.publicKey,
145
149
  storage,
150
+ delegatorProvider,
146
151
  });
147
152
  return { wallet, arkProvider, readonlyWallet: wallet };
148
153
  }
@@ -153,6 +158,7 @@ export class MessageBus {
153
158
  arkServerUrl: config.arkServer.url,
154
159
  arkServerPublicKey: config.arkServer.publicKey,
155
160
  storage,
161
+ delegatorProvider,
156
162
  });
157
163
  return { readonlyWallet, arkProvider };
158
164
  }
@@ -318,8 +318,35 @@ export type ResponseBurn = ResponseEnvelope & {
318
318
  txid: string;
319
319
  };
320
320
  };
321
- export type WalletUpdaterRequest = RequestInitWallet | RequestSettle | RequestSendBitcoin | RequestGetAddress | RequestGetBoardingAddress | RequestGetBalance | RequestGetVtxos | RequestGetBoardingUtxos | RequestGetTransactionHistory | RequestGetStatus | RequestClear | RequestReloadWallet | RequestSignTransaction | RequestCreateContract | RequestGetContracts | RequestGetContractsWithVtxos | RequestUpdateContract | RequestDeleteContract | RequestGetSpendablePaths | RequestGetAllSpendingPaths | RequestIsContractManagerWatching | RequestSend | RequestGetAssetDetails | RequestIssue | RequestReissue | RequestBurn;
322
- export type WalletUpdaterResponse = ResponseEnvelope & (ResponseInitWallet | ResponseSettle | ResponseSettleEvent | ResponseSendBitcoin | ResponseGetAddress | ResponseGetBoardingAddress | ResponseGetBalance | ResponseGetVtxos | ResponseGetBoardingUtxos | ResponseGetTransactionHistory | ResponseGetStatus | ResponseClear | ResponseReloadWallet | ResponseUtxoUpdate | ResponseVtxoUpdate | ResponseSignTransaction | ResponseCreateContract | ResponseGetContracts | ResponseGetContractsWithVtxos | ResponseUpdateContract | ResponseDeleteContract | ResponseGetSpendablePaths | ResponseGetAllSpendingPaths | ResponseIsContractManagerWatching | ResponseContractEvent | ResponseSend | ResponseGetAssetDetails | ResponseIssue | ResponseReissue | ResponseBurn);
321
+ export type RequestDelegate = RequestEnvelope & {
322
+ type: "DELEGATE";
323
+ payload: {
324
+ vtxoOutpoints: {
325
+ txid: string;
326
+ vout: number;
327
+ }[];
328
+ destination: string;
329
+ delegateAt?: number;
330
+ };
331
+ };
332
+ export type ResponseDelegate = ResponseEnvelope & {
333
+ type: "DELEGATE_SUCCESS";
334
+ payload: {
335
+ delegated: {
336
+ txid: string;
337
+ vout: number;
338
+ }[];
339
+ failed: {
340
+ outpoints: {
341
+ txid: string;
342
+ vout: number;
343
+ }[];
344
+ error: string;
345
+ }[];
346
+ };
347
+ };
348
+ export type WalletUpdaterRequest = RequestInitWallet | RequestSettle | RequestSendBitcoin | RequestGetAddress | RequestGetBoardingAddress | RequestGetBalance | RequestGetVtxos | RequestGetBoardingUtxos | RequestGetTransactionHistory | RequestGetStatus | RequestClear | RequestReloadWallet | RequestSignTransaction | RequestCreateContract | RequestGetContracts | RequestGetContractsWithVtxos | RequestUpdateContract | RequestDeleteContract | RequestGetSpendablePaths | RequestGetAllSpendingPaths | RequestIsContractManagerWatching | RequestSend | RequestGetAssetDetails | RequestIssue | RequestReissue | RequestBurn | RequestDelegate;
349
+ export type WalletUpdaterResponse = ResponseEnvelope & (ResponseInitWallet | ResponseSettle | ResponseSettleEvent | ResponseSendBitcoin | ResponseGetAddress | ResponseGetBoardingAddress | ResponseGetBalance | ResponseGetVtxos | ResponseGetBoardingUtxos | ResponseGetTransactionHistory | ResponseGetStatus | ResponseClear | ResponseReloadWallet | ResponseUtxoUpdate | ResponseVtxoUpdate | ResponseSignTransaction | ResponseCreateContract | ResponseGetContracts | ResponseGetContractsWithVtxos | ResponseUpdateContract | ResponseDeleteContract | ResponseGetSpendablePaths | ResponseGetAllSpendingPaths | ResponseIsContractManagerWatching | ResponseContractEvent | ResponseSend | ResponseGetAssetDetails | ResponseIssue | ResponseReissue | ResponseBurn | ResponseDelegate);
323
350
  export declare class WalletMessageHandler implements MessageHandler<WalletUpdaterRequest, WalletUpdaterResponse> {
324
351
  readonly messageTag: string;
325
352
  private wallet;
@@ -360,6 +387,7 @@ export declare class WalletMessageHandler implements MessageHandler<WalletUpdate
360
387
  private handleSettle;
361
388
  private handleSendBitcoin;
362
389
  private handleSignTransaction;
390
+ private handleDelegate;
363
391
  private handleGetVtxos;
364
392
  private clear;
365
393
  private ensureContractEventBroadcasting;
@@ -3,7 +3,7 @@ import { SettlementEvent } from "../../providers/ark";
3
3
  import { Identity, ReadonlyIdentity } from "../../identity";
4
4
  import { WalletRepository } from "../../repositories/walletRepository";
5
5
  import { ContractRepository } from "../../repositories/contractRepository";
6
- import { ResponseGetStatus, WalletUpdaterRequest, WalletUpdaterResponse } from "./wallet-message-handler";
6
+ import { ResponseGetStatus, WalletUpdaterRequest, WalletUpdaterResponse, ResponseDelegate } from "./wallet-message-handler";
7
7
  import type { IContractManager } from "../../contracts/contractManager";
8
8
  type PrivateKeyIdentity = Identity & {
9
9
  toHex(): string;
@@ -134,5 +134,9 @@ export declare class ServiceWorkerWallet extends ServiceWorkerReadonlyWallet imp
134
134
  sendBitcoin(params: SendBitcoinParams): Promise<string>;
135
135
  settle(params?: SettleParams, callback?: (event: SettlementEvent) => void): Promise<string>;
136
136
  send(...recipients: Recipient[]): Promise<string>;
137
+ delegate(vtxoOutpoints: {
138
+ txid: string;
139
+ vout: number;
140
+ }[], destination: string, delegateAt?: Date): Promise<ResponseDelegate["payload"]>;
137
141
  }
138
142
  export {};
@@ -1,11 +1,21 @@
1
+ type SetupServiceWorkerOptions = {
2
+ path: string;
3
+ updateViaCache?: ServiceWorkerUpdateViaCache;
4
+ autoReload?: boolean;
5
+ onNeedRefresh?: () => void;
6
+ onUpdated?: () => void;
7
+ debug?: boolean;
8
+ activationTimeoutMs?: number;
9
+ };
1
10
  /**
2
- * Registers a service worker for the given path only once and caches the
3
- * registration promise for subsequent calls.
11
+ * Registers a service worker for the given path only once, attaches an
12
+ * update/activation handshake (SKIP_WAITING + controllerchange reload), and
13
+ * caches the registration promise for subsequent calls.
4
14
  *
5
- * @param path - Service worker script path to register.
15
+ * @param pathOrOptions - Service worker script path or a configuration object.
6
16
  * @throws if service workers are not supported or registration fails.
7
17
  */
8
- export declare function setupServiceWorkerOnce(path: string): Promise<ServiceWorkerRegistration>;
18
+ export declare function setupServiceWorkerOnce(pathOrOptions: string | SetupServiceWorkerOptions): Promise<ServiceWorkerRegistration>;
9
19
  /**
10
20
  * Returns an active service worker instance, optionally ensuring a specific
11
21
  * script path is registered before resolving.
@@ -19,3 +29,4 @@ export declare function getActiveServiceWorker(path?: string): Promise<ServiceWo
19
29
  * Intended for tests to reset state between runs.
20
30
  */
21
31
  export declare const __resetServiceWorkerManager: () => void;
32
+ export {};
@@ -68,6 +68,7 @@ type Initialize = {
68
68
  url: string;
69
69
  publicKey?: string;
70
70
  };
71
+ delegatorUrl?: string;
71
72
  };
72
73
  };
73
74
  export declare class MessageBus {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arkade-os/sdk",
3
- "version": "0.4.0-next.3",
3
+ "version": "0.4.0-next.5",
4
4
  "description": "Bitcoin wallet SDK with Taproot and Ark integration",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",