@arkade-os/sdk 0.3.12 → 0.4.0-next.0

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 (250) hide show
  1. package/README.md +483 -54
  2. package/dist/cjs/adapters/expo-db.js +35 -0
  3. package/dist/cjs/asset/assetGroup.js +141 -0
  4. package/dist/cjs/asset/assetId.js +88 -0
  5. package/dist/cjs/asset/assetInput.js +204 -0
  6. package/dist/cjs/asset/assetOutput.js +159 -0
  7. package/dist/cjs/asset/assetRef.js +82 -0
  8. package/dist/cjs/asset/index.js +24 -0
  9. package/dist/cjs/asset/metadata.js +172 -0
  10. package/dist/cjs/asset/packet.js +164 -0
  11. package/dist/cjs/asset/types.js +25 -0
  12. package/dist/cjs/asset/utils.js +105 -0
  13. package/dist/cjs/contracts/arkcontract.js +148 -0
  14. package/dist/cjs/contracts/contractManager.js +436 -0
  15. package/dist/cjs/contracts/contractWatcher.js +567 -0
  16. package/dist/cjs/contracts/handlers/default.js +85 -0
  17. package/dist/cjs/contracts/handlers/delegate.js +89 -0
  18. package/dist/cjs/contracts/handlers/helpers.js +105 -0
  19. package/dist/cjs/contracts/handlers/index.js +19 -0
  20. package/dist/cjs/contracts/handlers/registry.js +89 -0
  21. package/dist/cjs/contracts/handlers/vhtlc.js +193 -0
  22. package/dist/cjs/contracts/index.js +41 -0
  23. package/dist/cjs/contracts/types.js +2 -0
  24. package/dist/cjs/db/manager.js +97 -0
  25. package/dist/cjs/forfeit.js +12 -8
  26. package/dist/cjs/identity/index.js +1 -0
  27. package/dist/cjs/identity/seedIdentity.js +255 -0
  28. package/dist/cjs/index.js +70 -14
  29. package/dist/cjs/intent/index.js +28 -2
  30. package/dist/cjs/providers/ark.js +7 -0
  31. package/dist/cjs/providers/delegator.js +66 -0
  32. package/dist/cjs/providers/expoIndexer.js +5 -0
  33. package/dist/cjs/providers/indexer.js +68 -1
  34. package/dist/cjs/providers/onchain.js +2 -2
  35. package/dist/cjs/providers/utils.js +1 -0
  36. package/dist/cjs/repositories/contractRepository.js +0 -103
  37. package/dist/cjs/repositories/inMemory/contractRepository.js +55 -0
  38. package/dist/cjs/repositories/inMemory/walletRepository.js +80 -0
  39. package/dist/cjs/repositories/index.js +16 -0
  40. package/dist/cjs/repositories/indexedDB/contractRepository.js +187 -0
  41. package/dist/cjs/repositories/indexedDB/db.js +57 -0
  42. package/dist/cjs/repositories/indexedDB/schema.js +159 -0
  43. package/dist/cjs/repositories/indexedDB/walletRepository.js +338 -0
  44. package/dist/cjs/repositories/indexedDB/websqlAdapter.js +144 -0
  45. package/dist/cjs/repositories/migrations/contractRepositoryImpl.js +127 -0
  46. package/dist/cjs/repositories/migrations/fromStorageAdapter.js +66 -0
  47. package/dist/cjs/repositories/migrations/walletRepositoryImpl.js +180 -0
  48. package/dist/cjs/repositories/walletRepository.js +0 -169
  49. package/dist/cjs/script/base.js +54 -0
  50. package/dist/cjs/script/delegate.js +49 -0
  51. package/dist/cjs/storage/asyncStorage.js +4 -1
  52. package/dist/cjs/storage/fileSystem.js +3 -0
  53. package/dist/cjs/storage/inMemory.js +3 -0
  54. package/dist/cjs/storage/indexedDB.js +5 -1
  55. package/dist/cjs/storage/localStorage.js +3 -0
  56. package/dist/cjs/utils/arkTransaction.js +16 -0
  57. package/dist/cjs/utils/transactionHistory.js +50 -0
  58. package/dist/cjs/utils/txSizeEstimator.js +39 -14
  59. package/dist/cjs/wallet/asset-manager.js +338 -0
  60. package/dist/cjs/wallet/asset.js +117 -0
  61. package/dist/cjs/wallet/batch.js +1 -1
  62. package/dist/cjs/wallet/delegator.js +235 -0
  63. package/dist/cjs/wallet/expo/background.js +133 -0
  64. package/dist/cjs/wallet/expo/index.js +9 -0
  65. package/dist/cjs/wallet/expo/wallet.js +231 -0
  66. package/dist/cjs/wallet/onchain.js +57 -12
  67. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +568 -0
  68. package/dist/cjs/wallet/serviceWorker/wallet.js +383 -102
  69. package/dist/cjs/wallet/unroll.js +7 -2
  70. package/dist/cjs/wallet/utils.js +60 -0
  71. package/dist/cjs/wallet/validation.js +151 -0
  72. package/dist/cjs/wallet/vtxo-manager.js +1 -1
  73. package/dist/cjs/wallet/wallet.js +702 -260
  74. package/dist/cjs/worker/browser/service-worker-manager.js +82 -0
  75. package/dist/cjs/{wallet/serviceWorker → worker/browser}/utils.js +2 -1
  76. package/dist/cjs/worker/expo/asyncStorageTaskQueue.js +78 -0
  77. package/dist/cjs/worker/expo/index.js +12 -0
  78. package/dist/cjs/worker/expo/processors/contractPollProcessor.js +61 -0
  79. package/dist/cjs/worker/expo/processors/index.js +6 -0
  80. package/dist/cjs/worker/expo/taskQueue.js +41 -0
  81. package/dist/cjs/worker/expo/taskRunner.js +57 -0
  82. package/dist/cjs/worker/messageBus.js +252 -0
  83. package/dist/esm/adapters/expo-db.js +27 -0
  84. package/dist/esm/asset/assetGroup.js +137 -0
  85. package/dist/esm/asset/assetId.js +84 -0
  86. package/dist/esm/asset/assetInput.js +199 -0
  87. package/dist/esm/asset/assetOutput.js +154 -0
  88. package/dist/esm/asset/assetRef.js +78 -0
  89. package/dist/esm/asset/index.js +8 -0
  90. package/dist/esm/asset/metadata.js +167 -0
  91. package/dist/esm/asset/packet.js +159 -0
  92. package/dist/esm/asset/types.js +22 -0
  93. package/dist/esm/asset/utils.js +99 -0
  94. package/dist/esm/contracts/arkcontract.js +141 -0
  95. package/dist/esm/contracts/contractManager.js +432 -0
  96. package/dist/esm/contracts/contractWatcher.js +563 -0
  97. package/dist/esm/contracts/handlers/default.js +82 -0
  98. package/dist/esm/contracts/handlers/delegate.js +86 -0
  99. package/dist/esm/contracts/handlers/helpers.js +66 -0
  100. package/dist/esm/contracts/handlers/index.js +12 -0
  101. package/dist/esm/contracts/handlers/registry.js +86 -0
  102. package/dist/esm/contracts/handlers/vhtlc.js +190 -0
  103. package/dist/esm/contracts/index.js +13 -0
  104. package/dist/esm/contracts/types.js +1 -0
  105. package/dist/esm/db/manager.js +92 -0
  106. package/dist/esm/forfeit.js +11 -8
  107. package/dist/esm/identity/index.js +1 -0
  108. package/dist/esm/identity/seedIdentity.js +249 -0
  109. package/dist/esm/index.js +25 -15
  110. package/dist/esm/intent/index.js +28 -2
  111. package/dist/esm/providers/ark.js +7 -0
  112. package/dist/esm/providers/delegator.js +62 -0
  113. package/dist/esm/providers/expoIndexer.js +5 -0
  114. package/dist/esm/providers/indexer.js +68 -1
  115. package/dist/esm/providers/onchain.js +2 -2
  116. package/dist/esm/providers/utils.js +1 -0
  117. package/dist/esm/repositories/contractRepository.js +1 -101
  118. package/dist/esm/repositories/inMemory/contractRepository.js +51 -0
  119. package/dist/esm/repositories/inMemory/walletRepository.js +76 -0
  120. package/dist/esm/repositories/index.js +8 -0
  121. package/dist/esm/repositories/indexedDB/contractRepository.js +183 -0
  122. package/dist/esm/repositories/indexedDB/db.js +42 -0
  123. package/dist/esm/repositories/indexedDB/schema.js +155 -0
  124. package/dist/esm/repositories/indexedDB/walletRepository.js +334 -0
  125. package/dist/esm/repositories/indexedDB/websqlAdapter.js +138 -0
  126. package/dist/esm/repositories/migrations/contractRepositoryImpl.js +121 -0
  127. package/dist/esm/repositories/migrations/fromStorageAdapter.js +58 -0
  128. package/dist/esm/repositories/migrations/walletRepositoryImpl.js +176 -0
  129. package/dist/esm/repositories/walletRepository.js +1 -167
  130. package/dist/esm/script/base.js +21 -1
  131. package/dist/esm/script/delegate.js +46 -0
  132. package/dist/esm/storage/asyncStorage.js +4 -1
  133. package/dist/esm/storage/fileSystem.js +3 -0
  134. package/dist/esm/storage/inMemory.js +3 -0
  135. package/dist/esm/storage/indexedDB.js +5 -1
  136. package/dist/esm/storage/localStorage.js +3 -0
  137. package/dist/esm/utils/arkTransaction.js +15 -0
  138. package/dist/esm/utils/transactionHistory.js +50 -0
  139. package/dist/esm/utils/txSizeEstimator.js +39 -14
  140. package/dist/esm/wallet/asset-manager.js +333 -0
  141. package/dist/esm/wallet/asset.js +111 -0
  142. package/dist/esm/wallet/batch.js +1 -1
  143. package/dist/esm/wallet/delegator.js +231 -0
  144. package/dist/esm/wallet/expo/background.js +128 -0
  145. package/dist/esm/wallet/expo/index.js +2 -0
  146. package/dist/esm/wallet/expo/wallet.js +194 -0
  147. package/dist/esm/wallet/onchain.js +57 -12
  148. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +564 -0
  149. package/dist/esm/wallet/serviceWorker/wallet.js +382 -101
  150. package/dist/esm/wallet/unroll.js +7 -2
  151. package/dist/esm/wallet/utils.js +55 -0
  152. package/dist/esm/wallet/validation.js +139 -0
  153. package/dist/esm/wallet/vtxo-manager.js +1 -1
  154. package/dist/esm/wallet/wallet.js +704 -229
  155. package/dist/esm/worker/browser/service-worker-manager.js +76 -0
  156. package/dist/esm/{wallet/serviceWorker → worker/browser}/utils.js +2 -1
  157. package/dist/esm/worker/expo/asyncStorageTaskQueue.js +74 -0
  158. package/dist/esm/worker/expo/index.js +4 -0
  159. package/dist/esm/worker/expo/processors/contractPollProcessor.js +58 -0
  160. package/dist/esm/worker/expo/processors/index.js +1 -0
  161. package/dist/esm/worker/expo/taskQueue.js +37 -0
  162. package/dist/esm/worker/expo/taskRunner.js +54 -0
  163. package/dist/esm/worker/messageBus.js +248 -0
  164. package/dist/types/adapters/expo-db.d.ts +7 -0
  165. package/dist/types/asset/assetGroup.d.ts +28 -0
  166. package/dist/types/asset/assetId.d.ts +19 -0
  167. package/dist/types/asset/assetInput.d.ts +46 -0
  168. package/dist/types/asset/assetOutput.d.ts +39 -0
  169. package/dist/types/asset/assetRef.d.ts +25 -0
  170. package/dist/types/asset/index.d.ts +8 -0
  171. package/dist/types/asset/metadata.d.ts +37 -0
  172. package/dist/types/asset/packet.d.ts +27 -0
  173. package/dist/types/asset/types.d.ts +18 -0
  174. package/dist/types/asset/utils.d.ts +21 -0
  175. package/dist/types/contracts/arkcontract.d.ts +101 -0
  176. package/dist/types/contracts/contractManager.d.ts +331 -0
  177. package/dist/types/contracts/contractWatcher.d.ts +192 -0
  178. package/dist/types/contracts/handlers/default.d.ts +19 -0
  179. package/dist/types/contracts/handlers/delegate.d.ts +21 -0
  180. package/dist/types/contracts/handlers/helpers.d.ts +18 -0
  181. package/dist/types/contracts/handlers/index.d.ts +7 -0
  182. package/dist/types/contracts/handlers/registry.d.ts +65 -0
  183. package/dist/types/contracts/handlers/vhtlc.d.ts +32 -0
  184. package/dist/types/contracts/index.d.ts +14 -0
  185. package/dist/types/contracts/types.d.ts +222 -0
  186. package/dist/types/db/manager.d.ts +22 -0
  187. package/dist/types/forfeit.d.ts +2 -1
  188. package/dist/types/identity/index.d.ts +1 -0
  189. package/dist/types/identity/seedIdentity.d.ts +128 -0
  190. package/dist/types/index.d.ts +21 -12
  191. package/dist/types/intent/index.d.ts +2 -1
  192. package/dist/types/providers/ark.d.ts +11 -2
  193. package/dist/types/providers/delegator.d.ts +29 -0
  194. package/dist/types/providers/indexer.d.ts +11 -1
  195. package/dist/types/repositories/contractRepository.d.ts +30 -19
  196. package/dist/types/repositories/inMemory/contractRepository.d.ts +17 -0
  197. package/dist/types/repositories/inMemory/walletRepository.d.ts +26 -0
  198. package/dist/types/repositories/index.d.ts +7 -0
  199. package/dist/types/repositories/indexedDB/contractRepository.d.ts +21 -0
  200. package/dist/types/repositories/indexedDB/db.d.ts +56 -0
  201. package/dist/types/repositories/indexedDB/schema.d.ts +8 -0
  202. package/dist/types/repositories/indexedDB/walletRepository.d.ts +25 -0
  203. package/dist/types/repositories/indexedDB/websqlAdapter.d.ts +49 -0
  204. package/dist/types/repositories/migrations/contractRepositoryImpl.d.ts +24 -0
  205. package/dist/types/repositories/migrations/fromStorageAdapter.d.ts +19 -0
  206. package/dist/types/repositories/migrations/walletRepositoryImpl.d.ts +27 -0
  207. package/dist/types/repositories/walletRepository.d.ts +13 -24
  208. package/dist/types/script/base.d.ts +1 -0
  209. package/dist/types/script/delegate.d.ts +36 -0
  210. package/dist/types/storage/asyncStorage.d.ts +4 -0
  211. package/dist/types/storage/fileSystem.d.ts +3 -0
  212. package/dist/types/storage/inMemory.d.ts +3 -0
  213. package/dist/types/storage/index.d.ts +3 -0
  214. package/dist/types/storage/indexedDB.d.ts +3 -0
  215. package/dist/types/storage/localStorage.d.ts +3 -0
  216. package/dist/types/utils/arkTransaction.d.ts +6 -0
  217. package/dist/types/utils/txSizeEstimator.d.ts +12 -2
  218. package/dist/types/wallet/asset-manager.d.ts +78 -0
  219. package/dist/types/wallet/asset.d.ts +21 -0
  220. package/dist/types/wallet/batch.d.ts +1 -1
  221. package/dist/types/wallet/delegator.d.ts +24 -0
  222. package/dist/types/wallet/expo/background.d.ts +66 -0
  223. package/dist/types/wallet/expo/index.d.ts +4 -0
  224. package/dist/types/wallet/expo/wallet.d.ts +97 -0
  225. package/dist/types/wallet/index.d.ts +75 -2
  226. package/dist/types/wallet/onchain.d.ts +22 -1
  227. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +366 -0
  228. package/dist/types/wallet/serviceWorker/wallet.d.ts +20 -11
  229. package/dist/types/wallet/utils.d.ts +13 -1
  230. package/dist/types/wallet/validation.d.ts +24 -0
  231. package/dist/types/wallet/wallet.d.ts +111 -17
  232. package/dist/types/worker/browser/service-worker-manager.d.ts +21 -0
  233. package/dist/types/{wallet/serviceWorker → worker/browser}/utils.d.ts +2 -1
  234. package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +46 -0
  235. package/dist/types/worker/expo/index.d.ts +7 -0
  236. package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +14 -0
  237. package/dist/types/worker/expo/processors/index.d.ts +1 -0
  238. package/dist/types/worker/expo/taskQueue.d.ts +50 -0
  239. package/dist/types/worker/expo/taskRunner.d.ts +42 -0
  240. package/dist/types/worker/messageBus.d.ts +109 -0
  241. package/package.json +71 -17
  242. package/dist/cjs/wallet/serviceWorker/request.js +0 -78
  243. package/dist/cjs/wallet/serviceWorker/response.js +0 -222
  244. package/dist/cjs/wallet/serviceWorker/worker.js +0 -655
  245. package/dist/esm/wallet/serviceWorker/request.js +0 -75
  246. package/dist/esm/wallet/serviceWorker/response.js +0 -219
  247. package/dist/esm/wallet/serviceWorker/worker.js +0 -651
  248. package/dist/types/wallet/serviceWorker/request.d.ts +0 -74
  249. package/dist/types/wallet/serviceWorker/response.d.ts +0 -123
  250. package/dist/types/wallet/serviceWorker/worker.d.ts +0 -53
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RestIndexerProvider = exports.ChainTxType = exports.IndexerTxType = void 0;
4
+ const base_1 = require("@scure/base");
4
5
  const ark_1 = require("./ark");
