@arkade-os/sdk 0.3.12 → 0.4.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +483 -54
- package/dist/cjs/adapters/expo-db.js +35 -0
- package/dist/cjs/asset/assetGroup.js +141 -0
- package/dist/cjs/asset/assetId.js +88 -0
- package/dist/cjs/asset/assetInput.js +204 -0
- package/dist/cjs/asset/assetOutput.js +159 -0
- package/dist/cjs/asset/assetRef.js +82 -0
- package/dist/cjs/asset/index.js +24 -0
- package/dist/cjs/asset/metadata.js +172 -0
- package/dist/cjs/asset/packet.js +164 -0
- package/dist/cjs/asset/types.js +25 -0
- package/dist/cjs/asset/utils.js +105 -0
- package/dist/cjs/contracts/arkcontract.js +148 -0
- package/dist/cjs/contracts/contractManager.js +436 -0
- package/dist/cjs/contracts/contractWatcher.js +567 -0
- package/dist/cjs/contracts/handlers/default.js +85 -0
- package/dist/cjs/contracts/handlers/delegate.js +89 -0
- package/dist/cjs/contracts/handlers/helpers.js +105 -0
- package/dist/cjs/contracts/handlers/index.js +19 -0
- package/dist/cjs/contracts/handlers/registry.js +89 -0
- package/dist/cjs/contracts/handlers/vhtlc.js +193 -0
- package/dist/cjs/contracts/index.js +41 -0
- package/dist/cjs/contracts/types.js +2 -0
- package/dist/cjs/db/manager.js +97 -0
- package/dist/cjs/forfeit.js +12 -8
- package/dist/cjs/identity/index.js +1 -0
- package/dist/cjs/identity/seedIdentity.js +255 -0
- package/dist/cjs/index.js +70 -14
- package/dist/cjs/intent/index.js +28 -2
- package/dist/cjs/providers/ark.js +7 -0
- package/dist/cjs/providers/delegator.js +66 -0
- package/dist/cjs/providers/expoIndexer.js +5 -0
- package/dist/cjs/providers/indexer.js +68 -1
- package/dist/cjs/providers/onchain.js +2 -2
- package/dist/cjs/providers/utils.js +1 -0
- package/dist/cjs/repositories/contractRepository.js +0 -103
- package/dist/cjs/repositories/inMemory/contractRepository.js +55 -0
- package/dist/cjs/repositories/inMemory/walletRepository.js +80 -0
- package/dist/cjs/repositories/index.js +16 -0
- package/dist/cjs/repositories/indexedDB/contractRepository.js +187 -0
- package/dist/cjs/repositories/indexedDB/db.js +57 -0
- package/dist/cjs/repositories/indexedDB/schema.js +159 -0
- package/dist/cjs/repositories/indexedDB/walletRepository.js +338 -0
- package/dist/cjs/repositories/indexedDB/websqlAdapter.js +144 -0
- package/dist/cjs/repositories/migrations/contractRepositoryImpl.js +127 -0
- package/dist/cjs/repositories/migrations/fromStorageAdapter.js +66 -0
- package/dist/cjs/repositories/migrations/walletRepositoryImpl.js +180 -0
- package/dist/cjs/repositories/walletRepository.js +0 -169
- package/dist/cjs/script/base.js +54 -0
- package/dist/cjs/script/delegate.js +49 -0
- package/dist/cjs/storage/asyncStorage.js +4 -1
- package/dist/cjs/storage/fileSystem.js +3 -0
- package/dist/cjs/storage/inMemory.js +3 -0
- package/dist/cjs/storage/indexedDB.js +5 -1
- package/dist/cjs/storage/localStorage.js +3 -0
- package/dist/cjs/utils/arkTransaction.js +16 -0
- package/dist/cjs/utils/transactionHistory.js +50 -0
- package/dist/cjs/utils/txSizeEstimator.js +39 -14
- package/dist/cjs/wallet/asset-manager.js +338 -0
- package/dist/cjs/wallet/asset.js +117 -0
- package/dist/cjs/wallet/batch.js +1 -1
- package/dist/cjs/wallet/delegator.js +235 -0
- package/dist/cjs/wallet/expo/background.js +133 -0
- package/dist/cjs/wallet/expo/index.js +9 -0
- package/dist/cjs/wallet/expo/wallet.js +231 -0
- package/dist/cjs/wallet/onchain.js +57 -12
- package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +568 -0
- package/dist/cjs/wallet/serviceWorker/wallet.js +383 -102
- package/dist/cjs/wallet/unroll.js +7 -2
- package/dist/cjs/wallet/utils.js +60 -0
- package/dist/cjs/wallet/validation.js +151 -0
- package/dist/cjs/wallet/vtxo-manager.js +1 -1
- package/dist/cjs/wallet/wallet.js +702 -260
- package/dist/cjs/worker/browser/service-worker-manager.js +82 -0
- package/dist/cjs/{wallet/serviceWorker → worker/browser}/utils.js +2 -1
- package/dist/cjs/worker/expo/asyncStorageTaskQueue.js +78 -0
- package/dist/cjs/worker/expo/index.js +12 -0
- package/dist/cjs/worker/expo/processors/contractPollProcessor.js +61 -0
- package/dist/cjs/worker/expo/processors/index.js +6 -0
- package/dist/cjs/worker/expo/taskQueue.js +41 -0
- package/dist/cjs/worker/expo/taskRunner.js +57 -0
- package/dist/cjs/worker/messageBus.js +252 -0
- package/dist/esm/adapters/expo-db.js +27 -0
- package/dist/esm/asset/assetGroup.js +137 -0
- package/dist/esm/asset/assetId.js +84 -0
- package/dist/esm/asset/assetInput.js +199 -0
- package/dist/esm/asset/assetOutput.js +154 -0
- package/dist/esm/asset/assetRef.js +78 -0
- package/dist/esm/asset/index.js +8 -0
- package/dist/esm/asset/metadata.js +167 -0
- package/dist/esm/asset/packet.js +159 -0
- package/dist/esm/asset/types.js +22 -0
- package/dist/esm/asset/utils.js +99 -0
- package/dist/esm/contracts/arkcontract.js +141 -0
- package/dist/esm/contracts/contractManager.js +432 -0
- package/dist/esm/contracts/contractWatcher.js +563 -0
- package/dist/esm/contracts/handlers/default.js +82 -0
- package/dist/esm/contracts/handlers/delegate.js +86 -0
- package/dist/esm/contracts/handlers/helpers.js +66 -0
- package/dist/esm/contracts/handlers/index.js +12 -0
- package/dist/esm/contracts/handlers/registry.js +86 -0
- package/dist/esm/contracts/handlers/vhtlc.js +190 -0
- package/dist/esm/contracts/index.js +13 -0
- package/dist/esm/contracts/types.js +1 -0
- package/dist/esm/db/manager.js +92 -0
- package/dist/esm/forfeit.js +11 -8
- package/dist/esm/identity/index.js +1 -0
- package/dist/esm/identity/seedIdentity.js +249 -0
- package/dist/esm/index.js +25 -15
- package/dist/esm/intent/index.js +28 -2
- package/dist/esm/providers/ark.js +7 -0
- package/dist/esm/providers/delegator.js +62 -0
- package/dist/esm/providers/expoIndexer.js +5 -0
- package/dist/esm/providers/indexer.js +68 -1
- package/dist/esm/providers/onchain.js +2 -2
- package/dist/esm/providers/utils.js +1 -0
- package/dist/esm/repositories/contractRepository.js +1 -101
- package/dist/esm/repositories/inMemory/contractRepository.js +51 -0
- package/dist/esm/repositories/inMemory/walletRepository.js +76 -0
- package/dist/esm/repositories/index.js +8 -0
- package/dist/esm/repositories/indexedDB/contractRepository.js +183 -0
- package/dist/esm/repositories/indexedDB/db.js +42 -0
- package/dist/esm/repositories/indexedDB/schema.js +155 -0
- package/dist/esm/repositories/indexedDB/walletRepository.js +334 -0
- package/dist/esm/repositories/indexedDB/websqlAdapter.js +138 -0
- package/dist/esm/repositories/migrations/contractRepositoryImpl.js +121 -0
- package/dist/esm/repositories/migrations/fromStorageAdapter.js +58 -0
- package/dist/esm/repositories/migrations/walletRepositoryImpl.js +176 -0
- package/dist/esm/repositories/walletRepository.js +1 -167
- package/dist/esm/script/base.js +21 -1
- package/dist/esm/script/delegate.js +46 -0
- package/dist/esm/storage/asyncStorage.js +4 -1
- package/dist/esm/storage/fileSystem.js +3 -0
- package/dist/esm/storage/inMemory.js +3 -0
- package/dist/esm/storage/indexedDB.js +5 -1
- package/dist/esm/storage/localStorage.js +3 -0
- package/dist/esm/utils/arkTransaction.js +15 -0
- package/dist/esm/utils/transactionHistory.js +50 -0
- package/dist/esm/utils/txSizeEstimator.js +39 -14
- package/dist/esm/wallet/asset-manager.js +333 -0
- package/dist/esm/wallet/asset.js +111 -0
- package/dist/esm/wallet/batch.js +1 -1
- package/dist/esm/wallet/delegator.js +231 -0
- package/dist/esm/wallet/expo/background.js +128 -0
- package/dist/esm/wallet/expo/index.js +2 -0
- package/dist/esm/wallet/expo/wallet.js +194 -0
- package/dist/esm/wallet/onchain.js +57 -12
- package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +564 -0
- package/dist/esm/wallet/serviceWorker/wallet.js +382 -101
- package/dist/esm/wallet/unroll.js +7 -2
- package/dist/esm/wallet/utils.js +55 -0
- package/dist/esm/wallet/validation.js +139 -0
- package/dist/esm/wallet/vtxo-manager.js +1 -1
- package/dist/esm/wallet/wallet.js +704 -229
- package/dist/esm/worker/browser/service-worker-manager.js +76 -0
- package/dist/esm/{wallet/serviceWorker → worker/browser}/utils.js +2 -1
- package/dist/esm/worker/expo/asyncStorageTaskQueue.js +74 -0
- package/dist/esm/worker/expo/index.js +4 -0
- package/dist/esm/worker/expo/processors/contractPollProcessor.js +58 -0
- package/dist/esm/worker/expo/processors/index.js +1 -0
- package/dist/esm/worker/expo/taskQueue.js +37 -0
- package/dist/esm/worker/expo/taskRunner.js +54 -0
- package/dist/esm/worker/messageBus.js +248 -0
- package/dist/types/adapters/expo-db.d.ts +7 -0
- package/dist/types/asset/assetGroup.d.ts +28 -0
- package/dist/types/asset/assetId.d.ts +19 -0
- package/dist/types/asset/assetInput.d.ts +46 -0
- package/dist/types/asset/assetOutput.d.ts +39 -0
- package/dist/types/asset/assetRef.d.ts +25 -0
- package/dist/types/asset/index.d.ts +8 -0
- package/dist/types/asset/metadata.d.ts +37 -0
- package/dist/types/asset/packet.d.ts +27 -0
- package/dist/types/asset/types.d.ts +18 -0
- package/dist/types/asset/utils.d.ts +21 -0
- package/dist/types/contracts/arkcontract.d.ts +101 -0
- package/dist/types/contracts/contractManager.d.ts +331 -0
- package/dist/types/contracts/contractWatcher.d.ts +192 -0
- package/dist/types/contracts/handlers/default.d.ts +19 -0
- package/dist/types/contracts/handlers/delegate.d.ts +21 -0
- package/dist/types/contracts/handlers/helpers.d.ts +18 -0
- package/dist/types/contracts/handlers/index.d.ts +7 -0
- package/dist/types/contracts/handlers/registry.d.ts +65 -0
- package/dist/types/contracts/handlers/vhtlc.d.ts +32 -0
- package/dist/types/contracts/index.d.ts +14 -0
- package/dist/types/contracts/types.d.ts +222 -0
- package/dist/types/db/manager.d.ts +22 -0
- package/dist/types/forfeit.d.ts +2 -1
- package/dist/types/identity/index.d.ts +1 -0
- package/dist/types/identity/seedIdentity.d.ts +128 -0
- package/dist/types/index.d.ts +21 -12
- package/dist/types/intent/index.d.ts +2 -1
- package/dist/types/providers/ark.d.ts +11 -2
- package/dist/types/providers/delegator.d.ts +29 -0
- package/dist/types/providers/indexer.d.ts +11 -1
- package/dist/types/repositories/contractRepository.d.ts +30 -19
- package/dist/types/repositories/inMemory/contractRepository.d.ts +17 -0
- package/dist/types/repositories/inMemory/walletRepository.d.ts +26 -0
- package/dist/types/repositories/index.d.ts +7 -0
- package/dist/types/repositories/indexedDB/contractRepository.d.ts +21 -0
- package/dist/types/repositories/indexedDB/db.d.ts +56 -0
- package/dist/types/repositories/indexedDB/schema.d.ts +8 -0
- package/dist/types/repositories/indexedDB/walletRepository.d.ts +25 -0
- package/dist/types/repositories/indexedDB/websqlAdapter.d.ts +49 -0
- package/dist/types/repositories/migrations/contractRepositoryImpl.d.ts +24 -0
- package/dist/types/repositories/migrations/fromStorageAdapter.d.ts +19 -0
- package/dist/types/repositories/migrations/walletRepositoryImpl.d.ts +27 -0
- package/dist/types/repositories/walletRepository.d.ts +13 -24
- package/dist/types/script/base.d.ts +1 -0
- package/dist/types/script/delegate.d.ts +36 -0
- package/dist/types/storage/asyncStorage.d.ts +4 -0
- package/dist/types/storage/fileSystem.d.ts +3 -0
- package/dist/types/storage/inMemory.d.ts +3 -0
- package/dist/types/storage/index.d.ts +3 -0
- package/dist/types/storage/indexedDB.d.ts +3 -0
- package/dist/types/storage/localStorage.d.ts +3 -0
- package/dist/types/utils/arkTransaction.d.ts +6 -0
- package/dist/types/utils/txSizeEstimator.d.ts +12 -2
- package/dist/types/wallet/asset-manager.d.ts +78 -0
- package/dist/types/wallet/asset.d.ts +21 -0
- package/dist/types/wallet/batch.d.ts +1 -1
- package/dist/types/wallet/delegator.d.ts +24 -0
- package/dist/types/wallet/expo/background.d.ts +66 -0
- package/dist/types/wallet/expo/index.d.ts +4 -0
- package/dist/types/wallet/expo/wallet.d.ts +97 -0
- package/dist/types/wallet/index.d.ts +75 -2
- package/dist/types/wallet/onchain.d.ts +22 -1
- package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +366 -0
- package/dist/types/wallet/serviceWorker/wallet.d.ts +20 -11
- package/dist/types/wallet/utils.d.ts +13 -1
- package/dist/types/wallet/validation.d.ts +24 -0
- package/dist/types/wallet/wallet.d.ts +111 -17
- package/dist/types/worker/browser/service-worker-manager.d.ts +21 -0
- package/dist/types/{wallet/serviceWorker → worker/browser}/utils.d.ts +2 -1
- package/dist/types/worker/expo/asyncStorageTaskQueue.d.ts +46 -0
- package/dist/types/worker/expo/index.d.ts +7 -0
- package/dist/types/worker/expo/processors/contractPollProcessor.d.ts +14 -0
- package/dist/types/worker/expo/processors/index.d.ts +1 -0
- package/dist/types/worker/expo/taskQueue.d.ts +50 -0
- package/dist/types/worker/expo/taskRunner.d.ts +42 -0
- package/dist/types/worker/messageBus.d.ts +109 -0
- package/package.json +71 -17
- package/dist/cjs/wallet/serviceWorker/request.js +0 -78
- package/dist/cjs/wallet/serviceWorker/response.js +0 -222
- package/dist/cjs/wallet/serviceWorker/worker.js +0 -655
- package/dist/esm/wallet/serviceWorker/request.js +0 -75
- package/dist/esm/wallet/serviceWorker/response.js +0 -219
- package/dist/esm/wallet/serviceWorker/worker.js +0 -651
- package/dist/types/wallet/serviceWorker/request.d.ts +0 -74
- package/dist/types/wallet/serviceWorker/response.d.ts +0 -123
- package/dist/types/wallet/serviceWorker/worker.d.ts +0 -53
package/README.md
CHANGED
|
@@ -16,10 +16,18 @@ npm install @arkade-os/sdk
|
|
|
16
16
|
### Creating a Wallet
|
|
17
17
|
|
|
18
18
|
```typescript
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
MnemonicIdentity,
|
|
21
|
+
Wallet,
|
|
22
|
+
IndexedDBWalletRepository,
|
|
23
|
+
IndexedDBContractRepository
|
|
24
|
+
} from '@arkade-os/sdk'
|
|
25
|
+
import { generateMnemonic } from '@scure/bip39'
|
|
26
|
+
import { wordlist } from '@scure/bip39/wordlists/english.js'
|
|
20
27
|
|
|
21
|
-
//
|
|
22
|
-
const
|
|
28
|
+
// Generate a new mnemonic or use an existing one
|
|
29
|
+
const mnemonic = generateMnemonic(wordlist)
|
|
30
|
+
const identity = MnemonicIdentity.fromMnemonic(mnemonic, { isMainnet: false })
|
|
23
31
|
|
|
24
32
|
// Create a wallet with Ark support
|
|
25
33
|
const wallet = await Wallet.create({
|
|
@@ -27,8 +35,11 @@ const wallet = await Wallet.create({
|
|
|
27
35
|
// Esplora API, can be left empty - mempool.space API will be used
|
|
28
36
|
esploraUrl: 'https://mutinynet.com/api',
|
|
29
37
|
arkServerUrl: 'https://mutinynet.arkade.sh',
|
|
30
|
-
// Optional:
|
|
31
|
-
// storage:
|
|
38
|
+
// Optional: provide repositories for persistence (defaults to IndexedDB)
|
|
39
|
+
// storage: {
|
|
40
|
+
// walletRepository: new IndexedDBWalletRepository('my-wallet-db'),
|
|
41
|
+
// contractRepository: new IndexedDBContractRepository('my-wallet-db')
|
|
42
|
+
// }
|
|
32
43
|
})
|
|
33
44
|
```
|
|
34
45
|
|
|
@@ -103,11 +114,88 @@ const readonlyWallet = await ReadonlyWallet.create({
|
|
|
103
114
|
})
|
|
104
115
|
```
|
|
105
116
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
117
|
+
### Seed & Mnemonic Identity (Recommended)
|
|
118
|
+
|
|
119
|
+
The SDK supports key derivation from BIP39 mnemonic phrases or raw seeds using BIP86 (Taproot) output descriptors. This is the recommended identity type for new integrations — it uses standard derivation paths that are interoperable with other wallets and HD-ready for future multi-address support.
|
|
120
|
+
|
|
121
|
+
> **Note:** Prefer `MnemonicIdentity` or `SeedIdentity` over `SingleKey` for new applications. `SingleKey` exists for backward compatibility with raw private keys.
|
|
122
|
+
|
|
123
|
+
#### Creating from Mnemonic
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { MnemonicIdentity, Wallet } from '@arkade-os/sdk'
|
|
127
|
+
import { generateMnemonic } from '@scure/bip39'
|
|
128
|
+
import { wordlist } from '@scure/bip39/wordlists/english.js'
|
|
129
|
+
|
|
130
|
+
// Generate a new 12-word mnemonic
|
|
131
|
+
const mnemonic = generateMnemonic(wordlist)
|
|
132
|
+
|
|
133
|
+
// Create identity from a 12 or 24 word mnemonic
|
|
134
|
+
const identity = MnemonicIdentity.fromMnemonic(mnemonic, { isMainnet: true })
|
|
135
|
+
|
|
136
|
+
// With optional passphrase for additional security
|
|
137
|
+
const identityWithPassphrase = MnemonicIdentity.fromMnemonic(mnemonic, {
|
|
138
|
+
isMainnet: true,
|
|
139
|
+
passphrase: 'my secret passphrase'
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
// Create wallet as usual
|
|
143
|
+
const wallet = await Wallet.create({
|
|
144
|
+
identity,
|
|
145
|
+
arkServerUrl: 'https://mutinynet.arkade.sh'
|
|
146
|
+
})
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
#### Creating from Raw Seed
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { SeedIdentity } from '@arkade-os/sdk'
|
|
153
|
+
import { mnemonicToSeedSync } from '@scure/bip39'
|
|
154
|
+
|
|
155
|
+
// If you already have a 64-byte seed
|
|
156
|
+
const seed = mnemonicToSeedSync(mnemonic)
|
|
157
|
+
const identity = SeedIdentity.fromSeed(seed, { isMainnet: true })
|
|
158
|
+
|
|
159
|
+
// Or with a custom output descriptor
|
|
160
|
+
const identity2 = SeedIdentity.fromSeed(seed, { descriptor })
|
|
161
|
+
|
|
162
|
+
// Or with a custom descriptor and passphrase (MnemonicIdentity)
|
|
163
|
+
const identity3 = MnemonicIdentity.fromMnemonic(mnemonic, {
|
|
164
|
+
descriptor,
|
|
165
|
+
passphrase: 'my secret passphrase'
|
|
166
|
+
})
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
#### Watch-Only with ReadonlyDescriptorIdentity
|
|
170
|
+
|
|
171
|
+
Create watch-only wallets from an output descriptor:
|
|
172
|
+
|
|
173
|
+
```typescript
|
|
174
|
+
import { ReadonlyDescriptorIdentity, ReadonlyWallet } from '@arkade-os/sdk'
|
|
175
|
+
|
|
176
|
+
// From a full identity
|
|
177
|
+
const readonly = await identity.toReadonly()
|
|
178
|
+
|
|
179
|
+
// Or directly from a descriptor (e.g., from another wallet)
|
|
180
|
+
const descriptor = "tr([12345678/86'/0'/0']xpub.../0/0)"
|
|
181
|
+
const readonlyFromDescriptor = ReadonlyDescriptorIdentity.fromDescriptor(descriptor)
|
|
182
|
+
|
|
183
|
+
// Use in a watch-only wallet
|
|
184
|
+
const readonlyWallet = await ReadonlyWallet.create({
|
|
185
|
+
identity: readonly,
|
|
186
|
+
arkServerUrl: 'https://mutinynet.arkade.sh'
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
// Can query but not sign
|
|
190
|
+
const balance = await readonlyWallet.getBalance()
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
**Derivation Path:** `m/86'/{coinType}'/0'/0/0`
|
|
194
|
+
- BIP86 (Taproot) purpose
|
|
195
|
+
- Coin type 0 for mainnet, 1 for testnet
|
|
196
|
+
- Account 0, external chain, first address
|
|
197
|
+
|
|
198
|
+
The descriptor format (`tr([fingerprint/path']xpub.../0/0)`) is HD-ready — future versions will support deriving multiple addresses and change outputs from the same seed.
|
|
111
199
|
|
|
112
200
|
### Receiving Bitcoin
|
|
113
201
|
|
|
@@ -169,6 +257,42 @@ const txid = await wallet.sendBitcoin({
|
|
|
169
257
|
})
|
|
170
258
|
```
|
|
171
259
|
|
|
260
|
+
### Assets (Issue, Reissue, Burn, Send)
|
|
261
|
+
|
|
262
|
+
The wallet's `assetManager` lets you create and manage assets on Ark. `send` method supports sending assets.
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
// Issue a new asset (non-reissuable by default)
|
|
266
|
+
const controlAssetIssuance = await wallet.assetManager.issue({
|
|
267
|
+
amount: 1000,
|
|
268
|
+
metadata: { name: 'My Token', ticker: 'MTK', decimals: 8 },
|
|
269
|
+
})
|
|
270
|
+
|
|
271
|
+
// Issue a new asset using the control asset as reference
|
|
272
|
+
const assetIssuance = await wallet.assetManager.issue({
|
|
273
|
+
amount: 500,
|
|
274
|
+
controlAssetId: controlAssetIssuance.assetId,
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
// Reissue more supply of the asset, need ownership of the control asset
|
|
278
|
+
const reissuanceTxid = await wallet.assetManager.reissue({
|
|
279
|
+
assetId: assetIssuance.assetId,
|
|
280
|
+
amount: 500,
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
// Burn some of the asset
|
|
284
|
+
const burnTxid = await wallet.assetManager.burn({
|
|
285
|
+
assetId: assetIssuance.assetId,
|
|
286
|
+
amount: 200,
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
// Send asset to another Ark address
|
|
290
|
+
const sendTxid = await wallet.send({
|
|
291
|
+
address: 'ark1qq4...',
|
|
292
|
+
assets: [{ assetId: assetIssuance.assetId, amount: 100 }],
|
|
293
|
+
})
|
|
294
|
+
```
|
|
295
|
+
|
|
172
296
|
### Batch Settlements
|
|
173
297
|
|
|
174
298
|
This can be used to move preconfirmed balances into finalized balances and to manually convert UTXOs and VTXOs.
|
|
@@ -233,6 +357,83 @@ const balance = await manager.getRecoverableBalance()
|
|
|
233
357
|
```
|
|
234
358
|
|
|
235
359
|
|
|
360
|
+
### VTXO Delegation
|
|
361
|
+
|
|
362
|
+
Delegation allows you to outsource VTXO renewal to a third-party delegator service. Instead of renewing VTXOs yourself, the delegator will automatically settle them before they expire, sending the funds back to your wallet address (minus a service fee). This is useful for wallets that cannot be online 24/7.
|
|
363
|
+
|
|
364
|
+
When a `delegatorProvider` is configured, the wallet address includes an extra tapscript path that authorizes the delegator to co-sign renewals alongside the Ark server.
|
|
365
|
+
|
|
366
|
+
#### Setting Up a Wallet with Delegation
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
import { Wallet, SingleKey, RestDelegatorProvider } from '@arkade-os/sdk'
|
|
370
|
+
|
|
371
|
+
const identity = SingleKey.fromHex('your_private_key_hex')
|
|
372
|
+
|
|
373
|
+
const wallet = await Wallet.create({
|
|
374
|
+
identity,
|
|
375
|
+
arkServerUrl: 'https://mutinynet.arkade.sh',
|
|
376
|
+
delegatorProvider: new RestDelegatorProvider('https://delegator.example.com'),
|
|
377
|
+
})
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
> **Note:** Adding a `delegatorProvider` changes your wallet address because the offchain tapscript includes an additional delegation path. Funds sent to an address without delegation cannot be delegated, and vice versa.
|
|
381
|
+
|
|
382
|
+
#### Delegating VTXOs
|
|
383
|
+
|
|
384
|
+
Once the wallet is configured with a delegator, use `wallet.delegatorManager` to delegate your VTXOs:
|
|
385
|
+
|
|
386
|
+
```typescript
|
|
387
|
+
// Get spendable VTXOs
|
|
388
|
+
const vtxos = (await wallet.getVtxos({ withRecoverable: true }))
|
|
389
|
+
.filter(v => v.virtualStatus.type === 'confirmed')
|
|
390
|
+
|
|
391
|
+
// Delegate all VTXOs — the delegator will renew them before expiry
|
|
392
|
+
const myAddress = await wallet.getAddress()
|
|
393
|
+
const result = await wallet.delegatorManager.delegate(vtxos, myAddress)
|
|
394
|
+
|
|
395
|
+
console.log('Delegated:', result.delegated.length)
|
|
396
|
+
console.log('Failed:', result.failed.length)
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
The `delegate` method groups VTXOs by expiry date and submits them to the delegator service. By default, delegation is scheduled at 90% of each VTXO's remaining lifetime. You can override this with an explicit date:
|
|
400
|
+
|
|
401
|
+
```typescript
|
|
402
|
+
// Delegate with a specific renewal time
|
|
403
|
+
const delegateAt = new Date(Date.now() + 12 * 60 * 60 * 1000) // 12 hours from now
|
|
404
|
+
await wallet.delegatorManager.delegate(vtxos, myAddress, delegateAt)
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
#### Service Worker Integration
|
|
408
|
+
|
|
409
|
+
When using a service worker wallet, pass the `delegatorUrl` option. The service worker will automatically delegate VTXOs after each VTXO update:
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
import { ServiceWorkerWallet, SingleKey } from '@arkade-os/sdk'
|
|
413
|
+
|
|
414
|
+
const wallet = await ServiceWorkerWallet.setup({
|
|
415
|
+
serviceWorkerPath: '/service-worker.js',
|
|
416
|
+
arkServerUrl: 'https://mutinynet.arkade.sh',
|
|
417
|
+
identity: SingleKey.fromHex('your_private_key_hex'),
|
|
418
|
+
delegatorUrl: 'https://delegator.example.com',
|
|
419
|
+
})
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
#### Querying Delegator Info
|
|
423
|
+
|
|
424
|
+
You can query the delegator service directly to inspect its public key, fee, and payment address:
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
import { RestDelegatorProvider } from '@arkade-os/sdk'
|
|
428
|
+
|
|
429
|
+
const provider = new RestDelegatorProvider('https://delegator.example.com')
|
|
430
|
+
const info = await provider.getDelegateInfo()
|
|
431
|
+
|
|
432
|
+
console.log('Delegator public key:', info.pubkey)
|
|
433
|
+
console.log('Service fee (sats):', info.fee)
|
|
434
|
+
console.log('Fee address:', info.delegatorAddress)
|
|
435
|
+
```
|
|
436
|
+
|
|
236
437
|
### Transaction History
|
|
237
438
|
|
|
238
439
|
```typescript
|
|
@@ -329,78 +530,204 @@ await Unroll.completeUnroll(
|
|
|
329
530
|
|
|
330
531
|
### Running the wallet in a service worker
|
|
331
532
|
|
|
332
|
-
|
|
533
|
+
The SDK provides a `MessageBus` orchestrator that runs inside a service worker
|
|
534
|
+
and routes messages to pluggable `MessageHandler`s. The built-in
|
|
535
|
+
`WalletMessageHandler` exposes all wallet operations over this message bus, and
|
|
536
|
+
`ServiceWorkerWallet` is a client-side proxy that communicates with it
|
|
537
|
+
transparently.
|
|
538
|
+
|
|
539
|
+
#### Service worker file
|
|
540
|
+
|
|
541
|
+
```javascript
|
|
542
|
+
// service-worker.js
|
|
543
|
+
import {
|
|
544
|
+
MessageBus,
|
|
545
|
+
WalletMessageHandler,
|
|
546
|
+
IndexedDBWalletRepository,
|
|
547
|
+
IndexedDBContractRepository,
|
|
548
|
+
} from '@arkade-os/sdk'
|
|
549
|
+
|
|
550
|
+
const walletRepo = new IndexedDBWalletRepository()
|
|
551
|
+
const contractRepo = new IndexedDBContractRepository()
|
|
552
|
+
|
|
553
|
+
const bus = new MessageBus(walletRepo, contractRepo, {
|
|
554
|
+
messageHandlers: [new WalletMessageHandler()],
|
|
555
|
+
tickIntervalMs: 10_000, // default 10s
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
bus.start()
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
#### Client-side usage
|
|
333
562
|
|
|
334
563
|
```typescript
|
|
335
|
-
//
|
|
336
|
-
import { ServiceWorkerWallet, SingleKey } from '@arkade-os/sdk'
|
|
564
|
+
// app.ts
|
|
565
|
+
import { ServiceWorkerWallet, SingleKey } from '@arkade-os/sdk'
|
|
337
566
|
|
|
338
|
-
|
|
339
|
-
const identity = SingleKey.fromHex('your_private_key_hex');
|
|
340
|
-
// Or generate a new one:
|
|
341
|
-
// const identity = SingleKey.fromRandomBytes();
|
|
567
|
+
const identity = SingleKey.fromHex('your_private_key_hex')
|
|
342
568
|
|
|
569
|
+
// One-liner: registers the SW, initializes the MessageBus, and creates the wallet
|
|
343
570
|
const wallet = await ServiceWorkerWallet.setup({
|
|
344
571
|
serviceWorkerPath: '/service-worker.js',
|
|
345
572
|
arkServerUrl: 'https://mutinynet.arkade.sh',
|
|
346
|
-
identity
|
|
347
|
-
})
|
|
573
|
+
identity,
|
|
574
|
+
})
|
|
348
575
|
|
|
349
|
-
//
|
|
350
|
-
const address = await wallet.getAddress()
|
|
351
|
-
const balance = await wallet.getBalance()
|
|
576
|
+
// Use like any other wallet — calls are proxied to the service worker
|
|
577
|
+
const address = await wallet.getAddress()
|
|
578
|
+
const balance = await wallet.getBalance()
|
|
352
579
|
```
|
|
353
580
|
|
|
354
|
-
|
|
581
|
+
For watch-only wallets, use `ServiceWorkerReadonlyWallet` with a
|
|
582
|
+
`ReadonlySingleKey` identity instead.
|
|
583
|
+
|
|
584
|
+
### Worker Architecture
|
|
585
|
+
|
|
586
|
+
The _worker_ captures the background processing infrastructure for the SDK.
|
|
587
|
+
Two platform-specific implementations share common patterns (pluggable
|
|
588
|
+
handlers, periodic scheduling, repository/provider dependency injection) but
|
|
589
|
+
differ in orchestration and communication.
|
|
590
|
+
|
|
591
|
+
| Platform | Directory | Orchestrator | Communication |
|
|
592
|
+
|----------|----------------------------------------------|-------------|---------------|
|
|
593
|
+
| **Browser** | [`browser/`](./src/worker/browser/README.md) | `MessageBus` inside a Service Worker | `postMessage` between SW and window clients |
|
|
594
|
+
| **Expo/React Native** | [`expo/`](./src/worker/expo/README.md) | `runTasks()` called from foreground interval and OS background wake | `AsyncStorageTaskQueue` inbox/outbox |
|
|
595
|
+
|
|
596
|
+
See the platform READMEs for architecture details, runtime flow, and usage
|
|
597
|
+
examples.
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
### Repositories (Storage)
|
|
602
|
+
|
|
603
|
+
The `StorageAdapter` API is deprecated. Use repositories instead. If you omit
|
|
604
|
+
`storage`, the SDK uses IndexedDB repositories with the default database name.
|
|
605
|
+
|
|
606
|
+
#### Migration from v1 StorageAdapter
|
|
607
|
+
|
|
608
|
+
> [!WARNING]
|
|
609
|
+
> If you previously used the v1 `StorageAdapter`-based repositories, migrate
|
|
610
|
+
> data into the new IndexedDB repositories before use:
|
|
611
|
+
>
|
|
612
|
+
> ```typescript
|
|
613
|
+
> import {
|
|
614
|
+
> IndexedDBWalletRepository,
|
|
615
|
+
> IndexedDBContractRepository,
|
|
616
|
+
> getMigrationStatus,
|
|
617
|
+
> migrateWalletRepository,
|
|
618
|
+
> rollbackMigration,
|
|
619
|
+
> } from '@arkade-os/sdk'
|
|
620
|
+
> import { IndexedDBStorageAdapter } from '@arkade-os/sdk/adapters/indexedDB'
|
|
621
|
+
>
|
|
622
|
+
> const oldStorage = new IndexedDBStorageAdapter('legacy-wallet', 1)
|
|
623
|
+
> const newDbName = 'my-app-db'
|
|
624
|
+
> const walletRepository = new IndexedDBWalletRepository(newDbName)
|
|
625
|
+
>
|
|
626
|
+
> // Check migration status before running
|
|
627
|
+
> const status = await getMigrationStatus('wallet', oldStorage)
|
|
628
|
+
> // status: "not-needed" | "pending" | "in-progress" | "done"
|
|
629
|
+
>
|
|
630
|
+
> if (status === 'pending' || status === 'in-progress') {
|
|
631
|
+
> try {
|
|
632
|
+
> await migrateWalletRepository(oldStorage, walletRepository, {
|
|
633
|
+
> onchain: [ 'address-1', 'address-2' ],
|
|
634
|
+
> offchain: [ 'onboarding-address-1' ],
|
|
635
|
+
> })
|
|
636
|
+
> } catch (err) {
|
|
637
|
+
> // Reset migration flag so the next attempt starts clean
|
|
638
|
+
> await rollbackMigration('wallet', oldStorage)
|
|
639
|
+
> throw err
|
|
640
|
+
> }
|
|
641
|
+
> }
|
|
642
|
+
> ```
|
|
643
|
+
>
|
|
644
|
+
> **Migration status helpers:**
|
|
645
|
+
>
|
|
646
|
+
> | Helper | Description |
|
|
647
|
+
> |--------|-------------|
|
|
648
|
+
> | `getMigrationStatus(repoType, adapter)` | Returns `"not-needed"` (no legacy DB), `"pending"`, `"in-progress"` (interrupted), or `"done"` |
|
|
649
|
+
> | `requiresMigration(repoType, adapter)` | Returns `true` if status is `"pending"` or `"in-progress"` |
|
|
650
|
+
> | `rollbackMigration(repoType, adapter)` | Removes the migration flag so migration can re-run from scratch |
|
|
651
|
+
> | `MIGRATION_KEY(repoType)` | Returns the storage key used for the migration flag |
|
|
652
|
+
>
|
|
653
|
+
> `migrateWalletRepository` sets an `"in-progress"` flag before copying data.
|
|
654
|
+
> If the process crashes mid-way, the flag remains as `"in-progress"` so the
|
|
655
|
+
> next call to `getMigrationStatus` can detect the partial migration. Old data
|
|
656
|
+
> is never deleted — re-running migration after a rollback is safe.
|
|
657
|
+
>
|
|
658
|
+
> Anything related to contract repository migration must be handled by the package which created them. The SDK doesn't manage contracts in V1. Data remains untouched and persisted in the same old location.
|
|
659
|
+
>
|
|
660
|
+
> If you persisted custom data in the ContractRepository via its `setContractData` method,
|
|
661
|
+
> or a custom collection via `saveToContractCollection`, you'll need to migrate it manually:
|
|
662
|
+
>
|
|
663
|
+
> ```typescript
|
|
664
|
+
> // Custom data stored in the ContractRepository
|
|
665
|
+
> const oldStorage = new IndexedDBStorageAdapter('legacy-wallet', 1)
|
|
666
|
+
> const oldRepo = new ContractRepositoryImpl(storageAdapter)
|
|
667
|
+
> const customContract = await oldRepo.getContractData('my-contract', 'status')
|
|
668
|
+
> await contractRepository.setContractData('my-contract', 'status', customData)
|
|
669
|
+
> const customCollection = await oldRepo.getContractCollection('swaps')
|
|
670
|
+
> await contractRepository.saveToContractCollection('swaps', customCollection)
|
|
671
|
+
> ```
|
|
672
|
+
|
|
673
|
+
#### Repository Versioning
|
|
674
|
+
|
|
675
|
+
`WalletRepository`, `ContractRepository`, and `SwapRepository` (in
|
|
676
|
+
`@arkade-os/boltz-swap`) each declare a `readonly version` field with a literal
|
|
677
|
+
type. All built-in implementations set this to the current version. If you
|
|
678
|
+
maintain a custom repository implementation, TypeScript will produce a compile
|
|
679
|
+
error when the version is bumped, signaling that a semantic update is required:
|
|
355
680
|
|
|
356
681
|
```typescript
|
|
357
|
-
|
|
358
|
-
import { Worker } from '@arkade-os/sdk'
|
|
682
|
+
import { WalletRepository } from '@arkade-os/sdk'
|
|
359
683
|
|
|
360
|
-
|
|
361
|
-
|
|
684
|
+
class MyWalletRepository implements WalletRepository {
|
|
685
|
+
readonly version = 1 // must match the interface's literal type
|
|
686
|
+
// ...
|
|
687
|
+
}
|
|
362
688
|
```
|
|
363
689
|
|
|
364
|
-
|
|
690
|
+
Note: `IndexedDB*Repository` requires [indexeddbshim](https://github.com/indexeddbshim/indexeddbshim) in Node or other
|
|
691
|
+
**non-browser environments**. It is a dev dependency of the SDK, so you must
|
|
692
|
+
install and initialize it in your app before using the repositories. This
|
|
693
|
+
also applies when you rely on the default storage behavior (no `storage`).
|
|
365
694
|
|
|
366
|
-
|
|
695
|
+
Please see the working example in [examples/node/multiple-wallets.ts](examples/node/multiple-wallets.ts).
|
|
367
696
|
|
|
368
697
|
```typescript
|
|
369
|
-
import {
|
|
370
|
-
|
|
371
|
-
Wallet,
|
|
372
|
-
InMemoryStorageAdapter, // Works everywhere, data lost on restart
|
|
373
|
-
} from '@arkade-os/sdk'
|
|
698
|
+
import { SingleKey, Wallet } from '@arkade-os/sdk'
|
|
699
|
+
import setGlobalVars from 'indexeddbshim'
|
|
374
700
|
|
|
375
|
-
|
|
376
|
-
import { LocalStorageAdapter } from '@arkade-os/sdk/adapters/localStorage' // Browser/PWA persistent storage
|
|
377
|
-
import { IndexedDBStorageAdapter } from '@arkade-os/sdk/adapters/indexedDB' // Browser/PWA/Service Worker advanced storage
|
|
378
|
-
import { AsyncStorageAdapter } from '@arkade-os/sdk/adapters/asyncStorage' // React Native persistent storage
|
|
379
|
-
import { FileSystemStorageAdapter } from '@arkade-os/sdk/adapters/fileSystem' // Node.js file-based storage
|
|
701
|
+
setGlobalVars()
|
|
380
702
|
|
|
381
|
-
|
|
382
|
-
const storage = new FileSystemStorageAdapter('./wallet-data')
|
|
703
|
+
const identity = SingleKey.fromHex('your_private_key_hex')
|
|
383
704
|
|
|
384
|
-
//
|
|
385
|
-
const
|
|
386
|
-
|
|
387
|
-
|
|
705
|
+
// Create wallet with default IndexedDB storage
|
|
706
|
+
const wallet = await Wallet.create({
|
|
707
|
+
identity,
|
|
708
|
+
arkServerUrl: 'https://mutinynet.arkade.sh',
|
|
709
|
+
})
|
|
710
|
+
```
|
|
388
711
|
|
|
389
|
-
|
|
390
|
-
|
|
712
|
+
If you want a custom database name or a different repository implementation,
|
|
713
|
+
pass `storage` explicitly.
|
|
391
714
|
|
|
392
|
-
|
|
393
|
-
const storage = new IndexedDBStorageAdapter('service-worker-wallet', 1)
|
|
715
|
+
For ephemeral storage (no persistence), pass the in-memory repositories:
|
|
394
716
|
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
717
|
+
```typescript
|
|
718
|
+
import {
|
|
719
|
+
InMemoryWalletRepository,
|
|
720
|
+
InMemoryContractRepository,
|
|
721
|
+
Wallet
|
|
722
|
+
} from '@arkade-os/sdk'
|
|
398
723
|
|
|
399
|
-
// Create wallet (same API everywhere)
|
|
400
724
|
const wallet = await Wallet.create({
|
|
401
725
|
identity,
|
|
402
726
|
arkServerUrl: 'https://mutinynet.arkade.sh',
|
|
403
|
-
storage
|
|
727
|
+
storage: {
|
|
728
|
+
walletRepository: new InMemoryWalletRepository(),
|
|
729
|
+
contractRepository: new InMemoryContractRepository()
|
|
730
|
+
}
|
|
404
731
|
})
|
|
405
732
|
```
|
|
406
733
|
|
|
@@ -432,6 +759,26 @@ Both ExpoArkProvider and ExpoIndexerProvider are available as adapters following
|
|
|
432
759
|
- **ExpoArkProvider**: Handles settlement events and transaction streaming using expo/fetch for Server-Sent Events
|
|
433
760
|
- **ExpoIndexerProvider**: Handles address subscriptions and VTXO updates using expo/fetch for JSON streaming
|
|
434
761
|
|
|
762
|
+
To use IndexedDB repositories in Expo/React Native, call `setupExpoDb()` before any SDK import.
|
|
763
|
+
This sets up `indexeddbshim` backed by expo-sqlite under the hood:
|
|
764
|
+
|
|
765
|
+
```typescript
|
|
766
|
+
import { setupExpoDb } from '@arkade-os/sdk/adapters/expo-db';
|
|
767
|
+
|
|
768
|
+
setupExpoDb();
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
> **Note:** `setupExpoDb` accepts an optional `SetupExpoDbOptions` object to
|
|
772
|
+
> customise `origin`, `checkOrigin`, and `cacheDatabaseInstances`.
|
|
773
|
+
|
|
774
|
+
> **Note:** `expo-sqlite` and `indexeddbshim` are optional peer dependencies,
|
|
775
|
+
> only required when importing from `@arkade-os/sdk/adapters/expo-db`. The
|
|
776
|
+
> streaming providers (`@arkade-os/sdk/adapters/expo`) have no expo-sqlite
|
|
777
|
+
> dependency. Install them with:
|
|
778
|
+
> ```bash
|
|
779
|
+
> npx expo install expo-sqlite && npm install indexeddbshim
|
|
780
|
+
> ```
|
|
781
|
+
|
|
435
782
|
#### Crypto Polyfill Requirement
|
|
436
783
|
|
|
437
784
|
Install `expo-crypto` and polyfill `crypto.getRandomValues()` at the top of your app entry point:
|
|
@@ -453,6 +800,88 @@ import { ExpoArkProvider, ExpoIndexerProvider } from '@arkade-os/sdk/adapters/ex
|
|
|
453
800
|
|
|
454
801
|
This is required for MuSig2 settlements and cryptographic operations.
|
|
455
802
|
|
|
803
|
+
### Contract Management
|
|
804
|
+
|
|
805
|
+
Both `Wallet` and `ServiceWorkerWallet` use a `ContractManager` internally to watch for VTXOs. This provides resilient connection handling with automatic reconnection and failsafe polling - for your wallet's default address and any external contracts you register (Boltz swaps, HTLCs, etc.).
|
|
806
|
+
|
|
807
|
+
When you call `wallet.notifyIncomingFunds()` or use `waitForIncomingFunds()`, it uses the ContractManager under the hood, giving you automatic reconnection and failsafe polling for free - no code changes needed.
|
|
808
|
+
|
|
809
|
+
For advanced use cases, you can access the ContractManager directly to register external contracts:
|
|
810
|
+
|
|
811
|
+
```typescript
|
|
812
|
+
// Get the contract manager (wallet's default address is already registered)
|
|
813
|
+
const manager = await wallet.getContractManager()
|
|
814
|
+
|
|
815
|
+
// Register a VHTLC contract (e.g., for a Lightning swap)
|
|
816
|
+
const contract = await manager.createContract({
|
|
817
|
+
type: 'vhtlc',
|
|
818
|
+
params: {
|
|
819
|
+
sender: alicePubKey,
|
|
820
|
+
receiver: bobPubKey,
|
|
821
|
+
server: serverPubKey,
|
|
822
|
+
hash: paymentHash,
|
|
823
|
+
refundLocktime: '800000',
|
|
824
|
+
claimDelay: '100',
|
|
825
|
+
refundDelay: '102',
|
|
826
|
+
refundNoReceiverDelay: '103',
|
|
827
|
+
},
|
|
828
|
+
script: swapScript,
|
|
829
|
+
address: swapAddress,
|
|
830
|
+
})
|
|
831
|
+
|
|
832
|
+
// Listen for all contracts events (wallet address + external contracts)
|
|
833
|
+
const unsubscribe = await manager.onContractEvent((event) => {
|
|
834
|
+
switch (event.type) {
|
|
835
|
+
case 'vtxo_received':
|
|
836
|
+
console.log(`Received ${event.vtxos.length} VTXOs on ${event.contractScript}`)
|
|
837
|
+
break
|
|
838
|
+
case 'vtxo_spent':
|
|
839
|
+
console.log(`Spent VTXOs on ${event.contractScript}`)
|
|
840
|
+
break
|
|
841
|
+
case 'contract_expired':
|
|
842
|
+
console.log(`Contract ${event.contractScript} expired`)
|
|
843
|
+
break
|
|
844
|
+
}
|
|
845
|
+
})
|
|
846
|
+
|
|
847
|
+
// Update contract data (e.g., set preimage when revealed)
|
|
848
|
+
await manager.updateContractParams(contract.script, { preimage: revealedPreimage })
|
|
849
|
+
|
|
850
|
+
// Check spendable paths (requires a specific VTXO)
|
|
851
|
+
const [withVtxos] = await manager.getContractsWithVtxos({ script: contract.script })
|
|
852
|
+
const vtxo = withVtxos.vtxos[0]
|
|
853
|
+
const paths = manager.getSpendablePaths({
|
|
854
|
+
contractScript: contract.script,
|
|
855
|
+
vtxo,
|
|
856
|
+
collaborative: true,
|
|
857
|
+
walletPubKey: myPubKey,
|
|
858
|
+
})
|
|
859
|
+
if (paths.length > 0) {
|
|
860
|
+
console.log('Contract is spendable via:', paths[0].leaf)
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
// Or list all possible paths for the current context (no spendability checks)
|
|
864
|
+
const allPaths = manager.getAllSpendingPaths({
|
|
865
|
+
contractScript: contract.script,
|
|
866
|
+
collaborative: true,
|
|
867
|
+
walletPubKey: myPubKey,
|
|
868
|
+
})
|
|
869
|
+
|
|
870
|
+
// Get balances across all contracts
|
|
871
|
+
const balances = await manager.getAllBalances()
|
|
872
|
+
|
|
873
|
+
// Manually sweep all eligible contracts
|
|
874
|
+
const sweepResults = await manager.sweepAll()
|
|
875
|
+
|
|
876
|
+
// Stop watching
|
|
877
|
+
unsubscribe()
|
|
878
|
+
```
|
|
879
|
+
|
|
880
|
+
The watcher features:
|
|
881
|
+
- **Automatic reconnection** with exponential backoff (1s → 30s max)
|
|
882
|
+
- **Failsafe polling** every 60 seconds to catch missed events
|
|
883
|
+
- **Immediate sync** on connection and after failures
|
|
884
|
+
|
|
456
885
|
### Repository Pattern
|
|
457
886
|
|
|
458
887
|
Access low-level data management through repositories:
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.openDatabase = void 0;
|
|
7
|
+
exports.setupExpoDb = setupExpoDb;
|
|
8
|
+
// Expo IndexedDB polyfill — requires expo-sqlite and indexeddbshim.
|
|
9
|
+
//
|
|
10
|
+
// Separated from ./expo so that consumers who only need the streaming
|
|
11
|
+
// providers (ExpoArkProvider, ExpoIndexerProvider) don't pull in a
|
|
12
|
+
// hard dependency on expo-sqlite at bundle time.
|
|
13
|
+
const indexeddbshim_1 = __importDefault(require("indexeddbshim"));
|
|
14
|
+
const websqlAdapter_1 = require("../repositories/indexedDB/websqlAdapter");
|
|
15
|
+
var websqlAdapter_2 = require("../repositories/indexedDB/websqlAdapter");
|
|
16
|
+
Object.defineProperty(exports, "openDatabase", { enumerable: true, get: function () { return websqlAdapter_2.openDatabase; } });
|
|
17
|
+
let _initialized = false;
|
|
18
|
+
function setupExpoDb(options) {
|
|
19
|
+
if (_initialized)
|
|
20
|
+
return;
|
|
21
|
+
const { origin = "expo://localhost", checkOrigin = false, cacheDatabaseInstances = true, } = options ?? {};
|
|
22
|
+
if (typeof globalThis.window === "undefined") {
|
|
23
|
+
globalThis.window = globalThis;
|
|
24
|
+
}
|
|
25
|
+
if (typeof globalThis.location === "undefined") {
|
|
26
|
+
globalThis.location = { origin };
|
|
27
|
+
}
|
|
28
|
+
globalThis.openDatabase = websqlAdapter_1.openDatabase;
|
|
29
|
+
(0, indexeddbshim_1.default)(globalThis, {
|
|
30
|
+
checkOrigin,
|
|
31
|
+
useSQLiteIndexes: true,
|
|
32
|
+
cacheDatabaseInstances,
|
|
33
|
+
});
|
|
34
|
+
_initialized = true;
|
|
35
|
+
}
|