@arkade-os/sdk 0.4.25 → 0.4.27
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 +5 -25
- package/dist/cjs/contracts/contractManager.js +31 -11
- package/dist/cjs/contracts/contractWatcher.js +2 -2
- package/dist/cjs/identity/hdCapableIdentity.js +18 -0
- package/dist/cjs/identity/index.js +3 -1
- package/dist/cjs/identity/seedIdentity.js +16 -0
- package/dist/cjs/index.js +4 -2
- package/dist/cjs/script/address.js +2 -2
- package/dist/cjs/wallet/delegator.js +10 -4
- package/dist/cjs/wallet/hdDescriptorProvider.js +29 -0
- package/dist/cjs/wallet/inputSignerRouter.js +98 -0
- package/dist/cjs/wallet/serviceWorker/wallet.js +1 -0
- package/dist/cjs/wallet/signingErrors.js +32 -0
- package/dist/cjs/wallet/unroll.js +5 -1
- package/dist/cjs/wallet/wallet.js +232 -86
- package/dist/cjs/wallet/walletReceiveRotator.js +547 -0
- package/dist/cjs/worker/messageBus.js +1 -0
- package/dist/esm/adapters/asyncStorage.js +1 -1
- package/dist/esm/adapters/expo.js +2 -2
- package/dist/esm/adapters/fileSystem.js +1 -1
- package/dist/esm/adapters/indexedDB.js +1 -1
- package/dist/esm/adapters/localStorage.js +1 -1
- package/dist/esm/arkfee/index.js +1 -1
- package/dist/esm/arknote/index.js +1 -1
- package/dist/esm/bip322/index.js +2 -2
- package/dist/esm/contracts/arkcontract.js +2 -2
- package/dist/esm/contracts/contractManager.js +36 -16
- package/dist/esm/contracts/contractWatcher.js +5 -5
- package/dist/esm/contracts/handlers/default.js +4 -4
- package/dist/esm/contracts/handlers/delegate.js +4 -4
- package/dist/esm/contracts/handlers/helpers.js +2 -2
- package/dist/esm/contracts/handlers/index.js +8 -8
- package/dist/esm/contracts/handlers/vhtlc.js +3 -3
- package/dist/esm/contracts/index.js +8 -8
- package/dist/esm/extension/asset/assetGroup.js +7 -7
- package/dist/esm/extension/asset/assetId.js +2 -2
- package/dist/esm/extension/asset/assetInput.js +2 -2
- package/dist/esm/extension/asset/assetOutput.js +1 -1
- package/dist/esm/extension/asset/assetRef.js +3 -3
- package/dist/esm/extension/asset/index.js +8 -8
- package/dist/esm/extension/asset/metadata.js +1 -1
- package/dist/esm/extension/asset/packet.js +3 -3
- package/dist/esm/extension/index.js +4 -4
- package/dist/esm/forfeit.js +2 -2
- package/dist/esm/identity/hdCapableIdentity.js +17 -1
- package/dist/esm/identity/index.js +6 -5
- package/dist/esm/identity/seedIdentity.js +18 -2
- package/dist/esm/identity/serialize.js +2 -2
- package/dist/esm/identity/singleKey.js +1 -1
- package/dist/esm/identity/staticDescriptorProvider.js +2 -2
- package/dist/esm/index.js +48 -48
- package/dist/esm/intent/index.js +3 -3
- package/dist/esm/musig2/index.js +3 -3
- package/dist/esm/musig2/sign.js +1 -1
- package/dist/esm/providers/ark.js +3 -3
- package/dist/esm/providers/delegator.js +1 -1
- package/dist/esm/providers/electrum.js +2 -2
- package/dist/esm/providers/expoArk.js +2 -2
- package/dist/esm/providers/expoIndexer.js +3 -3
- package/dist/esm/providers/indexer.js +3 -3
- package/dist/esm/repositories/inMemory/walletRepository.js +1 -1
- package/dist/esm/repositories/index.js +9 -9
- package/dist/esm/repositories/indexedDB/contractRepository.js +4 -4
- package/dist/esm/repositories/indexedDB/db.js +2 -2
- package/dist/esm/repositories/indexedDB/schema.js +1 -1
- package/dist/esm/repositories/indexedDB/walletRepository.js +6 -6
- package/dist/esm/repositories/migrations/fromStorageAdapter.js +1 -1
- package/dist/esm/repositories/migrations/walletRepositoryImpl.js +1 -1
- package/dist/esm/repositories/realm/index.js +3 -3
- package/dist/esm/repositories/realm/schemas.js +1 -1
- package/dist/esm/repositories/realm/walletRepository.js +3 -3
- package/dist/esm/repositories/scriptFromAddress.js +1 -1
- package/dist/esm/repositories/sqlite/index.js +2 -2
- package/dist/esm/repositories/sqlite/walletRepository.js +3 -3
- package/dist/esm/script/address.js +3 -3
- package/dist/esm/script/base.js +3 -3
- package/dist/esm/script/default.js +2 -2
- package/dist/esm/script/delegate.js +3 -3
- package/dist/esm/script/tapscript.js +1 -1
- package/dist/esm/script/vhtlc.js +2 -2
- package/dist/esm/storage/indexedDB.js +1 -1
- package/dist/esm/tree/signingSession.js +2 -2
- package/dist/esm/tree/validation.js +2 -2
- package/dist/esm/utils/arkTransaction.js +7 -7
- package/dist/esm/utils/transactionHistory.js +1 -1
- package/dist/esm/utils/unknownFields.js +1 -1
- package/dist/esm/wallet/asset-manager.js +5 -5
- package/dist/esm/wallet/asset.js +1 -1
- package/dist/esm/wallet/batch.js +2 -2
- package/dist/esm/wallet/delegator.js +16 -10
- package/dist/esm/wallet/expo/background.js +5 -5
- package/dist/esm/wallet/expo/index.js +2 -2
- package/dist/esm/wallet/expo/wallet.js +8 -8
- package/dist/esm/wallet/hdDescriptorProvider.js +31 -2
- package/dist/esm/wallet/inputSignerRouter.js +94 -0
- package/dist/esm/wallet/onchain.js +7 -7
- package/dist/esm/wallet/ramps.js +3 -3
- package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +6 -6
- package/dist/esm/wallet/serviceWorker/wallet.js +8 -7
- package/dist/esm/wallet/signingErrors.js +27 -0
- package/dist/esm/wallet/unroll.js +12 -8
- package/dist/esm/wallet/utils.js +2 -2
- package/dist/esm/wallet/validation.js +2 -2
- package/dist/esm/wallet/vtxo-manager.js +9 -9
- package/dist/esm/wallet/wallet.js +262 -117
- package/dist/esm/wallet/walletReceiveRotator.js +540 -0
- package/dist/esm/worker/expo/index.js +4 -4
- package/dist/esm/worker/expo/processors/contractPollProcessor.js +1 -1
- package/dist/esm/worker/expo/processors/index.js +1 -1
- package/dist/esm/worker/expo/taskRunner.js +1 -1
- package/dist/esm/worker/messageBus.js +7 -6
- package/dist/types/adapters/asyncStorage.d.ts +2 -2
- package/dist/types/adapters/expo.d.ts +4 -4
- package/dist/types/adapters/fileSystem.d.ts +2 -2
- package/dist/types/adapters/indexedDB.d.ts +2 -2
- package/dist/types/adapters/localStorage.d.ts +2 -2
- package/dist/types/arkfee/index.d.ts +2 -2
- package/dist/types/arknote/index.d.ts +2 -2
- package/dist/types/bip322/index.d.ts +1 -1
- package/dist/types/contracts/arkcontract.d.ts +1 -1
- package/dist/types/contracts/contractManager.d.ts +39 -9
- package/dist/types/contracts/contractWatcher.d.ts +3 -3
- package/dist/types/contracts/handlers/default.d.ts +3 -3
- package/dist/types/contracts/handlers/delegate.d.ts +3 -3
- package/dist/types/contracts/handlers/helpers.d.ts +1 -1
- package/dist/types/contracts/handlers/index.d.ts +7 -7
- package/dist/types/contracts/handlers/registry.d.ts +1 -1
- package/dist/types/contracts/handlers/vhtlc.d.ts +3 -3
- package/dist/types/contracts/index.d.ts +14 -14
- package/dist/types/contracts/types.d.ts +21 -4
- package/dist/types/contracts/vtxoOwnership.d.ts +3 -3
- package/dist/types/extension/asset/assetGroup.d.ts +6 -6
- package/dist/types/extension/asset/assetId.d.ts +1 -1
- package/dist/types/extension/asset/assetInput.d.ts +2 -2
- package/dist/types/extension/asset/assetOutput.d.ts +1 -1
- package/dist/types/extension/asset/assetRef.d.ts +3 -3
- package/dist/types/extension/asset/index.d.ts +8 -8
- package/dist/types/extension/asset/metadata.d.ts +1 -1
- package/dist/types/extension/asset/packet.d.ts +2 -2
- package/dist/types/extension/index.d.ts +6 -6
- package/dist/types/forfeit.d.ts +1 -1
- package/dist/types/identity/descriptorProvider.d.ts +8 -1
- package/dist/types/identity/hdCapableIdentity.d.ts +33 -6
- package/dist/types/identity/index.d.ts +12 -11
- package/dist/types/identity/seedIdentity.d.ts +21 -5
- package/dist/types/identity/serialize.d.ts +1 -1
- package/dist/types/identity/singleKey.d.ts +3 -3
- package/dist/types/identity/staticDescriptorProvider.d.ts +3 -3
- package/dist/types/index.d.ts +59 -59
- package/dist/types/intent/index.d.ts +2 -2
- package/dist/types/musig2/index.d.ts +4 -4
- package/dist/types/providers/ark.d.ts +5 -5
- package/dist/types/providers/delegator.d.ts +2 -2
- package/dist/types/providers/electrum.d.ts +5 -5
- package/dist/types/providers/expoArk.d.ts +1 -1
- package/dist/types/providers/expoIndexer.d.ts +1 -1
- package/dist/types/providers/indexer.d.ts +1 -1
- package/dist/types/providers/onchain.d.ts +2 -2
- package/dist/types/repositories/contractRepository.d.ts +1 -1
- package/dist/types/repositories/inMemory/contractRepository.d.ts +2 -2
- package/dist/types/repositories/inMemory/walletRepository.d.ts +2 -2
- package/dist/types/repositories/index.d.ts +9 -9
- package/dist/types/repositories/indexedDB/contractRepository.d.ts +2 -2
- package/dist/types/repositories/indexedDB/db.d.ts +3 -3
- package/dist/types/repositories/indexedDB/walletRepository.d.ts +2 -2
- package/dist/types/repositories/migrations/contractRepositoryImpl.d.ts +3 -3
- package/dist/types/repositories/migrations/fromStorageAdapter.d.ts +2 -2
- package/dist/types/repositories/migrations/walletRepositoryImpl.d.ts +3 -3
- package/dist/types/repositories/realm/contractRepository.d.ts +3 -3
- package/dist/types/repositories/realm/index.d.ts +4 -4
- package/dist/types/repositories/realm/walletRepository.d.ts +3 -3
- package/dist/types/repositories/serialization.d.ts +11 -11
- package/dist/types/repositories/sqlite/contractRepository.d.ts +3 -3
- package/dist/types/repositories/sqlite/index.d.ts +3 -3
- package/dist/types/repositories/sqlite/walletRepository.d.ts +3 -3
- package/dist/types/repositories/walletRepository.d.ts +1 -1
- package/dist/types/script/address.d.ts +2 -2
- package/dist/types/script/base.d.ts +2 -2
- package/dist/types/script/default.d.ts +2 -2
- package/dist/types/script/delegate.d.ts +3 -3
- package/dist/types/script/vhtlc.d.ts +2 -2
- package/dist/types/storage/asyncStorage.d.ts +1 -1
- package/dist/types/storage/fileSystem.d.ts +1 -1
- package/dist/types/storage/inMemory.d.ts +1 -1
- package/dist/types/storage/indexedDB.d.ts +1 -1
- package/dist/types/storage/localStorage.d.ts +1 -1
- package/dist/types/tree/signingSession.d.ts +2 -2
- package/dist/types/tree/validation.d.ts +1 -1
- package/dist/types/utils/arkTransaction.d.ts +5 -5
- package/dist/types/utils/syncCursors.d.ts +1 -1
- package/dist/types/utils/timelock.d.ts +1 -1
- package/dist/types/utils/transaction.d.ts +2 -2
- package/dist/types/utils/transactionHistory.d.ts +1 -1
- package/dist/types/utils/txSizeEstimator.d.ts +1 -1
- package/dist/types/wallet/asset-manager.d.ts +3 -3
- package/dist/types/wallet/asset.d.ts +2 -2
- package/dist/types/wallet/batch.d.ts +2 -2
- package/dist/types/wallet/delegator.d.ts +5 -5
- package/dist/types/wallet/expo/background.d.ts +4 -4
- package/dist/types/wallet/expo/index.d.ts +4 -4
- package/dist/types/wallet/expo/wallet.d.ts +8 -8
- package/dist/types/wallet/hdDescriptorProvider.d.ts +26 -5
- package/dist/types/wallet/index.d.ts +63 -26
- package/dist/types/wallet/inputSignerRouter.d.ts +35 -0
- package/dist/types/wallet/onchain.d.ts +6 -6
- package/dist/types/wallet/ramps.d.ts +2 -2
- package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +7 -7
- package/dist/types/wallet/serviceWorker/wallet.d.ts +20 -10
- package/dist/types/wallet/signingErrors.d.ts +19 -0
- package/dist/types/wallet/unroll.d.ts +6 -6
- package/dist/types/wallet/utils.d.ts +5 -5
- package/dist/types/wallet/validation.d.ts +3 -3
- package/dist/types/wallet/vtxo-manager.d.ts +2 -2
- package/dist/types/wallet/wallet.d.ts +71 -22
- package/dist/types/wallet/walletReceiveRotator.d.ts +306 -0
- package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +1 -1
- package/dist/types/worker/expo/index.d.ts +7 -7
- package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +1 -1
- package/dist/types/worker/expo/processors/index.d.ts +1 -1
- package/dist/types/worker/expo/taskRunner.d.ts +7 -7
- package/dist/types/worker/messageBus.d.ts +7 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -28,12 +28,11 @@ const mnemonic = generateMnemonic(wordlist)
|
|
|
28
28
|
const identity = MnemonicIdentity.fromMnemonic(mnemonic)
|
|
29
29
|
|
|
30
30
|
// Create a wallet with Arkade support
|
|
31
|
-
const wallet = await Wallet.create({
|
|
32
|
-
identity,
|
|
33
|
-
arkServerUrl: 'https://arkade.computer',
|
|
34
|
-
})
|
|
31
|
+
const wallet = await Wallet.create({ identity }) // defaults to mainnet
|
|
35
32
|
```
|
|
36
33
|
|
|
34
|
+
To use a different network, pass `arkServerUrl` option.
|
|
35
|
+
|
|
37
36
|
### Read-Only Wallets (Watch-Only)
|
|
38
37
|
|
|
39
38
|
The SDK supports read-only wallets that allow you to query wallet state without exposing private keys. This is useful for:
|
|
@@ -55,7 +54,6 @@ const readonlyIdentity = ReadonlySingleKey.fromPublicKey(publicKey)
|
|
|
55
54
|
// Create a read-only wallet
|
|
56
55
|
const readonlyWallet = await ReadonlyWallet.create({
|
|
57
56
|
identity: readonlyIdentity,
|
|
58
|
-
arkServerUrl: 'https://arkade.computer'
|
|
59
57
|
})
|
|
60
58
|
|
|
61
59
|
// Query operations work normally
|
|
@@ -75,10 +73,7 @@ import { Wallet, MnemonicIdentity } from '@arkade-os/sdk'
|
|
|
75
73
|
|
|
76
74
|
// Create a full wallet
|
|
77
75
|
const identity = MnemonicIdentity.fromMnemonic('abandon abandon...')
|
|
78
|
-
const wallet = await Wallet.create({
|
|
79
|
-
identity,
|
|
80
|
-
arkServerUrl: 'https://arkade.computer'
|
|
81
|
-
})
|
|
76
|
+
const wallet = await Wallet.create({ identity })
|
|
82
77
|
|
|
83
78
|
// Convert to read-only wallet (safe to share)
|
|
84
79
|
const readonlyWallet = await wallet.toReadonly()
|
|
@@ -101,7 +96,6 @@ const readonlyIdentity = await identity.toReadonly()
|
|
|
101
96
|
// Use in read-only wallet
|
|
102
97
|
const readonlyWallet = await ReadonlyWallet.create({
|
|
103
98
|
identity: readonlyIdentity,
|
|
104
|
-
arkServerUrl: 'https://arkade.computer'
|
|
105
99
|
})
|
|
106
100
|
```
|
|
107
101
|
|
|
@@ -132,7 +126,6 @@ const identityWithPassphrase = MnemonicIdentity.fromMnemonic(mnemonic, {
|
|
|
132
126
|
// Create wallet as usual
|
|
133
127
|
const wallet = await Wallet.create({
|
|
134
128
|
identity: identityWithPassphrase,
|
|
135
|
-
arkServerUrl: 'https://arkade.computer'
|
|
136
129
|
})
|
|
137
130
|
```
|
|
138
131
|
|
|
@@ -177,7 +170,6 @@ const readonlyFromTemplate = ReadonlyDescriptorIdentity.fromDescriptor(template)
|
|
|
177
170
|
// Use in a watch-only wallet
|
|
178
171
|
const readonlyWallet = await ReadonlyWallet.create({
|
|
179
172
|
identity: readonly,
|
|
180
|
-
arkServerUrl: 'https://arkade.computer'
|
|
181
173
|
})
|
|
182
174
|
|
|
183
175
|
// Can query but not sign
|
|
@@ -219,7 +211,7 @@ const identity = new MyBrowserWallet()
|
|
|
219
211
|
console.log(isBatchSignable(identity)) // true
|
|
220
212
|
|
|
221
213
|
// Wallet.send() uses one popup instead of N+1
|
|
222
|
-
const wallet = await Wallet.create({ identity
|
|
214
|
+
const wallet = await Wallet.create({ identity })
|
|
223
215
|
await wallet.send({ address: 'ark1q...', amount: 1000 })
|
|
224
216
|
```
|
|
225
217
|
|
|
@@ -456,7 +448,6 @@ Virtual output renewal at 3 days and boarding input sweep enabled.
|
|
|
456
448
|
```typescript
|
|
457
449
|
const wallet = await Wallet.create({
|
|
458
450
|
identity,
|
|
459
|
-
arkServerUrl: 'https://arkade.computer',
|
|
460
451
|
// Enable settlement with defaults explicitly:
|
|
461
452
|
settlementConfig: {
|
|
462
453
|
// Seconds before virtual output expiry to trigger renewal
|
|
@@ -473,7 +464,6 @@ const wallet = await Wallet.create({
|
|
|
473
464
|
// Enable both virtual output renewal and boarding input sweep
|
|
474
465
|
const wallet = await Wallet.create({
|
|
475
466
|
identity,
|
|
476
|
-
arkServerUrl: 'https://arkade.computer',
|
|
477
467
|
settlementConfig: {
|
|
478
468
|
vtxoThreshold: 60 * 60 * 24, // renew when 24 hours remain (in seconds)
|
|
479
469
|
boardingUtxoSweep: true, // sweep expired boarding inputs
|
|
@@ -485,7 +475,6 @@ const wallet = await Wallet.create({
|
|
|
485
475
|
// Explicitly disable all settlement
|
|
486
476
|
const wallet = await Wallet.create({
|
|
487
477
|
identity,
|
|
488
|
-
arkServerUrl: 'https://arkade.computer',
|
|
489
478
|
settlementConfig: false,
|
|
490
479
|
})
|
|
491
480
|
```
|
|
@@ -567,7 +556,6 @@ import { Wallet, MnemonicIdentity, RestDelegatorProvider } from '@arkade-os/sdk'
|
|
|
567
556
|
|
|
568
557
|
const wallet = await Wallet.create({
|
|
569
558
|
identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
|
|
570
|
-
arkServerUrl: 'https://arkade.computer',
|
|
571
559
|
delegatorProvider: new RestDelegatorProvider('http://localhost:7001'),
|
|
572
560
|
})
|
|
573
561
|
```
|
|
@@ -612,7 +600,6 @@ import { ServiceWorkerWallet, MnemonicIdentity } from '@arkade-os/sdk'
|
|
|
612
600
|
|
|
613
601
|
const wallet = await ServiceWorkerWallet.setup({
|
|
614
602
|
serviceWorkerPath: '/service-worker.js',
|
|
615
|
-
arkServerUrl: 'https://arkade.computer',
|
|
616
603
|
identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
|
|
617
604
|
delegatorUrl: 'http://localhost:7001',
|
|
618
605
|
})
|
|
@@ -686,7 +673,6 @@ import { Wallet, MnemonicIdentity, Ramps } from '@arkade-os/sdk'
|
|
|
686
673
|
|
|
687
674
|
const wallet = await Wallet.create({
|
|
688
675
|
identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
|
|
689
|
-
arkServerUrl: 'https://arkade.computer'
|
|
690
676
|
})
|
|
691
677
|
|
|
692
678
|
// Get fee information from the server
|
|
@@ -828,7 +814,6 @@ import { ServiceWorkerWallet, MnemonicIdentity } from '@arkade-os/sdk'
|
|
|
828
814
|
// One-liner: registers the SW, initializes the MessageBus, and creates the wallet
|
|
829
815
|
const wallet = await ServiceWorkerWallet.setup({
|
|
830
816
|
serviceWorkerPath: '/service-worker.js',
|
|
831
|
-
arkServerUrl: 'https://arkade.computer',
|
|
832
817
|
identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
|
|
833
818
|
})
|
|
834
819
|
|
|
@@ -968,7 +953,6 @@ const executor: SQLExecutor = {
|
|
|
968
953
|
|
|
969
954
|
const wallet = await Wallet.create({
|
|
970
955
|
identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
|
|
971
|
-
arkServerUrl: 'https://arkade.computer',
|
|
972
956
|
storage: {
|
|
973
957
|
walletRepository: new SQLiteWalletRepository(executor),
|
|
974
958
|
contractRepository: new SQLiteContractRepository(executor),
|
|
@@ -999,7 +983,6 @@ const realm = await Realm.open({
|
|
|
999
983
|
})
|
|
1000
984
|
const wallet = await Wallet.create({
|
|
1001
985
|
identity,
|
|
1002
|
-
arkServerUrl: 'https://arkade.computer',
|
|
1003
986
|
storage: {
|
|
1004
987
|
walletRepository: new RealmWalletRepository(realm),
|
|
1005
988
|
contractRepository: new RealmContractRepository(realm),
|
|
@@ -1017,7 +1000,6 @@ import { MnemonicIdentity, Wallet } from '@arkade-os/sdk'
|
|
|
1017
1000
|
|
|
1018
1001
|
const wallet = await Wallet.create({
|
|
1019
1002
|
identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
|
|
1020
|
-
arkServerUrl: 'https://arkade.computer',
|
|
1021
1003
|
// Uses IndexedDB by default in the browser
|
|
1022
1004
|
})
|
|
1023
1005
|
```
|
|
@@ -1037,7 +1019,6 @@ import {
|
|
|
1037
1019
|
|
|
1038
1020
|
const wallet = await Wallet.create({
|
|
1039
1021
|
identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
|
|
1040
|
-
arkServerUrl: 'https://arkade.computer',
|
|
1041
1022
|
storage: {
|
|
1042
1023
|
walletRepository: new InMemoryWalletRepository(),
|
|
1043
1024
|
contractRepository: new InMemoryContractRepository()
|
|
@@ -1121,7 +1102,6 @@ const executor = {
|
|
|
1121
1102
|
|
|
1122
1103
|
const wallet = await Wallet.create({
|
|
1123
1104
|
identity,
|
|
1124
|
-
arkServerUrl: 'https://arkade.computer',
|
|
1125
1105
|
arkProvider: new ExpoArkProvider('https://arkade.computer'),
|
|
1126
1106
|
indexerProvider: new ExpoIndexerProvider('https://arkade.computer'),
|
|
1127
1107
|
storage: {
|
|
@@ -350,9 +350,22 @@ class ContractManager {
|
|
|
350
350
|
/**
|
|
351
351
|
* Force refresh virtual outputs from the indexer.
|
|
352
352
|
*
|
|
353
|
-
* Without options, re-fetches every contract
|
|
354
|
-
*
|
|
355
|
-
*
|
|
353
|
+
* Without options, re-fetches every contract in the watcher's
|
|
354
|
+
* watched set and advances the global cursor.
|
|
355
|
+
*
|
|
356
|
+
* `scripts` narrows the refresh to a specific list (subset query —
|
|
357
|
+
* cursor is not advanced because contracts outside the list may
|
|
358
|
+
* have data we'd skip).
|
|
359
|
+
*
|
|
360
|
+
* `includeInactive: true` (and no `scripts`) widens the refresh to
|
|
361
|
+
* every contract in the repository, including ones marked
|
|
362
|
+
* `inactive` and ones that have dropped out of the watcher's
|
|
363
|
+
* active set. This is a *superset* of the watched set, so the
|
|
364
|
+
* cursor invariant still holds and the cursor advances normally.
|
|
365
|
+
*
|
|
366
|
+
* `after` / `before` apply a caller-supplied time window. The
|
|
367
|
+
* cursor never advances on a windowed query because the window
|
|
368
|
+
* may skip data outside its bounds.
|
|
356
369
|
*/
|
|
357
370
|
async refreshVtxos(opts) {
|
|
358
371
|
const contracts = opts?.scripts
|
|
@@ -368,6 +381,9 @@ class ContractManager {
|
|
|
368
381
|
const hasExplicitWindow = opts?.after !== undefined || opts?.before !== undefined;
|
|
369
382
|
await this.syncContracts({
|
|
370
383
|
contracts,
|
|
384
|
+
// Scope-only widener; never set together with explicit
|
|
385
|
+
// `contracts` because `scripts` already names the exact set.
|
|
386
|
+
includeInactive: contracts ? false : opts?.includeInactive,
|
|
371
387
|
window: hasExplicitWindow
|
|
372
388
|
? { after: opts?.after, before: opts?.before }
|
|
373
389
|
: undefined,
|
|
@@ -472,17 +488,21 @@ class ContractManager {
|
|
|
472
488
|
async syncContracts(options) {
|
|
473
489
|
const cursor = await (0, syncCursors_1.getSyncCursor)(this.config.walletRepository);
|
|
474
490
|
const window = options.window ?? (0, syncCursors_1.computeSyncWindow)(cursor);
|
|
475
|
-
// Advance the global cursor only on
|
|
476
|
-
//
|
|
477
|
-
//
|
|
478
|
-
//
|
|
479
|
-
//
|
|
480
|
-
//
|
|
481
|
-
//
|
|
491
|
+
// Advance the global cursor only on cursor-derived delta syncs
|
|
492
|
+
// whose contract scope covers at least the watcher's watched
|
|
493
|
+
// set. Targeted subset queries (caller-supplied `contracts`) and
|
|
494
|
+
// bounded-window queries must not move the cursor — they may
|
|
495
|
+
// skip data outside their bounds. `includeInactive` (with no
|
|
496
|
+
// `contracts`) widens the scope rather than narrowing it, so it
|
|
497
|
+
// is cursor-safe. `<=` lets the bootstrap case (cursor=0,
|
|
498
|
+
// window.after=0) write the migration marker on first boot.
|
|
482
499
|
const mustUpdateCursor = options.contracts === undefined &&
|
|
483
500
|
options.window === undefined &&
|
|
484
501
|
(window.after ?? 0) <= cursor;
|
|
485
|
-
const contracts = options.contracts ??
|
|
502
|
+
const contracts = options.contracts ??
|
|
503
|
+
(options.includeInactive
|
|
504
|
+
? await this.config.contractRepository.getContracts({})
|
|
505
|
+
: this.watcher.getWatchedContracts());
|
|
486
506
|
const requestStartedAt = Date.now();
|
|
487
507
|
const result = await this.fetchContractVxosFromIndexer(contracts, options.pageSize, window);
|
|
488
508
|
if (mustUpdateCursor) {
|
|
@@ -566,8 +566,8 @@ class ContractWatcher {
|
|
|
566
566
|
const extendedVtxo = (0, utils_1.extendVirtualCoinForContract)(v, state.contract);
|
|
567
567
|
extended.push({ ...extendedVtxo, contractScript });
|
|
568
568
|
}
|
|
569
|
-
catch {
|
|
570
|
-
console.warn(
|
|
569
|
+
catch (err) {
|
|
570
|
+
console.warn(`failed to extend vtxo ${v.txid}:${v.vout}`, err);
|
|
571
571
|
extended.push({ ...v, contractScript });
|
|
572
572
|
}
|
|
573
573
|
}
|
|
@@ -1,2 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isHDCapableIdentity = isHDCapableIdentity;
|
|
4
|
+
/**
|
|
5
|
+
* Structural type guard for {@link HDCapableIdentity}. Returns `true`
|
|
6
|
+
* when the value exposes the four members the HD wallet flow relies on:
|
|
7
|
+
* `descriptor`, `isOurs`, `signWithDescriptor`, and
|
|
8
|
+
* `signMessageWithDescriptor`. Used by callers that need to opt into
|
|
9
|
+
* the HD path (e.g. installing an `HDDescriptorProvider`) without
|
|
10
|
+
* coupling to a concrete identity class.
|
|
11
|
+
*/
|
|
12
|
+
function isHDCapableIdentity(value) {
|
|
13
|
+
if (typeof value !== "object" || value === null)
|
|
14
|
+
return false;
|
|
15
|
+
const v = value;
|
|
16
|
+
return (typeof v.descriptor === "string" &&
|
|
17
|
+
typeof v.isOurs === "function" &&
|
|
18
|
+
typeof v.signWithDescriptor === "function" &&
|
|
19
|
+
typeof v.signMessageWithDescriptor === "function");
|
|
20
|
+
}
|
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.StaticDescriptorProvider = exports.parseHDDescriptor = exports.extractPubKey = exports.normalizeToDescriptor = exports.isDescriptor = exports.ReadonlyDescriptorIdentity = exports.MnemonicIdentity = exports.SeedIdentity = void 0;
|
|
17
|
+
exports.StaticDescriptorProvider = exports.isHDCapableIdentity = exports.parseHDDescriptor = exports.extractPubKey = exports.normalizeToDescriptor = exports.isDescriptor = exports.ReadonlyDescriptorIdentity = exports.MnemonicIdentity = exports.SeedIdentity = void 0;
|
|
18
18
|
exports.isBatchSignable = isBatchSignable;
|
|
19
19
|
/** Type guard for identities that support batch signing. */
|
|
20
20
|
function isBatchSignable(identity) {
|
|
@@ -33,6 +33,8 @@ Object.defineProperty(exports, "isDescriptor", { enumerable: true, get: function
|
|
|
33
33
|
Object.defineProperty(exports, "normalizeToDescriptor", { enumerable: true, get: function () { return descriptor_1.normalizeToDescriptor; } });
|
|
34
34
|
Object.defineProperty(exports, "extractPubKey", { enumerable: true, get: function () { return descriptor_1.extractPubKey; } });
|
|
35
35
|
Object.defineProperty(exports, "parseHDDescriptor", { enumerable: true, get: function () { return descriptor_1.parseHDDescriptor; } });
|
|
36
|
+
var hdCapableIdentity_1 = require("./hdCapableIdentity");
|
|
37
|
+
Object.defineProperty(exports, "isHDCapableIdentity", { enumerable: true, get: function () { return hdCapableIdentity_1.isHDCapableIdentity; } });
|
|
36
38
|
// Static descriptor provider (wrapper for legacy Identity)
|
|
37
39
|
var staticDescriptorProvider_1 = require("./staticDescriptorProvider");
|
|
38
40
|
Object.defineProperty(exports, "StaticDescriptorProvider", { enumerable: true, get: function () { return staticDescriptorProvider_1.StaticDescriptorProvider; } });
|
|
@@ -185,6 +185,10 @@ class SeedIdentity {
|
|
|
185
185
|
* Returns true when `descriptor` is derived from this identity's seed.
|
|
186
186
|
* HD descriptors match by account xpub; bare `tr(pubkey)` descriptors
|
|
187
187
|
* match by raw pubkey. See {@link descriptorIsOurs}.
|
|
188
|
+
*
|
|
189
|
+
* @deprecated Prefer `DescriptorProvider.isOurs()` via
|
|
190
|
+
* `HDDescriptorProvider` for rotating HD wallets or
|
|
191
|
+
* `StaticDescriptorProvider` for legacy single-key wallets.
|
|
188
192
|
*/
|
|
189
193
|
isOurs(descriptor) {
|
|
190
194
|
return (0, descriptor_1.descriptorIsOurs)(descriptor, this.descriptor, (0, utils_js_1.pubSchnorr)(this.derivedKey));
|
|
@@ -192,6 +196,10 @@ class SeedIdentity {
|
|
|
192
196
|
/**
|
|
193
197
|
* Signs each request with the key derived from its descriptor.
|
|
194
198
|
* Each descriptor must share this identity's seed ({@link isOurs}).
|
|
199
|
+
*
|
|
200
|
+
* @deprecated Prefer `DescriptorProvider.signWithDescriptor()` via
|
|
201
|
+
* `HDDescriptorProvider` or `StaticDescriptorProvider`. Identities keep
|
|
202
|
+
* this method only as backing implementation for descriptor providers.
|
|
195
203
|
*/
|
|
196
204
|
async signWithDescriptor(requests) {
|
|
197
205
|
return requests.map((request) => {
|
|
@@ -204,6 +212,10 @@ class SeedIdentity {
|
|
|
204
212
|
}
|
|
205
213
|
/**
|
|
206
214
|
* Signs a message with the key derived from `descriptor`.
|
|
215
|
+
*
|
|
216
|
+
* @deprecated Prefer `DescriptorProvider.signMessageWithDescriptor()` via
|
|
217
|
+
* `HDDescriptorProvider` or `StaticDescriptorProvider`. Identities keep
|
|
218
|
+
* this method only as backing implementation for descriptor providers.
|
|
207
219
|
*/
|
|
208
220
|
async signMessageWithDescriptor(descriptor, message, signatureType = "schnorr") {
|
|
209
221
|
if (!this.isOurs(descriptor)) {
|
|
@@ -386,6 +398,10 @@ class ReadonlyDescriptorIdentity {
|
|
|
386
398
|
* HD descriptors match by account xpub; bare `tr(pubkey)` descriptors
|
|
387
399
|
* fall back to comparing against the index-0 x-only pubkey. See
|
|
388
400
|
* {@link descriptorIsOurs}.
|
|
401
|
+
*
|
|
402
|
+
* @deprecated Prefer `DescriptorProvider.isOurs()` via
|
|
403
|
+
* `HDDescriptorProvider` for rotating HD wallets or
|
|
404
|
+
* `StaticDescriptorProvider` for legacy single-key wallets.
|
|
389
405
|
*/
|
|
390
406
|
isOurs(descriptor) {
|
|
391
407
|
return (0, descriptor_1.descriptorIsOurs)(descriptor, this.descriptor, this.indexZero.pubkey);
|
package/dist/cjs/index.js
CHANGED
|
@@ -37,8 +37,8 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
})();
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.CLTVMultisigTapscript = exports.ConditionMultisigTapscript = exports.ConditionCSVMultisigTapscript = exports.CSVMultisigTapscript = exports.MultisigTapscript = exports.decodeTapscript = exports.DEFAULT_MESSAGE_TIMEOUTS = exports.ServiceWorkerReadonlyWallet = exports.ServiceWorkerWallet = exports.ServiceWorkerTimeoutError = exports.MessageBusNotInitializedError = exports.MESSAGE_BUS_NOT_INITIALIZED = exports.DelegatorNotConfiguredError = exports.ReadonlyWalletError = exports.WalletNotInitializedError = exports.WalletMessageHandler = exports.MessageBus = exports.setupServiceWorker = exports.SettlementEventType = exports.ChainTxType = exports.IndexerTxType = exports.TxType = exports.VHTLC = exports.VtxoScript = exports.DelegateVtxo = exports.DefaultVtxo = exports.ArkAddress = exports.RestIndexerProvider = exports.RestArkProvider = exports.WsElectrumChainSource = exports.ElectrumOnchainProvider = exports.ELECTRUM_TCP_HOST = exports.ELECTRUM_WS_URL = exports.EsploraProvider = exports.ESPLORA_URL = exports.RestDelegatorProvider = exports.DelegatorManagerImpl = exports.HDDescriptorProvider = exports.VtxoManager = exports.Ramps = exports.OnchainWallet = exports.isBatchSignable = exports.ReadonlyDescriptorIdentity = exports.MnemonicIdentity = exports.SeedIdentity = exports.ReadonlySingleKey = exports.SingleKey = exports.ReadonlyWallet = exports.Wallet = exports.asset = void 0;
|
|
40
|
-
exports.
|
|
41
|
-
exports.isArkContract = exports.contractFromArkContractWithAddress = exports.contractFromArkContract = exports.decodeArkContract = exports.encodeArkContract = exports.VHTLCContractHandler = exports.DelegateContractHandler = exports.DefaultContractHandler = exports.contractHandlers = exports.ContractWatcher = exports.ContractManager = exports.getSequence = void 0;
|
|
40
|
+
exports.isSpendable = exports.isRecoverable = exports.buildForfeitTx = exports.validateConnectorsTxGraph = exports.validateVtxoTxGraph = exports.Batch = exports.MissingSigningDescriptorError = exports.DescriptorSigningProviderMissingError = exports.maybeArkError = exports.ArkError = exports.sequenceToTimelock = exports.timelockToSequence = exports.TxWeightEstimator = exports.Transaction = exports.Unroll = exports.P2A = exports.TxTree = exports.BIP322 = exports.Intent = exports.ContractRepositoryImpl = exports.WalletRepositoryImpl = exports.rollbackMigration = exports.getMigrationStatus = exports.requiresMigration = exports.migrateWalletRepository = exports.MIGRATION_KEY = exports.InMemoryContractRepository = exports.InMemoryWalletRepository = exports.IndexedDBContractRepository = exports.IndexedDBWalletRepository = exports.openDatabase = exports.closeDatabase = exports.networks = exports.ArkNote = exports.isValidArkAddress = exports.isVtxoExpiringSoon = exports.combineTapscriptSigs = exports.hasBoardingTxExpired = exports.waitForIncomingFunds = exports.verifyTapscriptSignatures = exports.buildOffchainTx = exports.ConditionWitness = exports.VtxoTaprootTree = exports.VtxoTreeExpiry = exports.CosignerPublicKey = exports.getArkPsbtFields = exports.setArkPsbtField = exports.ArkPsbtFieldKeyType = exports.ArkPsbtFieldKey = exports.TapTreeCoder = void 0;
|
|
41
|
+
exports.isArkContract = exports.contractFromArkContractWithAddress = exports.contractFromArkContract = exports.decodeArkContract = exports.encodeArkContract = exports.VHTLCContractHandler = exports.DelegateContractHandler = exports.DefaultContractHandler = exports.contractHandlers = exports.ContractWatcher = exports.ContractManager = exports.getSequence = exports.isExpired = exports.isSubdust = void 0;
|
|
42
42
|
const transaction_1 = require("./utils/transaction");
|
|
43
43
|
Object.defineProperty(exports, "Transaction", { enumerable: true, get: function () { return transaction_1.Transaction; } });
|
|
44
44
|
const singleKey_1 = require("./identity/singleKey");
|
|
@@ -76,6 +76,8 @@ const wallet_2 = require("./wallet/wallet");
|
|
|
76
76
|
Object.defineProperty(exports, "Wallet", { enumerable: true, get: function () { return wallet_2.Wallet; } });
|
|
77
77
|
Object.defineProperty(exports, "ReadonlyWallet", { enumerable: true, get: function () { return wallet_2.ReadonlyWallet; } });
|
|
78
78
|
Object.defineProperty(exports, "waitForIncomingFunds", { enumerable: true, get: function () { return wallet_2.waitForIncomingFunds; } });
|
|
79
|
+
Object.defineProperty(exports, "DescriptorSigningProviderMissingError", { enumerable: true, get: function () { return wallet_2.DescriptorSigningProviderMissingError; } });
|
|
80
|
+
Object.defineProperty(exports, "MissingSigningDescriptorError", { enumerable: true, get: function () { return wallet_2.MissingSigningDescriptorError; } });
|
|
79
81
|
const txTree_1 = require("./tree/txTree");
|
|
80
82
|
Object.defineProperty(exports, "TxTree", { enumerable: true, get: function () { return txTree_1.TxTree; } });
|
|
81
83
|
const ramps_1 = require("./wallet/ramps");
|
|
@@ -35,10 +35,10 @@ const wallet_1 = require("../wallet");
|
|
|
35
35
|
*/
|
|
36
36
|
class ArkAddress {
|
|
37
37
|
/**
|
|
38
|
-
* Create an Arkade address from its server key,
|
|
38
|
+
* Create an Arkade address from its server public key, Taproot output key, and prefix.
|
|
39
39
|
*
|
|
40
40
|
* @param serverPubKey - 32-byte Arkade server public key
|
|
41
|
-
* @param vtxoTaprootKey - 32-byte
|
|
41
|
+
* @param vtxoTaprootKey - 32-byte Taproot output key (a.k.a. tweaked public key)
|
|
42
42
|
* @param hrp - Bech32 human-readable prefix
|
|
43
43
|
* @param version - Address version byte
|
|
44
44
|
* @defaultValue `version = 0`
|
|
@@ -29,10 +29,11 @@ class DelegatorManagerImpl {
|
|
|
29
29
|
// fetch server and delegator info once, shared across all groups
|
|
30
30
|
const arkInfo = await this.arkInfoProvider.getInfo();
|
|
31
31
|
const delegateInfo = await this.delegatorProvider.getDelegateInfo();
|
|
32
|
-
// keep only vtxos that can be signed by the delegate
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
// keep only vtxos that can be signed by the delegate. The guard
|
|
33
|
+
// narrows ContractVtxo (with optional taproot fields) to the
|
|
34
|
+
// ExtendedVirtualCoin shape required by makeDelegateForfeitTx.
|
|
35
|
+
const eligible = vtxos.filter((v) => isAnnotated(v) &&
|
|
36
|
+
findDelegateTapLeaf(v, delegateInfo.pubkey) !== undefined);
|
|
36
37
|
if (eligible.length === 0) {
|
|
37
38
|
return { delegated: [], failed: [] };
|
|
38
39
|
}
|
|
@@ -300,3 +301,8 @@ function findDelegateTapLeaf(vtxo, delegatePubkey) {
|
|
|
300
301
|
return arkTapscript.params.pubkeys.map(base_1.hex.encode).includes(pk);
|
|
301
302
|
});
|
|
302
303
|
}
|
|
304
|
+
function isAnnotated(v) {
|
|
305
|
+
return (v.tapTree !== undefined &&
|
|
306
|
+
v.forfeitTapLeafScript !== undefined &&
|
|
307
|
+
v.intentTapLeafScript !== undefined);
|
|
308
|
+
}
|
|
@@ -4,6 +4,7 @@ exports.HDDescriptorProvider = void 0;
|
|
|
4
4
|
const descriptors_scure_1 = require("@bitcoinerlab/descriptors-scure");
|
|
5
5
|
const descriptor_1 = require("../identity/descriptor");
|
|
6
6
|
const syncCursors_1 = require("../utils/syncCursors");
|
|
7
|
+
const walletReceiveRotator_1 = require("./walletReceiveRotator");
|
|
7
8
|
/** Settings key under {@link WalletState.settings} where HD state lives. */
|
|
8
9
|
const HD_SETTINGS_KEY = "hd";
|
|
9
10
|
/**
|
|
@@ -63,6 +64,25 @@ class HDDescriptorProvider {
|
|
|
63
64
|
return this.materializeAt(next);
|
|
64
65
|
});
|
|
65
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Re-derive the descriptor at the most recently allocated index
|
|
69
|
+
* WITHOUT advancing — i.e. read the same descriptor
|
|
70
|
+
* `getNextSigningDescriptor` last returned. Returns `undefined`
|
|
71
|
+
* when no descriptor has ever been allocated on this repo.
|
|
72
|
+
*
|
|
73
|
+
* Used by the boot path to keep the wallet's display address
|
|
74
|
+
* stable across restarts: when no tagged display contract exists
|
|
75
|
+
* (e.g. a fresh wallet that hasn't rotated yet, or a wallet whose
|
|
76
|
+
* baseline-only repo carries no rotation history), the boot should
|
|
77
|
+
* re-derive the existing index rather than burn a new one.
|
|
78
|
+
*/
|
|
79
|
+
async getCurrentSigningDescriptor() {
|
|
80
|
+
const state = await this.walletRepository.getWalletState();
|
|
81
|
+
const settings = this.parseSettings(state ?? {});
|
|
82
|
+
if (settings.lastIndexUsed === undefined)
|
|
83
|
+
return undefined;
|
|
84
|
+
return this.materializeAt(settings.lastIndexUsed);
|
|
85
|
+
}
|
|
66
86
|
/**
|
|
67
87
|
* Returns true when the given descriptor is derivable from this wallet's
|
|
68
88
|
* seed. Delegates to the underlying identity, which handles both HD and
|
|
@@ -83,6 +103,15 @@ class HDDescriptorProvider {
|
|
|
83
103
|
async signMessageWithDescriptor(descriptor, message, signatureType = "schnorr") {
|
|
84
104
|
return this.identity.signMessageWithDescriptor(descriptor, message, signatureType);
|
|
85
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* HD providers participate in receive rotation. The default
|
|
108
|
+
* factory boot (contract-repo lookup → allocate fresh descriptor)
|
|
109
|
+
* is exactly what we want, so this just delegates to
|
|
110
|
+
* {@link WalletReceiveRotator.defaultBoot}.
|
|
111
|
+
*/
|
|
112
|
+
async createReceiveRotator(opts) {
|
|
113
|
+
return walletReceiveRotator_1.WalletReceiveRotator.defaultBoot(this, opts);
|
|
114
|
+
}
|
|
86
115
|
// ── internals ────────────────────────────────────────────────────
|
|
87
116
|
/**
|
|
88
117
|
* Substitute the wildcard in the identity's account-descriptor template
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InputSignerRouter = void 0;
|
|
4
|
+
const base_1 = require("@scure/base");
|
|
5
|
+
const signingErrors_1 = require("./signingErrors");
|
|
6
|
+
const DESCRIPTOR_CAPABLE_CONTRACT_TYPES = new Set(["default", "delegate"]);
|
|
7
|
+
/**
|
|
8
|
+
* Routes PSBT inputs to the correct signer based on the owning contract.
|
|
9
|
+
* Inputs whose script matches a `default`/`delegate` contract with a
|
|
10
|
+
* non-baseline owner are sent to {@link DescriptorProvider}; everything
|
|
11
|
+
* else (baseline-owned contracts, non-default/non-delegate contracts,
|
|
12
|
+
* and the boarding script) is sent to {@link Identity}. Inputs with no
|
|
13
|
+
* matching contract and no boarding match are silently skipped, matching
|
|
14
|
+
* how the wallet historically handled cosigner/connector inputs.
|
|
15
|
+
*/
|
|
16
|
+
class InputSignerRouter {
|
|
17
|
+
constructor(deps) {
|
|
18
|
+
this.deps = deps;
|
|
19
|
+
}
|
|
20
|
+
async sign(tx, jobs) {
|
|
21
|
+
if (jobs.length === 0)
|
|
22
|
+
return tx;
|
|
23
|
+
const distinctScripts = Array.from(new Set(jobs.map((j) => base_1.hex.encode(j.lookupScript))));
|
|
24
|
+
const contracts = await this.deps.contractRepository.getContracts({
|
|
25
|
+
script: distinctScripts,
|
|
26
|
+
});
|
|
27
|
+
// Repo may yield duplicates if seeded oddly; keep the first one
|
|
28
|
+
// for each script to match the wallet's historical behaviour.
|
|
29
|
+
const scriptToContract = new Map();
|
|
30
|
+
for (const contract of contracts) {
|
|
31
|
+
if (!scriptToContract.has(contract.script)) {
|
|
32
|
+
scriptToContract.set(contract.script, contract);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const baselinePubKeyHex = base_1.hex.encode(await this.deps.identity.xOnlyPublicKey());
|
|
36
|
+
const boardingScriptHex = base_1.hex.encode(this.deps.boardingPkScript);
|
|
37
|
+
const identityIndexes = [];
|
|
38
|
+
const descriptorGroups = new Map();
|
|
39
|
+
for (const job of jobs) {
|
|
40
|
+
const scriptHex = base_1.hex.encode(job.lookupScript);
|
|
41
|
+
const contract = scriptToContract.get(scriptHex);
|
|
42
|
+
if (!contract) {
|
|
43
|
+
if (scriptHex === boardingScriptHex) {
|
|
44
|
+
identityIndexes.push(job.index);
|
|
45
|
+
}
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (!DESCRIPTOR_CAPABLE_CONTRACT_TYPES.has(contract.type)) {
|
|
49
|
+
identityIndexes.push(job.index);
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
// `baselinePubKeyHex` is freshly produced by `hex.encode`,
|
|
53
|
+
// so it is already lowercase. `contract.params.pubKey` is
|
|
54
|
+
// persisted data: a migration or custom repository adapter
|
|
55
|
+
// could legitimately store it uppercase, so canonicalize
|
|
56
|
+
// before comparing to match the legacy router behaviour.
|
|
57
|
+
const ownerPubKeyHex = contract.params.pubKey?.toLowerCase();
|
|
58
|
+
if (ownerPubKeyHex && ownerPubKeyHex === baselinePubKeyHex) {
|
|
59
|
+
identityIndexes.push(job.index);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const descriptor = contract.metadata?.signingDescriptor;
|
|
63
|
+
if (typeof descriptor !== "string" || descriptor.length === 0) {
|
|
64
|
+
throw new signingErrors_1.MissingSigningDescriptorError(contract.script, contract.type);
|
|
65
|
+
}
|
|
66
|
+
const bucket = descriptorGroups.get(descriptor);
|
|
67
|
+
if (bucket) {
|
|
68
|
+
bucket.push(job.index);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
descriptorGroups.set(descriptor, [job.index]);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
let signed = tx;
|
|
75
|
+
if (identityIndexes.length > 0) {
|
|
76
|
+
signed = await this.deps.identity.sign(signed, identityIndexes);
|
|
77
|
+
}
|
|
78
|
+
if (descriptorGroups.size > 0) {
|
|
79
|
+
if (!this.deps.descriptorProvider) {
|
|
80
|
+
throw new signingErrors_1.DescriptorSigningProviderMissingError();
|
|
81
|
+
}
|
|
82
|
+
const sortedDescriptors = Array.from(descriptorGroups.keys()).sort();
|
|
83
|
+
for (const descriptor of sortedDescriptors) {
|
|
84
|
+
const indexes = descriptorGroups.get(descriptor);
|
|
85
|
+
const [next] = await this.deps.descriptorProvider.signWithDescriptor([
|
|
86
|
+
{
|
|
87
|
+
tx: signed,
|
|
88
|
+
descriptor,
|
|
89
|
+
inputIndexes: indexes,
|
|
90
|
+
},
|
|
91
|
+
]);
|
|
92
|
+
signed = next;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return signed;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
exports.InputSignerRouter = InputSignerRouter;
|
|
@@ -921,6 +921,7 @@ class ServiceWorkerWallet extends ServiceWorkerReadonlyWallet {
|
|
|
921
921
|
indexerUrl: options.indexerUrl,
|
|
922
922
|
esploraUrl: options.esploraUrl,
|
|
923
923
|
settlementConfig: options.settlementConfig,
|
|
924
|
+
walletMode: options.walletMode,
|
|
924
925
|
watcherConfig: options.watcherConfig,
|
|
925
926
|
messageTimeouts,
|
|
926
927
|
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DescriptorSigningProviderMissingError = exports.MissingSigningDescriptorError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Thrown when a rotated contract (default or delegate) is missing the
|
|
6
|
+
* metadata.signingDescriptor required to route it to a descriptor-aware
|
|
7
|
+
* signer.
|
|
8
|
+
*/
|
|
9
|
+
class MissingSigningDescriptorError extends Error {
|
|
10
|
+
constructor(contractScript, contractType) {
|
|
11
|
+
super(`Cannot sign input for ${contractType} contract ${contractScript}: ` +
|
|
12
|
+
`metadata.signingDescriptor is missing. This wallet was rotated ` +
|
|
13
|
+
`on an earlier build that did not persist signing descriptors. ` +
|
|
14
|
+
`Manually set metadata.signingDescriptor on the contract record, ` +
|
|
15
|
+
`or restore from a pre-rotation snapshot.`);
|
|
16
|
+
this.contractScript = contractScript;
|
|
17
|
+
this.contractType = contractType;
|
|
18
|
+
this.name = "MissingSigningDescriptorError";
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.MissingSigningDescriptorError = MissingSigningDescriptorError;
|
|
22
|
+
/**
|
|
23
|
+
* Thrown when an input needs descriptor-aware signing but no
|
|
24
|
+
* DescriptorProvider was wired into the wallet.
|
|
25
|
+
*/
|
|
26
|
+
class DescriptorSigningProviderMissingError extends Error {
|
|
27
|
+
constructor() {
|
|
28
|
+
super("Descriptor signing requested but no DescriptorProvider was wired into this wallet");
|
|
29
|
+
this.name = "DescriptorSigningProviderMissingError";
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.DescriptorSigningProviderMissingError = DescriptorSigningProviderMissingError;
|
|
@@ -231,7 +231,11 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
231
231
|
if (!feeRate || feeRate < wallet_1.Wallet.MIN_FEE_RATE) {
|
|
232
232
|
feeRate = wallet_1.Wallet.MIN_FEE_RATE;
|
|
233
233
|
}
|
|
234
|
-
|
|
234
|
+
// Esplora returns a `number` and bitcoind regtest sometimes reports
|
|
235
|
+
// fractional sat/vB (e.g. 1.006). `BigInt(1.006)` throws RangeError
|
|
236
|
+
// — round up so we always pay AT LEAST the advertised rate and
|
|
237
|
+
// satisfy BigInt's integer requirement.
|
|
238
|
+
const feeAmount = txWeightEstimator.vsize().fee(BigInt(Math.ceil(feeRate)));
|
|
235
239
|
if (feeAmount > totalAmount) {
|
|
236
240
|
throw new Error("fee amount is greater than the total amount");
|
|
237
241
|
}
|