5
6
  const utils_1 = require("./utils");
7
+ const asset_1 = require("../asset");
6
8
  var IndexerTxType;
7
9
  (function (IndexerTxType) {
8
10
  IndexerTxType[IndexerTxType["INDEXER_TX_TYPE_UNSPECIFIED"] = 0] = "INDEXER_TX_TYPE_UNSPECIFIED";
@@ -301,6 +303,26 @@ class RestIndexerProvider {
301
303
  page: data.page,
302
304
  };
303
305
  }
306
+ async getAssetDetails(assetId) {
307
+ const url = `${this.serverUrl}/v1/indexer/asset/${encodeURIComponent(assetId)}`;
308
+ const res = await fetch(url);
309
+ if (!res.ok) {
310
+ throw new Error(`Failed to fetch asset details: ${res.statusText}`);
311
+ }
312
+ const data = await res.json();
313
+ if (!Response.isGetAssetResponse(data)) {
314
+ throw new Error("Invalid get asset response");
315
+ }
316
+ const metadata = data.metadata?.length
317
+ ? parseAssetMetadata(data.metadata)
318
+ : undefined;
319
+ return {
320
+ assetId: data.assetId ?? assetId,
321
+ supply: Number(data.supply ?? 0),
322
+ metadata,
323
+ controlAssetId: data.controlAsset || undefined,
324
+ };
325
+ }
304
326
  async subscribeForScripts(scripts, subscriptionId) {
305
327
  const url = `${this.serverUrl}/v1/indexer/script/subscribe`;
306
328
  const res = await fetch(url, {
@@ -335,6 +357,29 @@ class RestIndexerProvider {
335
357
  }
336
358
  }
337
359
  exports.RestIndexerProvider = RestIndexerProvider;
360
+ function parseAssetMetadata(metadata) {
361
+ const metadataList = asset_1.MetadataList.fromString(metadata);
362
+ const out = {};
363
+ const decoder = new TextDecoder();
364
+ for (const { key, value } of metadataList.items) {
365
+ const keyString = decoder.decode(key);
366
+ switch (keyString) {
367
+ case "decimals":
368
+ const n = Number(decoder.decode(value));
369
+ out[keyString] = Number.isFinite(n) ? n : base_1.hex.encode(value);
370
+ break;
371
+ case "name":
372
+ case "ticker":
373
+ case "icon":
374
+ out[keyString] = decoder.decode(value);
375
+ break;
376
+ default:
377
+ out[keyString] = base_1.hex.encode(value);
378
+ break;
379
+ }
380
+ }
381
+ return out;
382
+ }
338
383
  function convertVtxo(vtxo) {
339
384
  return {
340
385
  txid: vtxo.outpoint.txid,
@@ -361,6 +406,10 @@ function convertVtxo(vtxo) {
361
406
  createdAt: new Date(Number(vtxo.createdAt) * 1000),
362
407
  isUnrolled: vtxo.isUnrolled,
363
408
  isSpent: vtxo.isSpent,
409
+ assets: vtxo.assets?.map((a) => ({
410
+ assetId: a.assetId,
411
+ amount: Number(a.amount),
412
+ })),
364
413
  };
365
414
  }
366
415
  // Unexported namespace for type guards only
@@ -435,6 +484,12 @@ var Response;
435
484
  return Array.isArray(data) && data.every(isTxid);
436
485
  }
437
486
  Response.isTxidArray = isTxidArray;
487
+ function isVtxoAsset(data) {
488
+ return (typeof data === "object" &&
489
+ data !== null &&
490
+ typeof data.assetId === "string" &&
491
+ typeof data.amount === "string");
492
+ }
438
493
  function isVtxo(data) {
439
494
  return (typeof data === "object" &&
440
495
  isOutpoint(data.outpoint) &&
@@ -450,7 +505,9 @@ var Response;
450
505
  (!data.settledBy || typeof data.settledBy === "string") &&
451
506
  (!data.arkTxid || typeof data.arkTxid === "string") &&
452
507
  Array.isArray(data.commitmentTxids) &&
453
- data.commitmentTxids.every(isTxid));
508
+ data.commitmentTxids.every(isTxid) &&
509
+ (data.assets === undefined ||
510
+ (Array.isArray(data.assets) && data.assets.every(isVtxoAsset))));
454
511
  }
455
512
  function isPageResponse(data) {
456
513
  return (typeof data === "object" &&
@@ -519,4 +576,14 @@ var Response;
519
576
  (!data.page || isPageResponse(data.page)));
520
577
  }
521
578
  Response.isVtxosResponse = isVtxosResponse;
579
+ function isGetAssetResponse(data) {
580
+ return (typeof data === "object" &&
581
+ data !== null &&
582
+ typeof data.assetId === "string" &&
583
+ typeof data.supply === "string" &&
584
+ (data.controlAsset === undefined ||
585
+ typeof data.controlAsset === "string") &&
586
+ (data.metadata === undefined || typeof data.metadata === "string"));
587
+ }
588
+ Response.isGetAssetResponse = isGetAssetResponse;
522
589
  })(Response || (Response = {}));
