@utexo/rgb-sdk 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/Readme.md +267 -301
  2. package/cli/README.md +348 -0
  3. package/cli/commands/address.mjs +16 -0
  4. package/cli/commands/blindreceive.mjs +15 -0
  5. package/cli/commands/btcbalance.mjs +11 -0
  6. package/cli/commands/createlightninginvoice.mjs +14 -0
  7. package/cli/commands/createutxos.mjs +13 -0
  8. package/cli/commands/decodergbinvoice.mjs +9 -0
  9. package/cli/commands/generate_keys.mjs +35 -0
  10. package/cli/commands/getlightningreceiverequest.mjs +10 -0
  11. package/cli/commands/getlightningsendrequest.mjs +10 -0
  12. package/cli/commands/getonchainsendstatus.mjs +20 -0
  13. package/cli/commands/listassets.mjs +11 -0
  14. package/cli/commands/listtransfers.mjs +10 -0
  15. package/cli/commands/listunspents.mjs +10 -0
  16. package/cli/commands/onchainreceive.mjs +16 -0
  17. package/cli/commands/onchainsend.mjs +11 -0
  18. package/cli/commands/onchainsendbegin.mjs +9 -0
  19. package/cli/commands/onchainsendend.mjs +9 -0
  20. package/cli/commands/paylightninginvoice.mjs +11 -0
  21. package/cli/commands/paylightninginvoicebegin.mjs +10 -0
  22. package/cli/commands/paylightninginvoiceend.mjs +9 -0
  23. package/cli/commands/refresh.mjs +9 -0
  24. package/cli/commands/send.mjs +31 -0
  25. package/cli/commands/sign-psbt.mjs +12 -0
  26. package/cli/commands/signpsbt.mjs +10 -0
  27. package/cli/commands/witnessreceive.mjs +15 -0
  28. package/cli/generate_keys.mjs +66 -0
  29. package/cli/run.mjs +291 -0
  30. package/cli/utils.mjs +220 -0
  31. package/dist/index.cjs +1606 -121
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.mts +1235 -145
  34. package/dist/index.d.ts +1235 -145
  35. package/dist/index.mjs +1592 -116
  36. package/dist/index.mjs.map +1 -1
  37. package/package.json +21 -8
package/Readme.md CHANGED
@@ -1,11 +1,17 @@
1
+ # @utexo/rgb-sdk Overview
1
2
 
2
- # RGB SDK v2 Overview
3
+ > **Beta notice:** This package is currently in beta. Please test thoroughly in development environments before using in production.
3
4
 
4
5
  This is the underlying SDK used by RGB client applications. It provides a complete set of TypeScript/Node.js bindings for managing RGB-based transfers using **rgb-protocol libraries**
5
6
 
