@arkade-os/sdk 0.1.1 → 0.1.2
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/README.md +20 -3
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/providers/ark.js +16 -0
- package/dist/cjs/wallet/serviceWorker/utils.js +48 -0
- package/dist/cjs/wallet/serviceWorker/wallet.js +4 -77
- package/dist/esm/index.js +3 -4
- package/dist/esm/providers/ark.js +16 -0
- package/dist/esm/wallet/serviceWorker/utils.js +45 -0
- package/dist/esm/wallet/serviceWorker/wallet.js +4 -77
- package/dist/types/index.d.ts +2 -1
- package/dist/types/wallet/serviceWorker/utils.d.ts +1 -0
- package/dist/types/wallet/serviceWorker/wallet.d.ts +2 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -117,18 +117,26 @@ new Worker().start()
|
|
|
117
117
|
```typescript
|
|
118
118
|
// specify the path to the service worker file
|
|
119
119
|
// this will automatically register the service worker
|
|
120
|
-
const
|
|
120
|
+
const serviceWorker = await setupServiceWorker('/service-worker.js')
|
|
121
|
+
const wallet = new ServiceWorkerWallet(serviceWorker)
|
|
121
122
|
|
|
122
123
|
// initialize the wallet
|
|
123
124
|
await wallet.init({
|
|
124
125
|
network: 'mutinynet', // 'bitcoin', 'testnet', 'regtest', 'signet' or 'mutinynet'
|
|
125
|
-
|
|
126
|
+
privateKey: 'your_private_key_hex',
|
|
126
127
|
// Esplora API, can be left empty mempool.space API will be used
|
|
127
128
|
esploraUrl: 'https://mutinynet.com/api',
|
|
128
129
|
// OPTIONAL Ark Server connection information
|
|
129
130
|
arkServerUrl: 'https://mutinynet.arkade.sh',
|
|
130
131
|
arkServerPublicKey: 'fa73c6e4876ffb2dfc961d763cca9abc73d4b88efcb8f5e7ff92dc55e9aa553d'
|
|
131
132
|
})
|
|
133
|
+
|
|
134
|
+
// check service worker status
|
|
135
|
+
const status = await wallet.getStatus()
|
|
136
|
+
console.log('Service worker status:', status.walletInitialized)
|
|
137
|
+
|
|
138
|
+
// clear wallet data stored in the service worker memory
|
|
139
|
+
await wallet.clear()
|
|
132
140
|
```
|
|
133
141
|
|
|
134
142
|
## API Reference
|
|
@@ -149,6 +157,10 @@ interface WalletConfig {
|
|
|
149
157
|
arkServerUrl?: string;
|
|
150
158
|
/** Ark server public key (optional) */
|
|
151
159
|
arkServerPublicKey?: string;
|
|
160
|
+
/** Optional boarding timelock configuration */
|
|
161
|
+
boardingTimelock?: RelativeTimelock;
|
|
162
|
+
/** Optional exit timelock configuration */
|
|
163
|
+
exitTimelock?: RelativeTimelock;
|
|
152
164
|
}
|
|
153
165
|
```
|
|
154
166
|
|
|
@@ -175,7 +187,9 @@ interface IWallet {
|
|
|
175
187
|
total: number;
|
|
176
188
|
settled: number;
|
|
177
189
|
pending: number;
|
|
190
|
+
swept: number;
|
|
178
191
|
};
|
|
192
|
+
total: number;
|
|
179
193
|
}>;
|
|
180
194
|
|
|
181
195
|
/** Send bitcoin (on-chain or off-chain) */
|
|
@@ -183,7 +197,8 @@ interface IWallet {
|
|
|
183
197
|
address: string;
|
|
184
198
|
amount: number;
|
|
185
199
|
feeRate?: number;
|
|
186
|
-
|
|
200
|
+
memo?: string;
|
|
201
|
+
}, zeroFee?: boolean): Promise<string>;
|
|
187
202
|
|
|
188
203
|
/** Get virtual UTXOs */
|
|
189
204
|
getVtxos(): Promise<VirtualCoin[]>;
|
|
@@ -228,6 +243,8 @@ interface VirtualCoin {
|
|
|
228
243
|
virtualStatus: {
|
|
229
244
|
state: 'pending' | 'settled';
|
|
230
245
|
};
|
|
246
|
+
spentBy?: string;
|
|
247
|
+
createdAt: Date;
|
|
231
248
|
}
|
|
232
249
|
|
|
233
250
|
/** Boarding UTXO */
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.IndexedDBVtxoRepository = exports.networks = exports.ArkNoteData = exports.ArkNote = exports.createVirtualTx = exports.CONDITION_WITNESS_KEY_PREFIX = exports.addConditionWitness = exports.CLTVMultisigTapscript = exports.ConditionMultisigTapscript = exports.ConditionCSVMultisigTapscript = exports.CSVMultisigTapscript = exports.MultisigTapscript = exports.decodeTapscript = exports.Response = exports.Request = exports.Worker = exports.TxType = exports.VHTLC = exports.VtxoScript = exports.DefaultVtxo = exports.ArkAddress = exports.RestArkProvider = exports.EsploraProvider = exports.ESPLORA_URL = exports.InMemoryKey = exports.
|
|
3
|
+
exports.IndexedDBVtxoRepository = exports.networks = exports.ArkNoteData = exports.ArkNote = exports.createVirtualTx = exports.CONDITION_WITNESS_KEY_PREFIX = exports.addConditionWitness = exports.CLTVMultisigTapscript = exports.ConditionMultisigTapscript = exports.ConditionCSVMultisigTapscript = exports.CSVMultisigTapscript = exports.MultisigTapscript = exports.decodeTapscript = exports.Response = exports.Request = exports.ServiceWorkerWallet = exports.Worker = exports.setupServiceWorker = exports.TxType = exports.VHTLC = exports.VtxoScript = exports.DefaultVtxo = exports.ArkAddress = exports.RestArkProvider = exports.EsploraProvider = exports.ESPLORA_URL = exports.InMemoryKey = exports.Wallet = void 0;
|
|
4
4
|
const inMemoryKey_1 = require("./identity/inMemoryKey");
|
|
5
5
|
Object.defineProperty(exports, "InMemoryKey", { enumerable: true, get: function () { return inMemoryKey_1.InMemoryKey; } });
|
|
6
6
|
const address_1 = require("./script/address");
|
|
@@ -17,6 +17,8 @@ const wallet_1 = require("./wallet/wallet");
|
|
|
17
17
|
Object.defineProperty(exports, "Wallet", { enumerable: true, get: function () { return wallet_1.Wallet; } });
|
|
18
18
|
const wallet_2 = require("./wallet/serviceWorker/wallet");
|
|
19
19
|
Object.defineProperty(exports, "ServiceWorkerWallet", { enumerable: true, get: function () { return wallet_2.ServiceWorkerWallet; } });
|
|
20
|
+
const utils_1 = require("./wallet/serviceWorker/utils");
|
|
21
|
+
Object.defineProperty(exports, "setupServiceWorker", { enumerable: true, get: function () { return utils_1.setupServiceWorker; } });
|
|
20
22
|
const worker_1 = require("./wallet/serviceWorker/worker");
|
|
21
23
|
Object.defineProperty(exports, "Worker", { enumerable: true, get: function () { return worker_1.Worker; } });
|
|
22
24
|
const request_1 = require("./wallet/serviceWorker/request");
|
|
@@ -368,6 +368,12 @@ class RestArkProvider {
|
|
|
368
368
|
}
|
|
369
369
|
}
|
|
370
370
|
catch (error) {
|
|
371
|
+
// ignore timeout errors, they're expected when the server is not sending anything for 5 min
|
|
372
|
+
// these timeouts are set by builtin fetch function
|
|
373
|
+
if (isFetchTimeoutError(error)) {
|
|
374
|
+
console.debug("Timeout error ignored");
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
371
377
|
console.error("Address subscription error:", error);
|
|
372
378
|
throw error;
|
|
373
379
|
}
|
|
@@ -545,3 +551,13 @@ function convertVtxo(vtxo) {
|
|
|
545
551
|
createdAt: new Date(vtxo.createdAt * 1000),
|
|
546
552
|
};
|
|
547
553
|
}
|
|
554
|
+
function isFetchTimeoutError(err) {
|
|
555
|
+
const checkError = (error) => {
|
|
556
|
+
return (error instanceof Error &&
|
|
557
|
+
(error.name === "HeadersTimeoutError" ||
|
|
558
|
+
error.name === "BodyTimeoutError" ||
|
|
559
|
+
error.code === "UND_ERR_HEADERS_TIMEOUT" ||
|
|
560
|
+
error.code === "UND_ERR_BODY_TIMEOUT"));
|
|
561
|
+
};
|
|
562
|
+
return checkError(err) || checkError(err.cause);
|
|
563
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setupServiceWorker = setupServiceWorker;
|
|
4
|
+
async function setupServiceWorker(path) {
|
|
5
|
+
// check if service workers are supported
|
|
6
|
+
if (!("serviceWorker" in navigator)) {
|
|
7
|
+
throw new Error("Service workers are not supported in this browser");
|
|
8
|
+
}
|
|
9
|
+
// check for existing registration
|
|
10
|
+
const existingRegistration = await navigator.serviceWorker.getRegistration(path);
|
|
11
|
+
let registration;
|
|
12
|
+
if (existingRegistration) {
|
|
13
|
+
registration = existingRegistration;
|
|
14
|
+
// Force unregister and re-register to ensure we get the latest version
|
|
15
|
+
await existingRegistration.unregister();
|
|
16
|
+
}
|
|
17
|
+
registration = await navigator.serviceWorker.register(path);
|
|
18
|
+
// Handle updates
|
|
19
|
+
registration.addEventListener("updatefound", () => {
|
|
20
|
+
const newWorker = registration.installing;
|
|
21
|
+
if (!newWorker)
|
|
22
|
+
return;
|
|
23
|
+
newWorker.addEventListener("statechange", () => {
|
|
24
|
+
if (newWorker.state === "activated" &&
|
|
25
|
+
navigator.serviceWorker.controller) {
|
|
26
|
+
console.info("Service worker activated, reloading...");
|
|
27
|
+
window.location.reload();
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
const serviceWorker = registration.active || registration.waiting || registration.installing;
|
|
32
|
+
if (!serviceWorker) {
|
|
33
|
+
throw new Error("Failed to get service worker instance");
|
|
34
|
+
}
|
|
35
|
+
// wait for the service worker to be ready
|
|
36
|
+
if (serviceWorker.state !== "activated") {
|
|
37
|
+
await new Promise((resolve) => {
|
|
38
|
+
if (!serviceWorker)
|
|
39
|
+
return resolve();
|
|
40
|
+
serviceWorker.addEventListener("statechange", () => {
|
|
41
|
+
if (serviceWorker.state === "activated") {
|
|
42
|
+
resolve();
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return serviceWorker;
|
|
48
|
+
}
|
|
@@ -11,15 +11,8 @@ class UnexpectedResponseError extends Error {
|
|
|
11
11
|
}
|
|
12
12
|
// ServiceWorkerWallet is a wallet that uses a service worker as "backend" to handle the wallet logic
|
|
13
13
|
class ServiceWorkerWallet {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const wallet = new ServiceWorkerWallet();
|
|
17
|
-
await wallet.setupServiceWorker(svcWorkerPath);
|
|
18
|
-
return wallet;
|
|
19
|
-
}
|
|
20
|
-
catch (error) {
|
|
21
|
-
throw new Error(`Failed to initialize service worker wallet: ${error}`);
|
|
22
|
-
}
|
|
14
|
+
constructor(serviceWorker) {
|
|
15
|
+
this.serviceWorker = serviceWorker;
|
|
23
16
|
}
|
|
24
17
|
async getStatus() {
|
|
25
18
|
const message = {
|
|
@@ -64,64 +57,8 @@ class ServiceWorkerWallet {
|
|
|
64
57
|
};
|
|
65
58
|
await this.sendMessage(message);
|
|
66
59
|
}
|
|
67
|
-
// register the service worker
|
|
68
|
-
async setupServiceWorker(path) {
|
|
69
|
-
// check if service workers are supported
|
|
70
|
-
if (!("serviceWorker" in navigator)) {
|
|
71
|
-
throw new Error("Service workers are not supported in this browser");
|
|
72
|
-
}
|
|
73
|
-
try {
|
|
74
|
-
// check for existing registration
|
|
75
|
-
const existingRegistration = await navigator.serviceWorker.getRegistration(path);
|
|
76
|
-
let registration;
|
|
77
|
-
if (existingRegistration) {
|
|
78
|
-
registration = existingRegistration;
|
|
79
|
-
// Force unregister and re-register to ensure we get the latest version
|
|
80
|
-
await existingRegistration.unregister();
|
|
81
|
-
}
|
|
82
|
-
registration = await navigator.serviceWorker.register(path);
|
|
83
|
-
// Handle updates
|
|
84
|
-
registration.addEventListener("updatefound", () => {
|
|
85
|
-
const newWorker = registration.installing;
|
|
86
|
-
if (!newWorker)
|
|
87
|
-
return;
|
|
88
|
-
newWorker.addEventListener("statechange", () => {
|
|
89
|
-
if (newWorker.state === "activated" &&
|
|
90
|
-
navigator.serviceWorker.controller) {
|
|
91
|
-
console.info("Service worker activated, reloading...");
|
|
92
|
-
window.location.reload();
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
const sw = registration.active ||
|
|
97
|
-
registration.waiting ||
|
|
98
|
-
registration.installing;
|
|
99
|
-
if (!sw) {
|
|
100
|
-
throw new Error("Failed to get service worker instance");
|
|
101
|
-
}
|
|
102
|
-
this.serviceWorker = sw;
|
|
103
|
-
// wait for the service worker to be ready
|
|
104
|
-
if (this.serviceWorker?.state !== "activated") {
|
|
105
|
-
await new Promise((resolve) => {
|
|
106
|
-
if (!this.serviceWorker)
|
|
107
|
-
return resolve();
|
|
108
|
-
this.serviceWorker.addEventListener("statechange", () => {
|
|
109
|
-
if (this.serviceWorker?.state === "activated") {
|
|
110
|
-
resolve();
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
catch (error) {
|
|
117
|
-
throw new Error(`Failed to setup service worker: ${error}`);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
60
|
// send a message and wait for a response
|
|
121
61
|
async sendMessage(message) {
|
|
122
|
-
if (!this.serviceWorker) {
|
|
123
|
-
throw new Error("Service worker not initialized");
|
|
124
|
-
}
|
|
125
62
|
return new Promise((resolve, reject) => {
|
|
126
63
|
const messageHandler = (event) => {
|
|
127
64
|
const response = event.data;
|
|
@@ -141,12 +78,7 @@ class ServiceWorkerWallet {
|
|
|
141
78
|
}
|
|
142
79
|
};
|
|
143
80
|
navigator.serviceWorker.addEventListener("message", messageHandler);
|
|
144
|
-
|
|
145
|
-
this.serviceWorker.postMessage(message);
|
|
146
|
-
}
|
|
147
|
-
else {
|
|
148
|
-
reject(new Error("Service worker not initialized"));
|
|
149
|
-
}
|
|
81
|
+
this.serviceWorker.postMessage(message);
|
|
150
82
|
});
|
|
151
83
|
}
|
|
152
84
|
async getAddress() {
|
|
@@ -293,12 +225,7 @@ class ServiceWorkerWallet {
|
|
|
293
225
|
}
|
|
294
226
|
};
|
|
295
227
|
navigator.serviceWorker.addEventListener("message", messageHandler);
|
|
296
|
-
|
|
297
|
-
this.serviceWorker.postMessage(message);
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
reject(new Error("Service worker not initialized"));
|
|
301
|
-
}
|
|
228
|
+
this.serviceWorker.postMessage(message);
|
|
302
229
|
});
|
|
303
230
|
}
|
|
304
231
|
catch (error) {
|
package/dist/esm/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import { VtxoScript } from './script/base.js';
|
|
|
6
6
|
import { TxType, } from './wallet/index.js';
|
|
7
7
|
import { Wallet } from './wallet/wallet.js';
|
|
8
8
|
import { ServiceWorkerWallet } from './wallet/serviceWorker/wallet.js';
|
|
9
|
+
import { setupServiceWorker } from './wallet/serviceWorker/utils.js';
|
|
9
10
|
import { Worker } from './wallet/serviceWorker/worker.js';
|
|
10
11
|
import { Request } from './wallet/serviceWorker/request.js';
|
|
11
12
|
import { Response } from './wallet/serviceWorker/response.js';
|
|
@@ -16,9 +17,7 @@ import { addConditionWitness, CONDITION_WITNESS_KEY_PREFIX, createVirtualTx, } f
|
|
|
16
17
|
import { ArkNote, ArkNoteData } from './arknote/index.js';
|
|
17
18
|
import { IndexedDBVtxoRepository } from './wallet/serviceWorker/db/vtxo/idb.js';
|
|
18
19
|
import { networks } from './networks.js';
|
|
19
|
-
export {
|
|
20
|
-
// Classes
|
|
21
|
-
Wallet, ServiceWorkerWallet, InMemoryKey,
|
|
20
|
+
export { Wallet, InMemoryKey,
|
|
22
21
|
// Providers
|
|
23
22
|
ESPLORA_URL, EsploraProvider, RestArkProvider,
|
|
24
23
|
// Script-related
|
|
@@ -26,7 +25,7 @@ ArkAddress, DefaultVtxo, VtxoScript, VHTLC,
|
|
|
26
25
|
// Enums
|
|
27
26
|
TxType,
|
|
28
27
|
// Service Worker
|
|
29
|
-
Worker, Request, Response,
|
|
28
|
+
setupServiceWorker, Worker, ServiceWorkerWallet, Request, Response,
|
|
30
29
|
// Tapscript
|
|
31
30
|
decodeTapscript, MultisigTapscript, CSVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, CLTVMultisigTapscript,
|
|
32
31
|
// Utils
|
|
@@ -365,6 +365,12 @@ export class RestArkProvider {
|
|
|
365
365
|
}
|
|
366
366
|
}
|
|
367
367
|
catch (error) {
|
|
368
|
+
// ignore timeout errors, they're expected when the server is not sending anything for 5 min
|
|
369
|
+
// these timeouts are set by builtin fetch function
|
|
370
|
+
if (isFetchTimeoutError(error)) {
|
|
371
|
+
console.debug("Timeout error ignored");
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
368
374
|
console.error("Address subscription error:", error);
|
|
369
375
|
throw error;
|
|
370
376
|
}
|
|
@@ -541,3 +547,13 @@ function convertVtxo(vtxo) {
|
|
|
541
547
|
createdAt: new Date(vtxo.createdAt * 1000),
|
|
542
548
|
};
|
|
543
549
|
}
|
|
550
|
+
function isFetchTimeoutError(err) {
|
|
551
|
+
const checkError = (error) => {
|
|
552
|
+
return (error instanceof Error &&
|
|
553
|
+
(error.name === "HeadersTimeoutError" ||
|
|
554
|
+
error.name === "BodyTimeoutError" ||
|
|
555
|
+
error.code === "UND_ERR_HEADERS_TIMEOUT" ||
|
|
556
|
+
error.code === "UND_ERR_BODY_TIMEOUT"));
|
|
557
|
+
};
|
|
558
|
+
return checkError(err) || checkError(err.cause);
|
|
559
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export async function setupServiceWorker(path) {
|
|
2
|
+
// check if service workers are supported
|
|
3
|
+
if (!("serviceWorker" in navigator)) {
|
|
4
|
+
throw new Error("Service workers are not supported in this browser");
|
|
5
|
+
}
|
|
6
|
+
// check for existing registration
|
|
7
|
+
const existingRegistration = await navigator.serviceWorker.getRegistration(path);
|
|
8
|
+
let registration;
|
|
9
|
+
if (existingRegistration) {
|
|
10
|
+
registration = existingRegistration;
|
|
11
|
+
// Force unregister and re-register to ensure we get the latest version
|
|
12
|
+
await existingRegistration.unregister();
|
|
13
|
+
}
|
|
14
|
+
registration = await navigator.serviceWorker.register(path);
|
|
15
|
+
// Handle updates
|
|
16
|
+
registration.addEventListener("updatefound", () => {
|
|
17
|
+
const newWorker = registration.installing;
|
|
18
|
+
if (!newWorker)
|
|
19
|
+
return;
|
|
20
|
+
newWorker.addEventListener("statechange", () => {
|
|
21
|
+
if (newWorker.state === "activated" &&
|
|
22
|
+
navigator.serviceWorker.controller) {
|
|
23
|
+
console.info("Service worker activated, reloading...");
|
|
24
|
+
window.location.reload();
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
const serviceWorker = registration.active || registration.waiting || registration.installing;
|
|
29
|
+
if (!serviceWorker) {
|
|
30
|
+
throw new Error("Failed to get service worker instance");
|
|
31
|
+
}
|
|
32
|
+
// wait for the service worker to be ready
|
|
33
|
+
if (serviceWorker.state !== "activated") {
|
|
34
|
+
await new Promise((resolve) => {
|
|
35
|
+
if (!serviceWorker)
|
|
36
|
+
return resolve();
|
|
37
|
+
serviceWorker.addEventListener("statechange", () => {
|
|
38
|
+
if (serviceWorker.state === "activated") {
|
|
39
|
+
resolve();
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return serviceWorker;
|
|
45
|
+
}
|
|
@@ -8,15 +8,8 @@ class UnexpectedResponseError extends Error {
|
|
|
8
8
|
}
|
|
9
9
|
// ServiceWorkerWallet is a wallet that uses a service worker as "backend" to handle the wallet logic
|
|
10
10
|
export class ServiceWorkerWallet {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const wallet = new ServiceWorkerWallet();
|
|
14
|
-
await wallet.setupServiceWorker(svcWorkerPath);
|
|
15
|
-
return wallet;
|
|
16
|
-
}
|
|
17
|
-
catch (error) {
|
|
18
|
-
throw new Error(`Failed to initialize service worker wallet: ${error}`);
|
|
19
|
-
}
|
|
11
|
+
constructor(serviceWorker) {
|
|
12
|
+
this.serviceWorker = serviceWorker;
|
|
20
13
|
}
|
|
21
14
|
async getStatus() {
|
|
22
15
|
const message = {
|
|
@@ -61,64 +54,8 @@ export class ServiceWorkerWallet {
|
|
|
61
54
|
};
|
|
62
55
|
await this.sendMessage(message);
|
|
63
56
|
}
|
|
64
|
-
// register the service worker
|
|
65
|
-
async setupServiceWorker(path) {
|
|
66
|
-
// check if service workers are supported
|
|
67
|
-
if (!("serviceWorker" in navigator)) {
|
|
68
|
-
throw new Error("Service workers are not supported in this browser");
|
|
69
|
-
}
|
|
70
|
-
try {
|
|
71
|
-
// check for existing registration
|
|
72
|
-
const existingRegistration = await navigator.serviceWorker.getRegistration(path);
|
|
73
|
-
let registration;
|
|
74
|
-
if (existingRegistration) {
|
|
75
|
-
registration = existingRegistration;
|
|
76
|
-
// Force unregister and re-register to ensure we get the latest version
|
|
77
|
-
await existingRegistration.unregister();
|
|
78
|
-
}
|
|
79
|
-
registration = await navigator.serviceWorker.register(path);
|
|
80
|
-
// Handle updates
|
|
81
|
-
registration.addEventListener("updatefound", () => {
|
|
82
|
-
const newWorker = registration.installing;
|
|
83
|
-
if (!newWorker)
|
|
84
|
-
return;
|
|
85
|
-
newWorker.addEventListener("statechange", () => {
|
|
86
|
-
if (newWorker.state === "activated" &&
|
|
87
|
-
navigator.serviceWorker.controller) {
|
|
88
|
-
console.info("Service worker activated, reloading...");
|
|
89
|
-
window.location.reload();
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
});
|
|
93
|
-
const sw = registration.active ||
|
|
94
|
-
registration.waiting ||
|
|
95
|
-
registration.installing;
|
|
96
|
-
if (!sw) {
|
|
97
|
-
throw new Error("Failed to get service worker instance");
|
|
98
|
-
}
|
|
99
|
-
this.serviceWorker = sw;
|
|
100
|
-
// wait for the service worker to be ready
|
|
101
|
-
if (this.serviceWorker?.state !== "activated") {
|
|
102
|
-
await new Promise((resolve) => {
|
|
103
|
-
if (!this.serviceWorker)
|
|
104
|
-
return resolve();
|
|
105
|
-
this.serviceWorker.addEventListener("statechange", () => {
|
|
106
|
-
if (this.serviceWorker?.state === "activated") {
|
|
107
|
-
resolve();
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
throw new Error(`Failed to setup service worker: ${error}`);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
57
|
// send a message and wait for a response
|
|
118
58
|
async sendMessage(message) {
|
|
119
|
-
if (!this.serviceWorker) {
|
|
120
|
-
throw new Error("Service worker not initialized");
|
|
121
|
-
}
|
|
122
59
|
return new Promise((resolve, reject) => {
|
|
123
60
|
const messageHandler = (event) => {
|
|
124
61
|
const response = event.data;
|
|
@@ -138,12 +75,7 @@ export class ServiceWorkerWallet {
|
|
|
138
75
|
}
|
|
139
76
|
};
|
|
140
77
|
navigator.serviceWorker.addEventListener("message", messageHandler);
|
|
141
|
-
|
|
142
|
-
this.serviceWorker.postMessage(message);
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
reject(new Error("Service worker not initialized"));
|
|
146
|
-
}
|
|
78
|
+
this.serviceWorker.postMessage(message);
|
|
147
79
|
});
|
|
148
80
|
}
|
|
149
81
|
async getAddress() {
|
|
@@ -290,12 +222,7 @@ export class ServiceWorkerWallet {
|
|
|
290
222
|
}
|
|
291
223
|
};
|
|
292
224
|
navigator.serviceWorker.addEventListener("message", messageHandler);
|
|
293
|
-
|
|
294
|
-
this.serviceWorker.postMessage(message);
|
|
295
|
-
}
|
|
296
|
-
else {
|
|
297
|
-
reject(new Error("Service worker not initialized"));
|
|
298
|
-
}
|
|
225
|
+
this.serviceWorker.postMessage(message);
|
|
299
226
|
});
|
|
300
227
|
}
|
|
301
228
|
catch (error) {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { VtxoScript } from "./script/base";
|
|
|
7
7
|
import { TxType, IWallet, WalletConfig, ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, WalletBalance, SendBitcoinParams, Recipient, SettleParams, VtxoTaprootAddress, AddressInfo, TapscriptInfo, Status, VirtualStatus, Outpoint, VirtualCoin, TxKey, Addresses } from "./wallet/index";
|
|
8
8
|
import { Wallet } from "./wallet/wallet";
|
|
9
9
|
import { ServiceWorkerWallet } from "./wallet/serviceWorker/wallet";
|
|
10
|
+
import { setupServiceWorker } from "./wallet/serviceWorker/utils";
|
|
10
11
|
import { Worker } from "./wallet/serviceWorker/worker";
|
|
11
12
|
import { Request } from "./wallet/serviceWorker/request";
|
|
12
13
|
import { Response } from "./wallet/serviceWorker/response";
|
|
@@ -18,5 +19,5 @@ import { ArkNote, ArkNoteData } from "./arknote";
|
|
|
18
19
|
import { IndexedDBVtxoRepository } from "./wallet/serviceWorker/db/vtxo/idb";
|
|
19
20
|
import { VtxoRepository } from "./wallet/serviceWorker/db/vtxo";
|
|
20
21
|
import { networks } from "./networks";
|
|
21
|
-
export { Wallet,
|
|
22
|
+
export { Wallet, InMemoryKey, ESPLORA_URL, EsploraProvider, RestArkProvider, ArkAddress, DefaultVtxo, VtxoScript, VHTLC, TxType, setupServiceWorker, Worker, ServiceWorkerWallet, Request, Response, decodeTapscript, MultisigTapscript, CSVMultisigTapscript, ConditionCSVMultisigTapscript, ConditionMultisigTapscript, CLTVMultisigTapscript, addConditionWitness, CONDITION_WITNESS_KEY_PREFIX, createVirtualTx, ArkNote, ArkNoteData, networks, IndexedDBVtxoRepository, };
|
|
22
23
|
export type { Identity, IWallet, WalletConfig, ArkTransaction, Coin, ExtendedCoin, ExtendedVirtualCoin, WalletBalance, SendBitcoinParams, Recipient, SettleParams, VtxoTaprootAddress, AddressInfo, Addresses, TapscriptInfo, Status, VirtualStatus, Outpoint, VirtualCoin, TxKey, TapscriptType, VtxoRepository, };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupServiceWorker(path: string): Promise<ServiceWorker>;
|
|
@@ -2,14 +2,13 @@ import { IWallet, WalletBalance, SendBitcoinParams, SettleParams, AddressInfo, C
|
|
|
2
2
|
import { Response } from "./response";
|
|
3
3
|
import { SettlementEvent } from "../../providers/ark";
|
|
4
4
|
export declare class ServiceWorkerWallet implements IWallet {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
readonly serviceWorker: ServiceWorker;
|
|
6
|
+
constructor(serviceWorker: ServiceWorker);
|
|
7
7
|
getStatus(): Promise<Response.WalletStatus["status"]>;
|
|
8
8
|
init(config: Omit<WalletConfig, "identity"> & {
|
|
9
9
|
privateKey: string;
|
|
10
10
|
}, failIfInitialized?: boolean): Promise<void>;
|
|
11
11
|
clear(): Promise<void>;
|
|
12
|
-
private setupServiceWorker;
|
|
13
12
|
private sendMessage;
|
|
14
13
|
getAddress(): Promise<Addresses>;
|
|
15
14
|
getAddressInfo(): Promise<AddressInfo>;
|