@arkade-os/sdk 0.2.3 → 0.3.0-alpha.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.
- package/README.md +114 -43
- package/dist/cjs/adapters/asyncStorage.js +5 -0
- package/dist/cjs/adapters/fileSystem.js +5 -0
- package/dist/cjs/adapters/indexedDB.js +5 -0
- package/dist/cjs/adapters/localStorage.js +5 -0
- package/dist/cjs/arknote/index.js +4 -4
- package/dist/cjs/bip322/index.js +11 -9
- package/dist/cjs/forfeit.js +2 -2
- package/dist/cjs/identity/index.js +15 -0
- package/dist/cjs/identity/singleKey.js +24 -5
- package/dist/cjs/index.js +7 -5
- package/dist/cjs/musig2/keys.js +7 -7
- package/dist/cjs/musig2/nonces.js +1 -1
- package/dist/cjs/musig2/sign.js +6 -6
- package/dist/cjs/networks.js +6 -6
- package/dist/cjs/repositories/contractRepository.js +130 -0
- package/dist/cjs/repositories/index.js +18 -0
- package/dist/cjs/repositories/walletRepository.js +136 -0
- package/dist/cjs/script/address.js +3 -3
- package/dist/cjs/script/base.js +7 -7
- package/dist/cjs/script/tapscript.js +21 -21
- package/dist/cjs/script/vhtlc.js +2 -2
- package/dist/cjs/storage/asyncStorage.js +47 -0
- package/dist/cjs/storage/fileSystem.js +138 -0
- package/dist/cjs/storage/inMemory.js +21 -0
- package/dist/cjs/storage/indexedDB.js +97 -0
- package/dist/cjs/storage/localStorage.js +48 -0
- package/dist/cjs/tree/signingSession.js +12 -11
- package/dist/cjs/tree/txTree.js +6 -6
- package/dist/cjs/tree/validation.js +5 -5
- package/dist/cjs/utils/arkTransaction.js +5 -5
- package/dist/cjs/utils/unknownFields.js +5 -5
- package/dist/cjs/wallet/onchain.js +16 -10
- package/dist/cjs/wallet/serviceWorker/request.js +4 -14
- package/dist/cjs/wallet/serviceWorker/response.js +0 -13
- package/dist/cjs/wallet/serviceWorker/wallet.js +124 -130
- package/dist/cjs/wallet/serviceWorker/worker.js +84 -53
- package/dist/cjs/wallet/unroll.js +6 -6
- package/dist/cjs/wallet/wallet.js +37 -20
- package/dist/esm/adapters/asyncStorage.js +1 -0
- package/dist/esm/adapters/fileSystem.js +1 -0
- package/dist/esm/adapters/indexedDB.js +1 -0
- package/dist/esm/adapters/localStorage.js +1 -0
- package/dist/esm/arknote/index.js +2 -2
- package/dist/esm/bip322/index.js +4 -2
- package/dist/esm/forfeit.js +1 -1
- package/dist/esm/identity/index.js +1 -1
- package/dist/esm/identity/singleKey.js +22 -3
- package/dist/esm/index.js +5 -4
- package/dist/esm/musig2/keys.js +7 -7
- package/dist/esm/musig2/nonces.js +1 -1
- package/dist/esm/musig2/sign.js +5 -5
- package/dist/esm/networks.js +1 -1
- package/dist/esm/repositories/contractRepository.js +126 -0
- package/dist/esm/repositories/index.js +2 -0
- package/dist/esm/repositories/walletRepository.js +132 -0
- package/dist/esm/script/address.js +1 -1
- package/dist/esm/script/base.js +3 -3
- package/dist/esm/script/tapscript.js +2 -2
- package/dist/esm/script/vhtlc.js +1 -1
- package/dist/esm/storage/asyncStorage.js +43 -0
- package/dist/esm/storage/fileSystem.js +101 -0
- package/dist/esm/storage/inMemory.js +17 -0
- package/dist/esm/storage/indexedDB.js +93 -0
- package/dist/esm/storage/localStorage.js +44 -0
- package/dist/esm/tree/signingSession.js +4 -3
- package/dist/esm/tree/txTree.js +2 -2
- package/dist/esm/tree/validation.js +2 -2
- package/dist/esm/utils/arkTransaction.js +2 -2
- package/dist/esm/utils/unknownFields.js +1 -1
- package/dist/esm/wallet/onchain.js +14 -8
- package/dist/esm/wallet/serviceWorker/request.js +4 -14
- package/dist/esm/wallet/serviceWorker/response.js +0 -13
- package/dist/esm/wallet/serviceWorker/wallet.js +125 -131
- package/dist/esm/wallet/serviceWorker/worker.js +85 -54
- package/dist/esm/wallet/unroll.js +2 -2
- package/dist/esm/wallet/wallet.js +25 -8
- package/dist/types/adapters/asyncStorage.d.ts +2 -0
- package/dist/types/adapters/fileSystem.d.ts +2 -0
- package/dist/types/adapters/indexedDB.d.ts +2 -0
- package/dist/types/adapters/localStorage.d.ts +2 -0
- package/dist/types/arknote/index.d.ts +1 -1
- package/dist/types/bip322/index.d.ts +2 -2
- package/dist/types/forfeit.d.ts +1 -1
- package/dist/types/identity/index.d.ts +4 -2
- package/dist/types/identity/singleKey.d.ts +13 -2
- package/dist/types/index.d.ts +5 -5
- package/dist/types/repositories/contractRepository.d.ts +20 -0
- package/dist/types/repositories/index.d.ts +2 -0
- package/dist/types/repositories/walletRepository.d.ts +38 -0
- package/dist/types/script/address.d.ts +1 -1
- package/dist/types/script/base.d.ts +1 -1
- package/dist/types/script/default.d.ts +1 -1
- package/dist/types/script/tapscript.d.ts +1 -1
- package/dist/types/script/vhtlc.d.ts +1 -1
- package/dist/types/storage/asyncStorage.d.ts +9 -0
- package/dist/types/storage/fileSystem.d.ts +11 -0
- package/dist/types/storage/inMemory.d.ts +8 -0
- package/dist/types/storage/index.d.ts +6 -0
- package/dist/types/storage/indexedDB.d.ts +12 -0
- package/dist/types/storage/localStorage.d.ts +8 -0
- package/dist/types/tree/txTree.d.ts +1 -1
- package/dist/types/tree/validation.d.ts +1 -1
- package/dist/types/utils/anchor.d.ts +1 -1
- package/dist/types/utils/arkTransaction.d.ts +3 -3
- package/dist/types/utils/unknownFields.d.ts +1 -1
- package/dist/types/wallet/index.d.ts +4 -1
- package/dist/types/wallet/onchain.d.ts +5 -4
- package/dist/types/wallet/serviceWorker/request.d.ts +1 -7
- package/dist/types/wallet/serviceWorker/response.d.ts +1 -8
- package/dist/types/wallet/serviceWorker/wallet.d.ts +67 -21
- package/dist/types/wallet/serviceWorker/worker.d.ts +16 -4
- package/dist/types/wallet/unroll.d.ts +1 -1
- package/dist/types/wallet/wallet.d.ts +5 -1
- package/package.json +39 -15
- package/dist/cjs/wallet/serviceWorker/db/vtxo/idb.js +0 -185
- package/dist/esm/wallet/serviceWorker/db/vtxo/idb.js +0 -181
- package/dist/types/wallet/serviceWorker/db/vtxo/idb.d.ts +0 -20
- package/dist/types/wallet/serviceWorker/db/vtxo/index.d.ts +0 -14
- /package/dist/cjs/{wallet/serviceWorker/db/vtxo → storage}/index.js +0 -0
- /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
|
[](https://arkade-os.github.io/ts-sdk/)
|
|
5
|
-
[](https://deepwiki.com/
|
|
6
|
+
[](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
|
|
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
|
-
//
|
|
48
|
+
// Virtual coins received
|
|
44
49
|
console.log("VTXOs: ", incomingFunds.vtxos)
|
|
45
50
|
} else if (incomingFunds.type === "utxo") {
|
|
46
|
-
//
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
248
|
+
### Storage Adapters
|
|
249
|
+
|
|
250
|
+
Choose the appropriate storage adapter for your environment:
|
|
217
251
|
|
|
218
252
|
```typescript
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
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
|
-
|
|
234
|
-
const status = await wallet.getStatus()
|
|
235
|
-
console.log('Service worker status:', status.walletInitialized)
|
|
291
|
+
### Repository Pattern
|
|
236
292
|
|
|
237
|
-
|
|
238
|
-
await wallet.clear()
|
|
239
|
-
```
|
|
293
|
+
Access low-level data management through repositories:
|
|
240
294
|
|
|
241
|
-
|
|
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
|
-
|
|
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
|
|
370
|
+
# Build the TypeScript documentation
|
|
300
371
|
pnpm docs:build
|
|
301
|
-
#
|
|
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; } });
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ArkNote = void 0;
|
|
4
4
|
const base_1 = require("@scure/base");
|
|
5
5
|
const base_2 = require("../script/base");
|
|
6
|
-
const
|
|
7
|
-
const
|
|
6
|
+
const utils_js_1 = require("@scure/btc-signer/utils.js");
|
|
7
|
+
const script_js_1 = require("@scure/btc-signer/script.js");
|
|
8
8
|
/**
|
|
9
9
|
* ArkNotes are special virtual coins in the Ark protocol that can be created
|
|
10
10
|
* and spent without requiring any transactions. The server mints them, and they
|
|
@@ -29,7 +29,7 @@ class ArkNote {
|
|
|
29
29
|
this.value = value;
|
|
30
30
|
this.HRP = HRP;
|
|
31
31
|
this.vout = 0;
|
|
32
|
-
const preimageHash = (0,
|
|
32
|
+
const preimageHash = (0, utils_js_1.sha256)(this.preimage);
|
|
33
33
|
this.vtxoScript = new base_2.VtxoScript([noteTapscript(preimageHash)]);
|
|
34
34
|
const leaf = this.vtxoScript.leaves[0];
|
|
35
35
|
this.txid = base_1.hex.encode(new Uint8Array(preimageHash).reverse());
|
|
@@ -85,5 +85,5 @@ function readUInt32BE(array, offset) {
|
|
|
85
85
|
return view.getUint32(0, false);
|
|
86
86
|
}
|
|
87
87
|
function noteTapscript(preimageHash) {
|
|
88
|
-
return
|
|
88
|
+
return script_js_1.Script.encode(["SHA256", preimageHash, "EQUAL"]);
|
|
89
89
|
}
|
package/dist/cjs/bip322/index.js
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.BIP322 = void 0;
|
|
4
4
|
exports.craftToSpendTx = craftToSpendTx;
|
|
5
|
-
const
|
|
5
|
+
const script_js_1 = require("@scure/btc-signer/script.js");
|
|
6
|
+
const transaction_js_1 = require("@scure/btc-signer/transaction.js");
|
|
7
|
+
const script_js_2 = require("@scure/btc-signer/script.js");
|
|
6
8
|
const errors_1 = require("./errors");
|
|
7
|
-
const
|
|
9
|
+
const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
|
|
8
10
|
const base_1 = require("@scure/base");
|
|
9
11
|
/**
|
|
10
12
|
* BIP-322 signature implementation for Bitcoin message signing.
|
|
@@ -75,7 +77,7 @@ var BIP322;
|
|
|
75
77
|
}
|
|
76
78
|
BIP322.signature = signature;
|
|
77
79
|
})(BIP322 || (exports.BIP322 = BIP322 = {}));
|
|
78
|
-
const OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([
|
|
80
|
+
const OP_RETURN_EMPTY_PKSCRIPT = new Uint8Array([script_js_1.OP.RETURN]);
|
|
79
81
|
const ZERO_32 = new Uint8Array(32).fill(0);
|
|
80
82
|
const MAX_INDEX = 0xffffffff;
|
|
81
83
|
const TAG_BIP322 = "BIP0322-signed-message";
|
|
@@ -106,7 +108,7 @@ function validateOutputs(outputs) {
|
|
|
106
108
|
// craftToSpendTx creates the initial transaction that will be spent in the proof
|
|
107
109
|
function craftToSpendTx(message, pkScript) {
|
|
108
110
|
const messageHash = hashMessage(message);
|
|
109
|
-
const tx = new
|
|
111
|
+
const tx = new transaction_js_1.Transaction({
|
|
110
112
|
version: 0,
|
|
111
113
|
allowUnknownOutputs: true,
|
|
112
114
|
allowUnknown: true,
|
|
@@ -124,14 +126,14 @@ function craftToSpendTx(message, pkScript) {
|
|
|
124
126
|
script: pkScript,
|
|
125
127
|
});
|
|
126
128
|
tx.updateInput(0, {
|
|
127
|
-
finalScriptSig:
|
|
129
|
+
finalScriptSig: script_js_2.Script.encode(["OP_0", messageHash]),
|
|
128
130
|
});
|
|
129
131
|
return tx;
|
|
130
132
|
}
|
|
131
133
|
// craftToSignTx creates the transaction that will be signed for the proof
|
|
132
134
|
function craftToSignTx(toSpend, inputs, outputs) {
|
|
133
135
|
const firstInput = inputs[0];
|
|
134
|
-
const tx = new
|
|
136
|
+
const tx = new transaction_js_1.Transaction({
|
|
135
137
|
version: 2,
|
|
136
138
|
allowUnknownOutputs: outputs.length === 0,
|
|
137
139
|
allowUnknown: true,
|
|
@@ -147,13 +149,13 @@ function craftToSignTx(toSpend, inputs, outputs) {
|
|
|
147
149
|
script: firstInput.witnessUtxo.script,
|
|
148
150
|
amount: 0n,
|
|
149
151
|
},
|
|
150
|
-
sighashType:
|
|
152
|
+
sighashType: transaction_js_1.SigHash.ALL,
|
|
151
153
|
});
|
|
152
154
|
// add other inputs
|
|
153
155
|
for (const input of inputs) {
|
|
154
156
|
tx.addInput({
|
|
155
157
|
...input,
|
|
156
|
-
sighashType:
|
|
158
|
+
sighashType: transaction_js_1.SigHash.ALL,
|
|
157
159
|
});
|
|
158
160
|
}
|
|
159
161
|
// add the special OP_RETURN output if no outputs are provided
|
|
@@ -174,5 +176,5 @@ function craftToSignTx(toSpend, inputs, outputs) {
|
|
|
174
176
|
return tx;
|
|
175
177
|
}
|
|
176
178
|
function hashMessage(message) {
|
|
177
|
-
return
|
|
179
|
+
return secp256k1_js_1.schnorr.utils.taggedHash(TAG_BIP322, new TextEncoder().encode(message));
|
|
178
180
|
}
|
package/dist/cjs/forfeit.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.buildForfeitTx = buildForfeitTx;
|
|
4
|
-
const
|
|
4
|
+
const transaction_js_1 = require("@scure/btc-signer/transaction.js");
|
|
5
5
|
const anchor_1 = require("./utils/anchor");
|
|
6
6
|
function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
|
|
7
|
-
const tx = new
|
|
7
|
+
const tx = new transaction_js_1.Transaction({
|
|
8
8
|
version: 3,
|
|
9
9
|
lockTime: txLocktime,
|
|
10
10
|
});
|
|
@@ -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);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SingleKey = void 0;
|
|
4
|
-
const
|
|
4
|
+
const utils_js_1 = require("@scure/btc-signer/utils.js");
|
|
5
5
|
const base_1 = require("@scure/base");
|
|
6
|
-
const
|
|
6
|
+
const transaction_js_1 = require("@scure/btc-signer/transaction.js");
|
|
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
|
-
const ALL_SIGHASH = Object.values(
|
|
10
|
+
const ALL_SIGHASH = Object.values(transaction_js_1.SigHash).filter((x) => typeof x === "number");
|
|
10
11
|
/**
|
|
11
12
|
* In-memory single key implementation for Bitcoin transaction signing.
|
|
12
13
|
*
|
|
@@ -18,13 +19,16 @@ 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
|
* ```
|
|
24
28
|
*/
|
|
25
29
|
class SingleKey {
|
|
26
30
|
constructor(key) {
|
|
27
|
-
this.key = key || (0,
|
|
31
|
+
this.key = key || (0, utils_js_1.randomPrivateKeyBytes)();
|
|
28
32
|
}
|
|
29
33
|
static fromPrivateKey(privateKey) {
|
|
30
34
|
return new SingleKey(privateKey);
|
|
@@ -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_js_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,
|
|
77
|
+
return Promise.resolve((0, utils_js_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_js_1.sha256)(msgBytes), this.key);
|
|
85
|
+
}
|
|
67
86
|
}
|
|
68
87
|
exports.SingleKey = SingleKey;
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.BIP322 = exports.
|
|
4
|
-
const
|
|
5
|
-
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return
|
|
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
|
+
const transaction_js_1 = require("@scure/btc-signer/transaction.js");
|
|
5
|
+
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_js_1.Transaction; } });
|
|
6
6
|
const singleKey_1 = require("./identity/singleKey");
|
|
7
7
|
Object.defineProperty(exports, "SingleKey", { enumerable: true, get: function () { return singleKey_1.SingleKey; } });
|
|
8
8
|
const address_1 = require("./script/address");
|
|
@@ -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; } });
|
package/dist/cjs/musig2/keys.js
CHANGED
|
@@ -34,8 +34,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.aggregateKeys = aggregateKeys;
|
|
37
|
-
const musig = __importStar(require("@scure/btc-signer/musig2"));
|
|
38
|
-
const
|
|
37
|
+
const musig = __importStar(require("@scure/btc-signer/musig2.js"));
|
|
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.
|
|
48
|
-
finalKey: preTweakedKey.
|
|
47
|
+
preTweakedKey: preTweakedKey.toBytes(true),
|
|
48
|
+
finalKey: preTweakedKey.toBytes(true),
|
|
49
49
|
};
|
|
50
50
|
}
|
|
51
|
-
const tweakBytes =
|
|
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.
|
|
55
|
-
finalKey: finalKey.
|
|
54
|
+
preTweakedKey: preTweakedKey.toBytes(true),
|
|
55
|
+
finalKey: finalKey.toBytes(true),
|
|
56
56
|
};
|
|
57
57
|
}
|
|
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.generateNonces = generateNonces;
|
|
37
|
-
const musig = __importStar(require("@scure/btc-signer/musig2"));
|
|
37
|
+
const musig = __importStar(require("@scure/btc-signer/musig2.js"));
|
|
38
38
|
/**
|
|
39
39
|
* Generates a pair of public and secret nonces for MuSig2 signing
|
|
40
40
|
*/
|
package/dist/cjs/musig2/sign.js
CHANGED
|
@@ -35,11 +35,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.PartialSig = exports.PartialSignatureError = void 0;
|
|
37
37
|
exports.sign = sign;
|
|
38
|
-
const musig = __importStar(require("@scure/btc-signer/musig2"));
|
|
39
|
-
const
|
|
38
|
+
const musig = __importStar(require("@scure/btc-signer/musig2.js"));
|
|
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
|
|
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,
|
|
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 =
|
|
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);
|
package/dist/cjs/networks.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.networks = exports.getNetwork = void 0;
|
|
4
|
-
const
|
|
4
|
+
const utils_js_1 = require("@scure/btc-signer/utils.js");
|
|
5
5
|
const getNetwork = (network) => {
|
|
6
6
|
return exports.networks[network];
|
|
7
7
|
};
|
|
8
8
|
exports.getNetwork = getNetwork;
|
|
9
9
|
exports.networks = {
|
|
10
|
-
bitcoin: withArkPrefix(
|
|
11
|
-
testnet: withArkPrefix(
|
|
12
|
-
signet: withArkPrefix(
|
|
13
|
-
mutinynet: withArkPrefix(
|
|
10
|
+
bitcoin: withArkPrefix(utils_js_1.NETWORK, "ark"),
|
|
11
|
+
testnet: withArkPrefix(utils_js_1.TEST_NETWORK, "tark"),
|
|
12
|
+
signet: withArkPrefix(utils_js_1.TEST_NETWORK, "tark"),
|
|
13
|
+
mutinynet: withArkPrefix(utils_js_1.TEST_NETWORK, "tark"),
|
|
14
14
|
regtest: withArkPrefix({
|
|
15
|
-
...
|
|
15
|
+
...utils_js_1.TEST_NETWORK,
|
|
16
16
|
bech32: "bcrt",
|
|
17
17
|
pubKeyHash: 0x6f,
|
|
18
18
|
scriptHash: 0xc4,
|