7
+ ⚠️ **Security Notice**
8
+ If you're migrating from the legacy `rgb-sdk` (which relied on a remote RGB Node server), be aware that wallet metadata such as xpubs may have been exposed and this cannot be undone.
9
+
10
+ If you're upgrading from `rgb-sdk` to `@utexo/rgb-sdk`, see the **[Migration Guide](./MIGRATION.md)** for step-by-step instructions on moving your wallet state to local storage.
11
+
12
+ For full details on security implications and recommended actions, please read **[SECURITY.md](./SECURITY.md)**.
13
+
6
14
  > **RGB Protocol**: This SDK uses the [`rgb-lib`](https://github.com/RGB-Tools/rgb-lib) binding library to interact with the RGB protocol. All operations are performed locally, providing full control over wallet data and operations.
7
- >
8
- > **Migrating from v1?** If you're upgrading from RGB SDK v1 (using RGB Node server), see the [Migration Guide](./MIGRATION.md) for step-by-step instructions on moving your wallet state to local storage.
9
15
 
10
16
  ---
11
17
 
@@ -20,54 +26,84 @@ With this SDK, developers can:
20
26
 
21
27
  ---
22
28
 
23
- ## ⚙️ Capabilities of `@utexo/rgb-sdk` (via `WalletManager`)
24
-
25
- | Method | Description |
26
- |--------|-------------|
27
- | `generateKeys(network?)` | Generate new wallet keys (mnemonic, xpubs, master fingerprint) - top-level function |
28
- | `restoreFromBackup(params)` | High-level function to restore wallet from backup - top-level function |
29
- | `deriveKeysFromMnemonic(network, mnemonic)` | Derive wallet keys (xpub/xpriv) from existing mnemonic |
30
- | `deriveKeysFromSeed(network, seed)` | Derive wallet keys (xpub/xpriv) directly from a BIP39 seed |
31
- | `registerWallet()` | Register wallet (synchronous) |
32
- | `getBtcBalance()` | Get on-chain BTC balance (synchronous) |
33
- | `getAddress()` | Get a derived deposit address (synchronous) |
29
+ ## ⚙️ Capabilities of `@utexo/rgb-sdk` (via `UTEXOWallet`)
30
+
31
+ The primary wallet class is **`UTEXOWallet`**: initialize with a mnemonic (or seed) and optional `{ network, dataDir }`, then call `await wallet.initialize()` before use. It combines standard RGB operations with UTEXO features (Lightning, on-chain deposit/withdrawal).
32
+
33
+ | Method / Function | Description |
34
+ |-------------------|-------------|
35
+ | `generateKeys(network?)` | Generate new wallet keys (mnemonic, xpubs, master fingerprint) top-level function |
36
+ | `restoreUtxoWalletFromBackup({ backupPath, password, targetDir })` | Restore UTEXO wallet from file backup (layer1 + utexo) top-level function |
37
+ | `restoreUtxoWalletFromVss({ mnemonic, targetDir, config?, vssServerUrl? })` | Restore UTEXO wallet from VSS cloud backup – top-level function |
38
+ | `deriveKeysFromMnemonic(network, mnemonic)` | Derive wallet keys from existing mnemonic |
39
+ | `deriveKeysFromSeed(network, seed)` | Derive wallet keys from BIP39 seed |
40
+ | `getAddress()` | Get deposit address (async) |
41
+ | `getBtcBalance()` | Get on-chain BTC balance (async) |
42
+ | `getXpub()` | Get vanilla and colored xpubs |
43
+ | `getNetwork()` | Get current network |
34
44
  | `listUnspents()` | List unspent UTXOs |
35
- | `listAssets()` | List RGB assets held (synchronous) |
45
+ | `listAssets()` | List RGB assets held |
36
46
  | `getAssetBalance(assetId)` | Get balance for a specific asset |
37
- | `createUtxosBegin({ upTo, num, size, feeRate })` | Start creating new UTXOs |
38
- | `createUtxosEnd({ signedPsbt, skipSync? })` | Finalize UTXO creation with a signed PSBT |
47
+ | `createUtxos({ num?, size?, upTo? })` | Create UTXOs (async; combines begin, sign, end; feeRate defaults to 1) |
48
+ | `createUtxosBegin({ upTo?, num?, size? })` | Start creating UTXOs (returns unsigned PSBT) |
49
+ | `createUtxosEnd({ signedPsbt, skipSync? })` | Finalize UTXO creation with signed PSBT |
39
50
  | `blindReceive({ assetId, amount, minConfirmations?, durationSeconds? })` | Generate blinded UTXO for receiving |
40
51
  | `witnessReceive({ assetId, amount, minConfirmations?, durationSeconds? })` | Generate witness UTXO for receiving |
41
- | `issueAssetNia({...})` | Issue a new Non-Inflationary Asset |
42
- | `signPsbt(psbt, mnemonic?)` | Sign PSBT using mnemonic and BDK (async) |
43
- | `signMessage(message, options?)` | Produce a Schnorr signature for an arbitrary message |
44
- | `verifyMessage(message, signature, options?)` | Verify Schnorr message signatures using wallet keys or provided public key |
52
+ | `issueAssetNia({ ticker, name, amounts, precision })` | Issue a new Non-Inflationary Asset |
53
+ | `send({ invoice, assetId, amount, witnessData? })` | Complete send (begin sign end; use `witnessData` for witness invoices; feeRate defaults to 1) |
54
+ | `sendBegin({ invoice, assetId, amount, witnessData?, ... })` | Prepare transfer (returns unsigned PSBT) |
55
+ | `sendEnd({ signedPsbt, skipSync? })` | Complete transfer with signed PSBT |
56
+ | `signPsbt(psbt, mnemonic?)` | Sign PSBT using wallet mnemonic (async) |
45
57
  | `refreshWallet()` | Sync and refresh wallet state |
46
- | `syncWallet()` | Trigger wallet sync without additional refresh logic |
47
- | `listTransactions()` | List BTC-level transactions (synchronous) |
48
- | `listTransfers(assetId?)` | List RGB transfer history for asset (synchronous) |
58
+ | `syncWallet()` | Trigger wallet sync |
59
+ | `listTransactions()` | List BTC-level transactions |
60
+ | `listTransfers(assetId?)` | List RGB transfer history for asset |
49
61
  | `failTransfers(params)` | Mark waiting transfers as failed |
50
- | `deleteTransfers(params)` | Delete transfers from wallet |
51
- | `sendBegin(...)` | Prepare a transfer (build unsigned PSBT) |
52
- | `sendEnd({ signedPsbt, skipSync? })` | Submit signed PSBT to complete transfer |
53
- | `sendBtcBegin(params)` | Begin Bitcoin send operation (returns PSBT) |
54
- | `sendBtcEnd(params)` | Complete Bitcoin send operation with signed PSBT |
55
- | `send(...)` | Complete send operation: begin sign → end |
56
- | `createBackup({ backupPath, password })` | Create an encrypted wallet backup (backupPath required, filename includes master fingerprint) |
57
- | `restoreFromBackup({ backupFilePath, password, dataDir })` | Restore wallet state from a backup file (top-level function, call before creating wallet) |
62
+ | `createBackup({ backupPath, password })` | Create encrypted backup (layer1 + utexo in one folder) |
63
+ | `vssBackup(config?, mnemonic?)` | Backup to VSS (config optional; built from mnemonic + default server URL) |
64
+ | `vssBackupInfo(config?, mnemonic?)` | Get VSS backup info |
65
+ | *On-chain* | |
66
+ | `onchainReceive(params)` | Generate invoice for depositing from mainnet to UTEXO |
67
+ | `onchainSendBegin(params)` | Start on-chain withdraw (returns unsigned PSBT) |
68
+ | `onchainSendEnd(params)` | Finalize on-chain withdraw with signed PSBT |
69
+ | `onchainSend(params, mnemonic?)` | Complete on-chain withdraw (begin sign end) |
70
+ | `getOnchainSendStatus(invoice)` | Get status of on-chain withdraw |
71
+ | *Lightning* | |
72
+ | `createLightningInvoice(params)` | Create Lightning invoice for receiving |
73
+ | `payLightningInvoiceBegin(params)` | Start Lightning payment (returns unsigned PSBT) |
74
+ | `payLightningInvoiceEnd(params)` | Finalize Lightning payment with signed PSBT |
75
+ | `payLightningInvoice(params, mnemonic?)` | Complete Lightning payment (begin → sign → end) |
76
+ | `getLightningSendRequest(lnInvoice)` | Get status of Lightning send |
77
+ | `getLightningReceiveRequest(lnInvoice)` | Get status of Lightning receive |
78
+ | `listLightningPayments()` | List Lightning payments |
79
+
80
+ **Examples:** [examples/](./examples/). **CLI (dev tools):** [cli/](./cli/).
81
+
82
+ ```javascript
83
+ const { UTEXOWallet } = require('@utexo/rgb-sdk');
84
+
85
+ const wallet = new UTEXOWallet('your twelve word mnemonic phrase here ...', { network: 'testnet' });
86
+ await wallet.initialize();
87
+
88
+ const address = await wallet.getAddress();
89
+ const balance = await wallet.getBtcBalance();
90
+ const assets = await wallet.listAssets();
91
+ // ... onchainReceive(), onchainSend(), createLightningInvoice(), payLightningInvoice(), etc.
92
+
93
+ await wallet.dispose();
94
+ ```
58
95
 
59
96
  ---
60
97
 
61
98
  ## 🧩 Notes for Custom Integration
62
99
 
63
- - All RGB operations are handled locally using the `RGBLibClient` class, which wraps the native `rgb-lib` library.
64
- - The `signPsbt` method demonstrates how to integrate a signing flow using `bdk-wasm`. This can be replaced with your own HSM or hardware wallet integration if needed.
65
- - By using this SDK, developers have full control over:
66
- - Transfer orchestration
67
- - UTXO selection
100
+ - All RGB operations are handled locally; `RGBLibClient` wraps the native `rgb-lib` library via internal clients.
101
+ - The `signPsbt` method uses the wallet mnemonic for signing; it can be replaced with your own HSM or hardware wallet flow if needed.
102
+ - By using this SDK with `UTEXOWallet`, you have full control over:
103
+ - Transfer orchestration (send, witnessReceive, blindReceive)
104
+ - UTXO creation and sync
68
105
  - Invoice lifecycle
69
- - Signing policy
70
- - Wallet data storage (via `dataDir` parameter)
106
+ - Wallet data storage (via `dataDir` in options)
71
107
 
72
108
  This pattern enables advanced use cases, such as:
73
109
 
@@ -88,19 +124,23 @@ This SDK uses `rgb-protocol libraries`. All operations are performed locally.
88
124
 
89
125
  The SDK uses default endpoints for RGB transport and Bitcoin indexing. These are automatically used if not specified:
90
126
 
91
- **Transport Endpoint** (RGB protocol communication):
127
+ **Transport Endpoints** (RGB protocol communication):
92
128
 
93
- - Default: `rpcs://proxy.iriswallet.com/0.2/json-rpc`
129
+ - **Mainnet**: `rpcs://rgb-proxy-mainnet.utexo.com/json-rpc`
130
+ - **Testnet**: `rpcs://rgb-proxy-testnet3.utexo.com/json-rpc`
131
+ - **Testnet4**: `rpcs://proxy.iriswallet.com/0.2/json-rpc`
132
+ - **Signet**: `rpcs://rgb-proxy-utexo.utexo.com/json-rpc`
133
+ - **Regtest**: `rpcs://proxy.iriswallet.com/0.2/json-rpc`
94
134
 
95
135
  **Indexer URLs** (Bitcoin blockchain data):
96
136
 
97
137
  - **Mainnet**: `ssl://electrum.iriswallet.com:50003`
98
138
  - **Testnet**: `ssl://electrum.iriswallet.com:50013`
99
139
  - **Testnet4**: `ssl://electrum.iriswallet.com:50053`
100
- - **Signet**: `tcp://46.224.75.237:50001`
140
+ - **Signet**: `https://esplora-api.utexo.com`
101
141
  - **Regtest**: `tcp://regtest.thunderstack.org:50001`
102
142
 
103
- These defaults can be overridden by providing `transportEndpoint` and `indexerUrl` parameters when initializing `WalletManager`.
143
+ UTEXOWallet uses network (`testnet` / `mainnet`) that define indexer and transport endpoints internally.
104
144
 
105
145
  ### Installation
106
146
 
@@ -108,141 +148,30 @@ These defaults can be overridden by providing `transportEndpoint` and `indexerUr
108
148
  npm install @utexo/rgb-sdk
109
149
  ```
110
150
 
111
- ### Browser Compatibility
112
-
113
- This SDK is browser-compatible but requires polyfills for Node.js built-in modules. The SDK uses WebAssembly modules and dynamically loads dependencies based on the environment.
114
-
115
- #### Required Polyfills
116
-
117
- For React/Next.js applications, you'll need to configure webpack to polyfill Node.js modules. Install the required polyfills:
118
-
119
- ```bash
120
- npm install --save-dev crypto-browserify stream-browserify buffer process path-browserify
121
- ```
122
-
123
- #### CRACO Configuration (React with Create React App)
124
-
125
- If you're using Create React App with CRACO, create a `craco.config.js` file:
126
-
127
- ```javascript
128
- const path = require('path');
129
- const webpack = require('webpack');
130
-
131
- module.exports = {
132
- webpack: {
133
- alias: {
134
- "@": path.resolve(__dirname, "src/"),
135
- },
136
- configure: (webpackConfig) => {
137
- webpackConfig.resolve = webpackConfig.resolve || {};
138
- webpackConfig.resolve.fallback = {
139
- ...(webpackConfig.resolve.fallback || {}),
140
- crypto: require.resolve('crypto-browserify'),
141
- 'node:crypto': require.resolve('crypto-browserify'),
142
- stream: require.resolve('stream-browserify'),
143
- buffer: require.resolve('buffer'),
144
- process: require.resolve('process/browser'),
145
- path: require.resolve('path-browserify'),
146
- 'node:path': require.resolve('path-browserify'),
147
- fs: false,
148
- module: false,
149
- };
150
-
151
- // WASM rule for .wasm files
152
- const wasmRule = { test: /\.wasm$/, type: 'webassembly/sync' };
153
- const oneOf = webpackConfig.module?.rules?.find(r => Array.isArray(r.oneOf))?.oneOf;
154
- if (oneOf) {
155
- const assetIdx = oneOf.findIndex(r => r.type === 'asset/resource');
156
- if (assetIdx >= 0) oneOf.splice(assetIdx, 0, wasmRule);
157
- else oneOf.unshift(wasmRule);
158
- } else {
159
- webpackConfig.module = webpackConfig.module || {};
160
- webpackConfig.module.rules = [wasmRule, ...(webpackConfig.module.rules || [])];
161
- }
162
-
163
- webpackConfig.experiments = {
164
- ...webpackConfig.experiments,
165
- asyncWebAssembly: true,
166
- topLevelAwait: true,
167
- syncWebAssembly: true,
168
- layers: true,
169
- };
170
-
171
- webpackConfig.plugins = (webpackConfig.plugins || []).concat([
172
- new webpack.ProvidePlugin({
173
- Buffer: ['buffer', 'Buffer'],
174
- process: ['process'],
175
- }),
176
- ]);
177
-
178
- return webpackConfig;
179
- },
180
- },
181
- };
182
- ```
183
-
184
- #### Dynamic Import in Browser
185
-
186
- Use dynamic import to ensure WASM modules load correctly in browser environments:
187
-
188
- ```javascript
189
- // Dynamic import ensures the WASM/glue load together
190
- const sdk = await import('@utexo/rgb-sdk');
191
-
192
- const { WalletManager, generateKeys } = sdk;
193
-
194
- // Use the SDK normally
195
- const keys = generateKeys('testnet');
196
- const wallet = new WalletManager({
197
- xpubVan: keys.accountXpubVanilla,
198
- xpubCol: keys.accountXpubColored,
199
- masterFingerprint: keys.masterFingerprint,
200
- mnemonic: keys.mnemonic,
201
- network: 'testnet',
202
- transportEndpoint: 'rpcs://proxy.iriswallet.com/0.2/json-rpc',
203
- indexerUrl: 'ssl://electrum.iriswallet.com:50013'
204
- });
205
- ```
206
-
207
- ### Important: WASM Module Support
208
-
209
- This SDK uses WebAssembly modules for cryptographic operations. When running scripts, you may need to use the `--experimental-wasm-modules` flag:
151
+ ### Node.js only
210
152
 
211
- ```bash
212
- node --experimental-wasm-modules your-script.js
213
- ```
214
-
215
- **Note**: All npm scripts in this project already include this flag automatically. For browser environments, see the Browser Compatibility section above.
153
+ This SDK is designed for **Node.js** and is not browser-compatible. Use it in Node.js applications, scripts, and backends.
216
154
 
217
155
  ### Basic Usage
218
156
 
219
157
  ```javascript
220
- const { WalletManager, generateKeys } = require('@utexo/rgb-sdk');
158
+ const { UTEXOWallet, generateKeys } = require('@utexo/rgb-sdk');
221
159
 
222
- // 1. Generate wallet keys (synchronous)
223
- const keys = generateKeys('testnet');
224
- console.log('Master Fingerprint:', keys.masterFingerprint);
160
+ // 1. Generate wallet keys (async)
161
+ const keys = await generateKeys('testnet');
225
162
  console.log('Mnemonic:', keys.mnemonic); // Store securely!
226
163
 
227
- // 2. Initialize wallet (constructor-based)
228
- const wallet = new WalletManager({
229
- xpubVan: keys.accountXpubVanilla,
230
- xpubCol: keys.accountXpubColored,
231
- masterFingerprint: keys.masterFingerprint,
232
- mnemonic: keys.mnemonic,
233
- network: 'testnet',
234
- transportEndpoint: 'rpcs://proxy.iriswallet.com/0.2/json-rpc',
235
- indexerUrl: 'ssl://electrum.iriswallet.com:50013',
236
- dataDir: './wallet-data' // Optional: defaults to temp directory
237
- });
164
+ // 2. Create and initialize UTEXO wallet
165
+ const wallet = new UTEXOWallet(keys.mnemonic, { network: 'testnet' });
166
+ await wallet.initialize();
238
167
 
239
- // 3. Register wallet (synchronous)
240
- const { address } = wallet.registerWallet();
168
+ // 3. Get address and balance
169
+ const address = await wallet.getAddress();
241
170
  console.log('Wallet address:', address);
171
+ const balance = await wallet.getBtcBalance();
172
+ console.log('BTC balance:', balance);
242
173
 
243
- // 4. Check balance (synchronous)
244
- const balance = wallet.getBtcBalance();
245
- console.log('BTC Balance:', balance);
174
+ await wallet.dispose();
246
175
  ```
247
176
 
248
177
  ---
@@ -252,61 +181,50 @@ console.log('BTC Balance:', balance);
252
181
  ### Wallet Initialization
253
182
 
254
183
  ```javascript
255
- const { WalletManager, generateKeys, restoreFromBackup } = require('@utexo/rgb-sdk');
184
+ const { UTEXOWallet, generateKeys, restoreUtxoWalletFromBackup, restoreUtxoWalletFromVss } = require('@utexo/rgb-sdk');
256
185
 
257
- // Generate new wallet keys (synchronous)
258
- const keys = generateKeys('testnet');
186
+ // Generate new wallet keys (async)
187
+ const keys = await generateKeys('testnet');
259
188
 
260
- // Initialize wallet with keys (constructor-based - recommended)
261
- const wallet = new WalletManager({
262
- xpubVan: keys.accountXpubVanilla,
263
- xpubCol: keys.accountXpubColored,
264
- masterFingerprint: keys.masterFingerprint,
265
- mnemonic: keys.mnemonic,
266
- network: 'testnet', // 'mainnet', 'testnet', 'signet', or 'regtest'
267
- transportEndpoint: 'rpcs://proxy.iriswallet.com/0.2/json-rpc',
268
- indexerUrl: 'ssl://electrum.iriswallet.com:50013',
269
- dataDir: './wallet-data' // Optional: defaults to temp directory
270
- });
189
+ // Initialize UTEXO wallet with mnemonic
190
+ const wallet = new UTEXOWallet(keys.mnemonic, { network: 'testnet' });
191
+ await wallet.initialize();
271
192
 
272
- // Register wallet (synchronous)
273
- wallet.registerWallet();
193
+ // Optional: use dataDir for persistent storage (same layout as restore)
194
+ const walletWithDir = new UTEXOWallet(keys.mnemonic, { network: 'testnet', dataDir: './wallet-data' });
195
+ await walletWithDir.initialize();
274
196
 
275
- // Alternative: Restore wallet from backup (must be called before creating wallet)
276
- restoreFromBackup({
277
- backupFilePath: './backup/abc123.backup',
197
+ // Restore from file backup (layer1 + utexo in one folder)
198
+ const { targetDir } = restoreUtxoWalletFromBackup({
199
+ backupPath: './backup-folder',
278
200
  password: 'your-password',
279
- dataDir: './restored-wallet-data'
201
+ targetDir: './restored-wallet',
280
202
  });
203
+ const restoredWallet = new UTEXOWallet(keys.mnemonic, { dataDir: targetDir, network: 'testnet' });
204
+ await restoredWallet.initialize();
281
205
 
282
- // Then create wallet pointing to restored directory
283
- const restoredWallet = new WalletManager({
284
- xpubVan: keys.accountXpubVanilla,
285
- xpubCol: keys.accountXpubColored,
286
- masterFingerprint: keys.masterFingerprint,
206
+ // Restore from VSS (mnemonic required; vssServerUrl optional, uses default)
207
+ const { targetDir: vssDir } = await restoreUtxoWalletFromVss({
287
208
  mnemonic: keys.mnemonic,
288
- network: 'testnet',
289
- dataDir: './restored-wallet-data' // Point to restored directory
209
+ targetDir: './restored-from-vss',
290
210
  });
211
+ const fromVss = new UTEXOWallet(keys.mnemonic, { dataDir: vssDir, network: 'testnet' });
212
+ await fromVss.initialize();
291
213
  ```
292
214
 
293
215
  ### UTXO Management
294
216
 
295
217
  ```javascript
296
- // Step 1: Begin UTXO creation
297
- const psbt = wallet.createUtxosBegin({
298
- upTo: true,
299
- num: 5,
300
- size: 1000,
301
- feeRate: 1
302
- });
218
+ // Option 1: Create UTXOs in one call (begin → sign → end)
219
+ const count = await wallet.createUtxos({ num: 5, size: 1000 });
220
+ await wallet.syncWallet();
221
+ console.log(`Created ${count} UTXOs`);
303
222
 
304
- // Step 2: Sign the PSBT (async operation)
223
+ // Option 2: Begin/end flow for custom signing
224
+ const psbt = await wallet.createUtxosBegin({ num: 5, size: 1000 });
305
225
  const signedPsbt = await wallet.signPsbt(psbt);
306
-
307
- // Step 3: Finalize UTXO creation
308
- const utxosCreated = wallet.createUtxosEnd({ signedPsbt });
309
- console.log(`Created ${utxosCreated} UTXOs`);
226
+ const utxosCreated = await wallet.createUtxosEnd({ signedPsbt });
227
+ await wallet.syncWallet();
310
228
  ```
311
229
 
312
230
  ### Asset Issuance
@@ -326,62 +244,125 @@ console.log('Asset issued:', asset.asset?.assetId);
326
244
  ### Asset Transfers
327
245
 
328
246
  ```javascript
329
- // Create blind receive for receiving wallet
247
+ // Receiver: create blind or witness invoice
330
248
  const receiveData = receiverWallet.blindReceive({
331
249
  assetId: assetId,
332
250
  amount: 100,
333
- minConfirmations: 3, // Optional, default: 3
334
- durationSeconds: 2000 // Optional, default: 2000
251
+ minConfirmations: 3,
252
+ durationSeconds: 2000
335
253
  });
254
+ // For witness invoices, sender must pass witnessData when sending
255
+ const witnessData = await receiverWallet.witnessReceive({ assetId, amount: 50 });
336
256
 
337
- // Step 1: Begin asset transfer
338
- const sendPsbt = senderWallet.sendBegin({
257
+ // Sender: Option 1 complete send in one call
258
+ const sendResult = await senderWallet.send({
339
259
  invoice: receiveData.invoice,
340
- feeRate: 1,
341
- minConfirmations: 1
260
+ assetId,
261
+ amount: 100
262
+ });
263
+ // For witness invoice:
264
+ await senderWallet.send({
265
+ invoice: witnessData.invoice,
266
+ assetId,
267
+ amount: 50,
268
+ witnessData: { amountSat: 1000 }
342
269
  });
343
270
 
344
- // Step 2: Sign the PSBT (async operation)
271
+ // Sender: Option 2 begin/end flow for custom signing
272
+ const sendPsbt = await senderWallet.sendBegin({
273
+ invoice: receiveData.invoice,
274
+ assetId,
275
+ amount: 100
276
+ });
345
277
  const signedSendPsbt = await senderWallet.signPsbt(sendPsbt);
278
+ await senderWallet.sendEnd({ signedPsbt: signedSendPsbt });
346
279
 
347
- // Step 3: Finalize transfer
348
- const sendResult = senderWallet.sendEnd({
349
- signedPsbt: signedSendPsbt,
350
- skipSync: false // Optional, default: false
351
- });
280
+ // Refresh both wallets and list transfers
281
+ await senderWallet.refreshWallet();
282
+ await receiverWallet.refreshWallet();
283
+ const transfers = await receiverWallet.listTransfers(assetId);
284
+ ```
352
285
 
353
- // Alternative: Complete send in one call
354
- const sendResult2 = await senderWallet.send({
355
- invoice: receiveData.invoice,
356
- feeRate: 1,
357
- minConfirmations: 1
286
+ ### On-chain receive/send
287
+
288
+ ```javascript
289
+ const { UTEXOWallet } = require('@utexo/rgb-sdk');
290
+
291
+ const sender = new UTEXOWallet("test mnemonic sender", { network: 'testnet' });
292
+ const receiver = new UTEXOWallet("test mnemonic receiver", { network: 'testnet' });
293
+ await sender.initialize();
294
+ await receiver.initialize();
295
+
296
+ // 1) Receiver: onchainReceive – create mainnet invoice for deposit
297
+ const { invoice } = await receiver.onchainReceive({
298
+ assetId: "rgb:WPRv95Nj-icdrgPp-zpQhIp_-2TyJ~Ge-k~FvuMZ-~vVnkA0",
299
+ amount: 5,
300
+ });
301
+
302
+ // 2) Sender: onchainSend – pay that mainnet invoice from UTEXO
303
+ const sendResult = await sender.onchainSend({ invoice });
304
+ console.log('Onchain send result:', sendResult);
305
+
306
+ await receiver.refreshWallet()
307
+ await sender.refreshWallet()
308
+
309
+ // wait 3 confirmation blocks
310
+
311
+ await receiver.refreshWallet()
312
+ await sender.refreshWallet()
313
+
314
+ const status = await receiver.getOnchainSendStatus(invoice)
315
+ console.log(status)
316
+
317
+ ```
318
+
319
+ ### Lightning receive/send
320
+
321
+ ```javascript
322
+ const { UTEXOWallet } = require('@utexo/rgb-sdk');
323
+
324
+ const sender = new UTEXOWallet("test mnemonic sender", { network: 'testnet' });
325
+ const receiver = new UTEXOWallet("test mnemonic receiver", { network: 'testnet' });
326
+ await sender.initialize();
327
+ await receiver.initialize();
328
+
329
+ // 1) Receiver: createLightningInvoice – create Lightning invoice for receiving
330
+ const assetId = "rgb:WPRv95Nj-icdrgPp-zpQhIp_-2TyJ~Ge-k~FvuMZ-~vVnkA0";
331
+ const { lnInvoice } = await receiver.createLightningInvoice({
332
+ asset: { assetId, amount: 5 },
358
333
  });
359
334
 
360
- // Refresh both wallets to sync the transfer
361
- senderWallet.refreshWallet();
362
- receiverWallet.refreshWallet();
335
+ // 2) Sender: payLightningInvoice pay that Lightning invoice from UTEXO
336
+ const sendResult = await sender.payLightningInvoice({ lnInvoice, assetId, amount: 5 });
337
+ console.log('Lightning send result:', sendResult);
338
+
339
+ await receiver.refreshWallet();
340
+ await sender.refreshWallet();
341
+
342
+ const status = await sender.getLightningSendRequest(lnInvoice);
343
+ console.log(status);
363
344
  ```
364
345
 
365
346
  ### Balance and Asset Management
366
347
 
367
348
  ```javascript
368
- // Get BTC balance (synchronous)
369
- const btcBalance = wallet.getBtcBalance();
349
+ // Get BTC balance (async)
350
+ const btcBalance = await wallet.getBtcBalance();
370
351
 
371
- // List all assets (synchronous)
372
- const assets = wallet.listAssets();
352
+ // List all assets
353
+ const assets = await wallet.listAssets();
373
354
 
374
355
  // Get specific asset balance
375
- const assetBalance = wallet.getAssetBalance(assetId);
356
+ const assetBalance = await wallet.getAssetBalance(assetId);
376
357
 
377
358
  // List unspent UTXOs
378
- const unspents = wallet.listUnspents();
359
+ const unspents = await wallet.listUnspents();
379
360
 
380
- // List transactions (synchronous)
381
- const transactions = wallet.listTransactions();
361
+ // List transactions
362
+ const transactions = await wallet.listTransactions();
382
363
 
383
- // List transfers for specific asset (synchronous)
384
- const transfers = wallet.listTransfers(assetId);
364
+ // List transfers for specific asset
365
+ const transfers = await wallet.listTransfers(assetId);
385
366
  ```
386
367
 
387
368
  ---
@@ -389,50 +370,31 @@ const transfers = wallet.listTransfers(assetId);
389
370
  ## Setup wallet and issue asset
390
371
 
391
372
  ```javascript
392
- const { WalletManager, generateKeys } = require('@utexo/rgb-sdk');
373
+ const { UTEXOWallet, generateKeys } = require('@utexo/rgb-sdk');
393
374
 
394
375
  async function demo() {
395
- // 1. Generate and initialize wallet
396
- const keys = generateKeys('testnet');
397
- const wallet = new WalletManager({
398
- xpubVan: keys.accountXpubVanilla,
399
- xpubCol: keys.accountXpubColored,
400
- masterFingerprint: keys.masterFingerprint,
401
- mnemonic: keys.mnemonic,
402
- network: 'testnet',
403
- transportEndpoint: 'rpcs://proxy.iriswallet.com/0.2/json-rpc',
404
- indexerUrl: 'ssl://electrum.iriswallet.com:50013'
405
- });
406
-
407
- // 2. Register wallet (synchronous)
408
- const { address } = wallet.registerWallet();
376
+ const keys = await generateKeys('testnet');
377
+ const wallet = new UTEXOWallet(keys.mnemonic, { network: 'testnet' });
378
+ await wallet.initialize();
409
379
 
410
- // TODO: Send some BTC to this address for fees and UTXO creation
411
- const balance = wallet.getBtcBalance();
380
+ const address = await wallet.getAddress();
381
+ const balance = await wallet.getBtcBalance();
412
382
 
413
- // 4. Create UTXOs
414
- const psbt = wallet.createUtxosBegin({
415
- upTo: true,
416
- num: 5,
417
- size: 1000,
418
- feeRate: 1
419
- });
420
- const signedPsbt = await wallet.signPsbt(psbt); // Async operation
421
- const utxosCreated = wallet.createUtxosEnd({ signedPsbt });
383
+ // Create UTXOs and issue asset
384
+ const count = await wallet.createUtxos({ num: 5, size: 1000 });
385
+ await wallet.syncWallet();
422
386
 
423
- // 5. Issue asset
424
387
  const asset = await wallet.issueAssetNia({
425
- ticker: "DEMO",
426
- name: "Demo Token",
388
+ ticker: 'DEMO',
389
+ name: 'Demo Token',
427
390
  amounts: [1000],
428
391
  precision: 2
429
392
  });
430
393
 
431
- // 6. List assets and balances (synchronous)
432
- const assets = wallet.listAssets();
433
- const assetBalance = wallet.getAssetBalance(asset.asset?.assetId);
394
+ const assets = await wallet.listAssets();
395
+ const assetBalance = await wallet.getAssetBalance(asset.assetId);
434
396
 
435
- // Wallet is ready to send/receive RGB assets
397
+ await wallet.dispose();
436
398
  }
437
399
  ```
438
400
 
@@ -445,8 +407,8 @@ async function demo() {
445
407
  ```javascript
446
408
  const { generateKeys, deriveKeysFromMnemonic } = require('@utexo/rgb-sdk');
447
409
 
448
- // Generate new wallet keys (synchronous)
449
- const keys = generateKeys('testnet');
410
+ // Generate new wallet keys (async)
411
+ const keys = await generateKeys('testnet');
450
412
  const mnemonic = keys.mnemonic; // Sensitive - protect at rest
451
413
 
452
414
  // Store mnemonic securely for later restoration
@@ -473,41 +435,39 @@ const isValid = await verifyMessage({
473
435
 
474
436
  ### Backup and Restore
475
437
 
438
+ > **Backup modes:** UTEXOWallet supports **local (file) backups** (encrypted files on disk) and **VSS backups** (state persisted to a remote Versioned Storage Service). The recommended strategy is to use VSS and invoke `vssBackup()` after any state-changing operation (e.g. UTXO creation, asset issuance, transfers) to ensure the latest state is recoverable;
439
+ >
440
+ > **Concurrency constraint:** Do **not** run restores while any wallet instance is online. At most one instance of a given wallet should ever be connected to the indexer/VSS; before calling any restore function, ensure all instances for that wallet are offline.
441
+
476
442
  ```javascript
477
- const { WalletManager, restoreFromBackup, generateKeys } = require('@utexo/rgb-sdk');
478
-
479
- // Create backup
480
- const keys = generateKeys('testnet');
481
- const wallet = new WalletManager({
482
- xpubVan: keys.accountXpubVanilla,
483
- xpubCol: keys.accountXpubColored,
484
- masterFingerprint: keys.masterFingerprint,
485
- mnemonic: keys.mnemonic,
486
- network: 'testnet'
487
- });
443
+ const { UTEXOWallet, restoreUtxoWalletFromBackup, restoreUtxoWalletFromVss, generateKeys } = require('@utexo/rgb-sdk');
444
+
445
+ const keys = await generateKeys('testnet');
446
+ const wallet = new UTEXOWallet(keys.mnemonic, { network: 'testnet' });
447
+ await wallet.initialize();
488
448
 
489
- // Create backup (filename will be <masterFingerprint>.backup)
490
- const backup = wallet.createBackup({
491
- backupPath: './backups', // Directory must exist
449
+ // File backup (layer1 + utexo in one folder: wallet_<fp>_layer1.backup, wallet_<fp>_utexo.backup)
450
+ const backup = await wallet.createBackup({
451
+ backupPath: './backups',
492
452
  password: 'secure-password'
493
453
  });
494
- console.log('Backup created at:', backup.backupPath);
454
+ console.log('Backup created:', backup.layer1BackupPath, backup.utexoBackupPath);
495
455
 
496
- // Restore wallet from backup (must be called before creating wallet)
497
- restoreFromBackup({
498
- backupFilePath: './backups/abc123.backup',
456
+ // Restore from file backup
457
+ const { targetDir } = restoreUtxoWalletFromBackup({
458
+ backupPath: './backups',
499
459
  password: 'secure-password',
500
- dataDir: './restored-wallet'
460
+ targetDir: './restored-wallet'
501
461
  });
462
+ const restoredWallet = new UTEXOWallet(keys.mnemonic, { dataDir: targetDir, network: 'testnet' });
463
+ await restoredWallet.initialize();
502
464
 
503
- // Create wallet pointing to restored directory
504
- const restoredWallet = new WalletManager({
505
- xpubVan: keys.accountXpubVanilla,
506
- xpubCol: keys.accountXpubColored,
507
- masterFingerprint: keys.masterFingerprint,
465
+ // VSS backup (config optional; built from mnemonic + DEFAULT_VSS_SERVER_URL)
466
+ await wallet.vssBackup();
467
+ // Restore from VSS
468
+ const { targetDir: vssDir } = await restoreUtxoWalletFromVss({
508
469
  mnemonic: keys.mnemonic,
509
- network: 'testnet',
510
- dataDir: './restored-wallet'
470
+ targetDir: './restored-from-vss'
511
471
  });
512
472
  ```
513
473
 
@@ -515,7 +475,13 @@ const restoredWallet = new WalletManager({
515
475
 
516
476
  ## Full Examples
517
477
 
518
- For complete working examples demonstrating all features, see:
478
+ - [new-wallet](examples/new-wallet.mjs) Generate keys and create a new UTEXO wallet
479
+ - [read-wallet](examples/read-wallet.mjs) – Initialize by mnemonic and call getXpub, getNetwork, getAddress, getBtcBalance, listAssets
480
+ - [create-utxos-asset](examples/create-utxos-asset.mjs) – Create UTXOs and issue a NIA asset
481
+ - [transfer](examples/transfer.mjs) – Two wallets: witness + blind receive, refresh, listTransfers (requires ASSET_ID and funded wallets)
482
+ - [onchain-flow](examples/onchain-flow.mjs) – On-chain transfer: receive + send
483
+ - [lightning-flow](examples/lightning-flow.mjs) – Lightning transfer: createLightningInvoice + payLightningInvoice
484
+ - [utexo-vss-backup-restore](examples/utexo-vss-backup-restore.mjs) – VSS backup and restore
485
+ - [utexo-file-backup-restore](examples/utexo-file-backup-restore.mjs) – File backup and restore
519
486
 
520
- - `example-flow.js` - Complete RGB wallet workflow with two wallets, asset issuance, and transfers
521
- - `example-basic-usage.js` - Basic wallet operations and asset management
487
+ See [examples/README.md](examples/README.md) for run commands. CLI: [cli/](cli/).