@@ -235,14 +235,14 @@ exports.EsploraProvider = EsploraProvider;
235
235
  function isValidBlocksTip(tip) {
236
236
  return (Array.isArray(tip) &&
237
237
  tip.every((t) => {
238
- t &&
238
+ return (t &&
239
239
  typeof t === "object" &&
240
240
  typeof t.id === "string" &&
241
241
  t.id.length > 0 &&
242
242
  typeof t.height === "number" &&
243
243
  t.height >= 0 &&
244
244
  typeof t.mediantime === "number" &&
245
- t.mediantime > 0;
245
+ t.mediantime > 0);
246
246
  }));
247
247
  }
248
248
  const isExplorerTransaction = (tx) => {
@@ -17,6 +17,7 @@ async function* eventSourceIterator(eventSource) {
17
17
  };
18
18
  const errorHandler = () => {
19
19
  const error = new Error("EventSource error");
20
+ error.name = "EventSourceError";
20
21
  if (errorResolve) {
21
22
  errorResolve(error);
22
23
  errorResolve = null;
@@ -1,105 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ContractRepositoryImpl = void 0;
4
- const getContractStorageKey = (id, key) => `contract:${id}:${key}`;
5
- const getCollectionStorageKey = (type) => `collection:${type}`;
6
- class ContractRepositoryImpl {
7
- constructor(storage) {
8
- this.storage = storage;
9
- }
10
- async getContractData(contractId, key) {
11
- const stored = await this.storage.getItem(getContractStorageKey(contractId, key));
12
- if (!stored)
13
- return null;
14
- try {
15
- const data = JSON.parse(stored);
16
- return data;
17
- }
18
- catch (error) {
19
- console.error(`Failed to parse contract data for ${contractId}:${key}:`, error);
20
- return null;
21
- }
22
- }
23
- async setContractData(contractId, key, data) {
24
- try {
25
- await this.storage.setItem(getContractStorageKey(contractId, key), JSON.stringify(data));
26
- }
27
- catch (error) {
28
- console.error(`Failed to persist contract data for ${contractId}:${key}:`, error);
29
- throw error; // Rethrow to notify caller of failure
30
- }
31
- }
32
- async deleteContractData(contractId, key) {
33
- try {
34
- await this.storage.removeItem(getContractStorageKey(contractId, key));
35
- }
36
- catch (error) {
37
- console.error(`Failed to remove contract data for ${contractId}:${key}:`, error);
38
- throw error; // Rethrow to notify caller of failure
39
- }
40
- }
41
- async getContractCollection(contractType) {
42
- const stored = await this.storage.getItem(getCollectionStorageKey(contractType));
43
- if (!stored)
44
- return [];
45
- try {
46
- const collection = JSON.parse(stored);
47
- return collection;
48
- }
49
- catch (error) {
50
- console.error(`Failed to parse contract collection ${contractType}:`, error);
51
- return [];
52
- }
53
- }
54
- async saveToContractCollection(contractType, item, idField) {
55
- const collection = await this.getContractCollection(contractType);
56
- // Validate that the item has the required id field
57
- const itemId = item[idField];
58
- if (itemId === undefined || itemId === null) {
59
- throw new Error(`Item is missing required field '${String(idField)}'`);
60
- }
61
- // Find existing item index without mutating the original collection
62
- const existingIndex = collection.findIndex((i) => i[idField] === itemId);
63
- // Build new collection without mutating the cached one
64
- let newCollection;
65
- if (existingIndex !== -1) {
66
- // Replace existing item
67
- newCollection = [
68
- ...collection.slice(0, existingIndex),
69
- item,
70
- ...collection.slice(existingIndex + 1),
71
- ];
72
- }
73
- else {
74
- // Add new item
75
- newCollection = [...collection, item];
76
- }
77
- try {
78
- await this.storage.setItem(getCollectionStorageKey(contractType), JSON.stringify(newCollection));
79
- }
80
- catch (error) {
81
- console.error(`Failed to persist contract collection ${contractType}:`, error);
82
- throw error; // Rethrow to notify caller of failure
83
- }
84
- }
85
- async removeFromContractCollection(contractType, id, idField) {
86
- // Validate input parameters
87
- if (id === undefined || id === null) {
88
- throw new Error(`Invalid id provided for removal: ${String(id)}`);
89
- }
90
- const collection = await this.getContractCollection(contractType);
91
- // Build new collection without the specified item
92
- const filtered = collection.filter((item) => item[idField] !== id);
93
- try {
94
- await this.storage.setItem(getCollectionStorageKey(contractType), JSON.stringify(filtered));
95
- }
96
- catch (error) {
97
- console.error(`Failed to persist contract collection removal for ${contractType}:`, error);
98
- throw error; // Rethrow to notify caller of failure
99
- }
100
- }
101
- async clearContractData() {
102
- await this.storage.clear();
103
- }
104
- }
105
- exports.ContractRepositoryImpl = ContractRepositoryImpl;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InMemoryContractRepository = void 0;
4
+ /**
5
+ * In-memory implementation of ContractRepository.
6
+ * Data is ephemeral and scoped to the instance.
7
+ */
8
+ class InMemoryContractRepository {
9
+ constructor() {
10
+ this.version = 1;
11
+ this.contractData = new Map();
12
+ this.collections = new Map();
13
+ this.contractsByScript = new Map();
14
+ }
15
+ async clear() {
16
+ this.contractData.clear();
17
+ this.collections.clear();
18
+ this.contractsByScript.clear();
19
+ }
20
+ // Contract entity management methods
21
+ async getContracts(filter) {
22
+ const contracts = this.contractsByScript.values();
23
+ if (!filter) {
24
+ return [...contracts];
25
+ }
26
+ const matches = (value, criterion) => {
27
+ if (criterion === undefined) {
28
+ return true;
29
+ }
30
+ return Array.isArray(criterion)
31
+ ? criterion.includes(value)
32
+ : value === criterion;
33
+ };
34
+ const results = [];
35
+ for (const contract of contracts) {
36
+ if (matches(contract.script, filter.script) &&
37
+ matches(contract.state, filter.state) &&
38
+ matches(contract.type, filter.type)) {
39
+ results.push(contract);
40
+ }
41
+ }
42
+ return results;
43
+ }
44
+ async saveContract(contract) {
45
+ this.contractsByScript.set(contract.script, contract);
46
+ }
47
+ async deleteContract(script) {
48
+ this.contractsByScript.delete(script);
49
+ }
50
+ async [Symbol.asyncDispose]() {
51
+ // nothing to dispose, data is ephemeral and scoped to the instance
52
+ return;
53
+ }
54
+ }
55
+ exports.InMemoryContractRepository = InMemoryContractRepository;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InMemoryWalletRepository = void 0;
4
+ /**
5
+ * In-memory implementation of WalletRepository.
6
+ * Data is ephemeral and scoped to the instance.
7
+ */
8
+ class InMemoryWalletRepository {
9
+ constructor() {
10
+ this.version = 1;
11
+ this.vtxosByAddress = new Map();
12
+ this.utxosByAddress = new Map();
13
+ this.txsByAddress = new Map();
14
+ this.walletState = null;
15
+ }
16
+ async getVtxos(address) {
17
+ return this.vtxosByAddress.get(address) ?? [];
18
+ }
19
+ async saveVtxos(address, vtxos) {
20
+ const existing = this.vtxosByAddress.get(address) ?? [];
21
+ const next = mergeByKey(existing, vtxos, (item) => `${item.txid}:${item.vout}`);
22
+ this.vtxosByAddress.set(address, next);
23
+ }
24
+ async deleteVtxos(address) {
25
+ this.vtxosByAddress.delete(address);
26
+ }
27
+ async getUtxos(address) {
28
+ return this.utxosByAddress.get(address) ?? [];
29
+ }
30
+ async saveUtxos(address, utxos) {
31
+ const existing = this.utxosByAddress.get(address) ?? [];
32
+ const next = mergeByKey(existing, utxos, (item) => `${item.txid}:${item.vout}`);
33
+ this.utxosByAddress.set(address, next);
34
+ }
35
+ async deleteUtxos(address) {
36
+ this.utxosByAddress.delete(address);
37
+ }
38
+ async getTransactionHistory(address) {
39
+ return this.txsByAddress.get(address) ?? [];
40
+ }
41
+ async saveTransactions(address, txs) {
42
+ const existing = this.txsByAddress.get(address) ?? [];
43
+ const next = mergeByKey(existing, txs, serializeTxKey);
44
+ this.txsByAddress.set(address, next);
45
+ }
46
+ async deleteTransactions(address) {
47
+ this.txsByAddress.delete(address);
48
+ }
49
+ async getWalletState() {
50
+ return this.walletState;
51
+ }
52
+ async saveWalletState(state) {
53
+ this.walletState = state;
54
+ }
55
+ async clear() {
56
+ this.vtxosByAddress.clear();
57
+ this.utxosByAddress.clear();
58
+ this.txsByAddress.clear();
59
+ this.walletState = null;
60
+ }
61
+ async [Symbol.asyncDispose]() {
62
+ // nothing to dispose, data is ephemeral and scoped to the instance
63
+ return;
64
+ }
65
+ }
66
+ exports.InMemoryWalletRepository = InMemoryWalletRepository;
67
+ function serializeTxKey(tx) {
68
+ const key = tx.key;
69
+ return `${key.boardingTxid}:${key.commitmentTxid}:${key.arkTxid}`;
70
+ }
71
+ function mergeByKey(existing, incoming, toKey) {
72
+ const next = new Map();
73
+ existing.forEach((item) => {
74
+ next.set(toKey(item), item);
75
+ });
76
+ incoming.forEach((item) => {
77
+ next.set(toKey(item), item);
78
+ });
79
+ return Array.from(next.values());
80
+ }
@@ -14,5 +14,21 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.ContractRepositoryImpl = exports.WalletRepositoryImpl = exports.rollbackMigration = exports.getMigrationStatus = exports.requiresMigration = exports.migrateWalletRepository = exports.MIGRATION_KEY = void 0;
17
18
  __exportStar(require("./walletRepository"), exports);
18
19
  __exportStar(require("./contractRepository"), exports);
20
+ __exportStar(require("./inMemory/walletRepository"), exports);
21
+ __exportStar(require("./inMemory/contractRepository"), exports);
22
+ __exportStar(require("./indexedDB/contractRepository"), exports);
23
+ __exportStar(require("./indexedDB/walletRepository"), exports);
24
+ var fromStorageAdapter_1 = require("./migrations/fromStorageAdapter");
25
+ Object.defineProperty(exports, "MIGRATION_KEY", { enumerable: true, get: function () { return fromStorageAdapter_1.MIGRATION_KEY; } });
26
+ Object.defineProperty(exports, "migrateWalletRepository", { enumerable: true, get: function () { return fromStorageAdapter_1.migrateWalletRepository; } });
27
+ Object.defineProperty(exports, "requiresMigration", { enumerable: true, get: function () { return fromStorageAdapter_1.requiresMigration; } });
28
+ Object.defineProperty(exports, "getMigrationStatus", { enumerable: true, get: function () { return fromStorageAdapter_1.getMigrationStatus; } });
29
+ Object.defineProperty(exports, "rollbackMigration", { enumerable: true, get: function () { return fromStorageAdapter_1.rollbackMigration; } });
30
+ // Deprecated
31
+ var walletRepositoryImpl_1 = require("./migrations/walletRepositoryImpl");
32
+ Object.defineProperty(exports, "WalletRepositoryImpl", { enumerable: true, get: function () { return walletRepositoryImpl_1.WalletRepositoryImpl; } });
33
+ var contractRepositoryImpl_1 = require("./migrations/contractRepositoryImpl");
34
+ Object.defineProperty(exports, "ContractRepositoryImpl", { enumerable: true, get: function () { return contractRepositoryImpl_1.ContractRepositoryImpl; } });
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IndexedDBContractRepository = void 0;
4
+ const db_1 = require("./db");
5
+ const manager_1 = require("../../db/manager");
6
+ const schema_1 = require("./schema");
7
+ const utils_1 = require("../../worker/browser/utils");
8
+ /**
9
+ * IndexedDB-based implementation of ContractRepository.
10
+ *
11
+ * Data is stored as JSON strings in key/value stores.
12
+ */
13
+ class IndexedDBContractRepository {
14
+ constructor(dbName = utils_1.DEFAULT_DB_NAME) {
15
+ this.dbName = dbName;
16
+ this.version = 1;
17
+ this.db = null;
18
+ }
19
+ async clear() {
20
+ try {
21
+ const db = await this.getDB();
22
+ return new Promise((resolve, reject) => {
23
+ const transaction = db.transaction([db_1.STORE_CONTRACTS], "readwrite");
24
+ const contractDataStore = transaction.objectStore(db_1.STORE_CONTRACTS);
25
+ const contractsStore = transaction.objectStore(db_1.STORE_CONTRACTS);
26
+ const contractDataRequest = contractDataStore.clear();
27
+ const contractsRequest = contractsStore.clear();
28
+ let completed = 0;
29
+ const checkComplete = () => {
30
+ completed++;
31
+ if (completed === 2) {
32
+ resolve();
33
+ }
34
+ };
35
+ contractDataRequest.onsuccess = checkComplete;
36
+ contractsRequest.onsuccess = checkComplete;
37
+ contractDataRequest.onerror = () => reject(contractDataRequest.error);
38
+ contractsRequest.onerror = () => reject(contractsRequest.error);
39
+ });
40
+ }
41
+ catch (error) {
42
+ console.error("Failed to clear contract data:", error);
43
+ throw error;
44
+ }
45
+ }
46
+ async getContracts(filter) {
47
+ try {
48
+ const db = await this.getDB();
49
+ const store = db
50
+ .transaction([db_1.STORE_CONTRACTS], "readonly")
51
+ .objectStore(db_1.STORE_CONTRACTS);
52
+ if (!filter || Object.keys(filter).length === 0) {
53
+ return new Promise((resolve, reject) => {
54
+ const request = store.getAll();
55
+ request.onerror = () => reject(request.error);
56
+ request.onsuccess = () => resolve(request.result ?? []);
57
+ });
58
+ }
59
+ const normalizedFilter = normalizeFilter(filter);
60
+ // first by script, primary key
61
+ if (normalizedFilter.has("script")) {
62
+ const scripts = normalizedFilter.get("script");
63
+ const contracts = await Promise.all(scripts.map((script) => new Promise((resolve, reject) => {
64
+ const req = store.get(script);
65
+ req.onerror = () => reject(req.error);
66
+ req.onsuccess = () => resolve(req.result);
67
+ })));
68
+ return this.applyContractFilter(contracts, normalizedFilter);
69
+ }
70
+ // by state, still an index
71
+ if (normalizedFilter.has("state")) {
72
+ const contracts = await this.getContractsByIndexValues(store, "state", normalizedFilter.get("state"));
73
+ return this.applyContractFilter(contracts, normalizedFilter);
74
+ }
75
+ // by type, still an index
76
+ if (normalizedFilter.has("type")) {
77
+ const contracts = await this.getContractsByIndexValues(store, "type", normalizedFilter.get("type"));
78
+ return this.applyContractFilter(contracts, normalizedFilter);
79
+ }
80
+ // any other filtering happens in-memory
81
+ const allContracts = await new Promise((resolve, reject) => {
82
+ const request = store.getAll();
83
+ request.onerror = () => reject(request.error);
84
+ request.onsuccess = () => resolve(request.result ?? []);
85
+ });
86
+ return this.applyContractFilter(allContracts, normalizedFilter);
87
+ }
88
+ catch (error) {
89
+ console.error("Failed to get contracts:", error);
90
+ return [];
91
+ }
92
+ }
93
+ async saveContract(contract) {
94
+ try {
95
+ const db = await this.getDB();
96
+ return new Promise((resolve, reject) => {
97
+ const transaction = db.transaction([db_1.STORE_CONTRACTS], "readwrite");
98
+ const store = transaction.objectStore(db_1.STORE_CONTRACTS);
99
+ const request = store.put(contract);
100
+ request.onerror = () => reject(request.error);
101
+ request.onsuccess = () => resolve();
102
+ });
103
+ }
104
+ catch (error) {
105
+ console.error("Failed to save contract:", error);
106
+ throw error;
107
+ }
108
+ }
109
+ async deleteContract(script) {
110
+ try {
111
+ const db = await this.getDB();
112
+ return new Promise((resolve, reject) => {
113
+ const transaction = db.transaction([db_1.STORE_CONTRACTS], "readwrite");
114
+ const store = transaction.objectStore(db_1.STORE_CONTRACTS);
115
+ const getRequest = store.get(script);
116
+ getRequest.onerror = () => reject(getRequest.error);
117
+ getRequest.onsuccess = () => {
118
+ const request = store.delete(script);
119
+ request.onerror = () => reject(request.error);
120
+ request.onsuccess = () => resolve();
121
+ };
122
+ });
123
+ }
124
+ catch (error) {
125
+ console.error(`Failed to delete contract ${script}:`, error);
126
+ throw error;
127
+ }
128
+ }
129
+ getContractsByIndexValues(store, indexName, values) {
130
+ if (values.length === 0)
131
+ return Promise.resolve([]);
132
+ const index = store.index(indexName);
133
+ const requests = values.map((value) => new Promise((resolve, reject) => {
134
+ const request = index.getAll(value);
135
+ request.onerror = () => reject(request.error);
136
+ request.onsuccess = () => resolve(request.result ?? []);
137
+ }));
138
+ return Promise.all(requests).then((results) => results.flatMap((result) => result));
139
+ }
140
+ applyContractFilter(
141
+ // can filter directly the result of a query
142
+ contracts, filter) {
143
+ return contracts.filter((contract) => {
144
+ if (contract === undefined)
145
+ return false;
146
+ if (filter.has("script") &&
147
+ !filter.get("script")?.includes(contract.script))
148
+ return false;
149
+ if (filter.has("state") &&
150
+ !filter.get("state")?.includes(contract.state))
151
+ return false;
152
+ if (filter.has("type") &&
153
+ !filter.get("type")?.includes(contract.type))
154
+ return false;
155
+ return true;
156
+ });
157
+ }
158
+ async getDB() {
159
+ if (this.db)
160
+ return this.db;
161
+ this.db = await (0, manager_1.openDatabase)(this.dbName, db_1.DB_VERSION, schema_1.initDatabase);
162
+ return this.db;
163
+ }
164
+ async [Symbol.asyncDispose]() {
165
+ if (!this.db)
166
+ return;
167
+ await (0, manager_1.closeDatabase)(this.dbName);
168
+ this.db = null;
169
+ }
170
+ }
171
+ exports.IndexedDBContractRepository = IndexedDBContractRepository;
172
+ const FILTER_FIELDS = ["script", "state", "type"];
173
+ // Transform all filter fields into an array of values
174
+ function normalizeFilter(filter) {
175
+ const res = new Map();
176
+ FILTER_FIELDS.forEach((current) => {
177
+ if (!filter?.[current])
178
+ return;
179
+ if (Array.isArray(filter[current])) {
180
+ res.set(current, filter[current]);
181
+ }
182
+ else {
183
+ res.set(current, [filter[current]]);
184
+ }
185
+ });
186
+ return res;
187
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deserializeUtxo = exports.deserializeVtxo = exports.deserializeTapLeaf = exports.serializeUtxo = exports.serializeVtxo = exports.serializeTapLeaf = exports.DB_VERSION = exports.LEGACY_STORE_CONTRACT_COLLECTIONS = exports.STORE_CONTRACTS = exports.STORE_WALLET_STATE = exports.STORE_TRANSACTIONS = exports.STORE_UTXOS = exports.STORE_VTXOS = void 0;
4
+ const base_1 = require("@scure/base");
5
+ const btc_signer_1 = require("@scure/btc-signer");
6
+ const schema_1 = require("./schema");
7
+ Object.defineProperty(exports, "DB_VERSION", { enumerable: true, get: function () { return schema_1.DB_VERSION; } });
8
+ Object.defineProperty(exports, "STORE_CONTRACTS", { enumerable: true, get: function () { return schema_1.STORE_CONTRACTS; } });
9
+ Object.defineProperty(exports, "LEGACY_STORE_CONTRACT_COLLECTIONS", { enumerable: true, get: function () { return schema_1.LEGACY_STORE_CONTRACT_COLLECTIONS; } });
10
+ Object.defineProperty(exports, "STORE_TRANSACTIONS", { enumerable: true, get: function () { return schema_1.STORE_TRANSACTIONS; } });
11
+ Object.defineProperty(exports, "STORE_UTXOS", { enumerable: true, get: function () { return schema_1.STORE_UTXOS; } });
12
+ Object.defineProperty(exports, "STORE_VTXOS", { enumerable: true, get: function () { return schema_1.STORE_VTXOS; } });
13
+ Object.defineProperty(exports, "STORE_WALLET_STATE", { enumerable: true, get: function () { return schema_1.STORE_WALLET_STATE; } });
14
+ const serializeTapLeaf = ([cb, s]) => ({
15
+ cb: base_1.hex.encode(btc_signer_1.TaprootControlBlock.encode(cb)),
16
+ s: base_1.hex.encode(s),
17
+ });
18
+ exports.serializeTapLeaf = serializeTapLeaf;
19
+ const serializeVtxo = (v) => ({
20
+ ...v,
21
+ tapTree: base_1.hex.encode(v.tapTree),
22
+ forfeitTapLeafScript: (0, exports.serializeTapLeaf)(v.forfeitTapLeafScript),
23
+ intentTapLeafScript: (0, exports.serializeTapLeaf)(v.intentTapLeafScript),
24
+ extraWitness: v.extraWitness?.map(base_1.hex.encode),
25
+ });
26
+ exports.serializeVtxo = serializeVtxo;
27
+ const serializeUtxo = (u) => ({
28
+ ...u,
29
+ tapTree: base_1.hex.encode(u.tapTree),
30
+ forfeitTapLeafScript: (0, exports.serializeTapLeaf)(u.forfeitTapLeafScript),
31
+ intentTapLeafScript: (0, exports.serializeTapLeaf)(u.intentTapLeafScript),
32
+ extraWitness: u.extraWitness?.map(base_1.hex.encode),
33
+ });
34
+ exports.serializeUtxo = serializeUtxo;
35
+ const deserializeTapLeaf = (t) => {
36
+ const cb = btc_signer_1.TaprootControlBlock.decode(base_1.hex.decode(t.cb));
37
+ const s = base_1.hex.decode(t.s);
38
+ return [cb, s];
39
+ };
40
+ exports.deserializeTapLeaf = deserializeTapLeaf;
41
+ const deserializeVtxo = (o) => ({
42
+ ...o,
43
+ createdAt: new Date(o.createdAt),
44
+ tapTree: base_1.hex.decode(o.tapTree),
45
+ forfeitTapLeafScript: (0, exports.deserializeTapLeaf)(o.forfeitTapLeafScript),
46
+ intentTapLeafScript: (0, exports.deserializeTapLeaf)(o.intentTapLeafScript),
47
+ extraWitness: o.extraWitness?.map(base_1.hex.decode),
48
+ });
49
+ exports.deserializeVtxo = deserializeVtxo;
50
+ const deserializeUtxo = (o) => ({
51
+ ...o,
52
+ tapTree: base_1.hex.decode(o.tapTree),
53
+ forfeitTapLeafScript: (0, exports.deserializeTapLeaf)(o.forfeitTapLeafScript),
54
+ intentTapLeafScript: (0, exports.deserializeTapLeaf)(o.intentTapLeafScript),
55
+ extraWitness: o.extraWitness?.map(base_1.hex.decode),
56
+ });
57
+ exports.deserializeUtxo = deserializeUtxo;