@arkade-os/sdk 0.4.19 → 0.4.21

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 (61) hide show
  1. package/dist/cjs/contracts/contractWatcher.js +33 -3
  2. package/dist/cjs/contracts/handlers/default.js +10 -3
  3. package/dist/cjs/contracts/handlers/helpers.js +47 -5
  4. package/dist/cjs/contracts/handlers/vhtlc.js +4 -2
  5. package/dist/cjs/identity/descriptor.js +98 -0
  6. package/dist/cjs/identity/descriptorProvider.js +2 -0
  7. package/dist/cjs/identity/index.js +15 -1
  8. package/dist/cjs/identity/seedIdentity.js +91 -6
  9. package/dist/cjs/identity/serialize.js +166 -0
  10. package/dist/cjs/identity/staticDescriptorProvider.js +65 -0
  11. package/dist/cjs/index.js +6 -3
  12. package/dist/cjs/providers/ark.js +71 -46
  13. package/dist/cjs/providers/electrum.js +663 -0
  14. package/dist/cjs/providers/indexer.js +60 -43
  15. package/dist/cjs/providers/utils.js +62 -12
  16. package/dist/cjs/wallet/ramps.js +1 -1
  17. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +10 -0
  18. package/dist/cjs/wallet/serviceWorker/wallet.js +137 -91
  19. package/dist/cjs/wallet/vtxo-manager.js +56 -8
  20. package/dist/cjs/wallet/wallet.js +130 -156
  21. package/dist/cjs/worker/messageBus.js +200 -56
  22. package/dist/esm/contracts/contractWatcher.js +33 -3
  23. package/dist/esm/contracts/handlers/default.js +10 -3
  24. package/dist/esm/contracts/handlers/helpers.js +47 -5
  25. package/dist/esm/contracts/handlers/vhtlc.js +4 -2
  26. package/dist/esm/identity/descriptor.js +92 -0
  27. package/dist/esm/identity/descriptorProvider.js +1 -0
  28. package/dist/esm/identity/index.js +6 -1
  29. package/dist/esm/identity/seedIdentity.js +89 -6
  30. package/dist/esm/identity/serialize.js +159 -0
  31. package/dist/esm/identity/staticDescriptorProvider.js +61 -0
  32. package/dist/esm/index.js +2 -1
  33. package/dist/esm/providers/ark.js +72 -47
  34. package/dist/esm/providers/electrum.js +658 -0
  35. package/dist/esm/providers/indexer.js +61 -44
  36. package/dist/esm/providers/utils.js +61 -12
  37. package/dist/esm/wallet/ramps.js +1 -1
  38. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +10 -0
  39. package/dist/esm/wallet/serviceWorker/wallet.js +137 -91
  40. package/dist/esm/wallet/vtxo-manager.js +56 -8
  41. package/dist/esm/wallet/wallet.js +130 -156
  42. package/dist/esm/worker/messageBus.js +201 -57
  43. package/dist/types/contracts/contractWatcher.d.ts +3 -0
  44. package/dist/types/contracts/handlers/default.d.ts +1 -1
  45. package/dist/types/contracts/handlers/helpers.d.ts +1 -1
  46. package/dist/types/contracts/types.d.ts +11 -3
  47. package/dist/types/identity/descriptor.d.ts +35 -0
  48. package/dist/types/identity/descriptorProvider.d.ts +28 -0
  49. package/dist/types/identity/index.d.ts +7 -1
  50. package/dist/types/identity/seedIdentity.d.ts +41 -4
  51. package/dist/types/identity/serialize.d.ts +84 -0
  52. package/dist/types/identity/staticDescriptorProvider.d.ts +18 -0
  53. package/dist/types/index.d.ts +4 -2
  54. package/dist/types/providers/electrum.d.ts +212 -0
  55. package/dist/types/providers/utils.d.ts +10 -5
  56. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +11 -2
  57. package/dist/types/wallet/serviceWorker/wallet.d.ts +27 -10
  58. package/dist/types/wallet/vtxo-manager.d.ts +2 -0
  59. package/dist/types/wallet/wallet.d.ts +7 -6
  60. package/dist/types/worker/messageBus.d.ts +68 -8
  61. package/package.json +3 -2
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StaticDescriptorProvider = void 0;
4
+ const base_1 = require("@scure/base");
5
+ const _1 = require(".");
6
+ const descriptor_1 = require("./descriptor");
7
+ /**
8
+ * Wraps a legacy Identity (single-key) as a DescriptorProvider.
9
+ * The descriptor is always a simple tr(pubkey) format.
10
+ */
11
+ class StaticDescriptorProvider {
12
+ constructor(identity, pubKeyHex) {
13
+ this.identity = identity;
14
+ this.pubKeyHex = pubKeyHex;
15
+ this.descriptor = `tr(${pubKeyHex})`;
16
+ }
17
+ static async create(identity) {
18
+ const pubKey = await identity.xOnlyPublicKey();
19
+ return new StaticDescriptorProvider(identity, base_1.hex.encode(pubKey));
20
+ }
21
+ getSigningDescriptor() {
22
+ return this.descriptor;
23
+ }
24
+ isOurs(descriptor) {
25
+ try {
26
+ const normalized = (0, descriptor_1.normalizeToDescriptor)(descriptor);
27
+ const pubKey = (0, descriptor_1.extractPubKey)(normalized);
28
+ return pubKey.toLowerCase() === this.pubKeyHex.toLowerCase();
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ async signWithDescriptor(requests) {
35
+ for (const request of requests) {
36
+ if (!this.isOurs(request.descriptor)) {
37
+ throw new Error(`Descriptor ${request.descriptor} does not belong to this provider`);
38
+ }
39
+ }
40
+ // Use batch signing when the identity supports it (fewer confirmation popups)
41
+ if ((0, _1.isBatchSignable)(this.identity)) {
42
+ const signed = await this.identity.signMultiple(requests.map((r) => ({
43
+ tx: r.tx,
44
+ inputIndexes: r.inputIndexes,
45
+ })));
46
+ if (signed.length !== requests.length) {
47
+ throw new Error(`signMultiple returned ${signed.length} transactions, expected ${requests.length}`);
48
+ }
49
+ return signed;
50
+ }
51
+ const results = [];
52
+ for (const request of requests) {
53
+ const signed = await this.identity.sign(request.tx, request.inputIndexes);
54
+ results.push(signed);
55
+ }
56
+ return results;
57
+ }
58
+ async signMessageWithDescriptor(descriptor, message, type = "schnorr") {
59
+ if (!this.isOurs(descriptor)) {
60
+ throw new Error(`Descriptor ${descriptor} does not belong to this provider`);
61
+ }
62
+ return this.identity.signMessage(message, type);
63
+ }
64
+ }
65
+ exports.StaticDescriptorProvider = StaticDescriptorProvider;
package/dist/cjs/index.js CHANGED
@@ -36,9 +36,9 @@ var __importStar = (this && this.__importStar) || (function () {
36
36
  };
37
37
  })();
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.getArkPsbtFields = exports.setArkPsbtField = exports.ArkPsbtFieldKeyType = exports.ArkPsbtFieldKey = exports.TapTreeCoder = exports.CLTVMultisigTapscript = exports.ConditionMultisigTapscript = exports.ConditionCSVMultisigTapscript = exports.CSVMultisigTapscript = exports.MultisigTapscript = exports.decodeTapscript = exports.DEFAULT_MESSAGE_TIMEOUTS = exports.ServiceWorkerReadonlyWallet = exports.ServiceWorkerWallet = exports.ServiceWorkerTimeoutError = exports.MessageBusNotInitializedError = exports.MESSAGE_BUS_NOT_INITIALIZED = exports.DelegatorNotConfiguredError = exports.ReadonlyWalletError = exports.WalletNotInitializedError = exports.WalletMessageHandler = exports.MessageBus = exports.setupServiceWorker = exports.SettlementEventType = exports.ChainTxType = exports.IndexerTxType = exports.TxType = exports.VHTLC = exports.VtxoScript = exports.DelegateVtxo = exports.DefaultVtxo = exports.ArkAddress = exports.RestIndexerProvider = exports.RestArkProvider = exports.EsploraProvider = exports.ESPLORA_URL = exports.RestDelegatorProvider = exports.DelegatorManagerImpl = exports.VtxoManager = exports.Ramps = exports.OnchainWallet = exports.isBatchSignable = exports.ReadonlyDescriptorIdentity = exports.MnemonicIdentity = exports.SeedIdentity = exports.ReadonlySingleKey = exports.SingleKey = exports.ReadonlyWallet = exports.Wallet = exports.asset = void 0;
40
- exports.encodeArkContract = exports.VHTLCContractHandler = exports.DelegateContractHandler = exports.DefaultContractHandler = exports.contractHandlers = exports.ContractWatcher = exports.ContractManager = exports.getSequence = exports.isExpired = exports.isSubdust = exports.isSpendable = exports.isRecoverable = exports.buildForfeitTx = exports.validateConnectorsTxGraph = exports.validateVtxoTxGraph = exports.Batch = exports.maybeArkError = exports.ArkError = exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.BIP322 = exports.Intent = exports.ContractRepositoryImpl = exports.WalletRepositoryImpl = exports.rollbackMigration = exports.getMigrationStatus = exports.requiresMigration = exports.migrateWalletRepository = exports.MIGRATION_KEY = exports.InMemoryContractRepository = exports.InMemoryWalletRepository = exports.IndexedDBContractRepository = exports.IndexedDBWalletRepository = exports.openDatabase = exports.closeDatabase = exports.networks = exports.ArkNote = exports.isValidArkAddress = exports.isVtxoExpiringSoon = exports.combineTapscriptSigs = exports.hasBoardingTxExpired = exports.waitForIncomingFunds = exports.verifyTapscriptSignatures = exports.buildOffchainTx = exports.ConditionWitness = exports.VtxoTaprootTree = exports.VtxoTreeExpiry = exports.CosignerPublicKey = void 0;
41
- exports.isArkContract = exports.contractFromArkContractWithAddress = exports.contractFromArkContract = exports.decodeArkContract = void 0;
39
+ exports.ArkPsbtFieldKeyType = exports.ArkPsbtFieldKey = exports.TapTreeCoder = exports.CLTVMultisigTapscript = exports.ConditionMultisigTapscript = exports.ConditionCSVMultisigTapscript = exports.CSVMultisigTapscript = exports.MultisigTapscript = exports.decodeTapscript = exports.DEFAULT_MESSAGE_TIMEOUTS = exports.ServiceWorkerReadonlyWallet = exports.ServiceWorkerWallet = exports.ServiceWorkerTimeoutError = exports.MessageBusNotInitializedError = exports.MESSAGE_BUS_NOT_INITIALIZED = exports.DelegatorNotConfiguredError = exports.ReadonlyWalletError = exports.WalletNotInitializedError = exports.WalletMessageHandler = exports.MessageBus = exports.setupServiceWorker = exports.SettlementEventType = exports.ChainTxType = exports.IndexerTxType = exports.TxType = exports.VHTLC = exports.VtxoScript = exports.DelegateVtxo = exports.DefaultVtxo = exports.ArkAddress = exports.RestIndexerProvider = exports.RestArkProvider = exports.WsElectrumChainSource = exports.ElectrumOnchainProvider = exports.EsploraProvider = exports.ESPLORA_URL = exports.RestDelegatorProvider = exports.DelegatorManagerImpl = exports.VtxoManager = exports.Ramps = exports.OnchainWallet = exports.isBatchSignable = exports.ReadonlyDescriptorIdentity = exports.MnemonicIdentity = exports.SeedIdentity = exports.ReadonlySingleKey = exports.SingleKey = exports.ReadonlyWallet = exports.Wallet = exports.asset = void 0;
40
+ exports.DelegateContractHandler = exports.DefaultContractHandler = exports.contractHandlers = exports.ContractWatcher = exports.ContractManager = exports.getSequence = exports.isExpired = exports.isSubdust = exports.isSpendable = exports.isRecoverable = exports.buildForfeitTx = exports.validateConnectorsTxGraph = exports.validateVtxoTxGraph = exports.Batch = exports.maybeArkError = exports.ArkError = exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.BIP322 = exports.Intent = exports.ContractRepositoryImpl = exports.WalletRepositoryImpl = exports.rollbackMigration = exports.getMigrationStatus = exports.requiresMigration = exports.migrateWalletRepository = exports.MIGRATION_KEY = exports.InMemoryContractRepository = exports.InMemoryWalletRepository = exports.IndexedDBContractRepository = exports.IndexedDBWalletRepository = exports.openDatabase = exports.closeDatabase = exports.networks = exports.ArkNote = exports.isValidArkAddress = exports.isVtxoExpiringSoon = exports.combineTapscriptSigs = exports.hasBoardingTxExpired = exports.waitForIncomingFunds = exports.verifyTapscriptSignatures = exports.buildOffchainTx = exports.ConditionWitness = exports.VtxoTaprootTree = exports.VtxoTreeExpiry = exports.CosignerPublicKey = exports.getArkPsbtFields = exports.setArkPsbtField = void 0;
41
+ exports.isArkContract = exports.contractFromArkContractWithAddress = exports.contractFromArkContract = exports.decodeArkContract = exports.encodeArkContract = exports.VHTLCContractHandler = void 0;
42
42
  const transaction_1 = require("./utils/transaction");
43
43
  Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_1.Transaction; } });
