@arkade-os/sdk 0.3.13 → 0.4.0-next.1

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 (270) hide show
  1. package/README.md +586 -54
  2. package/dist/cjs/asset/assetGroup.js +141 -0
  3. package/dist/cjs/asset/assetId.js +88 -0
  4. package/dist/cjs/asset/assetInput.js +204 -0
  5. package/dist/cjs/asset/assetOutput.js +159 -0
  6. package/dist/cjs/asset/assetRef.js +82 -0
  7. package/dist/cjs/asset/index.js +24 -0
  8. package/dist/cjs/asset/metadata.js +172 -0
  9. package/dist/cjs/asset/packet.js +164 -0
  10. package/dist/cjs/asset/types.js +25 -0
  11. package/dist/cjs/asset/utils.js +105 -0
  12. package/dist/cjs/bip322/index.js +270 -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/forfeit.js +12 -8
  25. package/dist/cjs/identity/index.js +1 -0
  26. package/dist/cjs/identity/seedIdentity.js +255 -0
  27. package/dist/cjs/index.js +72 -14
  28. package/dist/cjs/intent/index.js +47 -11
  29. package/dist/cjs/providers/ark.js +7 -0
  30. package/dist/cjs/providers/delegator.js +66 -0
  31. package/dist/cjs/providers/expoIndexer.js +5 -0
  32. package/dist/cjs/providers/indexer.js +68 -1
  33. package/dist/cjs/providers/utils.js +1 -0
  34. package/dist/cjs/repositories/contractRepository.js +0 -103
  35. package/dist/cjs/repositories/inMemory/contractRepository.js +55 -0
  36. package/dist/cjs/repositories/inMemory/walletRepository.js +80 -0
  37. package/dist/cjs/repositories/index.js +16 -0
  38. package/dist/cjs/repositories/indexedDB/contractRepository.js +187 -0
  39. package/dist/cjs/repositories/indexedDB/db.js +19 -0
  40. package/dist/cjs/repositories/indexedDB/manager.js +97 -0
  41. package/dist/cjs/repositories/indexedDB/schema.js +159 -0
  42. package/dist/cjs/repositories/indexedDB/walletRepository.js +338 -0
  43. package/dist/cjs/repositories/indexedDB/websqlAdapter.js +144 -0
  44. package/dist/cjs/repositories/migrations/contractRepositoryImpl.js +127 -0
  45. package/dist/cjs/repositories/migrations/fromStorageAdapter.js +66 -0
  46. package/dist/cjs/repositories/migrations/walletRepositoryImpl.js +180 -0
  47. package/dist/cjs/repositories/realm/contractRepository.js +120 -0
  48. package/dist/cjs/repositories/realm/index.js +9 -0
  49. package/dist/cjs/repositories/realm/schemas.js +108 -0
  50. package/dist/cjs/repositories/realm/types.js +7 -0
  51. package/dist/cjs/repositories/realm/walletRepository.js +273 -0
  52. package/dist/cjs/repositories/serialization.js +49 -0
  53. package/dist/cjs/repositories/sqlite/contractRepository.js +139 -0
  54. package/dist/cjs/repositories/sqlite/index.js +7 -0
  55. package/dist/cjs/repositories/sqlite/types.js +2 -0
  56. package/dist/cjs/repositories/sqlite/walletRepository.js +328 -0
  57. package/dist/cjs/repositories/walletRepository.js +0 -169
  58. package/dist/cjs/script/base.js +54 -0
  59. package/dist/cjs/script/delegate.js +49 -0
  60. package/dist/cjs/storage/asyncStorage.js +4 -1
  61. package/dist/cjs/storage/fileSystem.js +3 -0
  62. package/dist/cjs/storage/inMemory.js +3 -0
  63. package/dist/cjs/storage/indexedDB.js +5 -1
  64. package/dist/cjs/storage/localStorage.js +3 -0
  65. package/dist/cjs/utils/arkTransaction.js +16 -0
  66. package/dist/cjs/utils/transactionHistory.js +50 -0
  67. package/dist/cjs/wallet/asset-manager.js +338 -0
  68. package/dist/cjs/wallet/asset.js +117 -0
  69. package/dist/cjs/wallet/batch.js +1 -1
  70. package/dist/cjs/wallet/delegator.js +235 -0
  71. package/dist/cjs/wallet/expo/background.js +133 -0
  72. package/dist/cjs/wallet/expo/index.js +9 -0
  73. package/dist/cjs/wallet/expo/wallet.js +231 -0
  74. package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +568 -0
  75. package/dist/cjs/wallet/serviceWorker/wallet.js +383 -102
  76. package/dist/cjs/wallet/utils.js +58 -0
  77. package/dist/cjs/wallet/validation.js +151 -0
  78. package/dist/cjs/wallet/vtxo-manager.js +8 -1
  79. package/dist/cjs/wallet/wallet.js +702 -260
  80. package/dist/cjs/worker/browser/service-worker-manager.js +82 -0
  81. package/dist/cjs/{wallet/serviceWorker → worker/browser}/utils.js +2 -1
  82. package/dist/cjs/worker/expo/asyncStorageTaskQueue.js +78 -0
  83. package/dist/cjs/worker/expo/index.js +12 -0
  84. package/dist/cjs/worker/expo/processors/contractPollProcessor.js +61 -0
  85. package/dist/cjs/worker/expo/processors/index.js +6 -0
  86. package/dist/cjs/worker/expo/taskQueue.js +41 -0
  87. package/dist/cjs/worker/expo/taskRunner.js +57 -0
  88. package/dist/cjs/worker/messageBus.js +252 -0
  89. package/dist/esm/asset/assetGroup.js +137 -0
  90. package/dist/esm/asset/assetId.js +84 -0
  91. package/dist/esm/asset/assetInput.js +199 -0
  92. package/dist/esm/asset/assetOutput.js +154 -0
  93. package/dist/esm/asset/assetRef.js +78 -0
  94. package/dist/esm/asset/index.js +8 -0
  95. package/dist/esm/asset/metadata.js +167 -0
  96. package/dist/esm/asset/packet.js +159 -0
  97. package/dist/esm/asset/types.js +22 -0
  98. package/dist/esm/asset/utils.js +99 -0
  99. package/dist/esm/bip322/index.js +267 -0
  100. package/dist/esm/contracts/arkcontract.js +141 -0
  101. package/dist/esm/contracts/contractManager.js +432 -0
  102. package/dist/esm/contracts/contractWatcher.js +563 -0
  103. package/dist/esm/contracts/handlers/default.js +82 -0
  104. package/dist/esm/contracts/handlers/delegate.js +86 -0
  105. package/dist/esm/contracts/handlers/helpers.js +66 -0
  106. package/dist/esm/contracts/handlers/index.js +12 -0
  107. package/dist/esm/contracts/handlers/registry.js +86 -0
  108. package/dist/esm/contracts/handlers/vhtlc.js +190 -0
  109. package/dist/esm/contracts/index.js +13 -0
  110. package/dist/esm/contracts/types.js +1 -0
  111. package/dist/esm/forfeit.js +11 -8
  112. package/dist/esm/identity/index.js +1 -0
  113. package/dist/esm/identity/seedIdentity.js +249 -0
  114. package/dist/esm/index.js +28 -15
  115. package/dist/esm/intent/index.js +44 -9
  116. package/dist/esm/providers/ark.js +7 -0
  117. package/dist/esm/providers/delegator.js +62 -0
  118. package/dist/esm/providers/expoIndexer.js +5 -0
  119. package/dist/esm/providers/indexer.js +68 -1
  120. package/dist/esm/providers/utils.js +1 -0
  121. package/dist/esm/repositories/contractRepository.js +1 -101
  122. package/dist/esm/repositories/inMemory/contractRepository.js +51 -0
  123. package/dist/esm/repositories/inMemory/walletRepository.js +76 -0
  124. package/dist/esm/repositories/index.js +8 -0
  125. package/dist/esm/repositories/indexedDB/contractRepository.js +183 -0
  126. package/dist/esm/repositories/indexedDB/db.js +4 -0
  127. package/dist/esm/repositories/indexedDB/manager.js +92 -0
  128. package/dist/esm/repositories/indexedDB/schema.js +155 -0
  129. package/dist/esm/repositories/indexedDB/walletRepository.js +334 -0
  130. package/dist/esm/repositories/indexedDB/websqlAdapter.js +138 -0
  131. package/dist/esm/repositories/migrations/contractRepositoryImpl.js +121 -0
  132. package/dist/esm/repositories/migrations/fromStorageAdapter.js +58 -0
  133. package/dist/esm/repositories/migrations/walletRepositoryImpl.js +176 -0
  134. package/dist/esm/repositories/realm/contractRepository.js +116 -0
  135. package/dist/esm/repositories/realm/index.js +3 -0
  136. package/dist/esm/repositories/realm/schemas.js +105 -0
  137. package/dist/esm/repositories/realm/types.js +6 -0
  138. package/dist/esm/repositories/realm/walletRepository.js +269 -0
  139. package/dist/esm/repositories/serialization.js +40 -0
  140. package/dist/esm/repositories/sqlite/contractRepository.js +135 -0
  141. package/dist/esm/repositories/sqlite/index.js +2 -0
  142. package/dist/esm/repositories/sqlite/types.js +1 -0
  143. package/dist/esm/repositories/sqlite/walletRepository.js +324 -0
  144. package/dist/esm/repositories/walletRepository.js +1 -167
  145. package/dist/esm/script/base.js +21 -1
  146. package/dist/esm/script/delegate.js +46 -0
  147. package/dist/esm/storage/asyncStorage.js +4 -1
  148. package/dist/esm/storage/fileSystem.js +3 -0
  149. package/dist/esm/storage/inMemory.js +3 -0
  150. package/dist/esm/storage/indexedDB.js +5 -1
  151. package/dist/esm/storage/localStorage.js +3 -0
  152. package/dist/esm/utils/arkTransaction.js +15 -0
  153. package/dist/esm/utils/transactionHistory.js +50 -0
  154. package/dist/esm/wallet/asset-manager.js +333 -0
  155. package/dist/esm/wallet/asset.js +111 -0
  156. package/dist/esm/wallet/batch.js +1 -1
  157. package/dist/esm/wallet/delegator.js +231 -0
  158. package/dist/esm/wallet/expo/background.js +128 -0
  159. package/dist/esm/wallet/expo/index.js +2 -0
  160. package/dist/esm/wallet/expo/wallet.js +194 -0
  161. package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +564 -0
  162. package/dist/esm/wallet/serviceWorker/wallet.js +382 -101
  163. package/dist/esm/wallet/utils.js +54 -0
  164. package/dist/esm/wallet/validation.js +139 -0
  165. package/dist/esm/wallet/vtxo-manager.js +8 -1
  166. package/dist/esm/wallet/wallet.js +704 -229
  167. package/dist/esm/worker/browser/service-worker-manager.js +76 -0
  168. package/dist/esm/{wallet/serviceWorker → worker/browser}/utils.js +2 -1
  169. package/dist/esm/worker/expo/asyncStorageTaskQueue.js +74 -0
  170. package/dist/esm/worker/expo/index.js +4 -0
  171. package/dist/esm/worker/expo/processors/contractPollProcessor.js +58 -0
  172. package/dist/esm/worker/expo/processors/index.js +1 -0
  173. package/dist/esm/worker/expo/taskQueue.js +37 -0
  174. package/dist/esm/worker/expo/taskRunner.js +54 -0
  175. package/dist/esm/worker/messageBus.js +248 -0
  176. package/dist/types/asset/assetGroup.d.ts +28 -0
  177. package/dist/types/asset/assetId.d.ts +19 -0
  178. package/dist/types/asset/assetInput.d.ts +46 -0
  179. package/dist/types/asset/assetOutput.d.ts +39 -0
  180. package/dist/types/asset/assetRef.d.ts +25 -0
  181. package/dist/types/asset/index.d.ts +8 -0
  182. package/dist/types/asset/metadata.d.ts +37 -0
  183. package/dist/types/asset/packet.d.ts +27 -0
  184. package/dist/types/asset/types.d.ts +18 -0
  185. package/dist/types/asset/utils.d.ts +21 -0
  186. package/dist/types/bip322/index.d.ts +55 -0
  187. package/dist/types/contracts/arkcontract.d.ts +101 -0
  188. package/dist/types/contracts/contractManager.d.ts +331 -0
  189. package/dist/types/contracts/contractWatcher.d.ts +192 -0
  190. package/dist/types/contracts/handlers/default.d.ts +19 -0
  191. package/dist/types/contracts/handlers/delegate.d.ts +21 -0
  192. package/dist/types/contracts/handlers/helpers.d.ts +18 -0
  193. package/dist/types/contracts/handlers/index.d.ts +7 -0
  194. package/dist/types/contracts/handlers/registry.d.ts +65 -0
  195. package/dist/types/contracts/handlers/vhtlc.d.ts +32 -0
  196. package/dist/types/contracts/index.d.ts +14 -0
  197. package/dist/types/contracts/types.d.ts +222 -0
  198. package/dist/types/forfeit.d.ts +2 -1
  199. package/dist/types/identity/index.d.ts +1 -0
  200. package/dist/types/identity/seedIdentity.d.ts +128 -0
  201. package/dist/types/index.d.ts +22 -12
  202. package/dist/types/intent/index.d.ts +15 -1
  203. package/dist/types/providers/ark.d.ts +11 -2
  204. package/dist/types/providers/delegator.d.ts +29 -0
  205. package/dist/types/providers/indexer.d.ts +11 -1
  206. package/dist/types/repositories/contractRepository.d.ts +30 -19
  207. package/dist/types/repositories/inMemory/contractRepository.d.ts +17 -0
  208. package/dist/types/repositories/inMemory/walletRepository.d.ts +26 -0
  209. package/dist/types/repositories/index.d.ts +7 -0
  210. package/dist/types/repositories/indexedDB/contractRepository.d.ts +21 -0
  211. package/dist/types/repositories/indexedDB/db.d.ts +4 -0
  212. package/dist/types/repositories/indexedDB/manager.d.ts +22 -0
  213. package/dist/types/repositories/indexedDB/schema.d.ts +8 -0
  214. package/dist/types/repositories/indexedDB/walletRepository.d.ts +25 -0
  215. package/dist/types/repositories/indexedDB/websqlAdapter.d.ts +49 -0
  216. package/dist/types/repositories/migrations/contractRepositoryImpl.d.ts +24 -0
  217. package/dist/types/repositories/migrations/fromStorageAdapter.d.ts +19 -0
  218. package/dist/types/repositories/migrations/walletRepositoryImpl.d.ts +27 -0
  219. package/dist/types/repositories/realm/contractRepository.d.ts +24 -0
  220. package/dist/types/repositories/realm/index.d.ts +4 -0
  221. package/dist/types/repositories/realm/schemas.d.ts +208 -0
  222. package/dist/types/repositories/realm/types.d.ts +16 -0
  223. package/dist/types/repositories/realm/walletRepository.d.ts +31 -0
  224. package/dist/types/repositories/serialization.d.ts +40 -0
  225. package/dist/types/repositories/sqlite/contractRepository.d.ts +33 -0
  226. package/dist/types/repositories/sqlite/index.d.ts +3 -0
  227. package/dist/types/repositories/sqlite/types.d.ts +18 -0
  228. package/dist/types/repositories/sqlite/walletRepository.d.ts +40 -0
  229. package/dist/types/repositories/walletRepository.d.ts +13 -24
  230. package/dist/types/script/base.d.ts +1 -0
  231. package/dist/types/script/delegate.d.ts +36 -0
  232. package/dist/types/storage/asyncStorage.d.ts +4 -0
  233. package/dist/types/storage/fileSystem.d.ts +3 -0
  234. package/dist/types/storage/inMemory.d.ts +3 -0
  235. package/dist/types/storage/index.d.ts +3 -0
  236. package/dist/types/storage/indexedDB.d.ts +3 -0
  237. package/dist/types/storage/localStorage.d.ts +3 -0
  238. package/dist/types/utils/arkTransaction.d.ts +6 -0
  239. package/dist/types/wallet/asset-manager.d.ts +78 -0
  240. package/dist/types/wallet/asset.d.ts +21 -0
  241. package/dist/types/wallet/batch.d.ts +1 -1
  242. package/dist/types/wallet/delegator.d.ts +24 -0
  243. package/dist/types/wallet/expo/background.d.ts +66 -0
  244. package/dist/types/wallet/expo/index.d.ts +4 -0
  245. package/dist/types/wallet/expo/wallet.d.ts +97 -0
  246. package/dist/types/wallet/index.d.ts +75 -2
  247. package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +366 -0
  248. package/dist/types/wallet/serviceWorker/wallet.d.ts +20 -11
  249. package/dist/types/wallet/utils.d.ts +12 -1
  250. package/dist/types/wallet/validation.d.ts +24 -0
  251. package/dist/types/wallet/wallet.d.ts +111 -17
  252. package/dist/types/worker/browser/service-worker-manager.d.ts +21 -0
  253. package/dist/types/{wallet/serviceWorker → worker/browser}/utils.d.ts +2 -1
  254. package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +46 -0
  255. package/dist/types/worker/expo/index.d.ts +7 -0
  256. package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +14 -0
  257. package/dist/types/worker/expo/processors/index.d.ts +1 -0
  258. package/dist/types/worker/expo/taskQueue.d.ts +50 -0
  259. package/dist/types/worker/expo/taskRunner.d.ts +42 -0
  260. package/dist/types/worker/messageBus.d.ts +109 -0
  261. package/package.json +69 -11
  262. package/dist/cjs/wallet/serviceWorker/request.js +0 -78
  263. package/dist/cjs/wallet/serviceWorker/response.js +0 -222
  264. package/dist/cjs/wallet/serviceWorker/worker.js +0 -655
  265. package/dist/esm/wallet/serviceWorker/request.js +0 -75
  266. package/dist/esm/wallet/serviceWorker/response.js +0 -219
  267. package/dist/esm/wallet/serviceWorker/worker.js +0 -651
  268. package/dist/types/wallet/serviceWorker/request.d.ts +0 -74
  269. package/dist/types/wallet/serviceWorker/response.d.ts +0 -123
  270. package/dist/types/wallet/serviceWorker/worker.d.ts +0 -53
