@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.
- package/Readme.md +267 -301
- package/cli/README.md +348 -0
- package/cli/commands/address.mjs +16 -0
- package/cli/commands/blindreceive.mjs +15 -0
- package/cli/commands/btcbalance.mjs +11 -0
- package/cli/commands/createlightninginvoice.mjs +14 -0
- package/cli/commands/createutxos.mjs +13 -0
- package/cli/commands/decodergbinvoice.mjs +9 -0
- package/cli/commands/generate_keys.mjs +35 -0
- package/cli/commands/getlightningreceiverequest.mjs +10 -0
- package/cli/commands/getlightningsendrequest.mjs +10 -0
- package/cli/commands/getonchainsendstatus.mjs +20 -0
- package/cli/commands/listassets.mjs +11 -0
- package/cli/commands/listtransfers.mjs +10 -0
- package/cli/commands/listunspents.mjs +10 -0
- package/cli/commands/onchainreceive.mjs +16 -0
- package/cli/commands/onchainsend.mjs +11 -0
- package/cli/commands/onchainsendbegin.mjs +9 -0
- package/cli/commands/onchainsendend.mjs +9 -0
- package/cli/commands/paylightninginvoice.mjs +11 -0
- package/cli/commands/paylightninginvoicebegin.mjs +10 -0
- package/cli/commands/paylightninginvoiceend.mjs +9 -0
- package/cli/commands/refresh.mjs +9 -0
- package/cli/commands/send.mjs +31 -0
- package/cli/commands/sign-psbt.mjs +12 -0
- package/cli/commands/signpsbt.mjs +10 -0
- package/cli/commands/witnessreceive.mjs +15 -0
- package/cli/generate_keys.mjs +66 -0
- package/cli/run.mjs +291 -0
- package/cli/utils.mjs +220 -0
- package/dist/index.cjs +1606 -121
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +1235 -145
- package/dist/index.d.ts +1235 -145
- package/dist/index.mjs +1592 -116
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -8
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
3
|
-
import * as
|
|
1
|
+
import * as path3 from 'path';
|
|
2
|
+
import path3__default from 'path';
|
|
3
|
+
import * as fs2 from 'fs';
|
|
4
|
+
import fs2__default from 'fs';
|
|
4
5
|
import rgblib from '@utexo/rgb-lib';
|
|
5
6
|
import * as noble from '@noble/hashes/legacy.js';
|
|
6
|
-
import
|
|
7
|
+
import { hmac } from '@noble/hashes/hmac.js';
|
|
8
|
+
import { sha256 as sha256$1 } from '@noble/hashes/sha2.js';
|
|
9
|
+
import axios from 'axios';
|
|
7
10
|
|
|
8
11
|
// src/client/rgb-lib-client.ts
|
|
9
12
|
|
|
13
|
+
// src/client/network-config.ts
|
|
14
|
+
var DEFAULT_TRANSPORT_ENDPOINTS = {
|
|
15
|
+
mainnet: "rpcs://rgb-proxy-mainnet.utexo.com/json-rpc",
|
|
16
|
+
testnet: "rpcs://rgb-proxy-testnet3.utexo.com/json-rpc",
|
|
17
|
+
testnet4: "rpcs://proxy.iriswallet.com/0.2/json-rpc",
|
|
18
|
+
signet: "rpcs://rgb-proxy-utexo.utexo.com/json-rpc",
|
|
19
|
+
regtest: "rpcs://proxy.iriswallet.com/0.2/json-rpc"
|
|
20
|
+
};
|
|
21
|
+
var DEFAULT_INDEXER_URLS = {
|
|
22
|
+
mainnet: "ssl://electrum.iriswallet.com:50003",
|
|
23
|
+
testnet: "ssl://electrum.iriswallet.com:50013",
|
|
24
|
+
testnet4: "ssl://electrum.iriswallet.com:50053",
|
|
25
|
+
signet: "https://esplora-api.utexo.com",
|
|
26
|
+
regtest: "tcp://regtest.thunderstack.org:50001"
|
|
27
|
+
};
|
|
28
|
+
|
|
10
29
|
// src/errors/index.ts
|
|
11
30
|
var SDKError = class _SDKError extends Error {
|
|
12
31
|
constructor(message, code, statusCode, cause) {
|
|
@@ -105,6 +124,135 @@ var DERIVATION_ACCOUNT = 0;
|
|
|
105
124
|
var KEYCHAIN_RGB = 0;
|
|
106
125
|
var KEYCHAIN_BTC = 0;
|
|
107
126
|
|
|
127
|
+
// src/utexo/config/utexo-presets.ts
|
|
128
|
+
function withGetAssetById(config) {
|
|
129
|
+
return {
|
|
130
|
+
...config,
|
|
131
|
+
getAssetById(tokenId) {
|
|
132
|
+
return config.assets.find((a) => a.tokenId === tokenId);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
var testnetPreset = {
|
|
137
|
+
networkMap: {
|
|
138
|
+
mainnet: "testnet",
|
|
139
|
+
utexo: "signet"
|
|
140
|
+
},
|
|
141
|
+
networkIdMap: {
|
|
142
|
+
mainnet: withGetAssetById({
|
|
143
|
+
networkName: "RGB",
|
|
144
|
+
networkId: 36,
|
|
145
|
+
assets: [
|
|
146
|
+
{
|
|
147
|
+
assetId: "rgb:WPRv95Nj-icdrgPp-zpQhIp_-2TyJ~Ge-k~FvuMZ-~vVnkA0",
|
|
148
|
+
tokenName: "tUSD",
|
|
149
|
+
longName: "USDT",
|
|
150
|
+
precision: 6,
|
|
151
|
+
tokenId: 4
|
|
152
|
+
}
|
|
153
|
+
]
|
|
154
|
+
}),
|
|
155
|
+
mainnetLightning: withGetAssetById({
|
|
156
|
+
networkName: "RGB Lightning",
|
|
157
|
+
networkId: 94,
|
|
158
|
+
assets: [
|
|
159
|
+
{
|
|
160
|
+
assetId: "rgb:WPRv95Nj-icdrgPp-zpQhIp_-2TyJ~Ge-k~FvuMZ-~vVnkA0",
|
|
161
|
+
tokenName: "tUSD",
|
|
162
|
+
longName: "USDT",
|
|
163
|
+
precision: 6,
|
|
164
|
+
tokenId: 4
|
|
165
|
+
}
|
|
166
|
+
]
|
|
167
|
+
}),
|
|
168
|
+
utexo: withGetAssetById({
|
|
169
|
+
networkName: "UTEXO",
|
|
170
|
+
networkId: 96,
|
|
171
|
+
assets: [
|
|
172
|
+
{
|
|
173
|
+
assetId: "rgb:yJW4k8si-~8JdNfl-nM91qFu-r5rH_HS-1hM7jpi-L~lBf90",
|
|
174
|
+
tokenName: "tUSD",
|
|
175
|
+
longName: "USDT",
|
|
176
|
+
precision: 6,
|
|
177
|
+
tokenId: 4
|
|
178
|
+
}
|
|
179
|
+
]
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
var mainnetPreset = {
|
|
184
|
+
networkMap: {
|
|
185
|
+
mainnet: "mainnet",
|
|
186
|
+
utexo: "signet"
|
|
187
|
+
},
|
|
188
|
+
networkIdMap: {
|
|
189
|
+
mainnet: withGetAssetById({
|
|
190
|
+
networkName: "RGB",
|
|
191
|
+
networkId: 36,
|
|
192
|
+
// TODO: Update to production network ID
|
|
193
|
+
assets: [
|
|
194
|
+
{
|
|
195
|
+
assetId: "rgb:WPRv95Nj-icdrgPp-zpQhIp_-2TyJ~Ge-k~FvuMZ-~vVnkA0",
|
|
196
|
+
// TODO: Update to production asset ID
|
|
197
|
+
tokenName: "tUSD",
|
|
198
|
+
longName: "USDT",
|
|
199
|
+
precision: 6,
|
|
200
|
+
tokenId: 4
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
}),
|
|
204
|
+
mainnetLightning: withGetAssetById({
|
|
205
|
+
networkName: "RGB Lightning",
|
|
206
|
+
networkId: 94,
|
|
207
|
+
// TODO: Update to production network ID
|
|
208
|
+
assets: [
|
|
209
|
+
{
|
|
210
|
+
assetId: "rgb:WPRv95Nj-icdrgPp-zpQhIp_-2TyJ~Ge-k~FvuMZ-~vVnkA0",
|
|
211
|
+
// TODO: Update to production asset ID
|
|
212
|
+
tokenName: "tUSD",
|
|
213
|
+
longName: "USDT",
|
|
214
|
+
precision: 6,
|
|
215
|
+
tokenId: 4
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
}),
|
|
219
|
+
utexo: withGetAssetById({
|
|
220
|
+
networkName: "UTEXO",
|
|
221
|
+
networkId: 96,
|
|
222
|
+
// TODO: Update to production network ID
|
|
223
|
+
assets: [
|
|
224
|
+
{
|
|
225
|
+
assetId: "rgb:yJW4k8si-~8JdNfl-nM91qFu-r5rH_HS-1hM7jpi-L~lBf90",
|
|
226
|
+
// TODO: Update to production asset ID
|
|
227
|
+
tokenName: "tUSD",
|
|
228
|
+
longName: "USDT",
|
|
229
|
+
precision: 6,
|
|
230
|
+
tokenId: 4
|
|
231
|
+
}
|
|
232
|
+
]
|
|
233
|
+
})
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
// src/utexo/utils/network.ts
|
|
238
|
+
var NETWORK_PRESETS = {
|
|
239
|
+
mainnet: mainnetPreset,
|
|
240
|
+
testnet: testnetPreset
|
|
241
|
+
};
|
|
242
|
+
function getUtxoNetworkConfig(preset) {
|
|
243
|
+
return NETWORK_PRESETS[preset];
|
|
244
|
+
}
|
|
245
|
+
var utexoNetworkMap = testnetPreset.networkMap;
|
|
246
|
+
var utexoNetworkIdMap = testnetPreset.networkIdMap;
|
|
247
|
+
function getDestinationAsset(senderNetwork, destinationNetwork, assetIdSender) {
|
|
248
|
+
const destinationConfig = utexoNetworkIdMap[destinationNetwork];
|
|
249
|
+
if (assetIdSender == null) return destinationConfig.assets[0];
|
|
250
|
+
const senderConfig = utexoNetworkIdMap[senderNetwork];
|
|
251
|
+
const senderAsset = senderConfig.assets.find((a) => a.assetId === assetIdSender);
|
|
252
|
+
if (!senderAsset) return void 0;
|
|
253
|
+
return destinationConfig.assets.find((a) => a.tokenId === senderAsset.tokenId);
|
|
254
|
+
}
|
|
255
|
+
|
|
108
256
|
// src/constants/network.ts
|
|
109
257
|
var COIN_RGB_MAINNET = 827166;
|
|
110
258
|
var COIN_RGB_TESTNET = 827167;
|
|
@@ -220,7 +368,6 @@ function validateString(value, field) {
|
|
|
220
368
|
throw new ValidationError(`${field} must be a non-empty string`, field);
|
|
221
369
|
}
|
|
222
370
|
}
|
|
223
|
-
var DEFAULT_TRANSPORT_ENDPOINT = "rpcs://proxy.iriswallet.com/0.2/json-rpc";
|
|
224
371
|
function mapNetworkToRgbLib(network) {
|
|
225
372
|
const networkMap = {
|
|
226
373
|
"mainnet": "Mainnet",
|
|
@@ -234,10 +381,10 @@ function mapNetworkToRgbLib(network) {
|
|
|
234
381
|
}
|
|
235
382
|
var restoreWallet = (params) => {
|
|
236
383
|
const { backupFilePath, password, dataDir } = params;
|
|
237
|
-
if (!
|
|
384
|
+
if (!fs2.existsSync(backupFilePath)) {
|
|
238
385
|
throw new ValidationError("Backup file not found", "backup");
|
|
239
386
|
}
|
|
240
|
-
if (!
|
|
387
|
+
if (!fs2.existsSync(dataDir)) {
|
|
241
388
|
throw new ValidationError(`Restore directory does not exist: ${dataDir}`, "restoreDir");
|
|
242
389
|
}
|
|
243
390
|
rgblib.restoreBackup(backupFilePath, password, dataDir);
|
|
@@ -245,6 +392,26 @@ var restoreWallet = (params) => {
|
|
|
245
392
|
message: "Wallet restored successfully"
|
|
246
393
|
};
|
|
247
394
|
};
|
|
395
|
+
var restoreFromVss = (params) => {
|
|
396
|
+
const anyLib = rgblib;
|
|
397
|
+
if (typeof anyLib.restoreFromVss !== "function") {
|
|
398
|
+
throw new WalletError("VSS restore is not available in the current rgb-lib build.");
|
|
399
|
+
}
|
|
400
|
+
if (!params.targetDir) {
|
|
401
|
+
throw new ValidationError("targetDir is required", "targetDir");
|
|
402
|
+
}
|
|
403
|
+
const { config, targetDir } = params;
|
|
404
|
+
const mappedConfig = {
|
|
405
|
+
server_url: config.serverUrl,
|
|
406
|
+
store_id: config.storeId,
|
|
407
|
+
signing_key: config.signingKey
|
|
408
|
+
};
|
|
409
|
+
const walletPath = anyLib.restoreFromVss(mappedConfig, targetDir);
|
|
410
|
+
return {
|
|
411
|
+
message: "Wallet restored from VSS successfully",
|
|
412
|
+
walletPath
|
|
413
|
+
};
|
|
414
|
+
};
|
|
248
415
|
var RGBLibClient = class {
|
|
249
416
|
constructor(params) {
|
|
250
417
|
this.online = null;
|
|
@@ -254,21 +421,14 @@ var RGBLibClient = class {
|
|
|
254
421
|
this.originalNetwork = params.network;
|
|
255
422
|
this.network = normalizeNetwork(this.originalNetwork);
|
|
256
423
|
this.dataDir = params.dataDir;
|
|
257
|
-
this.transportEndpoint = params.transportEndpoint ||
|
|
424
|
+
this.transportEndpoint = params.transportEndpoint || DEFAULT_TRANSPORT_ENDPOINTS[this.network] || DEFAULT_TRANSPORT_ENDPOINTS.signet;
|
|
258
425
|
if (params.indexerUrl) {
|
|
259
426
|
this.indexerUrl = params.indexerUrl;
|
|
260
427
|
} else {
|
|
261
|
-
|
|
262
|
-
"mainnet": "ssl://electrum.iriswallet.com:50003",
|
|
263
|
-
"testnet": "ssl://electrum.iriswallet.com:50013",
|
|
264
|
-
"testnet4": "ssl://electrum.iriswallet.com:50053",
|
|
265
|
-
"signet": "tcp://46.224.75.237:50001",
|
|
266
|
-
"regtest": "tcp://regtest.thunderstack.org:50001"
|
|
267
|
-
};
|
|
268
|
-
this.indexerUrl = defaultIndexerUrls[this.network] || defaultIndexerUrls["regtest"];
|
|
428
|
+
this.indexerUrl = DEFAULT_INDEXER_URLS[this.network] || DEFAULT_INDEXER_URLS.signet;
|
|
269
429
|
}
|
|
270
|
-
if (!
|
|
271
|
-
|
|
430
|
+
if (!fs2.existsSync(this.dataDir)) {
|
|
431
|
+
fs2.mkdirSync(this.dataDir, { recursive: true });
|
|
272
432
|
}
|
|
273
433
|
const walletData = {
|
|
274
434
|
dataDir: this.dataDir,
|
|
@@ -288,6 +448,7 @@ var RGBLibClient = class {
|
|
|
288
448
|
try {
|
|
289
449
|
this.wallet = new rgblib.Wallet(new rgblib.WalletData(walletData));
|
|
290
450
|
} catch (error) {
|
|
451
|
+
console.log("error", error);
|
|
291
452
|
throw new WalletError("Failed to initialize rgb-lib wallet", void 0, error);
|
|
292
453
|
}
|
|
293
454
|
}
|
|
@@ -299,7 +460,6 @@ var RGBLibClient = class {
|
|
|
299
460
|
return;
|
|
300
461
|
}
|
|
301
462
|
try {
|
|
302
|
-
console.log("indexerUrl", this.indexerUrl);
|
|
303
463
|
this.online = this.wallet.goOnline(false, this.indexerUrl);
|
|
304
464
|
} catch (error) {
|
|
305
465
|
throw new WalletError("Failed to establish online connection", void 0, error);
|
|
@@ -349,10 +509,9 @@ var RGBLibClient = class {
|
|
|
349
509
|
}
|
|
350
510
|
sendBegin(params) {
|
|
351
511
|
const online = this.getOnline();
|
|
352
|
-
console.log("sendBegin params", params);
|
|
353
512
|
const feeRate = String(params.feeRate ?? 1);
|
|
354
513
|
const minConfirmations = String(params.minConfirmations ?? 1);
|
|
355
|
-
const donation = false;
|
|
514
|
+
const donation = params.donation ?? false;
|
|
356
515
|
let assetId = params.assetId;
|
|
357
516
|
let amount = params.amount;
|
|
358
517
|
let recipientId;
|
|
@@ -400,6 +559,37 @@ var RGBLibClient = class {
|
|
|
400
559
|
);
|
|
401
560
|
return psbt;
|
|
402
561
|
}
|
|
562
|
+
/**
|
|
563
|
+
* Batch send: accepts an already-built recipientMap and calls sendBegin.
|
|
564
|
+
*/
|
|
565
|
+
sendBeginBatch(params) {
|
|
566
|
+
const online = this.getOnline();
|
|
567
|
+
const feeRate = String(params.feeRate ?? 1);
|
|
568
|
+
const minConfirmations = String(params.minConfirmations ?? 1);
|
|
569
|
+
const donation = params.donation ?? true;
|
|
570
|
+
const { recipientMap } = params;
|
|
571
|
+
if (!recipientMap || typeof recipientMap !== "object") {
|
|
572
|
+
throw new ValidationError("recipientMap is required and must be a non-empty object", "recipientMap");
|
|
573
|
+
}
|
|
574
|
+
const assetIds = Object.keys(recipientMap);
|
|
575
|
+
if (assetIds.length === 0) {
|
|
576
|
+
throw new ValidationError("recipientMap must contain at least one asset id", "recipientMap");
|
|
577
|
+
}
|
|
578
|
+
for (const assetId of assetIds) {
|
|
579
|
+
const recipients = recipientMap[assetId];
|
|
580
|
+
if (!Array.isArray(recipients) || recipients.length === 0) {
|
|
581
|
+
throw new ValidationError(`recipientMap["${assetId}"] must be a non-empty array of recipients`, "recipientMap");
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
const psbt = this.wallet.sendBegin(
|
|
585
|
+
online,
|
|
586
|
+
recipientMap,
|
|
587
|
+
donation,
|
|
588
|
+
feeRate,
|
|
589
|
+
minConfirmations
|
|
590
|
+
);
|
|
591
|
+
return psbt;
|
|
592
|
+
}
|
|
403
593
|
sendEnd(params) {
|
|
404
594
|
const online = this.getOnline();
|
|
405
595
|
const signedPsbt = params.signedPsbt;
|
|
@@ -503,7 +693,8 @@ var RGBLibClient = class {
|
|
|
503
693
|
const assetId = null;
|
|
504
694
|
const filter = [];
|
|
505
695
|
const skipSync = false;
|
|
506
|
-
this.wallet.refresh(online, assetId, filter, skipSync);
|
|
696
|
+
const result = this.wallet.refresh(online, assetId, filter, skipSync);
|
|
697
|
+
console.log("refresh state:", JSON.stringify(result, null, 2));
|
|
507
698
|
}
|
|
508
699
|
dropWallet() {
|
|
509
700
|
if (this.online) {
|
|
@@ -546,16 +737,105 @@ var RGBLibClient = class {
|
|
|
546
737
|
if (!params.password) {
|
|
547
738
|
throw new ValidationError("password is required", "password");
|
|
548
739
|
}
|
|
549
|
-
if (!
|
|
740
|
+
if (!fs2.existsSync(params.backupPath)) {
|
|
550
741
|
throw new ValidationError(`Backup directory does not exist: ${params.backupPath}`, "backupPath");
|
|
551
742
|
}
|
|
552
|
-
const fullBackupPath =
|
|
743
|
+
const fullBackupPath = path3.join(params.backupPath, `${this.masterFingerprint}.backup`);
|
|
553
744
|
this.wallet.backup(fullBackupPath, params.password);
|
|
554
745
|
return {
|
|
555
746
|
message: "Backup created successfully",
|
|
556
747
|
backupPath: fullBackupPath
|
|
557
748
|
};
|
|
558
749
|
}
|
|
750
|
+
/**
|
|
751
|
+
* Ensure VSS backup support is available in the underlying rgb-lib bindings.
|
|
752
|
+
* Returns the wallet instance and rgb-lib namespace as `any` for internal use.
|
|
753
|
+
*/
|
|
754
|
+
getVssBindingsOrThrow(methodName) {
|
|
755
|
+
const walletAny = this.wallet;
|
|
756
|
+
const anyLib = rgblib;
|
|
757
|
+
if (!walletAny || typeof anyLib.VssBackupClient !== "function" || typeof walletAny[methodName] !== "function") {
|
|
758
|
+
throw new WalletError("VSS backup is not available in the current rgb-lib build.");
|
|
759
|
+
}
|
|
760
|
+
return { walletAny, anyLib };
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Configure VSS cloud backup for this wallet.
|
|
764
|
+
*/
|
|
765
|
+
configureVssBackup(config) {
|
|
766
|
+
const walletAny = this.wallet;
|
|
767
|
+
if (!walletAny || typeof walletAny.configureVssBackup !== "function") {
|
|
768
|
+
throw new WalletError("VSS backup is not available in the current rgb-lib build.");
|
|
769
|
+
}
|
|
770
|
+
const mappedConfig = {
|
|
771
|
+
server_url: config.serverUrl,
|
|
772
|
+
store_id: config.storeId,
|
|
773
|
+
signing_key: config.signingKey
|
|
774
|
+
};
|
|
775
|
+
if (config.encryptionEnabled !== void 0) {
|
|
776
|
+
mappedConfig.encryptionEnabled = config.encryptionEnabled;
|
|
777
|
+
}
|
|
778
|
+
if (config.autoBackup !== void 0) {
|
|
779
|
+
mappedConfig.autoBackup = config.autoBackup;
|
|
780
|
+
}
|
|
781
|
+
if (config.backupMode !== void 0) {
|
|
782
|
+
mappedConfig.backupMode = config.backupMode;
|
|
783
|
+
}
|
|
784
|
+
walletAny.configureVssBackup(mappedConfig);
|
|
785
|
+
}
|
|
786
|
+
/**
|
|
787
|
+
* Disable automatic VSS backup for this wallet.
|
|
788
|
+
*/
|
|
789
|
+
disableVssAutoBackup() {
|
|
790
|
+
const walletAny = this.wallet;
|
|
791
|
+
if (!walletAny || typeof walletAny.disableVssAutoBackup !== "function") {
|
|
792
|
+
throw new WalletError("VSS backup is not available in the current rgb-lib build.");
|
|
793
|
+
}
|
|
794
|
+
walletAny.disableVssAutoBackup();
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Trigger a VSS backup immediately using a one-off client created from config.
|
|
798
|
+
* Returns the server version of the stored backup.
|
|
799
|
+
*/
|
|
800
|
+
vssBackup(config) {
|
|
801
|
+
const { walletAny, anyLib } = this.getVssBindingsOrThrow("vssBackup");
|
|
802
|
+
const client = new anyLib.VssBackupClient({
|
|
803
|
+
server_url: config.serverUrl,
|
|
804
|
+
store_id: config.storeId,
|
|
805
|
+
signing_key: config.signingKey
|
|
806
|
+
});
|
|
807
|
+
try {
|
|
808
|
+
const version = walletAny.vssBackup(client);
|
|
809
|
+
return version;
|
|
810
|
+
} finally {
|
|
811
|
+
if (typeof client.drop === "function") {
|
|
812
|
+
client.drop();
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Get VSS backup status information for this wallet using a one-off client.
|
|
818
|
+
*/
|
|
819
|
+
vssBackupInfo(config) {
|
|
820
|
+
const { walletAny, anyLib } = this.getVssBindingsOrThrow("vssBackupInfo");
|
|
821
|
+
const client = new anyLib.VssBackupClient({
|
|
822
|
+
server_url: config.serverUrl,
|
|
823
|
+
store_id: config.storeId,
|
|
824
|
+
signing_key: config.signingKey
|
|
825
|
+
});
|
|
826
|
+
try {
|
|
827
|
+
const info = walletAny.vssBackupInfo(client);
|
|
828
|
+
return {
|
|
829
|
+
backupExists: Boolean(info.backupExists ?? info.backup_exists),
|
|
830
|
+
serverVersion: info.serverVersion ?? info.server_version ?? null,
|
|
831
|
+
backupRequired: Boolean(info.backupRequired ?? info.backup_required)
|
|
832
|
+
};
|
|
833
|
+
} finally {
|
|
834
|
+
if (typeof client.drop === "function") {
|
|
835
|
+
client.drop();
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
}
|
|
559
839
|
/**
|
|
560
840
|
* Cleanup resources
|
|
561
841
|
*/
|
|
@@ -932,8 +1212,8 @@ async function mnemonicToRoot(mnemonic, bitcoinNetwork) {
|
|
|
932
1212
|
}
|
|
933
1213
|
async function getAccountXpub(mnemonic, bitcoinNetwork, rgb) {
|
|
934
1214
|
const root = await mnemonicToRoot(mnemonic, bitcoinNetwork);
|
|
935
|
-
const
|
|
936
|
-
const acct = root.derivePath(
|
|
1215
|
+
const path5 = accountDerivationPath(bitcoinNetwork, rgb);
|
|
1216
|
+
const acct = root.derivePath(path5);
|
|
937
1217
|
return acct.neutered().toBase58();
|
|
938
1218
|
}
|
|
939
1219
|
async function getMasterXpriv(mnemonic, bitcoinNetwork) {
|
|
@@ -1057,6 +1337,27 @@ async function deriveKeysFromSeed(bitcoinNetwork = "regtest", seed) {
|
|
|
1057
1337
|
throw new CryptoError("Failed to derive keys from seed", error);
|
|
1058
1338
|
}
|
|
1059
1339
|
}
|
|
1340
|
+
async function deriveKeysFromMnemonicOrSeed(bitcoinNetwork = "regtest", mnemonicOrSeed) {
|
|
1341
|
+
if (typeof mnemonicOrSeed === "string") {
|
|
1342
|
+
const trimmed = mnemonicOrSeed.trim();
|
|
1343
|
+
const words = trimmed.split(/\s+/);
|
|
1344
|
+
const isLikelyMnemonic = trimmed.includes(" ") && words.length >= 12 && words.length <= 24;
|
|
1345
|
+
if (isLikelyMnemonic) {
|
|
1346
|
+
try {
|
|
1347
|
+
return await deriveKeysFromMnemonic(bitcoinNetwork, trimmed);
|
|
1348
|
+
} catch (error) {
|
|
1349
|
+
if (error instanceof ValidationError) {
|
|
1350
|
+
return await deriveKeysFromSeed(bitcoinNetwork, trimmed);
|
|
1351
|
+
}
|
|
1352
|
+
throw error;
|
|
1353
|
+
}
|
|
1354
|
+
} else {
|
|
1355
|
+
return await deriveKeysFromSeed(bitcoinNetwork, trimmed);
|
|
1356
|
+
}
|
|
1357
|
+
} else {
|
|
1358
|
+
return await deriveKeysFromSeed(bitcoinNetwork, mnemonicOrSeed);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1060
1361
|
async function restoreKeys(bitcoinNetwork = "regtest", mnemonic) {
|
|
1061
1362
|
return deriveKeysFromMnemonic(bitcoinNetwork, mnemonic);
|
|
1062
1363
|
}
|
|
@@ -1119,28 +1420,28 @@ async function accountXpubsFromMnemonic(bitcoinNetwork = "regtest", mnemonic) {
|
|
|
1119
1420
|
}
|
|
1120
1421
|
|
|
1121
1422
|
// src/crypto/signer.ts
|
|
1122
|
-
function normalizePath(
|
|
1123
|
-
if (typeof
|
|
1124
|
-
if (
|
|
1125
|
-
return
|
|
1126
|
-
}
|
|
1127
|
-
return
|
|
1128
|
-
} else if (Array.isArray(
|
|
1129
|
-
if (
|
|
1130
|
-
const second =
|
|
1423
|
+
function normalizePath(path5) {
|
|
1424
|
+
if (typeof path5 === "string") {
|
|
1425
|
+
if (path5.startsWith("m/m/")) {
|
|
1426
|
+
return path5.replace(/^m\/m\//, "m/");
|
|
1427
|
+
}
|
|
1428
|
+
return path5;
|
|
1429
|
+
} else if (Array.isArray(path5)) {
|
|
1430
|
+
if (path5.length > 0 && path5[0] === 0 && path5.length > 1) {
|
|
1431
|
+
const second = path5[1];
|
|
1131
1432
|
if (typeof second === "number" && second >= 2147483648) {
|
|
1132
|
-
return
|
|
1433
|
+
return path5.slice(1);
|
|
1133
1434
|
}
|
|
1134
1435
|
}
|
|
1135
|
-
return
|
|
1436
|
+
return path5;
|
|
1136
1437
|
}
|
|
1137
|
-
return
|
|
1438
|
+
return path5;
|
|
1138
1439
|
}
|
|
1139
|
-
function pathToString(
|
|
1140
|
-
if (typeof
|
|
1141
|
-
return
|
|
1142
|
-
} else if (Array.isArray(
|
|
1143
|
-
return
|
|
1440
|
+
function pathToString(path5) {
|
|
1441
|
+
if (typeof path5 === "string") {
|
|
1442
|
+
return path5;
|
|
1443
|
+
} else if (Array.isArray(path5)) {
|
|
1444
|
+
return path5.map((p) => {
|
|
1144
1445
|
if (typeof p === "number") {
|
|
1145
1446
|
return p >= 2147483648 ? `${p & 2147483647}'` : `${p}`;
|
|
1146
1447
|
}
|
|
@@ -1449,6 +1750,14 @@ async function estimatePsbt(psbtBase64) {
|
|
|
1449
1750
|
throw new ValidationError("Invalid PSBT provided", "psbt");
|
|
1450
1751
|
}
|
|
1451
1752
|
}
|
|
1753
|
+
var VSS_SIGNING_KEY_DOMAIN = "rgb-lib-vss-backup-encryption-v1";
|
|
1754
|
+
function deriveVssSigningKeyFromMnemonic(mnemonic) {
|
|
1755
|
+
validateMnemonic(mnemonic, "mnemonic");
|
|
1756
|
+
const keyBytes = new TextEncoder().encode(VSS_SIGNING_KEY_DOMAIN);
|
|
1757
|
+
const messageBytes = new TextEncoder().encode(mnemonic.trim());
|
|
1758
|
+
const digest = hmac(sha256$1, keyBytes, messageBytes);
|
|
1759
|
+
return Array.from(digest).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1760
|
+
}
|
|
1452
1761
|
var restoreFromBackup = (params) => {
|
|
1453
1762
|
const {
|
|
1454
1763
|
backupFilePath,
|
|
@@ -1492,7 +1801,7 @@ var WalletManager = class {
|
|
|
1492
1801
|
this.mnemonic = params.mnemonic ?? null;
|
|
1493
1802
|
this.xpub = params.xpub ?? null;
|
|
1494
1803
|
this.masterFingerprint = params.masterFingerprint;
|
|
1495
|
-
this.dataDir = params.dataDir ??
|
|
1804
|
+
this.dataDir = params.dataDir ?? path3__default.join(process.cwd(), ".rgb-wallet", this.network, this.masterFingerprint);
|
|
1496
1805
|
this.client = new RGBLibClient({
|
|
1497
1806
|
xpubVan: params.xpubVan,
|
|
1498
1807
|
xpubCol: params.xpubCol,
|
|
@@ -1503,6 +1812,12 @@ var WalletManager = class {
|
|
|
1503
1812
|
dataDir: params.dataDir ?? this.dataDir
|
|
1504
1813
|
});
|
|
1505
1814
|
}
|
|
1815
|
+
async initialize() {
|
|
1816
|
+
console.log("initializing is not reqire");
|
|
1817
|
+
}
|
|
1818
|
+
async goOnline(indexerUrl, skipConsistencyCheck) {
|
|
1819
|
+
this.client.getOnline();
|
|
1820
|
+
}
|
|
1506
1821
|
/**
|
|
1507
1822
|
* Get wallet's extended public keys
|
|
1508
1823
|
*/
|
|
@@ -1523,7 +1838,7 @@ var WalletManager = class {
|
|
|
1523
1838
|
* Clears mnemonic and seed from memory
|
|
1524
1839
|
* Idempotent - safe to call multiple times
|
|
1525
1840
|
*/
|
|
1526
|
-
dispose() {
|
|
1841
|
+
async dispose() {
|
|
1527
1842
|
if (this.disposed) {
|
|
1528
1843
|
return;
|
|
1529
1844
|
}
|
|
@@ -1555,73 +1870,160 @@ var WalletManager = class {
|
|
|
1555
1870
|
registerWallet() {
|
|
1556
1871
|
return this.client.registerWallet();
|
|
1557
1872
|
}
|
|
1558
|
-
getBtcBalance() {
|
|
1873
|
+
async getBtcBalance() {
|
|
1559
1874
|
return this.client.getBtcBalance();
|
|
1560
1875
|
}
|
|
1561
|
-
getAddress() {
|
|
1876
|
+
async getAddress() {
|
|
1562
1877
|
return this.client.getAddress();
|
|
1563
1878
|
}
|
|
1564
|
-
listUnspents() {
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1879
|
+
async listUnspents() {
|
|
1880
|
+
const unspents = this.client.listUnspents();
|
|
1881
|
+
return unspents.map((unspent) => ({
|
|
1882
|
+
utxo: {
|
|
1883
|
+
...unspent.utxo,
|
|
1884
|
+
exists: unspent.utxo.exists ?? true
|
|
1885
|
+
},
|
|
1886
|
+
rgbAllocations: unspent.rgbAllocations.map((allocation) => {
|
|
1887
|
+
const assignmentKeys = Object.keys(allocation.assignment);
|
|
1888
|
+
const assignmentType = assignmentKeys[0];
|
|
1889
|
+
const assignment = {
|
|
1890
|
+
type: assignmentType ?? "Any",
|
|
1891
|
+
amount: assignmentType && allocation.assignment[assignmentType] ? Number(allocation.assignment[assignmentType]) : void 0
|
|
1892
|
+
};
|
|
1893
|
+
return {
|
|
1894
|
+
assetId: allocation.assetId,
|
|
1895
|
+
assignment,
|
|
1896
|
+
settled: allocation.settled
|
|
1897
|
+
};
|
|
1898
|
+
}),
|
|
1899
|
+
pendingBlinded: unspent.pendingBlinded ?? 0
|
|
1900
|
+
}));
|
|
1901
|
+
}
|
|
1902
|
+
async listAssets() {
|
|
1903
|
+
const assets = this.client.listAssets();
|
|
1904
|
+
return assets;
|
|
1905
|
+
}
|
|
1906
|
+
async getAssetBalance(asset_id) {
|
|
1907
|
+
const balance = this.client.getAssetBalance(asset_id);
|
|
1908
|
+
return {
|
|
1909
|
+
settled: balance.settled ?? 0,
|
|
1910
|
+
future: balance.future ?? 0,
|
|
1911
|
+
spendable: balance.spendable ?? 0,
|
|
1912
|
+
offchainOutbound: balance.offchainOutbound ?? 0,
|
|
1913
|
+
offchainInbound: balance.offchainInbound ?? 0
|
|
1914
|
+
};
|
|
1572
1915
|
}
|
|
1573
|
-
createUtxosBegin(params) {
|
|
1916
|
+
async createUtxosBegin(params) {
|
|
1574
1917
|
return this.client.createUtxosBegin(params);
|
|
1575
1918
|
}
|
|
1576
|
-
createUtxosEnd(params) {
|
|
1919
|
+
async createUtxosEnd(params) {
|
|
1577
1920
|
return this.client.createUtxosEnd(params);
|
|
1578
1921
|
}
|
|
1579
|
-
sendBegin(params) {
|
|
1922
|
+
async sendBegin(params) {
|
|
1580
1923
|
return this.client.sendBegin(params);
|
|
1581
1924
|
}
|
|
1582
|
-
|
|
1925
|
+
/**
|
|
1926
|
+
* Batch send begin: accepts already-built recipientMap.
|
|
1927
|
+
* Returns unsigned PSBT (use signPsbt then sendEnd to complete).
|
|
1928
|
+
*/
|
|
1929
|
+
async sendBeginBatch(params) {
|
|
1930
|
+
return this.client.sendBeginBatch(params);
|
|
1931
|
+
}
|
|
1932
|
+
/**
|
|
1933
|
+
* Complete batch send: sendBeginBatch → sign PSBT → sendEnd.
|
|
1934
|
+
*/
|
|
1935
|
+
async sendBatch(params, mnemonic) {
|
|
1936
|
+
this.ensureNotDisposed();
|
|
1937
|
+
const psbt = await this.sendBeginBatch(params);
|
|
1938
|
+
const signedPsbt = await this.signPsbt(psbt, mnemonic);
|
|
1939
|
+
return await this.sendEnd({ signedPsbt });
|
|
1940
|
+
}
|
|
1941
|
+
async sendEnd(params) {
|
|
1583
1942
|
return this.client.sendEnd(params);
|
|
1584
1943
|
}
|
|
1585
|
-
sendBtcBegin(params) {
|
|
1944
|
+
async sendBtcBegin(params) {
|
|
1586
1945
|
return this.client.sendBtcBegin(params);
|
|
1587
1946
|
}
|
|
1588
|
-
sendBtcEnd(params) {
|
|
1947
|
+
async sendBtcEnd(params) {
|
|
1589
1948
|
return this.client.sendBtcEnd(params);
|
|
1590
1949
|
}
|
|
1591
|
-
estimateFeeRate(blocks) {
|
|
1950
|
+
async estimateFeeRate(blocks) {
|
|
1592
1951
|
if (!Number.isFinite(blocks)) {
|
|
1593
1952
|
throw new ValidationError("blocks must be a finite number", "blocks");
|
|
1594
1953
|
}
|
|
1595
1954
|
if (!Number.isInteger(blocks) || blocks <= 0) {
|
|
1596
1955
|
throw new ValidationError("blocks must be a positive integer", "blocks");
|
|
1597
1956
|
}
|
|
1598
|
-
|
|
1957
|
+
const feeEstimation = await this.client.getFeeEstimation({ blocks });
|
|
1958
|
+
return feeEstimation;
|
|
1599
1959
|
}
|
|
1600
1960
|
async estimateFee(psbtBase64) {
|
|
1601
1961
|
return await estimatePsbt(psbtBase64);
|
|
1602
1962
|
}
|
|
1603
1963
|
async sendBtc(params) {
|
|
1604
1964
|
this.ensureNotDisposed();
|
|
1605
|
-
const psbt = this.sendBtcBegin(params);
|
|
1965
|
+
const psbt = await this.sendBtcBegin(params);
|
|
1606
1966
|
const signed = await this.signPsbt(psbt);
|
|
1607
|
-
return this.sendBtcEnd({ signedPsbt: signed });
|
|
1967
|
+
return await this.sendBtcEnd({ signedPsbt: signed });
|
|
1608
1968
|
}
|
|
1609
|
-
blindReceive(params) {
|
|
1610
|
-
|
|
1969
|
+
async blindReceive(params) {
|
|
1970
|
+
const invoice = await this.client.blindReceive({
|
|
1971
|
+
...params,
|
|
1972
|
+
assetId: params.assetId ?? "",
|
|
1973
|
+
amount: params.amount ?? 0
|
|
1974
|
+
});
|
|
1975
|
+
return {
|
|
1976
|
+
invoice: invoice.invoice,
|
|
1977
|
+
recipientId: invoice.recipientId,
|
|
1978
|
+
expirationTimestamp: invoice.expirationTimestamp ?? null,
|
|
1979
|
+
batchTransferIdx: invoice.batchTransferIdx
|
|
1980
|
+
};
|
|
1611
1981
|
}
|
|
1612
|
-
witnessReceive(params) {
|
|
1613
|
-
|
|
1982
|
+
async witnessReceive(params) {
|
|
1983
|
+
const invoice = await this.client.witnessReceive({
|
|
1984
|
+
...params,
|
|
1985
|
+
assetId: params.assetId ?? "",
|
|
1986
|
+
amount: params.amount ?? 0
|
|
1987
|
+
});
|
|
1988
|
+
return {
|
|
1989
|
+
invoice: invoice.invoice,
|
|
1990
|
+
recipientId: invoice.recipientId,
|
|
1991
|
+
expirationTimestamp: invoice.expirationTimestamp ?? null,
|
|
1992
|
+
batchTransferIdx: invoice.batchTransferIdx
|
|
1993
|
+
};
|
|
1614
1994
|
}
|
|
1615
|
-
|
|
1616
|
-
|
|
1995
|
+
async decodeRGBInvoice(params) {
|
|
1996
|
+
const invoiceData = await this.client.decodeRGBInvoice(params);
|
|
1997
|
+
const assignmentKeys = Object.keys(invoiceData.assignment);
|
|
1998
|
+
const assignmentType = assignmentKeys[0];
|
|
1999
|
+
const assignment = {
|
|
2000
|
+
type: assignmentType ?? "Any",
|
|
2001
|
+
amount: assignmentType && invoiceData.assignment[assignmentType] ? Number(invoiceData.assignment[assignmentType]) : void 0
|
|
2002
|
+
};
|
|
2003
|
+
return {
|
|
2004
|
+
invoice: params.invoice,
|
|
2005
|
+
recipientId: invoiceData.recipientId,
|
|
2006
|
+
assetSchema: invoiceData.assetSchema,
|
|
2007
|
+
assetId: invoiceData.assetId,
|
|
2008
|
+
network: invoiceData.network,
|
|
2009
|
+
assignment,
|
|
2010
|
+
assignmentName: invoiceData.assignmentName,
|
|
2011
|
+
expirationTimestamp: invoiceData.expirationTimestamp ?? null,
|
|
2012
|
+
transportEndpoints: invoiceData.transportEndpoints
|
|
2013
|
+
};
|
|
1617
2014
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
2015
|
+
async issueAssetNia(params) {
|
|
2016
|
+
const asset = await this.client.issueAssetNia(params);
|
|
2017
|
+
return asset;
|
|
1620
2018
|
}
|
|
1621
|
-
|
|
2019
|
+
async issueAssetIfa(params) {
|
|
2020
|
+
const asset = await this.client.issueAssetIfa(params);
|
|
2021
|
+
return asset;
|
|
2022
|
+
}
|
|
2023
|
+
async inflateBegin(params) {
|
|
1622
2024
|
return this.client.inflateBegin(params);
|
|
1623
2025
|
}
|
|
1624
|
-
inflateEnd(params) {
|
|
2026
|
+
async inflateEnd(params) {
|
|
1625
2027
|
return this.client.inflateEnd(params);
|
|
1626
2028
|
}
|
|
1627
2029
|
/**
|
|
@@ -1637,24 +2039,51 @@ var WalletManager = class {
|
|
|
1637
2039
|
signedPsbt
|
|
1638
2040
|
});
|
|
1639
2041
|
}
|
|
1640
|
-
refreshWallet() {
|
|
2042
|
+
async refreshWallet() {
|
|
1641
2043
|
this.client.refreshWallet();
|
|
1642
2044
|
}
|
|
1643
|
-
listTransactions() {
|
|
1644
|
-
|
|
2045
|
+
async listTransactions() {
|
|
2046
|
+
const transactions = this.client.listTransactions();
|
|
2047
|
+
return transactions;
|
|
1645
2048
|
}
|
|
1646
|
-
listTransfers(asset_id) {
|
|
1647
|
-
|
|
2049
|
+
async listTransfers(asset_id) {
|
|
2050
|
+
const transfers = this.client.listTransfers(asset_id);
|
|
2051
|
+
return transfers;
|
|
1648
2052
|
}
|
|
1649
|
-
failTransfers(params) {
|
|
2053
|
+
async failTransfers(params) {
|
|
1650
2054
|
return this.client.failTransfers(params);
|
|
1651
2055
|
}
|
|
1652
|
-
|
|
1653
|
-
return this.client.decodeRGBInvoice(params);
|
|
1654
|
-
}
|
|
1655
|
-
createBackup(params) {
|
|
2056
|
+
async createBackup(params) {
|
|
1656
2057
|
return this.client.createBackup(params);
|
|
1657
2058
|
}
|
|
2059
|
+
/**
|
|
2060
|
+
* Configure VSS cloud backup for this wallet.
|
|
2061
|
+
*/
|
|
2062
|
+
async configureVssBackup(config) {
|
|
2063
|
+
this.ensureNotDisposed();
|
|
2064
|
+
this.client.configureVssBackup(config);
|
|
2065
|
+
}
|
|
2066
|
+
/**
|
|
2067
|
+
* Disable automatic VSS backup.
|
|
2068
|
+
*/
|
|
2069
|
+
async disableVssAutoBackup() {
|
|
2070
|
+
this.ensureNotDisposed();
|
|
2071
|
+
this.client.disableVssAutoBackup();
|
|
2072
|
+
}
|
|
2073
|
+
/**
|
|
2074
|
+
* Trigger a VSS backup immediately and return the server version.
|
|
2075
|
+
*/
|
|
2076
|
+
async vssBackup(config) {
|
|
2077
|
+
this.ensureNotDisposed();
|
|
2078
|
+
return this.client.vssBackup(config);
|
|
2079
|
+
}
|
|
2080
|
+
/**
|
|
2081
|
+
* Get VSS backup info for this wallet.
|
|
2082
|
+
*/
|
|
2083
|
+
async vssBackupInfo(config) {
|
|
2084
|
+
this.ensureNotDisposed();
|
|
2085
|
+
return this.client.vssBackupInfo(config);
|
|
2086
|
+
}
|
|
1658
2087
|
/**
|
|
1659
2088
|
* Sign a PSBT using the wallet's mnemonic or a provided mnemonic
|
|
1660
2089
|
* @param psbt - Base64 encoded PSBT
|
|
@@ -1680,16 +2109,15 @@ var WalletManager = class {
|
|
|
1680
2109
|
this.ensureNotDisposed();
|
|
1681
2110
|
const psbt = await this.sendBegin(invoiceTransfer);
|
|
1682
2111
|
const signedPsbt = await this.signPsbt(psbt, mnemonic);
|
|
1683
|
-
console.log("send signedPsbt", signedPsbt);
|
|
1684
2112
|
return await this.sendEnd({ signedPsbt });
|
|
1685
2113
|
}
|
|
1686
2114
|
async createUtxos({ upTo, num, size, feeRate }) {
|
|
1687
2115
|
this.ensureNotDisposed();
|
|
1688
|
-
const psbt = this.createUtxosBegin({ upTo, num, size, feeRate });
|
|
2116
|
+
const psbt = await this.createUtxosBegin({ upTo, num, size, feeRate });
|
|
1689
2117
|
const signedPsbt = await this.signPsbt(psbt);
|
|
1690
2118
|
return this.createUtxosEnd({ signedPsbt });
|
|
1691
2119
|
}
|
|
1692
|
-
syncWallet() {
|
|
2120
|
+
async syncWallet() {
|
|
1693
2121
|
this.client.syncWallet();
|
|
1694
2122
|
}
|
|
1695
2123
|
async signMessage(message) {
|
|
@@ -1734,33 +2162,1081 @@ var wallet = new Proxy({}, {
|
|
|
1734
2162
|
}
|
|
1735
2163
|
});
|
|
1736
2164
|
|
|
1737
|
-
// src/
|
|
1738
|
-
var
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
}
|
|
2165
|
+
// src/utexo/utexo-protocol.ts
|
|
2166
|
+
var LightningProtocol = class {
|
|
2167
|
+
async createLightningInvoice(params) {
|
|
2168
|
+
throw new Error("createLightningInvoice not implemented");
|
|
2169
|
+
}
|
|
2170
|
+
async getLightningReceiveRequest(id) {
|
|
2171
|
+
throw new Error("getLightningReceiveRequest not implemented");
|
|
2172
|
+
}
|
|
2173
|
+
async getLightningSendRequest(id) {
|
|
2174
|
+
throw new Error("getLightningSendRequest not implemented");
|
|
2175
|
+
}
|
|
2176
|
+
async getLightningSendFeeEstimate(params) {
|
|
2177
|
+
throw new Error("getLightningSendFeeEstimate not implemented");
|
|
2178
|
+
}
|
|
2179
|
+
async payLightningInvoiceBegin(params) {
|
|
2180
|
+
throw new Error("payLightningInvoiceBegin not implemented");
|
|
2181
|
+
}
|
|
2182
|
+
async payLightningInvoiceEnd(params) {
|
|
2183
|
+
throw new Error("payLightningInvoiceEnd not implemented");
|
|
2184
|
+
}
|
|
2185
|
+
async payLightningInvoice(params, mnemonic) {
|
|
2186
|
+
throw new Error("payLightningInvoice not implemented");
|
|
2187
|
+
}
|
|
2188
|
+
async listLightningPayments() {
|
|
2189
|
+
throw new Error("listLightningPayments not implemented");
|
|
2190
|
+
}
|
|
2191
|
+
};
|
|
2192
|
+
var OnchainProtocol = class {
|
|
2193
|
+
async onchainReceive(params) {
|
|
2194
|
+
throw new Error("onchainReceive not implemented");
|
|
2195
|
+
}
|
|
2196
|
+
async onchainSendBegin(params) {
|
|
2197
|
+
throw new Error("onchainSendBegin not implemented");
|
|
2198
|
+
}
|
|
2199
|
+
async onchainSendEnd(params) {
|
|
2200
|
+
throw new Error("onchainSendEnd not implemented");
|
|
2201
|
+
}
|
|
2202
|
+
async onchainSend(params, mnemonic) {
|
|
2203
|
+
throw new Error("onchainSend not implemented");
|
|
2204
|
+
}
|
|
2205
|
+
async getOnchainSendStatus(send_id) {
|
|
2206
|
+
throw new Error("getOnchainSendStatus not implemented");
|
|
2207
|
+
}
|
|
2208
|
+
async listOnchainTransfers(asset_id) {
|
|
2209
|
+
throw new Error("listOnchainTransfers not implemented");
|
|
2210
|
+
}
|
|
2211
|
+
};
|
|
2212
|
+
var UTEXOProtocol = class extends LightningProtocol {
|
|
2213
|
+
constructor() {
|
|
2214
|
+
super(...arguments);
|
|
2215
|
+
this.onchainProtocol = new OnchainProtocol();
|
|
2216
|
+
}
|
|
2217
|
+
async onchainReceive(params) {
|
|
2218
|
+
return this.onchainProtocol.onchainReceive(params);
|
|
2219
|
+
}
|
|
2220
|
+
async onchainSendBegin(params) {
|
|
2221
|
+
return this.onchainProtocol.onchainSendBegin(params);
|
|
2222
|
+
}
|
|
2223
|
+
async onchainSendEnd(params) {
|
|
2224
|
+
return this.onchainProtocol.onchainSendEnd(params);
|
|
2225
|
+
}
|
|
2226
|
+
async onchainSend(params, mnemonic) {
|
|
2227
|
+
return this.onchainProtocol.onchainSend(params, mnemonic);
|
|
2228
|
+
}
|
|
2229
|
+
async getOnchainSendStatus(send_id) {
|
|
2230
|
+
return this.onchainProtocol.getOnchainSendStatus(send_id);
|
|
2231
|
+
}
|
|
2232
|
+
async listOnchainTransfers(asset_id) {
|
|
2233
|
+
return this.onchainProtocol.listOnchainTransfers(asset_id);
|
|
2234
|
+
}
|
|
2235
|
+
};
|
|
2236
|
+
|
|
2237
|
+
// src/utexo/config/gateway.ts
|
|
2238
|
+
var DEFAULT_GATEWAY_BASE_URLS = {
|
|
2239
|
+
mainnet: "https://gateway.utexo.tricorn.network/",
|
|
2240
|
+
testnet: "https://dev.gateway.utexo.tricorn.network/"
|
|
2241
|
+
};
|
|
2242
|
+
|
|
2243
|
+
// src/utexo/bridge/types.ts
|
|
2244
|
+
var TransferStatuses = /* @__PURE__ */ ((TransferStatuses2) => {
|
|
2245
|
+
TransferStatuses2[TransferStatuses2["Unspecified"] = 0] = "Unspecified";
|
|
2246
|
+
TransferStatuses2[TransferStatuses2["Confirming"] = 1] = "Confirming";
|
|
2247
|
+
TransferStatuses2[TransferStatuses2["Canceled"] = 2] = "Canceled";
|
|
2248
|
+
TransferStatuses2[TransferStatuses2["Finished"] = 3] = "Finished";
|
|
2249
|
+
TransferStatuses2[TransferStatuses2["Waiting"] = 4] = "Waiting";
|
|
2250
|
+
TransferStatuses2[TransferStatuses2["Cancelling"] = 5] = "Cancelling";
|
|
2251
|
+
TransferStatuses2[TransferStatuses2["Failed"] = 6] = "Failed";
|
|
2252
|
+
TransferStatuses2[TransferStatuses2["Fetching"] = 7] = "Fetching";
|
|
2253
|
+
return TransferStatuses2;
|
|
2254
|
+
})(TransferStatuses || {});
|
|
2255
|
+
|
|
2256
|
+
// src/utexo/bridge/api.ts
|
|
2257
|
+
var encodeTransferStatus = (transferStatus) => {
|
|
2258
|
+
const textEncoder = new TextEncoder();
|
|
2259
|
+
return textEncoder.encode(transferStatus.toString())[0];
|
|
2260
|
+
};
|
|
2261
|
+
var UtexoBridgeApiClient = class {
|
|
2262
|
+
/**
|
|
2263
|
+
* Creates a new UtexoBridgeApiClient instance
|
|
2264
|
+
*
|
|
2265
|
+
* @param axiosInstance - Axios instance to use for HTTP requests (required)
|
|
2266
|
+
* @param basePath - Base path for API endpoints (defaults to '/v1/utexo/bridge')
|
|
2267
|
+
*
|
|
2268
|
+
* @example
|
|
2269
|
+
* ```typescript
|
|
2270
|
+
* import axios from 'axios';
|
|
2271
|
+
* import { UtexoBridgeApiClient } from './utexoBridge';
|
|
2272
|
+
*
|
|
2273
|
+
* const axiosInstance = axios.create({
|
|
2274
|
+
* baseURL: 'https://api.example.com'
|
|
2275
|
+
* });
|
|
2276
|
+
*
|
|
2277
|
+
* const client = new UtexoBridgeApiClient(axiosInstance);
|
|
2278
|
+
* ```
|
|
2279
|
+
*/
|
|
2280
|
+
constructor(axiosInstance, basePath = "/v1/utexo/bridge") {
|
|
2281
|
+
this.axios = axiosInstance;
|
|
2282
|
+
this.basePath = basePath;
|
|
2283
|
+
}
|
|
2284
|
+
/**
|
|
2285
|
+
* Gets bridge-in signature for a transfer
|
|
2286
|
+
*
|
|
2287
|
+
* @param request - Bridge-in signature request data
|
|
2288
|
+
* @returns Promise resolving to bridge-in signature response
|
|
2289
|
+
* @throws {ApiError} If the request fails
|
|
2290
|
+
*/
|
|
2291
|
+
async getBridgeInSignature(request) {
|
|
2292
|
+
try {
|
|
2293
|
+
const { data } = await this.axios.post(
|
|
2294
|
+
`${this.basePath}/bridge-in-signature`,
|
|
2295
|
+
request
|
|
2296
|
+
);
|
|
2297
|
+
return data;
|
|
2298
|
+
} catch (error) {
|
|
2299
|
+
const responseData = error.response?.data;
|
|
2300
|
+
if (responseData !== void 0) {
|
|
2301
|
+
const message = typeof responseData === "string" ? responseData : JSON.stringify(responseData);
|
|
2302
|
+
throw new Error(message);
|
|
2303
|
+
}
|
|
2304
|
+
throw error;
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* Submits a signed transaction to the blockchain
|
|
2309
|
+
*
|
|
2310
|
+
* @param request - Submit transaction request data
|
|
2311
|
+
* @returns Promise resolving to transaction hash
|
|
2312
|
+
* @throws {ApiError} If the request fails
|
|
2313
|
+
*/
|
|
2314
|
+
async submitTransaction(request) {
|
|
2315
|
+
const { data } = await this.axios.post(
|
|
2316
|
+
`${this.basePath}/submit-transaction`,
|
|
2317
|
+
request
|
|
2318
|
+
);
|
|
2319
|
+
return data.txHash;
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* Verifies a bridge-in transaction after it has been sent
|
|
2323
|
+
*
|
|
2324
|
+
* @param request - Verify bridge-in request data
|
|
2325
|
+
* @returns Promise that resolves when verification is complete
|
|
2326
|
+
* @throws {ApiError} If the request fails
|
|
2327
|
+
*/
|
|
2328
|
+
async verifyBridgeIn(request) {
|
|
2329
|
+
await this.axios.post(`${this.basePath}/verify-bridge-in`, request);
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* Gets receiver invoice by transfer ID and network ID
|
|
2333
|
+
*
|
|
2334
|
+
* @param transferId - Transfer ID
|
|
2335
|
+
* @param networkId - Network ID
|
|
2336
|
+
* @returns Promise resolving to invoice string
|
|
2337
|
+
* @throws {ApiError} If the request fails
|
|
2338
|
+
*/
|
|
2339
|
+
async getReceiverInvoice(transferId, networkId) {
|
|
2340
|
+
const { data } = await this.axios.get(
|
|
2341
|
+
`${this.basePath}/receiver-invoice/${transferId}/${networkId}`
|
|
2342
|
+
);
|
|
2343
|
+
return data.invoice;
|
|
2344
|
+
}
|
|
2345
|
+
async getWithdrawTransfer(invoice, networkId) {
|
|
2346
|
+
const { data } = await this.axios.get(
|
|
2347
|
+
`${this.basePath}/transfers/history`,
|
|
2348
|
+
{
|
|
2349
|
+
params: {
|
|
2350
|
+
"network_id": String(networkId),
|
|
2351
|
+
"offset": String(0),
|
|
2352
|
+
"limit": String(10),
|
|
2353
|
+
"address": "rgb-address"
|
|
2354
|
+
}
|
|
2355
|
+
}
|
|
2356
|
+
);
|
|
2357
|
+
if (data.transfers.length === 0) {
|
|
2358
|
+
return null;
|
|
2359
|
+
}
|
|
2360
|
+
const withdrawTransfer = data.transfers.map((transfer) => ({ ...transfer, status: TransferStatuses[encodeTransferStatus(transfer.status)] })).find((transfer) => transfer.recipient.address === invoice);
|
|
2361
|
+
if (!withdrawTransfer) {
|
|
2362
|
+
return null;
|
|
2363
|
+
}
|
|
2364
|
+
return withdrawTransfer;
|
|
2365
|
+
}
|
|
2366
|
+
/**
|
|
2367
|
+
* Gets transfer information by mainnet invoice
|
|
2368
|
+
*
|
|
2369
|
+
* @param mainnetInvoice - Mainnet invoice string
|
|
2370
|
+
* @param networkId - Network ID
|
|
2371
|
+
* @returns Promise resolving to transfer information
|
|
2372
|
+
* @throws {ApiError} If the request fails
|
|
2373
|
+
*/
|
|
2374
|
+
async getTransferByMainnetInvoice(mainnetInvoice, networkId) {
|
|
2375
|
+
try {
|
|
2376
|
+
const { data } = await this.axios.get(
|
|
2377
|
+
`${this.basePath}/transfer-by-mainnet-invoice`,
|
|
2378
|
+
{
|
|
2379
|
+
params: {
|
|
2380
|
+
mainnet_invoice: mainnetInvoice,
|
|
2381
|
+
network_id: networkId
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
);
|
|
2385
|
+
if (data) {
|
|
2386
|
+
return { ...data, status: TransferStatuses[encodeTransferStatus(data.status)] };
|
|
2387
|
+
}
|
|
2388
|
+
return data;
|
|
2389
|
+
} catch (error) {
|
|
2390
|
+
console.log("Mainnet invoice not found");
|
|
2391
|
+
return null;
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
};
|
|
2395
|
+
function getBridgeAPI(network = "mainnet") {
|
|
2396
|
+
const axiosInstance = axios.create({
|
|
2397
|
+
baseURL: DEFAULT_GATEWAY_BASE_URLS[network]
|
|
2398
|
+
});
|
|
2399
|
+
return new UtexoBridgeApiClient(axiosInstance);
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
// src/utexo/utils/helpers.ts
|
|
2403
|
+
var UTXO_PATH_INDEX = 2;
|
|
2404
|
+
function toUnitsNumber(value, precision) {
|
|
2405
|
+
const s = String(value).trim();
|
|
2406
|
+
const neg = s.startsWith("-");
|
|
2407
|
+
const [iRaw, fRaw = ""] = (neg ? s.slice(1) : s).split(".");
|
|
2408
|
+
const frac = (fRaw + "0".repeat(precision)).slice(0, precision);
|
|
2409
|
+
const unitsStr = (iRaw || "0") + frac;
|
|
2410
|
+
const units = Number(unitsStr);
|
|
2411
|
+
if (!Number.isSafeInteger(units)) {
|
|
2412
|
+
throw new Error(
|
|
2413
|
+
`Amount exceeds MAX_SAFE_INTEGER. Use BigInt instead. got=${unitsStr}`
|
|
2414
|
+
);
|
|
2415
|
+
}
|
|
2416
|
+
return neg ? -units : units;
|
|
2417
|
+
}
|
|
2418
|
+
function fromUnitsNumber(units, precision) {
|
|
2419
|
+
const neg = units < 0;
|
|
2420
|
+
const base = 10 ** precision;
|
|
2421
|
+
const value = Math.abs(units) / base;
|
|
2422
|
+
return neg ? -value : value;
|
|
2423
|
+
}
|
|
2424
|
+
function decodeBridgeInvoice(hexInvoice) {
|
|
2425
|
+
const hex = hexInvoice.startsWith("0x") ? hexInvoice.slice(UTXO_PATH_INDEX) : hexInvoice;
|
|
2426
|
+
return Buffer.from(hex, "hex").toString("utf-8");
|
|
2427
|
+
}
|
|
2428
|
+
|
|
2429
|
+
// src/utexo/config/vss.ts
|
|
2430
|
+
var DEFAULT_VSS_SERVER_URL = "https://vss-server.utexo.com/vss";
|
|
2431
|
+
function getVssConfigs(config) {
|
|
2432
|
+
const base = { ...config };
|
|
2433
|
+
return {
|
|
2434
|
+
layer1: { ...base, storeId: `${config.storeId}_layer1` },
|
|
2435
|
+
utexo: { ...base, storeId: `${config.storeId}_utexo` }
|
|
2436
|
+
};
|
|
2437
|
+
}
|
|
2438
|
+
var BACKUP_FILE_SUFFIX = ".backup";
|
|
2439
|
+
var LAYER1_BACKUP_SUFFIX = "_layer1.backup";
|
|
2440
|
+
var UTEXO_BACKUP_SUFFIX = "_utexo.backup";
|
|
2441
|
+
var UTEXO_BACKUP_TMP_LAYER1 = ".layer1";
|
|
2442
|
+
var UTEXO_BACKUP_TMP_UTEXO = ".utexo";
|
|
2443
|
+
function getBackupStoreId(masterFingerprint) {
|
|
2444
|
+
return `wallet_${masterFingerprint}`;
|
|
2445
|
+
}
|
|
2446
|
+
function prepareUtxoBackupDirs(backupPath, masterFingerprint) {
|
|
2447
|
+
const storeId = getBackupStoreId(masterFingerprint);
|
|
2448
|
+
if (!fs2__default.existsSync(backupPath)) {
|
|
2449
|
+
fs2__default.mkdirSync(backupPath, { recursive: true });
|
|
2450
|
+
}
|
|
2451
|
+
const layer1TmpDir = path3__default.join(backupPath, UTEXO_BACKUP_TMP_LAYER1);
|
|
2452
|
+
const utexoTmpDir = path3__default.join(backupPath, UTEXO_BACKUP_TMP_UTEXO);
|
|
2453
|
+
fs2__default.mkdirSync(layer1TmpDir, { recursive: true });
|
|
2454
|
+
fs2__default.mkdirSync(utexoTmpDir, { recursive: true });
|
|
2455
|
+
return {
|
|
2456
|
+
storeId,
|
|
2457
|
+
layer1TmpDir,
|
|
2458
|
+
utexoTmpDir,
|
|
2459
|
+
layer1FinalPath: path3__default.join(backupPath, `${storeId}_layer1${BACKUP_FILE_SUFFIX}`),
|
|
2460
|
+
utexoFinalPath: path3__default.join(backupPath, `${storeId}_utexo${BACKUP_FILE_SUFFIX}`)
|
|
2461
|
+
};
|
|
2462
|
+
}
|
|
2463
|
+
function finalizeUtxoBackupPaths(params) {
|
|
2464
|
+
const { layer1BackupPath, utexoBackupPath, layer1FinalPath, utexoFinalPath, layer1TmpDir, utexoTmpDir } = params;
|
|
2465
|
+
fs2__default.renameSync(layer1BackupPath, layer1FinalPath);
|
|
2466
|
+
fs2__default.renameSync(utexoBackupPath, utexoFinalPath);
|
|
2467
|
+
fs2__default.rmdirSync(layer1TmpDir);
|
|
2468
|
+
fs2__default.rmdirSync(utexoTmpDir);
|
|
2469
|
+
}
|
|
2470
|
+
async function buildVssConfigFromMnemonic(mnemonic, serverUrl, networkPreset = "testnet") {
|
|
2471
|
+
const keys = await deriveKeysFromMnemonic(networkPreset, mnemonic.trim());
|
|
2472
|
+
return {
|
|
2473
|
+
serverUrl,
|
|
2474
|
+
storeId: `wallet_${keys.masterFingerprint}`,
|
|
2475
|
+
signingKey: deriveVssSigningKeyFromMnemonic(mnemonic.trim()),
|
|
2476
|
+
backupMode: "Blocking"
|
|
2477
|
+
};
|
|
2478
|
+
}
|
|
2479
|
+
async function restoreUtxoWalletFromVss(params) {
|
|
2480
|
+
const { mnemonic, targetDir, config: providedConfig, networkPreset = "testnet", vssServerUrl } = params;
|
|
2481
|
+
if (!mnemonic || !mnemonic.trim()) {
|
|
2482
|
+
throw new ValidationError("mnemonic is required", "mnemonic");
|
|
2483
|
+
}
|
|
2484
|
+
if (!targetDir) {
|
|
2485
|
+
throw new ValidationError("targetDir is required", "targetDir");
|
|
2486
|
+
}
|
|
2487
|
+
const serverUrl = vssServerUrl ?? DEFAULT_VSS_SERVER_URL;
|
|
2488
|
+
const config = providedConfig ?? await buildVssConfigFromMnemonic(mnemonic.trim(), serverUrl, networkPreset);
|
|
2489
|
+
const presetConfig = getUtxoNetworkConfig(networkPreset);
|
|
2490
|
+
const layer1Network = String(presetConfig.networkMap.mainnet);
|
|
2491
|
+
const utexoNetwork = String(presetConfig.networkMap.utexo);
|
|
2492
|
+
const masterFingerprint = config.storeId.replace(/^wallet_/, "") || config.storeId;
|
|
2493
|
+
const layer1Config = { ...config, storeId: `${config.storeId}_layer1` };
|
|
2494
|
+
const utexoConfig = { ...config, storeId: `${config.storeId}_utexo` };
|
|
2495
|
+
const { walletPath: layer1Path } = restoreFromVss({
|
|
2496
|
+
config: layer1Config,
|
|
2497
|
+
targetDir: path3__default.join(targetDir, layer1Network, masterFingerprint)
|
|
2498
|
+
});
|
|
2499
|
+
const { walletPath: utexoPath } = restoreFromVss({
|
|
2500
|
+
config: utexoConfig,
|
|
2501
|
+
targetDir: path3__default.join(targetDir, utexoNetwork, masterFingerprint)
|
|
2502
|
+
});
|
|
2503
|
+
return { layer1Path, utexoPath, targetDir };
|
|
2504
|
+
}
|
|
2505
|
+
function restoreUtxoWalletFromBackup(params) {
|
|
2506
|
+
const { backupPath, password, targetDir, networkPreset = "testnet" } = params;
|
|
2507
|
+
if (!backupPath || !password || !targetDir) {
|
|
2508
|
+
throw new ValidationError("backupPath, password, and targetDir are required", "restoreUtxoWalletFromBackup");
|
|
2509
|
+
}
|
|
2510
|
+
if (!fs2__default.existsSync(backupPath) || !fs2__default.statSync(backupPath).isDirectory()) {
|
|
2511
|
+
throw new ValidationError("backupPath must be an existing directory", "backupPath");
|
|
2512
|
+
}
|
|
2513
|
+
const files = fs2__default.readdirSync(backupPath);
|
|
2514
|
+
const layer1File = files.find((f) => f.endsWith(LAYER1_BACKUP_SUFFIX));
|
|
2515
|
+
const utexoFile = files.find((f) => f.endsWith(UTEXO_BACKUP_SUFFIX));
|
|
2516
|
+
if (!layer1File || !utexoFile) {
|
|
2517
|
+
throw new ValidationError(
|
|
2518
|
+
`backupPath must contain wallet_<fp>_layer1.backup and wallet_<fp>_utexo.backup (from createBackup)`,
|
|
2519
|
+
"backupPath"
|
|
2520
|
+
);
|
|
2521
|
+
}
|
|
2522
|
+
const masterFingerprint = layer1File.slice(0, -LAYER1_BACKUP_SUFFIX.length).replace(/^wallet_/, "");
|
|
2523
|
+
const expectedUtexoFile = `wallet_${masterFingerprint}${UTEXO_BACKUP_SUFFIX}`;
|
|
2524
|
+
if (utexoFile !== expectedUtexoFile) {
|
|
2525
|
+
throw new ValidationError(
|
|
2526
|
+
`Layer1 and utexo backup filenames must share the same wallet id (expected ${expectedUtexoFile})`,
|
|
2527
|
+
"backupPath"
|
|
2528
|
+
);
|
|
2529
|
+
}
|
|
2530
|
+
const layer1BackupFile = path3__default.join(backupPath, layer1File);
|
|
2531
|
+
const utexoBackupFile = path3__default.join(backupPath, utexoFile);
|
|
2532
|
+
if (!fs2__default.existsSync(layer1BackupFile) || !fs2__default.existsSync(utexoBackupFile)) {
|
|
2533
|
+
throw new ValidationError("Backup files not found", "backupPath");
|
|
2534
|
+
}
|
|
2535
|
+
const presetConfig = getUtxoNetworkConfig(networkPreset);
|
|
2536
|
+
const layer1Network = String(presetConfig.networkMap.mainnet);
|
|
2537
|
+
const utexoNetwork = String(presetConfig.networkMap.utexo);
|
|
2538
|
+
const layer1DataDir = path3__default.join(targetDir, layer1Network, masterFingerprint);
|
|
2539
|
+
const utexoDataDir = path3__default.join(targetDir, utexoNetwork, masterFingerprint);
|
|
2540
|
+
for (const dir of [layer1DataDir, utexoDataDir]) {
|
|
2541
|
+
if (!fs2__default.existsSync(path3__default.dirname(dir))) {
|
|
2542
|
+
fs2__default.mkdirSync(path3__default.dirname(dir), { recursive: true });
|
|
2543
|
+
}
|
|
2544
|
+
if (!fs2__default.existsSync(dir)) {
|
|
2545
|
+
fs2__default.mkdirSync(dir, { recursive: true });
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
restoreWallet({ backupFilePath: layer1BackupFile, password, dataDir: layer1DataDir });
|
|
2549
|
+
restoreWallet({ backupFilePath: utexoBackupFile, password, dataDir: utexoDataDir });
|
|
2550
|
+
return {
|
|
2551
|
+
layer1Path: layer1DataDir,
|
|
2552
|
+
utexoPath: utexoDataDir,
|
|
2553
|
+
targetDir
|
|
2554
|
+
};
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2557
|
+
// src/utexo/utexo-wallet.ts
|
|
2558
|
+
var UTEXOWallet = class extends UTEXOProtocol {
|
|
2559
|
+
/**
|
|
2560
|
+
* Creates a new UTEXOWallet instance
|
|
2561
|
+
* @param mnemonicOrSeed - Either a mnemonic phrase (string) or seed (Uint8Array)
|
|
2562
|
+
* @param options - Optional configuration options (defaults to { network: 'mainnet' })
|
|
2563
|
+
*/
|
|
2564
|
+
constructor(mnemonicOrSeed, options = {}) {
|
|
2565
|
+
super();
|
|
2566
|
+
this.layer1Keys = null;
|
|
2567
|
+
this.utexoKeys = null;
|
|
2568
|
+
this.layer1RGBWallet = null;
|
|
2569
|
+
this.utexoRGBWallet = null;
|
|
2570
|
+
this.mnemonicOrSeed = mnemonicOrSeed;
|
|
2571
|
+
this.options = options;
|
|
2572
|
+
const preset = options.network ?? "testnet";
|
|
2573
|
+
const networkConfig = getUtxoNetworkConfig(preset);
|
|
2574
|
+
this.networkMap = networkConfig.networkMap;
|
|
2575
|
+
this.networkIdMap = networkConfig.networkIdMap;
|
|
2576
|
+
this.bridge = getBridgeAPI(preset);
|
|
2577
|
+
}
|
|
2578
|
+
async initialize() {
|
|
2579
|
+
this.layer1Keys = await this.derivePublicKeys(this.networkMap.mainnet);
|
|
2580
|
+
this.utexoKeys = await this.derivePublicKeys(this.networkMap.utexo);
|
|
2581
|
+
const fp = this.utexoKeys.masterFingerprint;
|
|
2582
|
+
const dataDir = this.options.dataDir;
|
|
2583
|
+
this.utexoRGBWallet = new WalletManager({
|
|
2584
|
+
xpubVan: this.utexoKeys.accountXpubVanilla,
|
|
2585
|
+
xpubCol: this.utexoKeys.accountXpubColored,
|
|
2586
|
+
masterFingerprint: this.utexoKeys.masterFingerprint,
|
|
2587
|
+
network: this.networkMap.utexo,
|
|
2588
|
+
mnemonic: this.mnemonicOrSeed,
|
|
2589
|
+
dataDir: dataDir ? path3__default.join(dataDir, String(this.networkMap.utexo), fp) : void 0
|
|
2590
|
+
});
|
|
2591
|
+
this.layer1RGBWallet = new WalletManager({
|
|
2592
|
+
xpubVan: this.layer1Keys.accountXpubVanilla,
|
|
2593
|
+
xpubCol: this.layer1Keys.accountXpubVanilla,
|
|
2594
|
+
masterFingerprint: this.layer1Keys.masterFingerprint,
|
|
2595
|
+
network: this.networkMap.mainnet,
|
|
2596
|
+
mnemonic: this.mnemonicOrSeed,
|
|
2597
|
+
dataDir: dataDir ? path3__default.join(dataDir, String(this.networkMap.mainnet), fp) : void 0
|
|
2598
|
+
});
|
|
2599
|
+
}
|
|
2600
|
+
/**
|
|
2601
|
+
* Derive public keys from mnemonic or seed
|
|
2602
|
+
* @param network - BitcoinNetwork identifier
|
|
2603
|
+
* @returns Promise resolving to PublicKeys containing xpub, accountXpubVanilla, accountXpubColored, and masterFingerprint
|
|
2604
|
+
* @throws {ValidationError} If mnemonic is invalid
|
|
2605
|
+
*/
|
|
2606
|
+
async derivePublicKeys(network) {
|
|
2607
|
+
const generatedKeys = await deriveKeysFromMnemonicOrSeed(network, this.mnemonicOrSeed);
|
|
2608
|
+
const { xpub, accountXpubVanilla, accountXpubColored, masterFingerprint } = generatedKeys;
|
|
2609
|
+
return { xpub, accountXpubVanilla, accountXpubColored, masterFingerprint };
|
|
2610
|
+
}
|
|
2611
|
+
async getPubKeys() {
|
|
2612
|
+
if (!this.layer1Keys) {
|
|
2613
|
+
throw new ValidationError("Public keys are not set", "publicKeys");
|
|
2614
|
+
}
|
|
2615
|
+
return this.layer1Keys;
|
|
2616
|
+
}
|
|
2617
|
+
/**
|
|
2618
|
+
* Guard method to ensure wallet is initialized
|
|
2619
|
+
* @throws {WalletError} if wallet is not initialized
|
|
2620
|
+
*/
|
|
2621
|
+
ensureInitialized() {
|
|
2622
|
+
if (!this.utexoRGBWallet) {
|
|
2623
|
+
throw new WalletError("Wallet not initialized. Call initialize() first.");
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
// ==========================================
|
|
2627
|
+
// IWalletManager Implementation
|
|
2628
|
+
// ==========================================
|
|
2629
|
+
async goOnline(indexerUrl, skipConsistencyCheck) {
|
|
2630
|
+
this.ensureInitialized();
|
|
2631
|
+
throw new Error("goOnline not implemented");
|
|
2632
|
+
}
|
|
2633
|
+
getXpub() {
|
|
2634
|
+
this.ensureInitialized();
|
|
2635
|
+
return this.utexoRGBWallet.getXpub();
|
|
2636
|
+
}
|
|
2637
|
+
getNetwork() {
|
|
2638
|
+
this.ensureInitialized();
|
|
2639
|
+
return this.utexoRGBWallet.getNetwork();
|
|
2640
|
+
}
|
|
2641
|
+
async dispose() {
|
|
2642
|
+
if (this.layer1RGBWallet) {
|
|
2643
|
+
await this.layer1RGBWallet.dispose();
|
|
2644
|
+
}
|
|
2645
|
+
if (this.utexoRGBWallet) {
|
|
2646
|
+
await this.utexoRGBWallet.dispose();
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
isDisposed() {
|
|
2650
|
+
if (!this.utexoRGBWallet) {
|
|
2651
|
+
return false;
|
|
2652
|
+
}
|
|
2653
|
+
return this.utexoRGBWallet.isDisposed();
|
|
2654
|
+
}
|
|
2655
|
+
async getBtcBalance() {
|
|
2656
|
+
this.ensureInitialized();
|
|
2657
|
+
return this.utexoRGBWallet.getBtcBalance();
|
|
2658
|
+
}
|
|
2659
|
+
async getAddress() {
|
|
2660
|
+
this.ensureInitialized();
|
|
2661
|
+
return this.utexoRGBWallet.getAddress();
|
|
2662
|
+
}
|
|
2663
|
+
async listUnspents() {
|
|
2664
|
+
this.ensureInitialized();
|
|
2665
|
+
return this.utexoRGBWallet.listUnspents();
|
|
2666
|
+
}
|
|
2667
|
+
async createUtxosBegin(params) {
|
|
2668
|
+
this.ensureInitialized();
|
|
2669
|
+
return this.utexoRGBWallet.createUtxosBegin(params);
|
|
2670
|
+
}
|
|
2671
|
+
async createUtxosEnd(params) {
|
|
2672
|
+
this.ensureInitialized();
|
|
2673
|
+
return this.utexoRGBWallet.createUtxosEnd(params);
|
|
2674
|
+
}
|
|
2675
|
+
async createUtxos(params) {
|
|
2676
|
+
this.ensureInitialized();
|
|
2677
|
+
return this.utexoRGBWallet.createUtxos(params);
|
|
2678
|
+
}
|
|
2679
|
+
async listAssets() {
|
|
2680
|
+
this.ensureInitialized();
|
|
2681
|
+
return this.utexoRGBWallet.listAssets();
|
|
2682
|
+
}
|
|
2683
|
+
async getAssetBalance(asset_id) {
|
|
2684
|
+
this.ensureInitialized();
|
|
2685
|
+
return this.utexoRGBWallet.getAssetBalance(asset_id);
|
|
2686
|
+
}
|
|
2687
|
+
async issueAssetNia(params) {
|
|
2688
|
+
this.ensureInitialized();
|
|
2689
|
+
return this.utexoRGBWallet.issueAssetNia(params);
|
|
2690
|
+
}
|
|
2691
|
+
async issueAssetIfa(params) {
|
|
2692
|
+
this.ensureInitialized();
|
|
2693
|
+
return this.utexoRGBWallet.issueAssetIfa(params);
|
|
2694
|
+
}
|
|
2695
|
+
async inflateBegin(params) {
|
|
2696
|
+
this.ensureInitialized();
|
|
2697
|
+
return this.utexoRGBWallet.inflateBegin(params);
|
|
2698
|
+
}
|
|
2699
|
+
async inflateEnd(params) {
|
|
2700
|
+
this.ensureInitialized();
|
|
2701
|
+
return this.utexoRGBWallet.inflateEnd(params);
|
|
2702
|
+
}
|
|
2703
|
+
async inflate(params, mnemonic) {
|
|
2704
|
+
this.ensureInitialized();
|
|
2705
|
+
return this.utexoRGBWallet.inflate(params, mnemonic);
|
|
2706
|
+
}
|
|
2707
|
+
async sendBegin(params) {
|
|
2708
|
+
this.ensureInitialized();
|
|
2709
|
+
return this.utexoRGBWallet.sendBegin(params);
|
|
2710
|
+
}
|
|
2711
|
+
async sendEnd(params) {
|
|
2712
|
+
this.ensureInitialized();
|
|
2713
|
+
return this.utexoRGBWallet.sendEnd(params);
|
|
2714
|
+
}
|
|
2715
|
+
async send(invoiceTransfer, mnemonic) {
|
|
2716
|
+
this.ensureInitialized();
|
|
2717
|
+
return this.utexoRGBWallet.send(invoiceTransfer, mnemonic);
|
|
2718
|
+
}
|
|
2719
|
+
async sendBtcBegin(params) {
|
|
2720
|
+
this.ensureInitialized();
|
|
2721
|
+
return this.utexoRGBWallet.sendBtcBegin(params);
|
|
2722
|
+
}
|
|
2723
|
+
async sendBtcEnd(params) {
|
|
2724
|
+
this.ensureInitialized();
|
|
2725
|
+
return this.utexoRGBWallet.sendBtcEnd(params);
|
|
2726
|
+
}
|
|
2727
|
+
async sendBtc(params) {
|
|
2728
|
+
this.ensureInitialized();
|
|
2729
|
+
return this.utexoRGBWallet.sendBtc(params);
|
|
2730
|
+
}
|
|
2731
|
+
async blindReceive(params) {
|
|
2732
|
+
this.ensureInitialized();
|
|
2733
|
+
return this.utexoRGBWallet.blindReceive(params);
|
|
2734
|
+
}
|
|
2735
|
+
async witnessReceive(params) {
|
|
2736
|
+
this.ensureInitialized();
|
|
2737
|
+
return this.utexoRGBWallet.witnessReceive(params);
|
|
2738
|
+
}
|
|
2739
|
+
async decodeRGBInvoice(params) {
|
|
2740
|
+
this.ensureInitialized();
|
|
2741
|
+
return this.utexoRGBWallet.decodeRGBInvoice(params);
|
|
2742
|
+
}
|
|
2743
|
+
async listTransactions() {
|
|
2744
|
+
this.ensureInitialized();
|
|
2745
|
+
return this.utexoRGBWallet.listTransactions();
|
|
2746
|
+
}
|
|
2747
|
+
async listTransfers(asset_id) {
|
|
2748
|
+
this.ensureInitialized();
|
|
2749
|
+
return this.utexoRGBWallet.listTransfers(asset_id);
|
|
2750
|
+
}
|
|
2751
|
+
async failTransfers(params) {
|
|
2752
|
+
this.ensureInitialized();
|
|
2753
|
+
return this.utexoRGBWallet.failTransfers(params);
|
|
2754
|
+
}
|
|
2755
|
+
async refreshWallet() {
|
|
2756
|
+
this.ensureInitialized();
|
|
2757
|
+
this.utexoRGBWallet.refreshWallet();
|
|
2758
|
+
}
|
|
2759
|
+
async syncWallet() {
|
|
2760
|
+
this.ensureInitialized();
|
|
2761
|
+
this.utexoRGBWallet.syncWallet();
|
|
2762
|
+
}
|
|
2763
|
+
async estimateFeeRate(blocks) {
|
|
2764
|
+
this.ensureInitialized();
|
|
2765
|
+
return this.utexoRGBWallet.estimateFeeRate(blocks);
|
|
2766
|
+
}
|
|
2767
|
+
async estimateFee(psbtBase64) {
|
|
2768
|
+
this.ensureInitialized();
|
|
2769
|
+
return this.utexoRGBWallet.estimateFee(psbtBase64);
|
|
2770
|
+
}
|
|
2771
|
+
/**
|
|
2772
|
+
* Create backup for both layer1 and utexo stores in one folder.
|
|
2773
|
+
* Writes backupPath/wallet_{masterFingerprint}_layer1.backup and backupPath/wallet_{masterFingerprint}_utexo.backup
|
|
2774
|
+
* (same naming convention as VSS: storeId_layer1, storeId_utexo with storeId = wallet_<fp>).
|
|
2775
|
+
* Use restoreUtxoWalletFromBackup with the same backupPath to restore both.
|
|
2776
|
+
*/
|
|
2777
|
+
async createBackup(params) {
|
|
2778
|
+
this.ensureInitialized();
|
|
2779
|
+
const { backupPath, password } = params;
|
|
2780
|
+
if (!backupPath || !password) {
|
|
2781
|
+
throw new ValidationError("backupPath and password are required", "createBackup");
|
|
2782
|
+
}
|
|
2783
|
+
const fp = this.utexoKeys.masterFingerprint;
|
|
2784
|
+
const { layer1TmpDir, utexoTmpDir, layer1FinalPath, utexoFinalPath } = prepareUtxoBackupDirs(backupPath, fp);
|
|
2785
|
+
const layer1Result = await this.layer1RGBWallet.createBackup({ backupPath: layer1TmpDir, password });
|
|
2786
|
+
const utexoResult = await this.utexoRGBWallet.createBackup({ backupPath: utexoTmpDir, password });
|
|
2787
|
+
finalizeUtxoBackupPaths({
|
|
2788
|
+
layer1BackupPath: layer1Result.backupPath,
|
|
2789
|
+
utexoBackupPath: utexoResult.backupPath,
|
|
2790
|
+
layer1FinalPath,
|
|
2791
|
+
utexoFinalPath,
|
|
2792
|
+
layer1TmpDir,
|
|
2793
|
+
utexoTmpDir
|
|
2794
|
+
});
|
|
2795
|
+
return {
|
|
2796
|
+
message: "Backup created successfully (layer1 + utexo)",
|
|
2797
|
+
backupPath,
|
|
2798
|
+
layer1BackupPath: layer1FinalPath,
|
|
2799
|
+
utexoBackupPath: utexoFinalPath
|
|
2800
|
+
};
|
|
2801
|
+
}
|
|
2802
|
+
async configureVssBackup(config) {
|
|
2803
|
+
this.ensureInitialized();
|
|
2804
|
+
const { layer1, utexo } = getVssConfigs(config);
|
|
2805
|
+
await this.layer1RGBWallet.configureVssBackup(layer1);
|
|
2806
|
+
await this.utexoRGBWallet.configureVssBackup(utexo);
|
|
2807
|
+
}
|
|
2808
|
+
async disableVssAutoBackup() {
|
|
2809
|
+
this.ensureInitialized();
|
|
2810
|
+
await this.layer1RGBWallet.disableVssAutoBackup();
|
|
2811
|
+
await this.utexoRGBWallet.disableVssAutoBackup();
|
|
2812
|
+
}
|
|
2813
|
+
/**
|
|
2814
|
+
* Run VSS backup for both layer1 and utexo stores.
|
|
2815
|
+
* Config is optional: when omitted, builds config from mnemonic (option param or wallet mnemonic)
|
|
2816
|
+
* and options.vssServerUrl (or DEFAULT_VSS_SERVER_URL if not set).
|
|
2817
|
+
*
|
|
2818
|
+
* @param config - Optional; when omitted, built from mnemonic and vssServerUrl
|
|
2819
|
+
* @param mnemonic - Optional; when omitted, uses wallet mnemonic (only if wallet was created with mnemonic string)
|
|
2820
|
+
*/
|
|
2821
|
+
async vssBackup(config, mnemonic) {
|
|
2822
|
+
this.ensureInitialized();
|
|
2823
|
+
let vssConfig;
|
|
2824
|
+
if (config) {
|
|
2825
|
+
vssConfig = config;
|
|
2826
|
+
} else {
|
|
2827
|
+
const mnemonicToUse = mnemonic ?? (typeof this.mnemonicOrSeed === "string" ? this.mnemonicOrSeed : null);
|
|
2828
|
+
if (!mnemonicToUse) {
|
|
2829
|
+
throw new ValidationError(
|
|
2830
|
+
"mnemonic is required for VSS backup when config is not passed (wallet was created with seed)",
|
|
2831
|
+
"mnemonic"
|
|
2832
|
+
);
|
|
2833
|
+
}
|
|
2834
|
+
const serverUrl = this.options.vssServerUrl ?? DEFAULT_VSS_SERVER_URL;
|
|
2835
|
+
const preset = this.options.network ?? "mainnet";
|
|
2836
|
+
vssConfig = await buildVssConfigFromMnemonic(mnemonicToUse.trim(), serverUrl, preset);
|
|
2837
|
+
}
|
|
2838
|
+
const { layer1, utexo } = getVssConfigs(vssConfig);
|
|
2839
|
+
await this.layer1RGBWallet.vssBackup(layer1);
|
|
2840
|
+
const version = await this.utexoRGBWallet.vssBackup(utexo);
|
|
2841
|
+
return version;
|
|
2842
|
+
}
|
|
2843
|
+
/**
|
|
2844
|
+
* Get VSS backup info. Config is optional; when omitted, built from mnemonic (param or wallet)
|
|
2845
|
+
* and options.vssServerUrl (or DEFAULT_VSS_SERVER_URL if not set).
|
|
2846
|
+
*/
|
|
2847
|
+
async vssBackupInfo(config, mnemonic) {
|
|
2848
|
+
this.ensureInitialized();
|
|
2849
|
+
let vssConfig;
|
|
2850
|
+
if (config) {
|
|
2851
|
+
vssConfig = config;
|
|
2852
|
+
} else {
|
|
2853
|
+
const mnemonicToUse = mnemonic ?? (typeof this.mnemonicOrSeed === "string" ? this.mnemonicOrSeed : null);
|
|
2854
|
+
if (!mnemonicToUse) {
|
|
2855
|
+
throw new ValidationError("config or mnemonic required for vssBackupInfo", "config");
|
|
2856
|
+
}
|
|
2857
|
+
const serverUrl = this.options.vssServerUrl ?? DEFAULT_VSS_SERVER_URL;
|
|
2858
|
+
const preset = this.options.network ?? "mainnet";
|
|
2859
|
+
vssConfig = await buildVssConfigFromMnemonic(mnemonicToUse.trim(), serverUrl, preset);
|
|
2860
|
+
}
|
|
2861
|
+
const { utexo } = getVssConfigs(vssConfig);
|
|
2862
|
+
return this.utexoRGBWallet.vssBackupInfo(utexo);
|
|
2863
|
+
}
|
|
2864
|
+
async signPsbt(psbt, mnemonic) {
|
|
2865
|
+
this.ensureInitialized();
|
|
2866
|
+
return this.utexoRGBWallet.signPsbt(psbt, mnemonic);
|
|
2867
|
+
}
|
|
2868
|
+
async signMessage(message) {
|
|
2869
|
+
this.ensureInitialized();
|
|
2870
|
+
return this.utexoRGBWallet.signMessage(message);
|
|
2871
|
+
}
|
|
2872
|
+
async verifyMessage(message, signature, accountXpub) {
|
|
2873
|
+
this.ensureInitialized();
|
|
2874
|
+
return this.utexoRGBWallet.verifyMessage(message, signature, accountXpub);
|
|
2875
|
+
}
|
|
2876
|
+
/**
|
|
2877
|
+
* Validates that the wallet has sufficient spendable balance for the given asset and amount.
|
|
2878
|
+
* @param assetId - Asset ID to check balance for
|
|
2879
|
+
* @param amount - Required amount (in asset units)
|
|
2880
|
+
* @throws {ValidationError} If balance is not found or insufficient
|
|
2881
|
+
*/
|
|
2882
|
+
async validateBalance(assetId, amount) {
|
|
2883
|
+
const assetBalance = await this.getAssetBalance(assetId);
|
|
2884
|
+
if (!assetBalance || !assetBalance.spendable) {
|
|
2885
|
+
throw new ValidationError("Asset balance is not found", "assetBalance");
|
|
2886
|
+
}
|
|
2887
|
+
if (assetBalance.spendable < amount) {
|
|
2888
|
+
throw new ValidationError(`Insufficient balance ${assetBalance.spendable} < ${amount}`, "amount");
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
/**
|
|
2892
|
+
* Extracts invoice data and destination asset from a bridge transfer.
|
|
2893
|
+
*
|
|
2894
|
+
* @param bridgeTransfer - Bridge transfer response containing recipient invoice and token info
|
|
2895
|
+
* @returns Object containing invoice string, decoded invoice data, and destination asset
|
|
2896
|
+
* @throws {ValidationError} If destination asset is not supported
|
|
2897
|
+
*/
|
|
2898
|
+
async extractInvoiceAndAsset(bridgeTransfer) {
|
|
2899
|
+
const utexoInvoice = bridgeTransfer.recipient.address;
|
|
2900
|
+
const invoiceData = await this.decodeRGBInvoice({ invoice: utexoInvoice });
|
|
2901
|
+
const destinationAsset = this.networkIdMap.utexo.getAssetById(bridgeTransfer.recipientToken.id);
|
|
2902
|
+
if (!destinationAsset) {
|
|
2903
|
+
throw new ValidationError("Destination asset is not supported", "assetId");
|
|
2904
|
+
}
|
|
2905
|
+
return { utexoInvoice, invoiceData, destinationAsset };
|
|
2906
|
+
}
|
|
2907
|
+
/**
|
|
2908
|
+
* IUTEXOProtocol Implementation
|
|
2909
|
+
*/
|
|
2910
|
+
async onchainReceive(params) {
|
|
2911
|
+
this.ensureInitialized();
|
|
2912
|
+
const destinationAsset = getDestinationAsset("mainnet", "utexo", params.assetId ?? null);
|
|
2913
|
+
if (!destinationAsset) {
|
|
2914
|
+
throw new ValidationError("Destination asset is not supported", "assetId");
|
|
2915
|
+
}
|
|
2916
|
+
if (!params.amount) {
|
|
2917
|
+
throw new ValidationError("Amount is required", "amount");
|
|
2918
|
+
}
|
|
2919
|
+
const destinationInvoice = await this.utexoRGBWallet.witnessReceive({
|
|
2920
|
+
assetId: "",
|
|
2921
|
+
//invoice can receive any asset
|
|
2922
|
+
amount: params.amount,
|
|
2923
|
+
minConfirmations: params.minConfirmations,
|
|
2924
|
+
durationSeconds: params.durationSeconds
|
|
2925
|
+
});
|
|
2926
|
+
const bridgeTransfer = await this.bridge.getBridgeInSignature({
|
|
2927
|
+
sender: {
|
|
2928
|
+
address: "rgb-address",
|
|
2929
|
+
networkName: this.networkIdMap.mainnet.networkName,
|
|
2930
|
+
networkId: this.networkIdMap.mainnet.networkId
|
|
2931
|
+
},
|
|
2932
|
+
tokenId: destinationAsset.tokenId,
|
|
2933
|
+
amount: params.amount.toString(),
|
|
2934
|
+
destination: {
|
|
2935
|
+
address: destinationInvoice.invoice,
|
|
2936
|
+
networkName: this.networkIdMap.utexo.networkName,
|
|
2937
|
+
networkId: this.networkIdMap.utexo.networkId
|
|
2938
|
+
},
|
|
2939
|
+
additionalAddresses: []
|
|
2940
|
+
});
|
|
2941
|
+
const decodedInvoice = decodeBridgeInvoice(bridgeTransfer.signature);
|
|
2942
|
+
return {
|
|
2943
|
+
invoice: decodedInvoice
|
|
2944
|
+
};
|
|
2945
|
+
}
|
|
2946
|
+
async onchainSendBegin(params) {
|
|
2947
|
+
this.ensureInitialized();
|
|
2948
|
+
const bridgeTransfer = await this.bridge.getTransferByMainnetInvoice(params.invoice, this.networkIdMap.mainnet.networkId);
|
|
2949
|
+
if (!bridgeTransfer) {
|
|
2950
|
+
console.log("External invoice UTEXO -> Mainnet initiated");
|
|
2951
|
+
return this.UTEXOToMainnetRGB(params);
|
|
2952
|
+
}
|
|
2953
|
+
const utexoInvoice = bridgeTransfer.recipient.address;
|
|
2954
|
+
const invoiceData = await this.decodeRGBInvoice({ invoice: utexoInvoice });
|
|
2955
|
+
const bridgeAmount = bridgeTransfer.recipientAmount;
|
|
2956
|
+
const destinationAsset = this.networkIdMap.utexo.getAssetById(bridgeTransfer.recipientToken.id);
|
|
2957
|
+
if (!destinationAsset) {
|
|
2958
|
+
throw new ValidationError("Destination asset is not supported", "assetId");
|
|
2959
|
+
}
|
|
2960
|
+
const amount = toUnitsNumber(bridgeAmount, destinationAsset.precision);
|
|
2961
|
+
const isWitness = invoiceData.recipientId.includes("wvout:");
|
|
2962
|
+
await this.validateBalance(destinationAsset.assetId, amount);
|
|
2963
|
+
const psbt = await this.utexoRGBWallet.sendBegin({
|
|
2964
|
+
invoice: utexoInvoice,
|
|
2965
|
+
amount,
|
|
2966
|
+
assetId: destinationAsset.assetId,
|
|
2967
|
+
donation: true,
|
|
2968
|
+
...isWitness && {
|
|
2969
|
+
witnessData: {
|
|
2970
|
+
amountSat: 1e3,
|
|
2971
|
+
blinding: 0
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
});
|
|
2975
|
+
return psbt;
|
|
2976
|
+
}
|
|
2977
|
+
async onchainSendEnd(params) {
|
|
2978
|
+
this.ensureInitialized();
|
|
2979
|
+
const sendResult = await this.utexoRGBWallet.sendEnd({ signedPsbt: params.signedPsbt });
|
|
2980
|
+
return sendResult;
|
|
2981
|
+
}
|
|
2982
|
+
async onchainSend(params, mnemonic) {
|
|
2983
|
+
this.ensureInitialized();
|
|
2984
|
+
const psbt = await this.onchainSendBegin(params);
|
|
2985
|
+
const signed_psbt = await this.utexoRGBWallet.signPsbt(psbt, mnemonic);
|
|
2986
|
+
return await this.onchainSendEnd({ signedPsbt: signed_psbt, invoice: params.invoice });
|
|
2987
|
+
}
|
|
2988
|
+
async getOnchainSendStatus(invoice) {
|
|
2989
|
+
const bridgeTransfer = await this.bridge.getTransferByMainnetInvoice(invoice, this.networkIdMap.mainnet.networkId);
|
|
2990
|
+
if (!bridgeTransfer) {
|
|
2991
|
+
const withdrawTransfer = await this.bridge.getWithdrawTransfer(invoice, this.networkIdMap.utexo.networkId);
|
|
2992
|
+
if (!withdrawTransfer) {
|
|
2993
|
+
return null;
|
|
2994
|
+
}
|
|
2995
|
+
return withdrawTransfer.status;
|
|
2996
|
+
}
|
|
2997
|
+
const { invoiceData, destinationAsset } = await this.extractInvoiceAndAsset(bridgeTransfer);
|
|
2998
|
+
const transfers = await this.utexoRGBWallet.listTransfers(destinationAsset.assetId);
|
|
2999
|
+
const transfer = transfers.find((transfer2) => transfer2.recipientId === invoiceData.recipientId);
|
|
3000
|
+
if (transfer) {
|
|
3001
|
+
return transfer.status;
|
|
3002
|
+
}
|
|
3003
|
+
if (bridgeTransfer) {
|
|
3004
|
+
return bridgeTransfer.status;
|
|
3005
|
+
}
|
|
3006
|
+
return null;
|
|
3007
|
+
}
|
|
3008
|
+
async listOnchainTransfers(asset_id) {
|
|
3009
|
+
this.ensureInitialized();
|
|
3010
|
+
return this.utexoRGBWallet.listTransfers(asset_id);
|
|
3011
|
+
}
|
|
3012
|
+
async createLightningInvoice(params) {
|
|
3013
|
+
this.ensureInitialized();
|
|
3014
|
+
const asset = params.asset;
|
|
3015
|
+
if (!asset) {
|
|
3016
|
+
throw new ValidationError("Asset is required", "asset");
|
|
3017
|
+
}
|
|
3018
|
+
if (!asset.assetId) {
|
|
3019
|
+
throw new ValidationError("Asset ID is required", "assetId");
|
|
3020
|
+
}
|
|
3021
|
+
if (!asset.amount) {
|
|
3022
|
+
throw new ValidationError("Amount is required", "amount");
|
|
3023
|
+
}
|
|
3024
|
+
const destinationAsset = getDestinationAsset("mainnet", "utexo", asset.assetId);
|
|
3025
|
+
if (!destinationAsset) {
|
|
3026
|
+
throw new ValidationError("Destination asset is not supported", "assetId");
|
|
3027
|
+
}
|
|
3028
|
+
const destinationInvoice = await this.utexoRGBWallet.witnessReceive({
|
|
3029
|
+
assetId: "",
|
|
3030
|
+
//invoice can receive any asset
|
|
3031
|
+
amount: asset.amount
|
|
3032
|
+
});
|
|
3033
|
+
const bridgeTransfer = await this.bridge.getBridgeInSignature({
|
|
3034
|
+
sender: {
|
|
3035
|
+
address: "rgb-address",
|
|
3036
|
+
networkName: this.networkIdMap.mainnetLightning.networkName,
|
|
3037
|
+
networkId: this.networkIdMap.mainnetLightning.networkId
|
|
3038
|
+
},
|
|
3039
|
+
tokenId: destinationAsset.tokenId,
|
|
3040
|
+
amount: asset.amount.toString(),
|
|
3041
|
+
destination: {
|
|
3042
|
+
address: destinationInvoice.invoice,
|
|
3043
|
+
networkName: this.networkIdMap.utexo.networkName,
|
|
3044
|
+
networkId: this.networkIdMap.utexo.networkId
|
|
3045
|
+
},
|
|
3046
|
+
additionalAddresses: []
|
|
3047
|
+
});
|
|
3048
|
+
const decodedLnInvoice = decodeBridgeInvoice(bridgeTransfer.signature);
|
|
3049
|
+
return {
|
|
3050
|
+
lnInvoice: decodedLnInvoice
|
|
3051
|
+
};
|
|
3052
|
+
}
|
|
3053
|
+
async payLightningInvoiceBegin(params) {
|
|
3054
|
+
this.ensureInitialized();
|
|
3055
|
+
const bridgeTransfer = await this.bridge.getTransferByMainnetInvoice(params.lnInvoice, this.networkIdMap.mainnetLightning.networkId);
|
|
3056
|
+
if (!bridgeTransfer) {
|
|
3057
|
+
console.log("External invoice UTEXO -> Mainnet Lightning initiated");
|
|
3058
|
+
return this.UtexoToMainnetLightning(params);
|
|
3059
|
+
}
|
|
3060
|
+
const bridgeAmount = bridgeTransfer.recipientAmount;
|
|
3061
|
+
const { utexoInvoice, invoiceData, destinationAsset } = await this.extractInvoiceAndAsset(bridgeTransfer);
|
|
3062
|
+
const amount = toUnitsNumber(bridgeAmount, destinationAsset.precision);
|
|
3063
|
+
const isWitness = invoiceData.recipientId.includes("wvout:");
|
|
3064
|
+
const psbt = await this.utexoRGBWallet.sendBegin({
|
|
3065
|
+
invoice: utexoInvoice,
|
|
3066
|
+
amount,
|
|
3067
|
+
assetId: destinationAsset.assetId,
|
|
3068
|
+
donation: true,
|
|
3069
|
+
...isWitness && {
|
|
3070
|
+
witnessData: {
|
|
3071
|
+
amountSat: 1e3,
|
|
3072
|
+
blinding: 0
|
|
3073
|
+
}
|
|
3074
|
+
}
|
|
3075
|
+
});
|
|
3076
|
+
return psbt;
|
|
3077
|
+
}
|
|
3078
|
+
async payLightningInvoiceEnd(params) {
|
|
3079
|
+
this.ensureInitialized();
|
|
3080
|
+
const sendResult = await this.utexoRGBWallet.sendEnd({ signedPsbt: params.signedPsbt });
|
|
3081
|
+
return sendResult;
|
|
3082
|
+
}
|
|
3083
|
+
async payLightningInvoice(params, mnemonic) {
|
|
3084
|
+
this.ensureInitialized();
|
|
3085
|
+
const psbt = await this.payLightningInvoiceBegin(params);
|
|
3086
|
+
const signed_psbt = await this.utexoRGBWallet.signPsbt(psbt, mnemonic);
|
|
3087
|
+
return await this.payLightningInvoiceEnd({ signedPsbt: signed_psbt, lnInvoice: params.lnInvoice });
|
|
3088
|
+
}
|
|
3089
|
+
async getLightningSendRequest(lnInvoice) {
|
|
3090
|
+
this.ensureInitialized();
|
|
3091
|
+
const bridgeTransfer = await this.bridge.getTransferByMainnetInvoice(lnInvoice, this.networkIdMap.mainnetLightning.networkId);
|
|
3092
|
+
if (!bridgeTransfer) {
|
|
3093
|
+
const withdrawTransfer = await this.bridge.getWithdrawTransfer(lnInvoice, this.networkIdMap.utexo.networkId);
|
|
3094
|
+
if (!withdrawTransfer) {
|
|
3095
|
+
return null;
|
|
3096
|
+
}
|
|
3097
|
+
return withdrawTransfer.status;
|
|
3098
|
+
}
|
|
3099
|
+
const { invoiceData, destinationAsset } = await this.extractInvoiceAndAsset(bridgeTransfer);
|
|
3100
|
+
const transfers = await this.utexoRGBWallet.listTransfers(destinationAsset.assetId);
|
|
3101
|
+
return transfers.length > 0 ? transfers.find((transfer) => transfer.recipientId === invoiceData.recipientId)?.status ?? null : null;
|
|
3102
|
+
}
|
|
3103
|
+
async getLightningReceiveRequest(lnInvoice) {
|
|
3104
|
+
this.ensureInitialized();
|
|
3105
|
+
const bridgeTransfer = await this.bridge.getTransferByMainnetInvoice(lnInvoice, this.networkIdMap.mainnetLightning.networkId);
|
|
3106
|
+
if (!bridgeTransfer) {
|
|
3107
|
+
const withdrawTransfer = await this.bridge.getWithdrawTransfer(lnInvoice, this.networkIdMap.utexo.networkId);
|
|
3108
|
+
if (!withdrawTransfer) {
|
|
3109
|
+
return null;
|
|
3110
|
+
}
|
|
3111
|
+
return withdrawTransfer.status;
|
|
3112
|
+
}
|
|
3113
|
+
const { invoiceData, destinationAsset } = await this.extractInvoiceAndAsset(bridgeTransfer);
|
|
3114
|
+
const transfers = await this.utexoRGBWallet.listTransfers(destinationAsset.assetId);
|
|
3115
|
+
return transfers.length > 0 ? transfers.find((transfer) => transfer.recipientId === invoiceData.recipientId)?.status ?? null : null;
|
|
3116
|
+
}
|
|
3117
|
+
async UTEXOToMainnetRGB(params) {
|
|
3118
|
+
this.ensureInitialized();
|
|
3119
|
+
const invoiceData = await this.decodeRGBInvoice({ invoice: params.invoice });
|
|
3120
|
+
if (!params.assetId && !invoiceData.assetId) {
|
|
3121
|
+
throw new ValidationError("Asset ID is required for external invoice", "assetId");
|
|
3122
|
+
}
|
|
3123
|
+
const assetId = params.assetId ?? invoiceData.assetId;
|
|
3124
|
+
const utexoAsset = getDestinationAsset("mainnet", "utexo", assetId ?? null);
|
|
3125
|
+
if (!utexoAsset) {
|
|
3126
|
+
throw new ValidationError("UTEXO asset is not supported", "assetId");
|
|
3127
|
+
}
|
|
3128
|
+
const destinationAsset = this.networkIdMap.mainnet.getAssetById(utexoAsset?.tokenId ?? 0);
|
|
3129
|
+
if (!destinationAsset) {
|
|
3130
|
+
throw new ValidationError("Destination asset is not supported", "assetId");
|
|
3131
|
+
}
|
|
3132
|
+
if (!params.amount && !invoiceData.assignment.amount) {
|
|
3133
|
+
throw new ValidationError("Amount is required for external invoice", "amount");
|
|
3134
|
+
}
|
|
3135
|
+
let amount;
|
|
3136
|
+
if (params.amount) {
|
|
3137
|
+
amount = params.amount;
|
|
3138
|
+
} else if (invoiceData.assignment.amount) {
|
|
3139
|
+
amount = fromUnitsNumber(invoiceData.assignment.amount, destinationAsset.precision);
|
|
3140
|
+
} else {
|
|
3141
|
+
throw new ValidationError("Amount is required", "amount");
|
|
3142
|
+
}
|
|
3143
|
+
await this.validateBalance(utexoAsset.assetId, toUnitsNumber(amount.toString(), utexoAsset.precision));
|
|
3144
|
+
const payload = {
|
|
3145
|
+
sender: {
|
|
3146
|
+
address: "rgb-address",
|
|
3147
|
+
networkName: this.networkIdMap.utexo.networkName,
|
|
3148
|
+
networkId: this.networkIdMap.utexo.networkId
|
|
3149
|
+
},
|
|
3150
|
+
tokenId: destinationAsset.tokenId,
|
|
3151
|
+
amount: amount.toString(),
|
|
3152
|
+
destination: {
|
|
3153
|
+
address: params.invoice,
|
|
3154
|
+
networkName: this.networkIdMap.mainnet.networkName,
|
|
3155
|
+
networkId: this.networkIdMap.mainnet.networkId
|
|
3156
|
+
},
|
|
3157
|
+
additionalAddresses: []
|
|
3158
|
+
};
|
|
3159
|
+
console.log("payload", payload);
|
|
3160
|
+
const bridgeOutTransfer = await this.bridge.getBridgeInSignature(payload);
|
|
3161
|
+
const decodedInvoice = decodeBridgeInvoice(bridgeOutTransfer.signature);
|
|
3162
|
+
const isWitness = decodedInvoice.includes("wvout:");
|
|
3163
|
+
const psbt = await this.utexoRGBWallet.sendBegin({
|
|
3164
|
+
invoice: decodedInvoice,
|
|
3165
|
+
amount: Number(bridgeOutTransfer.amount),
|
|
3166
|
+
assetId: utexoAsset.assetId,
|
|
3167
|
+
donation: true,
|
|
3168
|
+
...isWitness && {
|
|
3169
|
+
witnessData: {
|
|
3170
|
+
amountSat: 1e3,
|
|
3171
|
+
blinding: 0
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3174
|
+
});
|
|
3175
|
+
return psbt;
|
|
3176
|
+
}
|
|
3177
|
+
async UtexoToMainnetLightning(params) {
|
|
3178
|
+
this.ensureInitialized();
|
|
3179
|
+
if (!params.assetId) {
|
|
3180
|
+
throw new ValidationError("Asset ID is required for external invoice", "assetId");
|
|
3181
|
+
}
|
|
3182
|
+
const assetId = params.assetId;
|
|
3183
|
+
const utexoAsset = getDestinationAsset("mainnet", "utexo", assetId ?? null);
|
|
3184
|
+
const destinationAsset = this.networkIdMap.mainnet.getAssetById(utexoAsset?.tokenId ?? 0);
|
|
3185
|
+
if (!destinationAsset) {
|
|
3186
|
+
throw new ValidationError("Destination asset is not supported", "assetId");
|
|
3187
|
+
}
|
|
3188
|
+
if (!utexoAsset) {
|
|
3189
|
+
throw new ValidationError("Destination asset is not supported", "assetId");
|
|
3190
|
+
}
|
|
3191
|
+
if (!params.amount) {
|
|
3192
|
+
throw new ValidationError("Amount is required for external invoice", "amount");
|
|
3193
|
+
}
|
|
3194
|
+
const amount = params.amount;
|
|
3195
|
+
await this.validateBalance(utexoAsset.assetId, toUnitsNumber(amount.toString(), utexoAsset.precision));
|
|
3196
|
+
const bridgeOutTransfer = await this.bridge.getBridgeInSignature({
|
|
3197
|
+
sender: {
|
|
3198
|
+
address: "rgb-address",
|
|
3199
|
+
networkName: this.networkIdMap.utexo.networkName,
|
|
3200
|
+
networkId: this.networkIdMap.utexo.networkId
|
|
3201
|
+
},
|
|
3202
|
+
tokenId: destinationAsset.tokenId,
|
|
3203
|
+
amount: amount.toString(),
|
|
3204
|
+
destination: {
|
|
3205
|
+
address: params.lnInvoice,
|
|
3206
|
+
networkName: this.networkIdMap.mainnetLightning.networkName,
|
|
3207
|
+
networkId: this.networkIdMap.mainnetLightning.networkId
|
|
3208
|
+
},
|
|
3209
|
+
additionalAddresses: []
|
|
3210
|
+
});
|
|
3211
|
+
const decodedInvoice = decodeBridgeInvoice(bridgeOutTransfer.signature);
|
|
3212
|
+
const isWitness = decodedInvoice.includes("wvout:");
|
|
3213
|
+
const psbt = await this.utexoRGBWallet.sendBegin({
|
|
3214
|
+
invoice: decodedInvoice,
|
|
3215
|
+
amount: Number(bridgeOutTransfer.amount),
|
|
3216
|
+
assetId: utexoAsset.assetId,
|
|
3217
|
+
donation: true,
|
|
3218
|
+
...isWitness && {
|
|
3219
|
+
witnessData: {
|
|
3220
|
+
amountSat: 1e3,
|
|
3221
|
+
blinding: 0
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3224
|
+
});
|
|
3225
|
+
return psbt;
|
|
3226
|
+
}
|
|
3227
|
+
// TODO: Implement remaining methods as needed:
|
|
3228
|
+
// - createLightningInvoice() - will use utexoRGBWallet
|
|
3229
|
+
// - getLightningReceiveRequest() - will use utexoRGBWallet
|
|
3230
|
+
// - getLightningSendRequest() - will use utexoRGBWallet
|
|
3231
|
+
// - getLightningSendFeeEstimate() - will use utexoRGBWallet
|
|
3232
|
+
// - payLightningInvoiceBegin() - will use utexoRGBWallet
|
|
3233
|
+
// - payLightningInvoiceEnd() - will use utexoRGBWallet
|
|
3234
|
+
// - onchainSendBegin() - will use layer1RGBWallet or utexoRGBWallet
|
|
3235
|
+
// - onchainSendEnd() - will use layer1RGBWallet or utexoRGBWallet
|
|
3236
|
+
// - getOnchainSendStatus() - will use layer1RGBWallet or utexoRGBWallet
|
|
3237
|
+
// - listOnchainTransfers() - will use layer1RGBWallet or utexoRGBWallet
|
|
3238
|
+
// - listLightningPayments() - will use utexoRGBWallet
|
|
3239
|
+
};
|
|
1764
3240
|
|
|
1765
3241
|
// src/utils/logger.ts
|
|
1766
3242
|
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
@@ -1825,6 +3301,6 @@ function configureLogging(level) {
|
|
|
1825
3301
|
logger.setLevel(level);
|
|
1826
3302
|
}
|
|
1827
3303
|
|
|
1828
|
-
export {
|
|
3304
|
+
export { BIP32_VERSIONS, BadRequestError, COIN_BITCOIN_MAINNET, COIN_BITCOIN_TESTNET, COIN_RGB_MAINNET, COIN_RGB_TESTNET, ConfigurationError, ConflictError, CryptoError, DEFAULT_API_TIMEOUT, DEFAULT_LOG_LEVEL, DEFAULT_MAX_RETRIES, DEFAULT_NETWORK, DEFAULT_VSS_SERVER_URL, DERIVATION_ACCOUNT, DERIVATION_PURPOSE, KEYCHAIN_BTC, KEYCHAIN_RGB, LightningProtocol, LogLevel, NETWORK_MAP, NetworkError, NotFoundError, OnchainProtocol, RgbNodeError, SDKError, UTEXOProtocol, UTEXOWallet, ValidationError, WalletError, WalletManager, accountXpubsFromMnemonic, configureLogging, createWallet, createWalletManager, deriveKeysFromMnemonic, deriveKeysFromMnemonicOrSeed, deriveKeysFromSeed, deriveKeysFromXpriv, deriveVssSigningKeyFromMnemonic, generateKeys2 as generateKeys, getDestinationAsset, getEnvironment, getUtxoNetworkConfig, getXprivFromMnemonic, getXpubFromXpriv, isBrowser, isNode, logger, normalizeNetwork, restoreFromBackup, restoreFromVss, restoreKeys, restoreUtxoWalletFromBackup, restoreUtxoWalletFromVss, signMessage, signPsbt, signPsbtFromSeed, signPsbtSync, utexoNetworkIdMap, utexoNetworkMap, validateBase64, validateHex, validateMnemonic, validateNetwork, validatePsbt, validateRequired, validateString, verifyMessage, wallet };
|
|
1829
3305
|
//# sourceMappingURL=index.mjs.map
|
|
1830
3306
|
//# sourceMappingURL=index.mjs.map
|