@arkade-os/sdk 0.2.2 → 0.3.0-alpha.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 (81) hide show
  1. package/README.md +114 -43
  2. package/dist/cjs/adapters/asyncStorage.js +5 -0
  3. package/dist/cjs/adapters/fileSystem.js +5 -0
  4. package/dist/cjs/adapters/indexedDB.js +5 -0
  5. package/dist/cjs/adapters/localStorage.js +5 -0
  6. package/dist/cjs/bip322/index.js +2 -2
  7. package/dist/cjs/identity/index.js +15 -0
  8. package/dist/cjs/identity/singleKey.js +20 -1
  9. package/dist/cjs/index.js +5 -3
  10. package/dist/cjs/musig2/keys.js +6 -6
  11. package/dist/cjs/musig2/sign.js +5 -5
  12. package/dist/cjs/repositories/contractRepository.js +130 -0
  13. package/dist/cjs/repositories/index.js +18 -0
  14. package/dist/cjs/repositories/walletRepository.js +136 -0
  15. package/dist/cjs/storage/asyncStorage.js +47 -0
  16. package/dist/cjs/storage/fileSystem.js +138 -0
  17. package/dist/cjs/storage/inMemory.js +21 -0
  18. package/dist/cjs/storage/indexedDB.js +97 -0
  19. package/dist/cjs/storage/localStorage.js +48 -0
  20. package/dist/cjs/tree/signingSession.js +4 -4
  21. package/dist/cjs/wallet/onchain.js +12 -6
  22. package/dist/cjs/wallet/serviceWorker/request.js +4 -14
  23. package/dist/cjs/wallet/serviceWorker/response.js +0 -13
  24. package/dist/cjs/wallet/serviceWorker/wallet.js +124 -130
  25. package/dist/cjs/wallet/serviceWorker/worker.js +89 -53
  26. package/dist/cjs/wallet/wallet.js +21 -4
  27. package/dist/esm/adapters/asyncStorage.js +1 -0
  28. package/dist/esm/adapters/fileSystem.js +1 -0
  29. package/dist/esm/adapters/indexedDB.js +1 -0
  30. package/dist/esm/adapters/localStorage.js +1 -0
  31. package/dist/esm/bip322/index.js +1 -1
  32. package/dist/esm/identity/index.js +1 -1
  33. package/dist/esm/identity/singleKey.js +21 -2
  34. package/dist/esm/index.js +4 -3
  35. package/dist/esm/musig2/keys.js +6 -6
  36. package/dist/esm/musig2/sign.js +4 -4
  37. package/dist/esm/repositories/contractRepository.js +126 -0
  38. package/dist/esm/repositories/index.js +2 -0
  39. package/dist/esm/repositories/walletRepository.js +132 -0
  40. package/dist/esm/storage/asyncStorage.js +43 -0
  41. package/dist/esm/storage/fileSystem.js +101 -0
  42. package/dist/esm/storage/inMemory.js +17 -0
  43. package/dist/esm/storage/indexedDB.js +93 -0
  44. package/dist/esm/storage/localStorage.js +44 -0
  45. package/dist/esm/tree/signingSession.js +1 -1
  46. package/dist/esm/wallet/onchain.js +12 -6
  47. package/dist/esm/wallet/serviceWorker/request.js +4 -14
  48. package/dist/esm/wallet/serviceWorker/response.js +0 -13
  49. package/dist/esm/wallet/serviceWorker/wallet.js +125 -131
  50. package/dist/esm/wallet/serviceWorker/worker.js +90 -54
  51. package/dist/esm/wallet/wallet.js +21 -4
  52. package/dist/types/adapters/asyncStorage.d.ts +2 -0
  53. package/dist/types/adapters/fileSystem.d.ts +2 -0
  54. package/dist/types/adapters/indexedDB.d.ts +2 -0
  55. package/dist/types/adapters/localStorage.d.ts +2 -0
  56. package/dist/types/identity/index.d.ts +3 -1
  57. package/dist/types/identity/singleKey.d.ts +12 -1
  58. package/dist/types/index.d.ts +4 -4
  59. package/dist/types/repositories/contractRepository.d.ts +20 -0
  60. package/dist/types/repositories/index.d.ts +2 -0
  61. package/dist/types/repositories/walletRepository.d.ts +38 -0
  62. package/dist/types/storage/asyncStorage.d.ts +9 -0
  63. package/dist/types/storage/fileSystem.d.ts +11 -0
  64. package/dist/types/storage/inMemory.d.ts +8 -0
  65. package/dist/types/storage/index.d.ts +6 -0
  66. package/dist/types/storage/indexedDB.d.ts +12 -0
  67. package/dist/types/storage/localStorage.d.ts +8 -0
  68. package/dist/types/wallet/index.d.ts +3 -0
  69. package/dist/types/wallet/onchain.d.ts +3 -2
  70. package/dist/types/wallet/serviceWorker/request.d.ts +1 -7
  71. package/dist/types/wallet/serviceWorker/response.d.ts +1 -8
  72. package/dist/types/wallet/serviceWorker/wallet.d.ts +67 -21
  73. package/dist/types/wallet/serviceWorker/worker.d.ts +17 -4
  74. package/dist/types/wallet/wallet.d.ts +4 -0
  75. package/package.json +38 -14
  76. package/dist/cjs/wallet/serviceWorker/db/vtxo/idb.js +0 -185
  77. package/dist/esm/wallet/serviceWorker/db/vtxo/idb.js +0 -181
  78. package/dist/types/wallet/serviceWorker/db/vtxo/idb.d.ts +0 -20
  79. package/dist/types/wallet/serviceWorker/db/vtxo/index.d.ts +0 -14
  80. /package/dist/cjs/{wallet/serviceWorker/db/vtxo → storage}/index.js +0 -0
  81. /package/dist/esm/{wallet/serviceWorker/db/vtxo → storage}/index.js +0 -0