@@ -1,101 +1 @@
1
- const getContractStorageKey = (id, key) => `contract:${id}:${key}`;
2
- const getCollectionStorageKey = (type) => `collection:${type}`;
3
- export class ContractRepositoryImpl {
4
- constructor(storage) {
5
- this.storage = storage;
6
- }
7
- async getContractData(contractId, key) {
8
- const stored = await this.storage.getItem(getContractStorageKey(contractId, key));
9
- if (!stored)
10
- return null;
11
- try {
12
- const data = JSON.parse(stored);
13
- return data;
14
- }
15
- catch (error) {
16
- console.error(`Failed to parse contract data for ${contractId}:${key}:`, error);
17
- return null;
18
- }
19
- }
20
- async setContractData(contractId, key, data) {
21
- try {
22
- await this.storage.setItem(getContractStorageKey(contractId, key), JSON.stringify(data));
23
- }
24
- catch (error) {
25
- console.error(`Failed to persist contract data for ${contractId}:${key}:`, error);
26
- throw error; // Rethrow to notify caller of failure
27
- }
28
- }
29
- async deleteContractData(contractId, key) {
30
- try {
31
- await this.storage.removeItem(getContractStorageKey(contractId, key));
32
- }
33
- catch (error) {
34
- console.error(`Failed to remove contract data for ${contractId}:${key}:`, error);
35
- throw error; // Rethrow to notify caller of failure
36
- }
37
- }
38
- async getContractCollection(contractType) {
39
- const stored = await this.storage.getItem(getCollectionStorageKey(contractType));
40
- if (!stored)
41
- return [];
42
- try {
43
- const collection = JSON.parse(stored);
44
- return collection;
45
- }
46
- catch (error) {
47
- console.error(`Failed to parse contract collection ${contractType}:`, error);
48
- return [];
49
- }
50
- }
51
- async saveToContractCollection(contractType, item, idField) {
52
- const collection = await this.getContractCollection(contractType);
53
- // Validate that the item has the required id field
54
- const itemId = item[idField];
55
- if (itemId === undefined || itemId === null) {
56
- throw new Error(`Item is missing required field '${String(idField)}'`);
57
- }
58
- // Find existing item index without mutating the original collection
59
- const existingIndex = collection.findIndex((i) => i[idField] === itemId);
60
- // Build new collection without mutating the cached one
61
- let newCollection;
62
- if (existingIndex !== -1) {
63
- // Replace existing item
64
- newCollection = [
65
- ...collection.slice(0, existingIndex),
66
- item,
67
- ...collection.slice(existingIndex + 1),
68
- ];
69
- }
70
- else {
71
- // Add new item
72
- newCollection = [...collection, item];
73
- }
74
- try {
75
- await this.storage.setItem(getCollectionStorageKey(contractType), JSON.stringify(newCollection));
76
- }
77
- catch (error) {
78
- console.error(`Failed to persist contract collection ${contractType}:`, error);
79
- throw error; // Rethrow to notify caller of failure
80
- }
81
- }
82
- async removeFromContractCollection(contractType, id, idField) {
83
- // Validate input parameters
84
- if (id === undefined || id === null) {
85
- throw new Error(`Invalid id provided for removal: ${String(id)}`);
86
- }
87
- const collection = await this.getContractCollection(contractType);
88
- // Build new collection without the specified item
89
- const filtered = collection.filter((item) => item[idField] !== id);
90
- try {
91
- await this.storage.setItem(getCollectionStorageKey(contractType), JSON.stringify(filtered));
92
- }
93
- catch (error) {
94
- console.error(`Failed to persist contract collection removal for ${contractType}:`, error);
95
- throw error; // Rethrow to notify caller of failure
96
- }
97
- }
98
- async clearContractData() {
99
- await this.storage.clear();
100
- }
101
- }
1
+ export {};
@@ -0,0 +1,51 @@
1
+ /**
2
+ * In-memory implementation of ContractRepository.
3
+ * Data is ephemeral and scoped to the instance.
4
+ */
5
+ export class InMemoryContractRepository {
6
+ constructor() {
7
+ this.version = 1;
8
+ this.contractData = new Map();
9
+ this.collections = new Map();
10
+ this.contractsByScript = new Map();
11
+ }
12
+ async clear() {
13
+ this.contractData.clear();
14
+ this.collections.clear();
15
+ this.contractsByScript.clear();
16
+ }
17
+ // Contract entity management methods
18
+ async getContracts(filter) {
19
+ const contracts = this.contractsByScript.values();
20
+ if (!filter) {
21
+ return [...contracts];
22
+ }
23
+ const matches = (value, criterion) => {
24
+ if (criterion === undefined) {
25
+ return true;
26
+ }
27
+ return Array.isArray(criterion)
28
+ ? criterion.includes(value)
29
+ : value === criterion;
30
+ };
31
+ const results = [];
32
+ for (const contract of contracts) {
33
+ if (matches(contract.script, filter.script) &&
34
+ matches(contract.state, filter.state) &&
35
+ matches(contract.type, filter.type)) {
36
+ results.push(contract);
37
+ }
38
+ }
39
+ return results;
40
+ }
41
+ async saveContract(contract) {
42
+ this.contractsByScript.set(contract.script, contract);
43
+ }
44
+ async deleteContract(script) {
45
+ this.contractsByScript.delete(script);
46
+ }
47
+ async [Symbol.asyncDispose]() {
48
+ // nothing to dispose, data is ephemeral and scoped to the instance
49
+ return;
50
+ }
51
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * In-memory implementation of WalletRepository.
3
+ * Data is ephemeral and scoped to the instance.
4
+ */
5
+ export class InMemoryWalletRepository {
6
+ constructor() {
7
+ this.version = 1;
8
+ this.vtxosByAddress = new Map();
9
+ this.utxosByAddress = new Map();
10
+ this.txsByAddress = new Map();
11
+ this.walletState = null;
12
+ }
13
+ async getVtxos(address) {
14
+ return this.vtxosByAddress.get(address) ?? [];
15
+ }
16
+ async saveVtxos(address, vtxos) {
17
+ const existing = this.vtxosByAddress.get(address) ?? [];
18
+ const next = mergeByKey(existing, vtxos, (item) => `${item.txid}:${item.vout}`);
19
+ this.vtxosByAddress.set(address, next);
20
+ }
21
+ async deleteVtxos(address) {
22
+ this.vtxosByAddress.delete(address);
23
+ }
24
+ async getUtxos(address) {
25
+ return this.utxosByAddress.get(address) ?? [];
26
+ }
27
+ async saveUtxos(address, utxos) {
28
+ const existing = this.utxosByAddress.get(address) ?? [];
29
+ const next = mergeByKey(existing, utxos, (item) => `${item.txid}:${item.vout}`);
30
+ this.utxosByAddress.set(address, next);
31
+ }
32
+ async deleteUtxos(address) {
33
+ this.utxosByAddress.delete(address);
34
+ }
35
+ async getTransactionHistory(address) {
36
+ return this.txsByAddress.get(address) ?? [];
37
+ }
38
+ async saveTransactions(address, txs) {
39
+ const existing = this.txsByAddress.get(address) ?? [];
40
+ const next = mergeByKey(existing, txs, serializeTxKey);
41
+ this.txsByAddress.set(address, next);
42
+ }
43
+ async deleteTransactions(address) {
44
+ this.txsByAddress.delete(address);
45
+ }
46
+ async getWalletState() {
47
+ return this.walletState;
48
+ }
49
+ async saveWalletState(state) {
50
+ this.walletState = state;
51
+ }
52
+ async clear() {
53
+ this.vtxosByAddress.clear();
54
+ this.utxosByAddress.clear();
55
+ this.txsByAddress.clear();
56
+ this.walletState = null;
57
+ }
58
+ async [Symbol.asyncDispose]() {
59
+ // nothing to dispose, data is ephemeral and scoped to the instance
60
+ return;
61
+ }
62
+ }
63
+ function serializeTxKey(tx) {
64
+ const key = tx.key;
65
+ return `${key.boardingTxid}:${key.commitmentTxid}:${key.arkTxid}`;
66
+ }
67
+ function mergeByKey(existing, incoming, toKey) {
68
+ const next = new Map();
69
+ existing.forEach((item) => {
70
+ next.set(toKey(item), item);
71
+ });
72
+ incoming.forEach((item) => {
73
+ next.set(toKey(item), item);
74
+ });
75
+ return Array.from(next.values());
76
+ }
@@ -1,2 +1,10 @@
1
1
  export * from './walletRepository.js';
2
2
  export * from './contractRepository.js';
3
+ export * from './inMemory/walletRepository.js';
4
+ export * from './inMemory/contractRepository.js';
5
+ export * from './indexedDB/contractRepository.js';
6
+ export * from './indexedDB/walletRepository.js';
7
+ export { MIGRATION_KEY, migrateWalletRepository, requiresMigration, getMigrationStatus, rollbackMigration, } from './migrations/fromStorageAdapter.js';
8
+ // Deprecated
9
+ export { WalletRepositoryImpl } from './migrations/walletRepositoryImpl.js';
10
+ export { ContractRepositoryImpl } from './migrations/contractRepositoryImpl.js';
@@ -0,0 +1,183 @@
1
+ import { DB_VERSION, STORE_CONTRACTS } from './db.js';
2
+ import { closeDatabase, openDatabase } from './manager.js';
3
+ import { initDatabase } from './schema.js';
4
+ import { DEFAULT_DB_NAME } from '../../worker/browser/utils.js';
5
+ /**
6
+ * IndexedDB-based implementation of ContractRepository.
7
+ *
8
+ * Data is stored as JSON strings in key/value stores.
9
+ */
10
+ export class IndexedDBContractRepository {
11
+ constructor(dbName = DEFAULT_DB_NAME) {
12
+ this.dbName = dbName;
13
+ this.version = 1;
14
+ this.db = null;
15
+ }
16
+ async clear() {
17
+ try {
18
+ const db = await this.getDB();
19
+ return new Promise((resolve, reject) => {
20
+ const transaction = db.transaction([STORE_CONTRACTS], "readwrite");
21
+ const contractDataStore = transaction.objectStore(STORE_CONTRACTS);
22
+ const contractsStore = transaction.objectStore(STORE_CONTRACTS);
23
+ const contractDataRequest = contractDataStore.clear();
24
+ const contractsRequest = contractsStore.clear();
25
+ let completed = 0;
26
+ const checkComplete = () => {
27
+ completed++;
28
+ if (completed === 2) {
29
+ resolve();
30
+ }
31
+ };
32
+ contractDataRequest.onsuccess = checkComplete;
33
+ contractsRequest.onsuccess = checkComplete;
34
+ contractDataRequest.onerror = () => reject(contractDataRequest.error);
35
+ contractsRequest.onerror = () => reject(contractsRequest.error);
36
+ });
37
+ }
38
+ catch (error) {
39
+ console.error("Failed to clear contract data:", error);
40
+ throw error;
41
+ }
42
+ }
43
+ async getContracts(filter) {
44
+ try {
45
+ const db = await this.getDB();
46
+ const store = db
47
+ .transaction([STORE_CONTRACTS], "readonly")
48
+ .objectStore(STORE_CONTRACTS);
49
+ if (!filter || Object.keys(filter).length === 0) {
50
+ return new Promise((resolve, reject) => {
51
+ const request = store.getAll();
52
+ request.onerror = () => reject(request.error);
53
+ request.onsuccess = () => resolve(request.result ?? []);
54
+ });
55
+ }
56
+ const normalizedFilter = normalizeFilter(filter);
57
+ // first by script, primary key
58
+ if (normalizedFilter.has("script")) {
59
+ const scripts = normalizedFilter.get("script");
60
+ const contracts = await Promise.all(scripts.map((script) => new Promise((resolve, reject) => {
61
+ const req = store.get(script);
62
+ req.onerror = () => reject(req.error);
63
+ req.onsuccess = () => resolve(req.result);
64
+ })));
65
+ return this.applyContractFilter(contracts, normalizedFilter);
66
+ }
67
+ // by state, still an index
68
+ if (normalizedFilter.has("state")) {
69
+ const contracts = await this.getContractsByIndexValues(store, "state", normalizedFilter.get("state"));
70
+ return this.applyContractFilter(contracts, normalizedFilter);
71
+ }
72
+ // by type, still an index
73
+ if (normalizedFilter.has("type")) {
74
+ const contracts = await this.getContractsByIndexValues(store, "type", normalizedFilter.get("type"));
75
+ return this.applyContractFilter(contracts, normalizedFilter);
76
+ }
77
+ // any other filtering happens in-memory
78
+ const allContracts = await new Promise((resolve, reject) => {
79
+ const request = store.getAll();
80
+ request.onerror = () => reject(request.error);
81
+ request.onsuccess = () => resolve(request.result ?? []);
82
+ });
83
+ return this.applyContractFilter(allContracts, normalizedFilter);
84
+ }
85
+ catch (error) {
86
+ console.error("Failed to get contracts:", error);
87
+ return [];
88
+ }
89
+ }
90
+ async saveContract(contract) {
91
+ try {
92
+ const db = await this.getDB();
93
+ return new Promise((resolve, reject) => {
94
+ const transaction = db.transaction([STORE_CONTRACTS], "readwrite");
95
+ const store = transaction.objectStore(STORE_CONTRACTS);
96
+ const request = store.put(contract);
97
+ request.onerror = () => reject(request.error);
98
+ request.onsuccess = () => resolve();
99
+ });
100
+ }
101
+ catch (error) {
102
+ console.error("Failed to save contract:", error);
103
+ throw error;
104
+ }
105
+ }
106
+ async deleteContract(script) {
107
+ try {
108
+ const db = await this.getDB();
109
+ return new Promise((resolve, reject) => {
110
+ const transaction = db.transaction([STORE_CONTRACTS], "readwrite");
111
+ const store = transaction.objectStore(STORE_CONTRACTS);
112
+ const getRequest = store.get(script);
113
+ getRequest.onerror = () => reject(getRequest.error);
114
+ getRequest.onsuccess = () => {
115
+ const request = store.delete(script);
116
+ request.onerror = () => reject(request.error);
117
+ request.onsuccess = () => resolve();
118
+ };
119
+ });
120
+ }
121
+ catch (error) {
122
+ console.error(`Failed to delete contract ${script}:`, error);
123
+ throw error;
124
+ }
125
+ }
126
+ getContractsByIndexValues(store, indexName, values) {
127
+ if (values.length === 0)
128
+ return Promise.resolve([]);
129
+ const index = store.index(indexName);
130
+ const requests = values.map((value) => new Promise((resolve, reject) => {
131
+ const request = index.getAll(value);
132
+ request.onerror = () => reject(request.error);
133
+ request.onsuccess = () => resolve(request.result ?? []);
134
+ }));
135
+ return Promise.all(requests).then((results) => results.flatMap((result) => result));
136
+ }
137
+ applyContractFilter(
138
+ // can filter directly the result of a query
139
+ contracts, filter) {
140
+ return contracts.filter((contract) => {
141
+ if (contract === undefined)
142
+ return false;
143
+ if (filter.has("script") &&
144
+ !filter.get("script")?.includes(contract.script))
145
+ return false;
146
+ if (filter.has("state") &&
147
+ !filter.get("state")?.includes(contract.state))
148
+ return false;
149
+ if (filter.has("type") &&
150
+ !filter.get("type")?.includes(contract.type))
151
+ return false;
152
+ return true;
153
+ });
154
+ }
155
+ async getDB() {
156
+ if (this.db)
157
+ return this.db;
158
+ this.db = await openDatabase(this.dbName, DB_VERSION, initDatabase);
159
+ return this.db;
160
+ }
161
+ async [Symbol.asyncDispose]() {
162
+ if (!this.db)
163
+ return;
164
+ await closeDatabase(this.dbName);
165
+ this.db = null;
166
+ }
167
+ }
168
+ const FILTER_FIELDS = ["script", "state", "type"];
169
+ // Transform all filter fields into an array of values
170
+ function normalizeFilter(filter) {
171
+ const res = new Map();
172
+ FILTER_FIELDS.forEach((current) => {
173
+ if (!filter?.[current])
174
+ return;
175
+ if (Array.isArray(filter[current])) {
176
+ res.set(current, filter[current]);
177
+ }
178
+ else {
179
+ res.set(current, [filter[current]]);
180
+ }
181
+ });
182
+ return res;
183
+ }
@@ -0,0 +1,4 @@
1
+ import { DB_VERSION, STORE_CONTRACTS, LEGACY_STORE_CONTRACT_COLLECTIONS, STORE_TRANSACTIONS, STORE_UTXOS, STORE_VTXOS, STORE_WALLET_STATE, } from './schema.js';
2
+ export { STORE_VTXOS, STORE_UTXOS, STORE_TRANSACTIONS, STORE_WALLET_STATE, STORE_CONTRACTS, LEGACY_STORE_CONTRACT_COLLECTIONS, DB_VERSION, };
3
+ // Serialization helpers (re-exported from shared module)
4
+ export { serializeTapLeaf, serializeVtxo, serializeUtxo, deserializeTapLeaf, deserializeVtxo, deserializeUtxo, } from '../serialization.js';
@@ -0,0 +1,92 @@
1
+ export function getGlobalObject() {
2
+ if (typeof globalThis !== "undefined") {
3
+ if (typeof globalThis.self === "object" && globalThis.self !== null) {
4
+ return { globalObject: globalThis.self };
5
+ }
6
+ if (typeof globalThis.window === "object" &&
7
+ globalThis.window !== null) {
8
+ return { globalObject: globalThis.window };
9
+ }
10
+ return { globalObject: globalThis };
11
+ }
12
+ throw new Error("Global object not found");
13
+ }
14
+ // database instance cache, avoiding multiple open requests
15
+ const dbCache = new Map();
16
+ // track reference counts for each database to avoid closing it prematurely
17
+ const refCounts = new Map();
18
+ /**
19
+ * Opens an IndexedDB database and increments the reference count.
20
+ * Handles global object detection and callbacks.
21
+ *
22
+ * @param dbName The name of the database to open.
23
+ * @param dbVersion The database version to open.
24
+ * @param initDatabase A function that migrates the database schema, called on `onupgradeneeded` only.
25
+ *
26
+ * @returns A promise that resolves to the database instance.
27
+ */
28
+ export async function openDatabase(dbName, dbVersion, initDatabase) {
29
+ const { globalObject } = getGlobalObject();
30
+ if (!globalObject.indexedDB) {
31
+ throw new Error("IndexedDB is not available in this environment");
32
+ }
33
+ // Return cached promise if available (handles concurrent calls)
34
+ const cached = dbCache.get(dbName);
35
+ if (cached) {
36
+ if (cached.version !== dbVersion) {
37
+ throw new Error(`Database "${dbName}" already opened with version ${cached.version}; requested ${dbVersion}`);
38
+ }
39
+ refCounts.set(dbName, (refCounts.get(dbName) ?? 0) + 1);
40
+ return cached.promise;
41
+ }
42
+ const dbPromise = new Promise((resolve, reject) => {
43
+ const request = globalObject.indexedDB.open(dbName, dbVersion);
44
+ request.onerror = () => {
45
+ dbCache.delete(dbName); // Clean up on failure
46
+ refCounts.delete(dbName);
47
+ reject(request.error);
48
+ };
49
+ request.onsuccess = () => {
50
+ resolve(request.result);
51
+ };
52
+ request.onupgradeneeded = () => {
53
+ const db = request.result;
54
+ initDatabase(db);
55
+ };
56
+ request.onblocked = () => {
57
+ console.warn("Database upgrade blocked - close other tabs/connections");
58
+ };
59
+ });
60
+ // Cache immediately before awaiting
61
+ dbCache.set(dbName, { version: dbVersion, promise: dbPromise });
62
+ refCounts.set(dbName, 1);
63
+ return dbPromise;
64
+ }
65
+ /**
66
+ * Decrements the reference count and closes the database when no references remain.
67
+ *
68
+ * @param dbName The name of the database to close.
69
+ *
70
+ * @returns True if the database was closed, false otherwise.
71
+ */
72
+ export async function closeDatabase(dbName) {
73
+ const cachedEntry = dbCache.get(dbName);
74
+ if (!cachedEntry)
75
+ return false;
76
+ const count = (refCounts.get(dbName) ?? 1) - 1;
77
+ if (count > 0) {
78
+ refCounts.set(dbName, count);
79
+ return false;
80
+ }
81
+ // Last reference — actually close
82
+ refCounts.delete(dbName);
83
+ dbCache.delete(dbName);
84
+ try {
85
+ const db = await cachedEntry.promise;
86
+ db.close();
87
+ }
88
+ catch {
89
+ // DB failed to open, nothing to close
90
+ }
91
+ return true;
92
+ }
@@ -0,0 +1,155 @@
1
+ // Store names introduced in V2, they are all new to the migration
2
+ export const STORE_VTXOS = "vtxos";
3
+ export const STORE_UTXOS = "utxos";
4
+ export const STORE_TRANSACTIONS = "transactions";
5
+ export const STORE_WALLET_STATE = "walletState";
6
+ export const STORE_CONTRACTS = "contracts";
7
+ // @deprecated use only for migrations, this is created in V1
8
+ export const LEGACY_STORE_CONTRACT_COLLECTIONS = "contractsCollections";
9
+ export const DB_VERSION = 2;
10
+ export function initDatabase(db) {
11
+ // Create wallet stores
12
+ if (!db.objectStoreNames.contains(STORE_VTXOS)) {
13
+ const vtxosStore = db.createObjectStore(STORE_VTXOS, {
14
+ keyPath: ["address", "txid", "vout"],
15
+ });
16
+ if (!vtxosStore.indexNames.contains("address")) {
17
+ vtxosStore.createIndex("address", "address", {
18
+ unique: false,
19
+ });
20
+ }
21
+ if (!vtxosStore.indexNames.contains("txid")) {
22
+ vtxosStore.createIndex("txid", "txid", { unique: false });
23
+ }
24
+ if (!vtxosStore.indexNames.contains("value")) {
25
+ vtxosStore.createIndex("value", "value", { unique: false });
26
+ }
27
+ if (!vtxosStore.indexNames.contains("status")) {
28
+ vtxosStore.createIndex("status", "status", {
29
+ unique: false,
30
+ });
31
+ }
32
+ if (!vtxosStore.indexNames.contains("virtualStatus")) {
33
+ vtxosStore.createIndex("virtualStatus", "virtualStatus", {
34
+ unique: false,
35
+ });
36
+ }
37
+ if (!vtxosStore.indexNames.contains("createdAt")) {
38
+ vtxosStore.createIndex("createdAt", "createdAt", {
39
+ unique: false,
40
+ });
41
+ }
42
+ if (!vtxosStore.indexNames.contains("isSpent")) {
43
+ vtxosStore.createIndex("isSpent", "isSpent", {
44
+ unique: false,
45
+ });
46
+ }
47
+ if (!vtxosStore.indexNames.contains("isUnrolled")) {
48
+ vtxosStore.createIndex("isUnrolled", "isUnrolled", {
49
+ unique: false,
50
+ });
51
+ }
52
+ if (!vtxosStore.indexNames.contains("spentBy")) {
53
+ vtxosStore.createIndex("spentBy", "spentBy", {
54
+ unique: false,
55
+ });
56
+ }
57
+ if (!vtxosStore.indexNames.contains("settledBy")) {
58
+ vtxosStore.createIndex("settledBy", "settledBy", {
59
+ unique: false,
60
+ });
61
+ }
62
+ if (!vtxosStore.indexNames.contains("arkTxId")) {
63
+ vtxosStore.createIndex("arkTxId", "arkTxId", {
64
+ unique: false,
65
+ });
66
+ }
67
+ }
68
+ if (!db.objectStoreNames.contains(STORE_UTXOS)) {
69
+ const utxosStore = db.createObjectStore(STORE_UTXOS, {
70
+ keyPath: ["address", "txid", "vout"],
71
+ });
72
+ if (!utxosStore.indexNames.contains("address")) {
73
+ utxosStore.createIndex("address", "address", {
74
+ unique: false,
75
+ });
76
+ }
77
+ if (!utxosStore.indexNames.contains("txid")) {
78
+ utxosStore.createIndex("txid", "txid", { unique: false });
79
+ }
80
+ if (!utxosStore.indexNames.contains("value")) {
81
+ utxosStore.createIndex("value", "value", { unique: false });
82
+ }
83
+ if (!utxosStore.indexNames.contains("status")) {
84
+ utxosStore.createIndex("status", "status", {
85
+ unique: false,
86
+ });
87
+ }
88
+ }
89
+ if (!db.objectStoreNames.contains(STORE_TRANSACTIONS)) {
90
+ const transactionsStore = db.createObjectStore(STORE_TRANSACTIONS, {
91
+ keyPath: [
92
+ "address",
93
+ "keyBoardingTxid",
94
+ "keyCommitmentTxid",
95
+ "keyArkTxid",
96
+ ],
97
+ });
98
+ if (!transactionsStore.indexNames.contains("address")) {
99
+ transactionsStore.createIndex("address", "address", {
100
+ unique: false,
101
+ });
102
+ }
103
+ if (!transactionsStore.indexNames.contains("type")) {
104
+ transactionsStore.createIndex("type", "type", {
105
+ unique: false,
106
+ });
107
+ }
108
+ if (!transactionsStore.indexNames.contains("amount")) {
109
+ transactionsStore.createIndex("amount", "amount", {
110
+ unique: false,
111
+ });
112
+ }
113
+ if (!transactionsStore.indexNames.contains("settled")) {
114
+ transactionsStore.createIndex("settled", "settled", {
115
+ unique: false,
116
+ });
117
+ }
118
+ if (!transactionsStore.indexNames.contains("createdAt")) {
119
+ transactionsStore.createIndex("createdAt", "createdAt", {
120
+ unique: false,
121
+ });
122
+ }
123
+ if (!transactionsStore.indexNames.contains("arkTxid")) {
124
+ transactionsStore.createIndex("arkTxid", "key.arkTxid", {
125
+ unique: false,
126
+ });
127
+ }
128
+ }
129
+ if (!db.objectStoreNames.contains(STORE_WALLET_STATE)) {
130
+ db.createObjectStore(STORE_WALLET_STATE, {
131
+ keyPath: "key",
132
+ });
133
+ }
134
+ // Create contract stores
135
+ if (!db.objectStoreNames.contains(STORE_CONTRACTS)) {
136
+ const contractsStore = db.createObjectStore(STORE_CONTRACTS, {
137
+ keyPath: "script",
138
+ });
139
+ if (!contractsStore.indexNames.contains("type")) {
140
+ contractsStore.createIndex("type", "type", {
141
+ unique: false,
142
+ });
143
+ }
144
+ if (!contractsStore.indexNames.contains("state")) {
145
+ contractsStore.createIndex("state", "state", {
146
+ unique: false,
147
+ });
148
+ }
149
+ }
150
+ if (!db.objectStoreNames.contains(LEGACY_STORE_CONTRACT_COLLECTIONS)) {
151
+ db.createObjectStore(LEGACY_STORE_CONTRACT_COLLECTIONS, {
152
+ keyPath: "key",
153
+ });
154
+ }
155
+ }