44
44
  const singleKey_1 = require("./identity/singleKey");
@@ -94,6 +94,9 @@ Object.defineProperty(exports, "setupServiceWorker", { enumerable: true, get: fu
94
94
  const onchain_2 = require("./providers/onchain");
95
95
  Object.defineProperty(exports, "ESPLORA_URL", { enumerable: true, get: function () { return onchain_2.ESPLORA_URL; } });
96
96
  Object.defineProperty(exports, "EsploraProvider", { enumerable: true, get: function () { return onchain_2.EsploraProvider; } });
97
+ const electrum_1 = require("./providers/electrum");
98
+ Object.defineProperty(exports, "ElectrumOnchainProvider", { enumerable: true, get: function () { return electrum_1.ElectrumOnchainProvider; } });
99
+ Object.defineProperty(exports, "WsElectrumChainSource", { enumerable: true, get: function () { return electrum_1.WsElectrumChainSource; } });
97
100
  const ark_1 = require("./providers/ark");
98
101
  Object.defineProperty(exports, "RestArkProvider", { enumerable: true, get: function () { return ark_1.RestArkProvider; } });
99
102
  Object.defineProperty(exports, "SettlementEventType", { enumerable: true, get: function () { return ark_1.SettlementEventType; } });
@@ -236,18 +236,19 @@ class RestArkProvider {
236
236
  // leak the underlying SSE connection. `return()` is overridden below
237
237
  // so that closing the generator also closes the connection even when
238
238
  // the body is currently suspended at an await point.
239
- let eventSource = null;
239
+ let iterator = null;
240
+ const closeIterator = () => iterator?.close();
240
241
  // eslint-disable-next-line @typescript-eslint/no-this-alias
241
242
  const self = this;
242
243
  const gen = (async function* () {
243
- const abortHandler = () => eventSource?.close();
244
+ const abortHandler = closeIterator;
244
245
  signal?.addEventListener("abort", abortHandler);
245
246
  try {
246
247
  while (!signal?.aborted) {
247
- eventSource = new EventSource(url + queryParams);
248
- const iterator = (0, utils_1.eventSourceIterator)(eventSource);
248
+ const currentIterator = (0, utils_1.eventSourceIterator)(new EventSource(url + queryParams));
249
+ iterator = currentIterator;
249
250
  try {
250
- for await (const event of iterator) {
251
+ for await (const event of currentIterator) {
251
252
  if (signal?.aborted)
252
253
  break;
253
254
  try {
@@ -264,8 +265,9 @@ class RestArkProvider {
264
265
  }
265
266
  }
266
267
  catch (error) {
267
- if (error instanceof Error &&
268
- error.name === "AbortError") {
268
+ if (signal?.aborted ||
269
+ (error instanceof Error &&
270
+ error.name === "AbortError")) {
269
271
  break;
270
272
  }
271
273
  // ignore timeout errors, they're expected when the server is not sending anything for 5 min
@@ -273,71 +275,94 @@ class RestArkProvider {
273
275
  console.debug("Timeout error ignored");
274
276
  continue;
275
277
  }
278
+ if ((0, utils_1.isEventSourceError)(error)) {
279
+ throw error;
280
+ }
276
281
  console.error("Event stream error:", error);
277
282
  throw error;
278
283
  }
279
284
  finally {
280
- eventSource.close();
285
+ currentIterator.close();
286
+ iterator = null;
281
287
  }
282
288
  }
283
289
  }
284
290
  finally {
285
291
  signal?.removeEventListener("abort", abortHandler);
286
- eventSource?.close();
292
+ closeIterator();
287
293
  }
288
294
  })();
289
295
  const origReturn = gen.return.bind(gen);
290
296
  gen.return = (value) => {
291
- eventSource?.close();
297
+ closeIterator();
292
298
  return origReturn(value);
293
299
  };
294
300
  return gen;
295
301
  }
296
- async *getTransactionsStream(signal) {
302
+ getTransactionsStream(signal) {
297
303
  const url = `${this.serverUrl}/v1/txs`;
298
- while (!signal?.aborted) {
304
+ let iterator = null;
305
+ const closeIterator = () => iterator?.close();
306
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
307
+ const self = this;
308
+ const gen = (async function* () {
309
+ const abortHandler = closeIterator;
310
+ signal?.addEventListener("abort", abortHandler);
299
311
  try {
300
- const eventSource = new EventSource(url);
301
- // Set up abort handling
302
- const abortHandler = () => {
303
- eventSource.close();
304
- };
305
- signal?.addEventListener("abort", abortHandler);
306
- try {
307
- for await (const event of (0, utils_1.eventSourceIterator)(eventSource)) {
308
- if (signal?.aborted)
309
- break;
310
- try {
311
- const data = JSON.parse(event.data);
312
- const txNotification = this.parseTransactionNotification(data);
313
- if (txNotification) {
314
- yield txNotification;
312
+ while (!signal?.aborted) {
313
+ try {
314
+ const currentIterator = (0, utils_1.eventSourceIterator)(new EventSource(url));
315
+ iterator = currentIterator;
316
+ for await (const event of currentIterator) {
317
+ if (signal?.aborted)
318
+ break;
319
+ try {
320
+ const data = JSON.parse(event.data);
321
+ const txNotification = self.parseTransactionNotification(data);
322
+ if (txNotification) {
323
+ yield txNotification;
324
+ }
325
+ }
326
+ catch (err) {
327
+ console.error("Failed to parse transaction notification:", err);
328
+ throw err;
315
329
  }
316
330
  }
317
- catch (err) {
318
- console.error("Failed to parse transaction notification:", err);
319
- throw err;
331
+ }
332
+ catch (error) {
333
+ if (signal?.aborted ||
334
+ (error instanceof Error &&
335
+ error.name === "AbortError")) {
336
+ break;
337
+ }
338
+ // ignore timeout errors, they're expected when the server is not sending anything for 5 min
339
+ if (isFetchTimeoutError(error)) {
340
+ console.debug("Timeout error ignored");
341
+ continue;
342
+ }
343
+ if ((0, utils_1.isEventSourceError)(error)) {
344
+ throw error;
320
345
  }
346
+ console.error("Transaction stream error:", error);
347
+ throw error;
348
+ }
349
+ finally {
350
+ closeIterator();
351
+ iterator = null;
321
352
  }
322
- }
323
- finally {
324
- signal?.removeEventListener("abort", abortHandler);
325
- eventSource.close();
326
353
  }
327
354
  }
328
- catch (error) {
329
- if (error instanceof Error && error.name === "AbortError") {
330
- break;
331
- }
332
- // ignore timeout errors, they're expected when the server is not sending anything for 5 min
333
- if (isFetchTimeoutError(error)) {
334
- console.debug("Timeout error ignored");
335
- continue;
336
- }
337
- console.error("Transaction stream error:", error);
338
- throw error;
355
+ finally {
356
+ signal?.removeEventListener("abort", abortHandler);
357
+ closeIterator();
339
358
  }
340
- }
359
+ })();
360
+ const origReturn = gen.return.bind(gen);
361
+ gen.return = (value) => {
362
+ closeIterator();
363
+ return origReturn(value);
364
+ };
365
+ return gen;
341
366
  }
342
367
  async getPendingTxs(intent) {
343
368
  const url = `${this.serverUrl}/v1/tx/pending`;