package/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  # Arkade TypeScript SDK
2
+
2
3
  The Arkade SDK is a TypeScript library for building Bitcoin wallets with support for both on-chain and off-chain transactions via the Ark protocol.
3
4
 
4
5
  [![TypeScript Documentation](https://img.shields.io/badge/TypeScript-Documentation-blue?style=flat-square)](https://arkade-os.github.io/ts-sdk/)
5
- [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/arkade-os/ts-sdk)
6
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/ark-ts-sdk)
6
7
 
7
8
  ## Installation
8
9
 
@@ -22,16 +23,20 @@ const identity = SingleKey.fromHex('your_private_key_hex')
22
23
 
23
24
  // Create a wallet with Ark support
24
25
  const wallet = await Wallet.create({
25
- identity: identity,
26
- // Esplora API, can be left empty mempool.space API will be used
26
+ identity,
27
+ // Esplora API, can be left empty - mempool.space API will be used
27
28
  esploraUrl: 'https://mutinynet.com/api',
28
29
  arkServerUrl: 'https://mutinynet.arkade.sh',
30
+ // Optional: specify storage adapter (defaults to InMemoryStorageAdapter)
31
+ // storage: new LocalStorageAdapter() // for browser persistence
29
32
  })
30
33
  ```
31
34
 
32
35
  ### Receiving Bitcoin
33
36
 
34
37
  ```typescript
38
+ import { waitForIncomingFunds } from '@arkade-os/sdk'
39
+
35
40
  // Get wallet addresses
36
41
  const arkAddress = await wallet.getAddress()
37
42
  const boardingAddress = await wallet.getBoardingAddress()
@@ -40,17 +45,17 @@ console.log('Boarding Address:', boardingAddress)
40
45
 
41
46
  const incomingFunds = await waitForIncomingFunds(wallet)
42
47
  if (incomingFunds.type === "vtxo") {
43
- // virtual coins received
48
+ // Virtual coins received
44
49
  console.log("VTXOs: ", incomingFunds.vtxos)
45
50
  } else if (incomingFunds.type === "utxo") {
46
- // boarding coins received
51
+ // Boarding coins received
47
52
  console.log("UTXOs: ", incomingFunds.coins)
48
53
  }
49
54
  ```
50
55
 
51
56
  ### Onboarding
52
57
 
53
- Onboarding allows you to swap onchain funds into VTXOs
58
+ Onboarding allows you to swap on-chain funds into VTXOs:
54
59
 
55
60
  ```typescript
56
61
  import { Ramps } from '@arkade-os/sdk'
@@ -88,9 +93,9 @@ const txid = await wallet.sendBitcoin({
88
93
  })
89
94
  ```
90
95
 
91
- ### Batch Settlements
96
+ ### Batch Settlements
92
97
 
93
- This can be used to move preconfirmed balances into finalized balances, to convert manually UTXOs and VTXOs.
98
+ This can be used to move preconfirmed balances into finalized balances and to manually convert UTXOs and VTXOs.
94
99
 
95
100
  ```typescript
96
101
  // For settling transactions
@@ -127,7 +132,7 @@ console.log('History:', history)
127
132
 
128
133
  ### Offboarding
129
134
 
130
- Collaborative exit or "offboarding" allows you to withdraw your virtual funds to an onchain address.
135
+ Collaborative exit or "offboarding" allows you to withdraw your virtual funds to an on-chain address:
131
136
 
132
137
  ```typescript
133
138
  import { Ramps } from '@arkade-os/sdk'
@@ -145,11 +150,14 @@ Unilateral exit allows you to withdraw your funds from the Ark protocol back to
145
150
  #### Step 1: Unrolling VTXOs
146
151
 
147
152
  ```typescript
148
- import { Unroll, OnchainWallet } from '@arkade-os/sdk'
153
+ import { Unroll, OnchainWallet, SingleKey } from '@arkade-os/sdk'
154
+
155
+ // Create an identity for the onchain wallet
156
+ const onchainIdentity = SingleKey.fromHex('your_onchain_private_key_hex');
149
157
 
150
158
  // Create an onchain wallet to pay for P2A outputs in VTXO branches
151
159
  // OnchainWallet implements the AnchorBumper interface
152
- const onchainWallet = new OnchainWallet(wallet.identity, 'regtest');
160
+ const onchainWallet = await OnchainWallet.create(onchainIdentity, 'regtest');
153
161
 
154
162
  // Unroll a specific VTXO
155
163
  const vtxo = { txid: 'your_vtxo_txid', vout: 0 };
@@ -177,6 +185,7 @@ for await (const step of session) {
177
185
  ```
178
186
 
179
187
  The unrolling process works by:
188
+
180
189
  - Traversing the transaction chain from the root (most recent) to the leaf (oldest)
181
190
  - Broadcasting each transaction that isn't already on-chain
182
191
  - Waiting for confirmations between steps
@@ -196,6 +205,7 @@ await Unroll.completeUnroll(
196
205
  ```
197
206
 
198
207
  **Important Notes:**
208
+
199
209
  - Each VTXO may require multiple unroll steps depending on the transaction chain length
200
210
  - Each unroll step must be confirmed before proceeding to the next
201
211
  - The `completeUnroll` method can only be called after VTXOs are fully unrolled and the timelock has expired
@@ -203,42 +213,103 @@ await Unroll.completeUnroll(
203
213
 
204
214
  ### Running the wallet in a service worker
205
215
 
206
- 1. Create a service worker file
216
+ **Ultra-simplified setup!** We handle all the complex service worker registration and identity management for you:
217
+
218
+ ```typescript
219
+ // SIMPLE SETUP with identity! 🎉
220
+ import { ServiceWorkerWallet, SingleKey } from '@arkade-os/sdk';
221
+
222
+ // Create your identity
223
+ const identity = SingleKey.fromHex('your_private_key_hex');
224
+ // Or generate a new one:
225
+ // const identity = SingleKey.fromRandomBytes();
226
+
227
+ const wallet = await ServiceWorkerWallet.setup({
228
+ serviceWorkerPath: '/service-worker.js',
229
+ arkServerUrl: 'https://mutinynet.arkade.sh',
230
+ identity
231
+ });
232
+
233
+ // That's it! Ready to use immediately:
234
+ const address = await wallet.getAddress();
235
+ const balance = await wallet.getBalance();
236
+ ```
237
+
238
+ You'll also need to create a service worker file:
207
239
 
208
240
  ```typescript
209
- // service-worker.ts
241
+ // service-worker.js
210
242
  import { Worker } from '@arkade-os/sdk'
211
243
 
212
244
  // Worker handles communication between the main thread and service worker
213
245
  new Worker().start()
214
246
  ```
215
247
 
216
- 2. Instantiate the ServiceWorkerWallet
248
+ ### Storage Adapters
249
+
250
+ Choose the appropriate storage adapter for your environment:
217
251
 
218
252
  ```typescript
219
- // specify the path to the service worker file
220
- // this will automatically register the service worker
221
- const serviceWorker = await setupServiceWorker('/service-worker.js')
222
- const wallet = new ServiceWorkerWallet(serviceWorker)
223
-
224
- // Initialize the wallet
225
- await wallet.init({
226
- privateKey: 'your_private_key_hex',
227
- // Esplora API, can be left empty mempool.space API will be used
228
- esploraUrl: 'https://mutinynet.com/api',
229
- // OPTIONAL Ark Server connection information
253
+ import {
254
+ SingleKey,
255
+ Wallet,
256
+ InMemoryStorageAdapter, // Works everywhere, data lost on restart
257
+ } from '@arkade-os/sdk'
258
+
259
+ // Import additional storage adapters as needed:
260
+ import { LocalStorageAdapter } from '@arkade-os/sdk/adapters/localStorage' // Browser/PWA persistent storage
261
+ import { IndexedDBStorageAdapter } from '@arkade-os/sdk/adapters/indexedDB' // Browser/PWA/Service Worker advanced storage
262
+ import { AsyncStorageAdapter } from '@arkade-os/sdk/adapters/asyncStorage' // React Native persistent storage
263
+ import { FileSystemStorageAdapter } from '@arkade-os/sdk/adapters/fileSystem' // Node.js file-based storage
264
+
265
+ // Node.js
266
+ const storage = new FileSystemStorageAdapter('./wallet-data')
267
+
268
+ // Browser/PWA
269
+ const storage = new LocalStorageAdapter()
270
+ // or for advanced features:
271
+ const storage = new IndexedDBStorageAdapter('my-app', 1)
272
+
273
+ // React Native
274
+ const storage = new AsyncStorageAdapter()
275
+
276
+ // Service Worker
277
+ const storage = new IndexedDBStorageAdapter('service-worker-wallet', 1)
278
+
279
+ // Load identity from storage (simple pattern everywhere)
280
+ const privateKeyHex = await storage.getItem('private-key')
281
+ const identity = SingleKey.fromHex(privateKeyHex)
282
+
283
+ // Create wallet (same API everywhere)
284
+ const wallet = await Wallet.create({
285
+ identity,
230
286
  arkServerUrl: 'https://mutinynet.arkade.sh',
287
+ storage // optional
231
288
  })
289
+ ```
232
290
 
233
- // check service worker status
234
- const status = await wallet.getStatus()
235
- console.log('Service worker status:', status.walletInitialized)
291
+ ### Repository Pattern
236
292
 
237
- // clear wallet data stored in the service worker memory
238
- await wallet.clear()
239
- ```
293
+ Access low-level data management through repositories:
240
294
 
241
- _For complete API documentation, visit our [TypeScript documentation](https://arkade-os.github.io/ts-sdk/)._
295
+ ```typescript
296
+ // VTXO management (automatically cached for performance)
297
+ const addr = await wallet.getAddress()
298
+ const vtxos = await wallet.walletRepository.getVtxos(addr)
299
+ await wallet.walletRepository.saveVtxos(addr, vtxos)
300
+
301
+ // Contract data for SDK integrations
302
+ await wallet.contractRepository.setContractData('my-contract', 'status', 'active')
303
+ const status = await wallet.contractRepository.getContractData('my-contract', 'status')
304
+
305
+ // Collection management for related data
306
+ await wallet.contractRepository.saveToContractCollection(
307
+ 'swaps',
308
+ { id: 'swap-1', amount: 50000, type: 'reverse' },
309
+ 'id' // key field
310
+ )
311
+ const swaps = await wallet.contractRepository.getContractCollection('swaps')
312
+ ```
242
313
 
243
314
  ## Development
244
315
 
@@ -251,17 +322,17 @@ _For complete API documentation, visit our [TypeScript documentation](https://ar
251
322
 
252
323
  1. Install dependencies:
253
324
 
254
- ```bash
255
- pnpm install
256
- pnpm format
257
- pnpm lint
258
- ```
325
+ ```bash
326
+ pnpm install
327
+ pnpm format
328
+ pnpm lint
329
+ ```
259
330
 
260
- 2. Install nigiri for integration tests:
331
+ 1. Install nigiri for integration tests:
261
332
 
262
- ```bash
263
- curl https://getnigiri.vulpem.com | bash
264
- ```
333
+ ```bash
334
+ curl https://getnigiri.vulpem.com | bash
335
+ ```
265
336
 
266
337
  ### Running Tests
267
338
 
@@ -296,9 +367,9 @@ pnpm test:coverage
296
367
  ### Building the documentation
297
368
 
298
369
  ```bash
299
- # Build the TS doc
370
+ # Build the TypeScript documentation
300
371
  pnpm docs:build
301
- # open the docs in the browser
372
+ # Open the docs in the browser
302
373
  pnpm docs:open
303
374
  ```
304
375
 
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AsyncStorageAdapter = void 0;
4
+ var asyncStorage_1 = require("../storage/asyncStorage");
5
+ Object.defineProperty(exports, "AsyncStorageAdapter", { enumerable: true, get: function () { return asyncStorage_1.AsyncStorageAdapter; } });
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FileSystemStorageAdapter = void 0;
4
+ var fileSystem_1 = require("../storage/fileSystem");
5
+ Object.defineProperty(exports, "FileSystemStorageAdapter", { enumerable: true, get: function () { return fileSystem_1.FileSystemStorageAdapter; } });
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IndexedDBStorageAdapter = void 0;
4
+ var indexedDB_1 = require("../storage/indexedDB");
5
+ Object.defineProperty(exports, "IndexedDBStorageAdapter", { enumerable: true, get: function () { return indexedDB_1.IndexedDBStorageAdapter; } });
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LocalStorageAdapter = void 0;
4
+ var localStorage_1 = require("../storage/localStorage");
5
+ Object.defineProperty(exports, "LocalStorageAdapter", { enumerable: true, get: function () { return localStorage_1.LocalStorageAdapter; } });
@@ -4,7 +4,7 @@ exports.BIP322 = void 0;
4
4
  exports.craftToSpendTx = craftToSpendTx;
5
5
  const btc_signer_1 = require("@scure/btc-signer");
6
6
  const errors_1 = require("./errors");
7
- const secp256k1_1 = require("@noble/curves/secp256k1");
7
+ const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
8
8
  const base_1 = require("@scure/base");
9
9
  /**
10
10
  * BIP-322 signature implementation for Bitcoin message signing.
@@ -174,5 +174,5 @@ function craftToSignTx(toSpend, inputs, outputs) {
174
174
  return tx;
175
175
  }
176
176
  function hashMessage(message) {
177
- return secp256k1_1.schnorr.utils.taggedHash(TAG_BIP322, new TextEncoder().encode(message));
177
+ return secp256k1_js_1.schnorr.utils.taggedHash(TAG_BIP322, new TextEncoder().encode(message));
178
178
  }
@@ -1,2 +1,17 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
2
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./singleKey"), exports);
@@ -5,6 +5,7 @@ const utils_1 = require("@scure/btc-signer/utils");
5
5
  const base_1 = require("@scure/base");
6
6
  const btc_signer_1 = require("@scure/btc-signer");
7
7
  const signingSession_1 = require("../tree/signingSession");
8
+ const secp256k1_1 = require("@noble/secp256k1");
8
9
  const ZERO_32 = new Uint8Array(32).fill(0);
9
10
  const ALL_SIGHASH = Object.values(btc_signer_1.SigHash).filter((x) => typeof x === "number");
10
11
  /**
@@ -18,6 +19,9 @@ const ALL_SIGHASH = Object.values(btc_signer_1.SigHash).filter((x) => typeof x =
18
19
  * // Create from raw bytes
19
20
  * const key = SingleKey.fromPrivateKey(privateKeyBytes);
20
21
  *
22
+ * // Create random key
23
+ * const randomKey = SingleKey.fromRandomBytes();
24
+ *
21
25
  * // Sign a transaction
22
26
  * const signedTx = await key.sign(transaction);
23
27
  * ```
@@ -32,6 +36,17 @@ class SingleKey {
32
36
  static fromHex(privateKeyHex) {
33
37
  return new SingleKey(base_1.hex.decode(privateKeyHex));
34
38
  }
39
+ static fromRandomBytes() {
40
+ return new SingleKey((0, utils_1.randomPrivateKeyBytes)());
41
+ }
42
+ /**
43
+ * Export the private key as a hex string.
44
+ *
45
+ * @returns The private key as a hex string
46
+ */
47
+ toHex() {
48
+ return base_1.hex.encode(this.key);
49
+ }
35
50
  async sign(tx, inputIndexes) {
36
51
  const txCpy = tx.clone();
37
52
  if (!inputIndexes) {
@@ -59,10 +74,14 @@ class SingleKey {
59
74
  return txCpy;
60
75
  }
61
76
  xOnlyPublicKey() {
62
- return (0, utils_1.pubSchnorr)(this.key);
77
+ return Promise.resolve((0, utils_1.pubSchnorr)(this.key));
63
78
  }
64
79
  signerSession() {
65
80
  return signingSession_1.TreeSignerSession.random();
66
81
  }
82
+ async signMessage(message) {
83
+ const msgBytes = new TextEncoder().encode(message);
84
+ return secp256k1_1.schnorr.sign((0, utils_1.sha256)(msgBytes), this.key);
85
+ }
67
86
  }
68
87
  exports.SingleKey = SingleKey;
package/dist/cjs/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.BIP322 = exports.IndexedDBVtxoRepository = exports.networks = exports.ArkNote = exports.waitForIncomingFunds = exports.buildOffchainTx = exports.ConditionWitness = exports.VtxoTaprootTree = exports.VtxoTreeExpiry = exports.CosignerPublicKey = exports.getArkPsbtFields = exports.setArkPsbtField = exports.ArkPsbtFieldKeyType = exports.ArkPsbtFieldKey = exports.CLTVMultisigTapscript = exports.ConditionMultisigTapscript = exports.ConditionCSVMultisigTapscript = exports.CSVMultisigTapscript = exports.MultisigTapscript = exports.decodeTapscript = exports.Response = exports.Request = exports.ServiceWorkerWallet = exports.Worker = exports.setupServiceWorker = exports.SettlementEventType = exports.ChainTxType = exports.IndexerTxType = exports.TxType = exports.VHTLC = exports.VtxoScript = exports.DefaultVtxo = exports.ArkAddress = exports.RestIndexerProvider = exports.RestArkProvider = exports.EsploraProvider = exports.ESPLORA_URL = exports.Ramps = exports.OnchainWallet = exports.SingleKey = exports.Wallet = void 0;
3
+ exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.BIP322 = exports.ContractRepositoryImpl = exports.WalletRepositoryImpl = exports.networks = exports.ArkNote = exports.waitForIncomingFunds = exports.buildOffchainTx = exports.ConditionWitness = exports.VtxoTaprootTree = exports.VtxoTreeExpiry = exports.CosignerPublicKey = exports.getArkPsbtFields = exports.setArkPsbtField = exports.ArkPsbtFieldKeyType = exports.ArkPsbtFieldKey = exports.CLTVMultisigTapscript = exports.ConditionMultisigTapscript = exports.ConditionCSVMultisigTapscript = exports.CSVMultisigTapscript = exports.MultisigTapscript = exports.decodeTapscript = exports.Response = exports.Request = exports.ServiceWorkerWallet = exports.Worker = exports.setupServiceWorker = exports.SettlementEventType = exports.ChainTxType = exports.IndexerTxType = exports.TxType = exports.VHTLC = exports.VtxoScript = exports.DefaultVtxo = exports.ArkAddress = exports.RestIndexerProvider = exports.RestArkProvider = exports.EsploraProvider = exports.ESPLORA_URL = exports.Ramps = exports.OnchainWallet = exports.SingleKey = exports.Wallet = void 0;
4
4
  const btc_signer_1 = require("@scure/btc-signer");
5
5
  Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return btc_signer_1.Transaction; } });
6
6
  const singleKey_1 = require("./identity/singleKey");
@@ -62,8 +62,6 @@ const bip322_1 = require("./bip322");
62
62
  Object.defineProperty(exports, "BIP322", { enumerable: true, get: function () { return bip322_1.BIP322; } });
63
63
  const arknote_1 = require("./arknote");
64
64
  Object.defineProperty(exports, "ArkNote", { enumerable: true, get: function () { return arknote_1.ArkNote; } });
65
- const idb_1 = require("./wallet/serviceWorker/db/vtxo/idb");
66
- Object.defineProperty(exports, "IndexedDBVtxoRepository", { enumerable: true, get: function () { return idb_1.IndexedDBVtxoRepository; } });
67
65
  const networks_1 = require("./networks");
68
66
  Object.defineProperty(exports, "networks", { enumerable: true, get: function () { return networks_1.networks; } });
69
67
  const indexer_1 = require("./providers/indexer");
@@ -74,3 +72,7 @@ const anchor_1 = require("./utils/anchor");
74
72
  Object.defineProperty(exports, "P2A", { enumerable: true, get: function () { return anchor_1.P2A; } });
75
73
  const unroll_1 = require("./wallet/unroll");
76
74
  Object.defineProperty(exports, "Unroll", { enumerable: true, get: function () { return unroll_1.Unroll; } });
75
+ const walletRepository_1 = require("./repositories/walletRepository");
76
+ Object.defineProperty(exports, "WalletRepositoryImpl", { enumerable: true, get: function () { return walletRepository_1.WalletRepositoryImpl; } });
77
+ const contractRepository_1 = require("./repositories/contractRepository");
78
+ Object.defineProperty(exports, "ContractRepositoryImpl", { enumerable: true, get: function () { return contractRepository_1.ContractRepositoryImpl; } });
@@ -35,7 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.aggregateKeys = aggregateKeys;
37
37
  const musig = __importStar(require("@scure/btc-signer/musig2"));
38
- const secp256k1_1 = require("@noble/curves/secp256k1");
38
+ const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
39
39
  // Aggregates multiple public keys according to the MuSig2 algorithm
40
40
  function aggregateKeys(publicKeys, sort, options = {}) {
41
41
  if (sort) {
@@ -44,14 +44,14 @@ function aggregateKeys(publicKeys, sort, options = {}) {
44
44
  const { aggPublicKey: preTweakedKey } = musig.keyAggregate(publicKeys);
45
45
  if (!options.taprootTweak) {
46
46
  return {
47
- preTweakedKey: preTweakedKey.toRawBytes(true),
48
- finalKey: preTweakedKey.toRawBytes(true),
47
+ preTweakedKey: preTweakedKey.toBytes(true),
48
+ finalKey: preTweakedKey.toBytes(true),
49
49
  };
50
50
  }
51
- const tweakBytes = secp256k1_1.schnorr.utils.taggedHash("TapTweak", preTweakedKey.toRawBytes(true).subarray(1), options.taprootTweak ?? new Uint8Array(0));
51
+ const tweakBytes = secp256k1_js_1.schnorr.utils.taggedHash("TapTweak", preTweakedKey.toBytes(true).subarray(1), options.taprootTweak ?? new Uint8Array(0));
52
52
  const { aggPublicKey: finalKey } = musig.keyAggregate(publicKeys, [tweakBytes], [true]);
53
53
  return {
54
- preTweakedKey: preTweakedKey.toRawBytes(true),
55
- finalKey: finalKey.toRawBytes(true),
54
+ preTweakedKey: preTweakedKey.toBytes(true),
55
+ finalKey: finalKey.toBytes(true),
56
56
  };
57
57
  }
@@ -36,10 +36,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.PartialSig = exports.PartialSignatureError = void 0;
37
37
  exports.sign = sign;
38
38
  const musig = __importStar(require("@scure/btc-signer/musig2"));
39
- const utils_1 = require("@noble/curves/abstract/utils");
39
+ const utils_js_1 = require("@noble/curves/utils.js");
40
40
  const secp256k1_1 = require("@noble/secp256k1");
41
41
  const keys_1 = require("./keys");
42
- const secp256k1_2 = require("@noble/curves/secp256k1");
42
+ const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
43
43
  // Add this error type for decode failures
44
44
  class PartialSignatureError extends Error {
45
45
  constructor(message) {
@@ -77,8 +77,8 @@ class PartialSig {
77
77
  throw new PartialSignatureError("Invalid partial signature length");
78
78
  }
79
79
  // Verify s is less than curve order
80
- const s = (0, utils_1.bytesToNumberBE)(bytes);
81
- if (s >= secp256k1_1.CURVE.n) {
80
+ const s = (0, utils_js_1.bytesToNumberBE)(bytes);
81
+ if (s >= secp256k1_1.Point.CURVE().n) {
82
82
  throw new PartialSignatureError("s value overflows curve order");
83
83
  }
84
84
  // For decode we don't have R, so we'll need to compute it later
@@ -94,7 +94,7 @@ function sign(secNonce, privateKey, combinedNonce, publicKeys, message, options)
94
94
  let tweakBytes;
95
95
  if (options?.taprootTweak !== undefined) {
96
96
  const { preTweakedKey } = (0, keys_1.aggregateKeys)(options?.sortKeys ? musig.sortKeys(publicKeys) : publicKeys, true);
97
- tweakBytes = secp256k1_2.schnorr.utils.taggedHash("TapTweak", preTweakedKey.subarray(1), options.taprootTweak);
97
+ tweakBytes = secp256k1_js_1.schnorr.utils.taggedHash("TapTweak", preTweakedKey.subarray(1), options.taprootTweak);
98
98
  }
99
99
  const session = new musig.Session(combinedNonce, options?.sortKeys ? musig.sortKeys(publicKeys) : publicKeys, message, tweakBytes ? [tweakBytes] : undefined, tweakBytes ? [true] : undefined);
100
100
  const partialSig = session.sign(secNonce, privateKey);
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContractRepositoryImpl = void 0;
4
+ class ContractRepositoryImpl {
5
+ constructor(storage) {
6
+ this.cache = new Map();
7
+ this.storage = storage;
8
+ }
9
+ async getContractData(contractId, key) {
10
+ const storageKey = `contract:${contractId}:${key}`;
11
+ const cached = this.cache.get(storageKey);
12
+ if (cached !== undefined)
13
+ return cached;
14
+ const stored = await this.storage.getItem(storageKey);
15
+ if (!stored)
16
+ return null;
17
+ try {
18
+ const data = JSON.parse(stored);
19
+ this.cache.set(storageKey, data);
20
+ return data;
21
+ }
22
+ catch (error) {
23
+ console.error(`Failed to parse contract data for ${contractId}:${key}:`, error);
24
+ return null;
25
+ }
26
+ }
27
+ async setContractData(contractId, key, data) {
28
+ const storageKey = `contract:${contractId}:${key}`;
29
+ try {
30
+ // First persist to storage, only update cache if successful
31
+ await this.storage.setItem(storageKey, JSON.stringify(data));
32
+ this.cache.set(storageKey, data);
33
+ }
34
+ catch (error) {
35
+ // Storage operation failed, cache remains unchanged
36
+ console.error(`Failed to persist contract data for ${contractId}:${key}:`, error);
37
+ throw error; // Rethrow to notify caller of failure
38
+ }
39
+ }
40
+ async deleteContractData(contractId, key) {
41
+ const storageKey = `contract:${contractId}:${key}`;
42
+ try {
43
+ // First remove from persistent storage, only delete from cache if successful
44
+ await this.storage.removeItem(storageKey);
45
+ this.cache.delete(storageKey);
46
+ }
47
+ catch (error) {
48
+ // Storage operation failed, cache remains unchanged
49
+ console.error(`Failed to remove contract data for ${contractId}:${key}:`, error);
50
+ throw error; // Rethrow to notify caller of failure
51
+ }
52
+ }
53
+ async getContractCollection(contractType) {
54
+ const storageKey = `collection:${contractType}`;
55
+ const cached = this.cache.get(storageKey);
56
+ if (cached !== undefined)
57
+ return cached;
58
+ const stored = await this.storage.getItem(storageKey);
59
+ if (!stored) {
60
+ this.cache.set(storageKey, []);
61
+ return [];
62
+ }
63
+ try {
64
+ const collection = JSON.parse(stored);
65
+ this.cache.set(storageKey, collection);
66
+ return collection;
67
+ }
68
+ catch (error) {
69
+ console.error(`Failed to parse contract collection ${contractType}:`, error);
70
+ this.cache.set(storageKey, []);
71
+ return [];
72
+ }
73
+ }
74
+ async saveToContractCollection(contractType, item, idField) {
75
+ const collection = await this.getContractCollection(contractType);
76
+ // Validate that the item has the required id field
77
+ const itemId = item[idField];
78
+ if (itemId === undefined || itemId === null) {
79
+ throw new Error(`Item is missing required field '${String(idField)}'`);
80
+ }
81
+ // Find existing item index without mutating the original collection
82
+ const existingIndex = collection.findIndex((i) => i[idField] === itemId);
83
+ // Build new collection without mutating the cached one
84
+ let newCollection;
85
+ if (existingIndex !== -1) {
86
+ // Replace existing item
87
+ newCollection = [
88
+ ...collection.slice(0, existingIndex),
89
+ item,
90
+ ...collection.slice(existingIndex + 1),
91
+ ];
92
+ }
93
+ else {
94
+ // Add new item
95
+ newCollection = [...collection, item];
96
+ }
97
+ const storageKey = `collection:${contractType}`;
98
+ try {
99
+ // First persist to storage, only update cache if successful
100
+ await this.storage.setItem(storageKey, JSON.stringify(newCollection));
101
+ this.cache.set(storageKey, newCollection);
102
+ }
103
+ catch (error) {
104
+ // Storage operation failed, cache remains unchanged
105
+ console.error(`Failed to persist contract collection ${contractType}:`, error);
106
+ throw error; // Rethrow to notify caller of failure
107
+ }
108
+ }
109
+ async removeFromContractCollection(contractType, id, idField) {
110
+ // Validate input parameters
111
+ if (id === undefined || id === null) {
112
+ throw new Error(`Invalid id provided for removal: ${String(id)}`);
113
+ }
114
+ const collection = await this.getContractCollection(contractType);
115
+ // Build new collection without the specified item
116
+ const filtered = collection.filter((item) => item[idField] !== id);
117
+ const storageKey = `collection:${contractType}`;
118
+ try {
119
+ // First persist to storage, only update cache if successful
120
+ await this.storage.setItem(storageKey, JSON.stringify(filtered));
121
+ this.cache.set(storageKey, filtered);
122
+ }
123
+ catch (error) {
124
+ // Storage operation failed, cache remains unchanged
125
+ console.error(`Failed to persist contract collection removal for ${contractType}:`, error);
126
+ throw error; // Rethrow to notify caller of failure
127
+ }
128
+ }
129
+ }
130
+ exports.ContractRepositoryImpl = ContractRepositoryImpl;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./walletRepository"), exports);
18
+ __exportStar(require("./contractRepository"), exports);