@arkade-os/sdk 0.4.44 → 0.4.46
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 +35 -0
- package/dist/adapters/expo.cjs +5 -5
- package/dist/adapters/expo.d.cts +2 -2
- package/dist/adapters/expo.d.ts +2 -2
- package/dist/adapters/expo.js +3 -3
- package/dist/adapters/indexedDB.cjs +5 -5
- package/dist/adapters/indexedDB.js +4 -4
- package/dist/{ark-I8jfe5VE.d.cts → ark-C9ognsOV.d.cts} +94 -2
- package/dist/{ark-I8jfe5VE.d.ts → ark-C9ognsOV.d.ts} +94 -2
- package/dist/{asyncStorageTaskQueue-BtSOVZFn.d.ts → asyncStorageTaskQueue-BAKZ5cS5.d.ts} +2 -2
- package/dist/{asyncStorageTaskQueue-Dap7qUlF.d.cts → asyncStorageTaskQueue-CmBYVlxw.d.cts} +2 -2
- package/dist/{chunk-32YKLQPS.cjs → chunk-4KXOCVXP.cjs} +32 -29
- package/dist/chunk-4KXOCVXP.cjs.map +1 -0
- package/dist/{chunk-RJ6XVCX4.cjs → chunk-6TQJOD72.cjs} +7 -7
- package/dist/{chunk-RJ6XVCX4.cjs.map → chunk-6TQJOD72.cjs.map} +1 -1
- package/dist/{chunk-UBYY2TPK.cjs → chunk-7IYIFMF4.cjs} +178 -79
- package/dist/chunk-7IYIFMF4.cjs.map +1 -0
- package/dist/{chunk-LJ35HPJW.js → chunk-CWJ7ZCP7.js} +171 -75
- package/dist/chunk-CWJ7ZCP7.js.map +1 -0
- package/dist/{chunk-XIVCG6EP.cjs → chunk-D46YDM36.cjs} +1173 -425
- package/dist/chunk-D46YDM36.cjs.map +1 -0
- package/dist/{chunk-BE5MUB7T.js → chunk-FWG4TSPN.js} +7 -2
- package/dist/chunk-FWG4TSPN.js.map +1 -0
- package/dist/{chunk-V7WIZR2B.js → chunk-JTCQ6QXQ.js} +4 -4
- package/dist/{chunk-V7WIZR2B.js.map → chunk-JTCQ6QXQ.js.map} +1 -1
- package/dist/{chunk-HXDZ2QTW.cjs → chunk-MQB5H4X5.cjs} +7 -2
- package/dist/chunk-MQB5H4X5.cjs.map +1 -0
- package/dist/{chunk-FMI2GKYO.js → chunk-P6VBP3CT.js} +977 -231
- package/dist/chunk-P6VBP3CT.js.map +1 -0
- package/dist/{chunk-YNEDJTX2.js → chunk-QKC2T54O.js} +6 -3
- package/dist/chunk-QKC2T54O.js.map +1 -0
- package/dist/{chunk-LCQQPOIT.js → chunk-R2SVAM5Q.js} +3 -3
- package/dist/{chunk-LCQQPOIT.js.map → chunk-R2SVAM5Q.js.map} +1 -1
- package/dist/{chunk-X37EKDIH.cjs → chunk-SOXGAA52.cjs} +14 -14
- package/dist/{chunk-X37EKDIH.cjs.map → chunk-SOXGAA52.cjs.map} +1 -1
- package/dist/contracts/handlers/index.cjs +7 -7
- package/dist/contracts/handlers/index.d.cts +3 -3
- package/dist/contracts/handlers/index.d.ts +3 -3
- package/dist/contracts/handlers/index.js +2 -2
- package/dist/{delegate-BRqbh2fW.d.cts → delegate-DVEgyRwI.d.cts} +1 -1
- package/dist/{delegate-CgjVjYOP.d.ts → delegate-aOd5qINr.d.ts} +1 -1
- package/dist/{index-DvWNB_rl.d.ts → index-CPzL4tqg.d.ts} +2 -2
- package/dist/{index-DHuXlDEg.d.cts → index-D8vmtWWO.d.cts} +2 -2
- package/dist/index.cjs +176 -156
- package/dist/index.d.cts +45 -20
- package/dist/index.d.ts +45 -20
- package/dist/index.js +4 -4
- package/dist/repositories/realm/index.cjs +23 -19
- package/dist/repositories/realm/index.cjs.map +1 -1
- package/dist/repositories/realm/index.d.cts +2 -2
- package/dist/repositories/realm/index.d.ts +2 -2
- package/dist/repositories/realm/index.js +9 -5
- package/dist/repositories/realm/index.js.map +1 -1
- package/dist/repositories/sqlite/index.cjs +22 -18
- package/dist/repositories/sqlite/index.cjs.map +1 -1
- package/dist/repositories/sqlite/index.d.cts +2 -2
- package/dist/repositories/sqlite/index.d.ts +2 -2
- package/dist/repositories/sqlite/index.js +9 -5
- package/dist/repositories/sqlite/index.js.map +1 -1
- package/dist/{taskRunner-Bptw9UMa.d.ts → taskRunner-B48-V-Pb.d.ts} +2 -2
- package/dist/{taskRunner-CeFxKhSH.d.cts → taskRunner-nNecmQ2C.d.cts} +2 -2
- package/dist/wallet/expo/background.cjs +14 -14
- package/dist/wallet/expo/background.d.cts +3 -3
- package/dist/wallet/expo/background.d.ts +3 -3
- package/dist/wallet/expo/background.js +6 -6
- package/dist/wallet/expo/index.cjs +27 -14
- package/dist/wallet/expo/index.cjs.map +1 -1
- package/dist/wallet/expo/index.d.cts +11 -4
- package/dist/wallet/expo/index.d.ts +11 -4
- package/dist/wallet/expo/index.js +18 -5
- package/dist/wallet/expo/index.js.map +1 -1
- package/dist/{wallet-BsqRU8KM.d.cts → wallet-BUg3D4WJ.d.cts} +139 -3
- package/dist/{wallet-D9z7wssl.d.ts → wallet-DM0oShTu.d.ts} +139 -3
- package/dist/worker/expo/index.cjs +10 -9
- package/dist/worker/expo/index.cjs.map +1 -1
- package/dist/worker/expo/index.d.cts +4 -4
- package/dist/worker/expo/index.d.ts +4 -4
- package/dist/worker/expo/index.js +6 -5
- package/dist/worker/expo/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-32YKLQPS.cjs.map +0 -1
- package/dist/chunk-BE5MUB7T.js.map +0 -1
- package/dist/chunk-FMI2GKYO.js.map +0 -1
- package/dist/chunk-HXDZ2QTW.cjs.map +0 -1
- package/dist/chunk-LJ35HPJW.js.map +0 -1
- package/dist/chunk-UBYY2TPK.cjs.map +0 -1
- package/dist/chunk-XIVCG6EP.cjs.map +0 -1
- package/dist/chunk-YNEDJTX2.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunk7IYIFMF4_cjs = require('./chunk-7IYIFMF4.cjs');
|
|
4
|
+
var chunk4KXOCVXP_cjs = require('./chunk-4KXOCVXP.cjs');
|
|
5
|
+
var chunkMQB5H4X5_cjs = require('./chunk-MQB5H4X5.cjs');
|
|
6
6
|
var utils_js = require('@scure/btc-signer/utils.js');
|
|
7
7
|
var btcSigner = require('@scure/btc-signer');
|
|
8
8
|
var base = require('@scure/base');
|
|
@@ -84,6 +84,8 @@ var PartialSig = class _PartialSig {
|
|
|
84
84
|
throw new PartialSignatureError("Invalid R length");
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
+
s;
|
|
88
|
+
R;
|
|
87
89
|
/**
|
|
88
90
|
* Encodes the partial signature into bytes
|
|
89
91
|
* Returns a 32-byte array containing just the s value
|
|
@@ -133,6 +135,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
133
135
|
constructor(secretKey) {
|
|
134
136
|
this.secretKey = secretKey;
|
|
135
137
|
}
|
|
138
|
+
secretKey;
|
|
136
139
|
static NOT_INITIALIZED = new Error("session not initialized, call init method");
|
|
137
140
|
myNonces = null;
|
|
138
141
|
aggregateNonces = null;
|
|
@@ -181,7 +184,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
181
184
|
noncesByPubkey.set(base.hex.encode(myPublicKey.subarray(1)), myNonce);
|
|
182
185
|
const tx = this.graph.find(txid);
|
|
183
186
|
if (!tx) throw new Error(`missing tx for txid ${txid}`);
|
|
184
|
-
const cosigners =
|
|
187
|
+
const cosigners = chunk7IYIFMF4_cjs.getArkPsbtFields(tx.root, 0, chunk7IYIFMF4_cjs.CosignerPublicKey).map(
|
|
185
188
|
(c) => base.hex.encode(c.key.subarray(1))
|
|
186
189
|
// xonly pubkey
|
|
187
190
|
);
|
|
@@ -233,7 +236,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
233
236
|
if (!aggNonce) throw new Error("missing aggregate nonce");
|
|
234
237
|
const prevoutAmounts = [];
|
|
235
238
|
const prevoutScripts = [];
|
|
236
|
-
const cosigners =
|
|
239
|
+
const cosigners = chunk7IYIFMF4_cjs.getArkPsbtFields(g.root, 0, chunk7IYIFMF4_cjs.CosignerPublicKey).map((c) => c.key);
|
|
237
240
|
const { finalKey } = aggregateKeys(cosigners, true, {
|
|
238
241
|
taprootTweak: this.scriptRoot
|
|
239
242
|
});
|
|
@@ -359,6 +362,7 @@ var ReadonlySingleKey = class _ReadonlySingleKey {
|
|
|
359
362
|
throw new Error("Invalid public key length");
|
|
360
363
|
}
|
|
361
364
|
}
|
|
365
|
+
publicKey;
|
|
362
366
|
/**
|
|
363
367
|
* Create a ReadonlySingleKey from a compressed public key.
|
|
364
368
|
*
|
|
@@ -411,7 +415,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
411
415
|
let network;
|
|
412
416
|
if ("descriptor" in opts && typeof opts.descriptor === "string") {
|
|
413
417
|
descriptor = opts.descriptor;
|
|
414
|
-
network =
|
|
418
|
+
network = chunk4KXOCVXP_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
415
419
|
} else {
|
|
416
420
|
network = opts.isMainnet ?? true ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
417
421
|
descriptor = descriptorsScure.scriptExpressions.trBIP32({
|
|
@@ -496,7 +500,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
496
500
|
* `StaticDescriptorProvider` for legacy single-key wallets.
|
|
497
501
|
*/
|
|
498
502
|
isOurs(descriptor) {
|
|
499
|
-
return
|
|
503
|
+
return chunk4KXOCVXP_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
|
|
500
504
|
}
|
|
501
505
|
/**
|
|
502
506
|
* Signs each request with the key derived from its descriptor.
|
|
@@ -533,7 +537,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
533
537
|
}
|
|
534
538
|
// ── internal helpers ─────────────────────────────────────────────
|
|
535
539
|
derivePrivateKeyForDescriptor(descriptor) {
|
|
536
|
-
const network =
|
|
540
|
+
const network = chunk4KXOCVXP_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
537
541
|
const expansion = descriptorsScure.expand({ descriptor, network });
|
|
538
542
|
if (expansion.isRanged) {
|
|
539
543
|
throw new Error(
|
|
@@ -619,7 +623,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
|
|
|
619
623
|
*/
|
|
620
624
|
descriptor;
|
|
621
625
|
constructor(descriptor) {
|
|
622
|
-
const network =
|
|
626
|
+
const network = chunk4KXOCVXP_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
623
627
|
let expansion;
|
|
624
628
|
try {
|
|
625
629
|
expansion = descriptorsScure.expand({ descriptor, network, index: 0 });
|
|
@@ -669,7 +673,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
|
|
|
669
673
|
* `StaticDescriptorProvider` for legacy single-key wallets.
|
|
670
674
|
*/
|
|
671
675
|
isOurs(descriptor) {
|
|
672
|
-
return
|
|
676
|
+
return chunk4KXOCVXP_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
|
|
673
677
|
}
|
|
674
678
|
};
|
|
675
679
|
function serializeSeedOwnedSigningIdentity(identity) {
|
|
@@ -970,6 +974,7 @@ var RestDelegateProvider = class {
|
|
|
970
974
|
constructor(url) {
|
|
971
975
|
this.url = url;
|
|
972
976
|
}
|
|
977
|
+
url;
|
|
973
978
|
/**
|
|
974
979
|
* Submit a delegation request to the remote delegation service.
|
|
975
980
|
*
|
|
@@ -980,14 +985,14 @@ var RestDelegateProvider = class {
|
|
|
980
985
|
*/
|
|
981
986
|
async delegate(intent, forfeitTxs, options) {
|
|
982
987
|
const url = `${this.url}/v1/delegate`;
|
|
983
|
-
const response = await
|
|
988
|
+
const response = await chunk7IYIFMF4_cjs.baseFetch(url, {
|
|
984
989
|
method: "POST",
|
|
985
990
|
headers: {
|
|
986
991
|
"Content-Type": "application/json"
|
|
987
992
|
},
|
|
988
993
|
body: JSON.stringify({
|
|
989
994
|
intent: {
|
|
990
|
-
message:
|
|
995
|
+
message: chunk7IYIFMF4_cjs.Intent.encodeMessage(intent.message),
|
|
991
996
|
proof: intent.proof
|
|
992
997
|
},
|
|
993
998
|
forfeit_txs: forfeitTxs,
|
|
@@ -1007,7 +1012,7 @@ var RestDelegateProvider = class {
|
|
|
1007
1012
|
*/
|
|
1008
1013
|
async getDelegateInfo() {
|
|
1009
1014
|
const url = `${this.url}/v1/delegator/info`;
|
|
1010
|
-
const response = await
|
|
1015
|
+
const response = await chunk7IYIFMF4_cjs.baseFetch(url);
|
|
1011
1016
|
if (!response.ok) {
|
|
1012
1017
|
const errorText2 = await response.text();
|
|
1013
1018
|
throw new Error(`Failed to get delegate info: ${errorText2}`);
|
|
@@ -1034,22 +1039,23 @@ var ESPLORA_URL = {
|
|
|
1034
1039
|
regtest: "http://localhost:3000/api"
|
|
1035
1040
|
};
|
|
1036
1041
|
var EsploraProvider = class {
|
|
1037
|
-
constructor(baseUrl = ESPLORA_URL[
|
|
1042
|
+
constructor(baseUrl = ESPLORA_URL[chunkMQB5H4X5_cjs.DEFAULT_NETWORK_NAME], opts) {
|
|
1038
1043
|
this.baseUrl = baseUrl;
|
|
1039
1044
|
this.pollingInterval = opts?.pollingInterval ?? 15e3;
|
|
1040
1045
|
this.forcePolling = opts?.forcePolling ?? false;
|
|
1041
1046
|
}
|
|
1047
|
+
baseUrl;
|
|
1042
1048
|
pollingInterval;
|
|
1043
1049
|
forcePolling;
|
|
1044
1050
|
async getCoins(address) {
|
|
1045
|
-
const response = await
|
|
1051
|
+
const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
|
|
1046
1052
|
if (!response.ok) {
|
|
1047
1053
|
throw new Error(`Failed to fetch UTXOs: ${response.statusText}`);
|
|
1048
1054
|
}
|
|
1049
1055
|
return response.json();
|
|
1050
1056
|
}
|
|
1051
1057
|
async getFeeRate() {
|
|
1052
|
-
const response = await
|
|
1058
|
+
const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/fee-estimates`);
|
|
1053
1059
|
if (response.status === 404) {
|
|
1054
1060
|
return void 0;
|
|
1055
1061
|
}
|
|
@@ -1070,7 +1076,7 @@ var EsploraProvider = class {
|
|
|
1070
1076
|
}
|
|
1071
1077
|
}
|
|
1072
1078
|
async getTxOutspends(txid) {
|
|
1073
|
-
const response = await
|
|
1079
|
+
const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
|
|
1074
1080
|
if (!response.ok) {
|
|
1075
1081
|
const error = await response.text();
|
|
1076
1082
|
throw new Error(`Failed to get transaction outspends: ${error}`);
|
|
@@ -1078,7 +1084,7 @@ var EsploraProvider = class {
|
|
|
1078
1084
|
return response.json();
|
|
1079
1085
|
}
|
|
1080
1086
|
async getTransactions(address) {
|
|
1081
|
-
const response = await
|
|
1087
|
+
const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
|
|
1082
1088
|
if (!response.ok) {
|
|
1083
1089
|
const error = await response.text();
|
|
1084
1090
|
throw new Error(`Failed to get transactions: ${error}`);
|
|
@@ -1086,7 +1092,7 @@ var EsploraProvider = class {
|
|
|
1086
1092
|
return response.json();
|
|
1087
1093
|
}
|
|
1088
1094
|
async getTxStatus(txid) {
|
|
1089
|
-
const txresponse = await
|
|
1095
|
+
const txresponse = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
|
|
1090
1096
|
if (!txresponse.ok) {
|
|
1091
1097
|
throw new Error(txresponse.statusText);
|
|
1092
1098
|
}
|
|
@@ -1094,7 +1100,7 @@ var EsploraProvider = class {
|
|
|
1094
1100
|
if (!tx.status.confirmed) {
|
|
1095
1101
|
return { confirmed: false };
|
|
1096
1102
|
}
|
|
1097
|
-
const response = await
|
|
1103
|
+
const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
|
|
1098
1104
|
if (!response.ok) {
|
|
1099
1105
|
throw new Error(`Failed to get transaction status: ${response.statusText}`);
|
|
1100
1106
|
}
|
|
@@ -1178,7 +1184,7 @@ var EsploraProvider = class {
|
|
|
1178
1184
|
return stopFunc;
|
|
1179
1185
|
}
|
|
1180
1186
|
async getChainTip() {
|
|
1181
|
-
const tipBlocks = await
|
|
1187
|
+
const tipBlocks = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/blocks`);
|
|
1182
1188
|
if (!tipBlocks.ok) {
|
|
1183
1189
|
throw new Error(`Failed to get chain tip: ${tipBlocks.statusText}`);
|
|
1184
1190
|
}
|
|
@@ -1197,7 +1203,7 @@ var EsploraProvider = class {
|
|
|
1197
1203
|
};
|
|
1198
1204
|
}
|
|
1199
1205
|
async broadcastPackage(parent, child) {
|
|
1200
|
-
const response = await
|
|
1206
|
+
const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
|
|
1201
1207
|
method: "POST",
|
|
1202
1208
|
headers: {
|
|
1203
1209
|
"Content-Type": "application/json"
|
|
@@ -1211,7 +1217,7 @@ var EsploraProvider = class {
|
|
|
1211
1217
|
return response.json();
|
|
1212
1218
|
}
|
|
1213
1219
|
async broadcastTx(tx) {
|
|
1214
|
-
const response = await
|
|
1220
|
+
const response = await chunk7IYIFMF4_cjs.baseFetch(`${this.baseUrl}/tx`, {
|
|
1215
1221
|
method: "POST",
|
|
1216
1222
|
headers: {
|
|
1217
1223
|
"Content-Type": "text/plain"
|
|
@@ -1373,7 +1379,7 @@ function findP2AOutput(tx) {
|
|
|
1373
1379
|
var CHILD_DUST_AMOUNT = 546;
|
|
1374
1380
|
function buildAnchorChild(params) {
|
|
1375
1381
|
const { parent, feeRate, fundingCoins, changeAddress, tapInternalKey, network } = params;
|
|
1376
|
-
const child = new
|
|
1382
|
+
const child = new chunk7IYIFMF4_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
|
|
1377
1383
|
child.addInput(findP2AOutput(parent));
|
|
1378
1384
|
const estimator = TxWeightEstimator.create().addP2AInput();
|
|
1379
1385
|
for (const _ of fundingCoins) {
|
|
@@ -1421,7 +1427,7 @@ function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
|
|
|
1421
1427
|
);
|
|
1422
1428
|
}
|
|
1423
1429
|
function buildForfeitTxWithOutput(inputs, output, txLocktime) {
|
|
1424
|
-
const tx = new
|
|
1430
|
+
const tx = new chunk7IYIFMF4_cjs.Transaction({
|
|
1425
1431
|
version: 3,
|
|
1426
1432
|
lockTime: txLocktime
|
|
1427
1433
|
});
|
|
@@ -1497,7 +1503,7 @@ function validateVtxoTxGraph(graph, roundTransaction, sweepTapTreeRoot) {
|
|
|
1497
1503
|
if (previousScriptKey.length !== 32) {
|
|
1498
1504
|
throw new Error(`parent output ${childIndex} has invalid script`);
|
|
1499
1505
|
}
|
|
1500
|
-
const cosigners =
|
|
1506
|
+
const cosigners = chunk7IYIFMF4_cjs.getArkPsbtFields(child.root, 0, chunk7IYIFMF4_cjs.CosignerPublicKey);
|
|
1501
1507
|
if (cosigners.length === 0) {
|
|
1502
1508
|
throw ErrMissingCosignersPublicKeys;
|
|
1503
1509
|
}
|
|
@@ -1518,6 +1524,8 @@ var UnknownPacket = class {
|
|
|
1518
1524
|
this.packetType = packetType;
|
|
1519
1525
|
this.data = data;
|
|
1520
1526
|
}
|
|
1527
|
+
packetType;
|
|
1528
|
+
data;
|
|
1521
1529
|
type() {
|
|
1522
1530
|
return this.packetType;
|
|
1523
1531
|
}
|
|
@@ -1538,6 +1546,7 @@ var Extension = class _Extension {
|
|
|
1538
1546
|
constructor(packets) {
|
|
1539
1547
|
this.packets = packets;
|
|
1540
1548
|
}
|
|
1549
|
+
packets;
|
|
1541
1550
|
static create(packets) {
|
|
1542
1551
|
if (packets.length === 0) {
|
|
1543
1552
|
throw new Error("missing packets");
|
|
@@ -1597,7 +1606,7 @@ var Extension = class _Extension {
|
|
|
1597
1606
|
`expected magic prefix ${base.hex.encode(ARKADE_MAGIC)}, got ${base.hex.encode(payload.slice(0, Math.min(payload.length, ARKADE_MAGIC.length)))}`
|
|
1598
1607
|
);
|
|
1599
1608
|
}
|
|
1600
|
-
const reader = new
|
|
1609
|
+
const reader = new chunk7IYIFMF4_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
|
|
1601
1610
|
const packets = [];
|
|
1602
1611
|
while (reader.remaining() > 0) {
|
|
1603
1612
|
const packetType = reader.readByte();
|
|
@@ -1671,7 +1680,7 @@ var Extension = class _Extension {
|
|
|
1671
1680
|
*/
|
|
1672
1681
|
getAssetPacket() {
|
|
1673
1682
|
for (const p of this.packets) {
|
|
1674
|
-
if (p instanceof
|
|
1683
|
+
if (p instanceof chunk7IYIFMF4_cjs.Packet) {
|
|
1675
1684
|
return p;
|
|
1676
1685
|
}
|
|
1677
1686
|
}
|
|
@@ -1679,8 +1688,8 @@ var Extension = class _Extension {
|
|
|
1679
1688
|
}
|
|
1680
1689
|
};
|
|
1681
1690
|
function parsePacket(packetType, data) {
|
|
1682
|
-
if (packetType ===
|
|
1683
|
-
return
|
|
1691
|
+
if (packetType === chunk7IYIFMF4_cjs.Packet.PACKET_TYPE) {
|
|
1692
|
+
return chunk7IYIFMF4_cjs.Packet.fromBytes(data);
|
|
1684
1693
|
}
|
|
1685
1694
|
return new UnknownPacket(packetType, data);
|
|
1686
1695
|
}
|
|
@@ -1738,7 +1747,7 @@ function validateBatchRecipients(commitmentTx, vtxoTreeLeaves, recipients, netwo
|
|
|
1738
1747
|
for (const recipient of recipients) {
|
|
1739
1748
|
let arkAddress;
|
|
1740
1749
|
try {
|
|
1741
|
-
arkAddress =
|
|
1750
|
+
arkAddress = chunkMQB5H4X5_cjs.ArkAddress.decode(recipient.address);
|
|
1742
1751
|
} catch {
|
|
1743
1752
|
validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
|
|
1744
1753
|
continue;
|
|
@@ -1976,6 +1985,7 @@ function isExpired(vtxo) {
|
|
|
1976
1985
|
return expiry <= Date.now();
|
|
1977
1986
|
}
|
|
1978
1987
|
function isSubdust(vtxo, dust) {
|
|
1988
|
+
if (typeof vtxo === "bigint") return vtxo < dust;
|
|
1979
1989
|
return vtxo.value < dust;
|
|
1980
1990
|
}
|
|
1981
1991
|
|
|
@@ -1987,7 +1997,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
1987
1997
|
const existing = inputsByAssetId.get(asset.assetId);
|
|
1988
1998
|
inputsByAssetId.set(asset.assetId, [
|
|
1989
1999
|
...existing ?? [],
|
|
1990
|
-
|
|
2000
|
+
chunk7IYIFMF4_cjs.AssetInput.create(inputIndex, asset.amount)
|
|
1991
2001
|
]);
|
|
1992
2002
|
}
|
|
1993
2003
|
}
|
|
@@ -1999,7 +2009,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
1999
2009
|
const existing = outputsByAssetId.get(asset.assetId);
|
|
2000
2010
|
outputsByAssetId.set(asset.assetId, [
|
|
2001
2011
|
...existing ?? [],
|
|
2002
|
-
|
|
2012
|
+
chunk7IYIFMF4_cjs.AssetOutput.create(outputIndex, asset.amount)
|
|
2003
2013
|
]);
|
|
2004
2014
|
}
|
|
2005
2015
|
}
|
|
@@ -2010,7 +2020,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
2010
2020
|
const existing = outputsByAssetId.get(asset.assetId);
|
|
2011
2021
|
outputsByAssetId.set(asset.assetId, [
|
|
2012
2022
|
...existing ?? [],
|
|
2013
|
-
|
|
2023
|
+
chunk7IYIFMF4_cjs.AssetOutput.create(outputIndex, asset.amount)
|
|
2014
2024
|
]);
|
|
2015
2025
|
}
|
|
2016
2026
|
}
|
|
@@ -2019,11 +2029,11 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
2019
2029
|
for (const assetIdStr of allAssetIds) {
|
|
2020
2030
|
const inputs = inputsByAssetId.get(assetIdStr);
|
|
2021
2031
|
const outputs = outputsByAssetId.get(assetIdStr);
|
|
2022
|
-
const assetId =
|
|
2023
|
-
const group =
|
|
2032
|
+
const assetId = chunk7IYIFMF4_cjs.AssetId.fromString(assetIdStr);
|
|
2033
|
+
const group = chunk7IYIFMF4_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
|
|
2024
2034
|
groups.push(group);
|
|
2025
2035
|
}
|
|
2026
|
-
return
|
|
2036
|
+
return chunk7IYIFMF4_cjs.Packet.create(groups);
|
|
2027
2037
|
}
|
|
2028
2038
|
function selectCoinsWithAsset(coins, assetId, requiredAmount) {
|
|
2029
2039
|
const coinsWithAsset = coins.filter((coin) => coin.assets?.some((a) => a.assetId === assetId));
|
|
@@ -2128,8 +2138,8 @@ function buildOffchainTx(inputs, outputs, serverUnrollScript) {
|
|
|
2128
2138
|
function buildVirtualTx(inputs, outputs) {
|
|
2129
2139
|
let lockTime = 0n;
|
|
2130
2140
|
for (const input of inputs) {
|
|
2131
|
-
const tapscript =
|
|
2132
|
-
if (
|
|
2141
|
+
const tapscript = chunkMQB5H4X5_cjs.decodeTapscript(chunkMQB5H4X5_cjs.scriptFromTapLeafScript(input.tapLeafScript));
|
|
2142
|
+
if (chunkMQB5H4X5_cjs.CLTVMultisigTapscript.is(tapscript)) {
|
|
2133
2143
|
if (lockTime !== 0n) {
|
|
2134
2144
|
if (isSeconds(lockTime) !== isSeconds(tapscript.params.absoluteTimelock)) {
|
|
2135
2145
|
throw new Error("cannot mix seconds and blocks locktime");
|
|
@@ -2140,7 +2150,7 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
2140
2150
|
}
|
|
2141
2151
|
}
|
|
2142
2152
|
}
|
|
2143
|
-
const tx = new
|
|
2153
|
+
const tx = new chunk7IYIFMF4_cjs.Transaction({
|
|
2144
2154
|
version: 3,
|
|
2145
2155
|
lockTime: Number(lockTime)
|
|
2146
2156
|
});
|
|
@@ -2150,12 +2160,12 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
2150
2160
|
index: input.vout,
|
|
2151
2161
|
sequence: lockTime ? btcSigner.DEFAULT_SEQUENCE - 1 : void 0,
|
|
2152
2162
|
witnessUtxo: {
|
|
2153
|
-
script:
|
|
2163
|
+
script: chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).pkScript,
|
|
2154
2164
|
amount: BigInt(input.value)
|
|
2155
2165
|
},
|
|
2156
2166
|
tapLeafScript: [input.tapLeafScript]
|
|
2157
2167
|
});
|
|
2158
|
-
|
|
2168
|
+
chunk7IYIFMF4_cjs.setArkPsbtField(tx, i, chunk7IYIFMF4_cjs.VtxoTaprootTree, input.tapTree);
|
|
2159
2169
|
}
|
|
2160
2170
|
for (const output of outputs) {
|
|
2161
2171
|
tx.addOutput(output);
|
|
@@ -2164,8 +2174,8 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
2164
2174
|
return tx;
|
|
2165
2175
|
}
|
|
2166
2176
|
function buildCheckpointTx(vtxo, serverUnrollScript) {
|
|
2167
|
-
const collaborativeClosure =
|
|
2168
|
-
const checkpointVtxoScript = new
|
|
2177
|
+
const collaborativeClosure = chunkMQB5H4X5_cjs.decodeTapscript(chunkMQB5H4X5_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
|
|
2178
|
+
const checkpointVtxoScript = new chunkMQB5H4X5_cjs.VtxoScript([
|
|
2169
2179
|
serverUnrollScript.script,
|
|
2170
2180
|
collaborativeClosure.script
|
|
2171
2181
|
]);
|
|
@@ -2309,7 +2319,7 @@ function combineTapscriptSigs(signedTx, originalTx) {
|
|
|
2309
2319
|
}
|
|
2310
2320
|
function isValidArkAddress(address) {
|
|
2311
2321
|
try {
|
|
2312
|
-
|
|
2322
|
+
chunkMQB5H4X5_cjs.ArkAddress.decode(address);
|
|
2313
2323
|
return true;
|
|
2314
2324
|
} catch (e) {
|
|
2315
2325
|
return false;
|
|
@@ -2334,6 +2344,7 @@ var FeeAmount = class _FeeAmount {
|
|
|
2334
2344
|
constructor(value) {
|
|
2335
2345
|
this.value = value;
|
|
2336
2346
|
}
|
|
2347
|
+
value;
|
|
2337
2348
|
static ZERO = new _FeeAmount(0);
|
|
2338
2349
|
/** Returns the fee amount rounded up to whole satoshis. */
|
|
2339
2350
|
get satoshis() {
|
|
@@ -2358,6 +2369,7 @@ var Estimator = class {
|
|
|
2358
2369
|
this.intentOffchainOutput = config.offchainOutput ? parseProgram(config.offchainOutput, IntentOutputEnv) : void 0;
|
|
2359
2370
|
this.intentOnchainOutput = config.onchainOutput ? parseProgram(config.onchainOutput, IntentOutputEnv) : void 0;
|
|
2360
2371
|
}
|
|
2372
|
+
config;
|
|
2361
2373
|
intentOffchainInput;
|
|
2362
2374
|
intentOnchainInput;
|
|
2363
2375
|
intentOffchainOutput;
|
|
@@ -2482,7 +2494,7 @@ function extendCoinWithTapscript(boardingTapscript, utxo) {
|
|
|
2482
2494
|
};
|
|
2483
2495
|
}
|
|
2484
2496
|
function deriveContractTapscripts(contract) {
|
|
2485
|
-
const handler =
|
|
2497
|
+
const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
|
|
2486
2498
|
if (!handler) {
|
|
2487
2499
|
throw new Error(`No handler for contract type '${contract.type}'`);
|
|
2488
2500
|
}
|
|
@@ -2552,7 +2564,7 @@ function validateRecipients(recipients, dustAmount) {
|
|
|
2552
2564
|
for (const recipient of recipients) {
|
|
2553
2565
|
let address;
|
|
2554
2566
|
try {
|
|
2555
|
-
address =
|
|
2567
|
+
address = chunkMQB5H4X5_cjs.ArkAddress.decode(recipient.address);
|
|
2556
2568
|
} catch (e) {
|
|
2557
2569
|
throw new Error(`Invalid Arkade address: ${recipient.address}`);
|
|
2558
2570
|
}
|
|
@@ -2760,6 +2772,8 @@ var VtxoManager = class _VtxoManager {
|
|
|
2760
2772
|
}
|
|
2761
2773
|
this.contractEventsSubscriptionReady = this.initializeSubscription();
|
|
2762
2774
|
}
|
|
2775
|
+
wallet;
|
|
2776
|
+
renewalConfig;
|
|
2763
2777
|
settlementConfig;
|
|
2764
2778
|
contractEventsSubscriptionReady;
|
|
2765
2779
|
disposePromise;
|
|
@@ -3157,11 +3171,11 @@ var VtxoManager = class _VtxoManager {
|
|
|
3157
3171
|
`Sweep not economical: output ${outputAmount} sats after ${fee} sats fee is below dust (${dustAmount} sats)`
|
|
3158
3172
|
);
|
|
3159
3173
|
}
|
|
3160
|
-
const tx = new
|
|
3174
|
+
const tx = new chunk7IYIFMF4_cjs.Transaction();
|
|
3161
3175
|
for (const utxo of expiredUtxos) {
|
|
3162
|
-
const utxoScript =
|
|
3176
|
+
const utxoScript = chunkMQB5H4X5_cjs.VtxoScript.decode(utxo.tapTree);
|
|
3163
3177
|
const utxoExitLeaf = utxoScript.leaves.find(
|
|
3164
|
-
(leaf) =>
|
|
3178
|
+
(leaf) => chunkMQB5H4X5_cjs.CSVMultisigTapscript.isScriptValid(chunkMQB5H4X5_cjs.scriptFromTapLeafScript(leaf)) === true
|
|
3165
3179
|
);
|
|
3166
3180
|
if (!utxoExitLeaf) {
|
|
3167
3181
|
throw new Error(
|
|
@@ -3176,7 +3190,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
3176
3190
|
amount: BigInt(utxo.value)
|
|
3177
3191
|
},
|
|
3178
3192
|
tapLeafScript: [utxoExitLeaf],
|
|
3179
|
-
sequence:
|
|
3193
|
+
sequence: chunkMQB5H4X5_cjs.getSequence(utxoExitLeaf)
|
|
3180
3194
|
});
|
|
3181
3195
|
}
|
|
3182
3196
|
tx.addOutputAddress(boardingAddress, outputAmount, this.getNetwork());
|
|
@@ -3665,7 +3679,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
3665
3679
|
/** Decodes the boarding tapscript exit path to extract the CSV timelock. */
|
|
3666
3680
|
getBoardingTimelock() {
|
|
3667
3681
|
const wallet = this.getSweepWallet();
|
|
3668
|
-
const exitScript =
|
|
3682
|
+
const exitScript = chunkMQB5H4X5_cjs.CSVMultisigTapscript.decode(
|
|
3669
3683
|
base.hex.decode(wallet.boardingTapscript.exitScript)
|
|
3670
3684
|
);
|
|
3671
3685
|
return exitScript.params.timelock;
|
|
@@ -3796,8 +3810,8 @@ var VtxoManager = class _VtxoManager {
|
|
|
3796
3810
|
* or doesn't carry the metadata.
|
|
3797
3811
|
*/
|
|
3798
3812
|
extractSpentOutpoint(error) {
|
|
3799
|
-
const ark =
|
|
3800
|
-
if (!ark
|
|
3813
|
+
const ark = chunk7IYIFMF4_cjs.maybeArkError(error);
|
|
3814
|
+
if (!chunk7IYIFMF4_cjs.isArkError(ark, chunk7IYIFMF4_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
|
|
3801
3815
|
const raw = ark.metadata?.vtxo_outpoint;
|
|
3802
3816
|
if (typeof raw !== "string") return void 0;
|
|
3803
3817
|
const [txid, voutStr] = raw.split(":");
|
|
@@ -4011,7 +4025,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
4011
4025
|
const arkAddress = await this.wallet.getAddress();
|
|
4012
4026
|
const outputFee = estimator.evalOffchainOutput({
|
|
4013
4027
|
amount: totalAmount,
|
|
4014
|
-
script: base.hex.encode(
|
|
4028
|
+
script: base.hex.encode(chunkMQB5H4X5_cjs.ArkAddress.decode(arkAddress).pkScript)
|
|
4015
4029
|
});
|
|
4016
4030
|
totalAmount -= BigInt(outputFee.satoshis);
|
|
4017
4031
|
if (totalAmount < dustAmount) return;
|
|
@@ -4091,7 +4105,7 @@ var ArkNote = class _ArkNote {
|
|
|
4091
4105
|
this.value = value;
|
|
4092
4106
|
this.HRP = HRP;
|
|
4093
4107
|
const preimageHash = utils_js.sha256(this.preimage);
|
|
4094
|
-
this.vtxoScript = new
|
|
4108
|
+
this.vtxoScript = new chunkMQB5H4X5_cjs.VtxoScript([noteTapscript(preimageHash)]);
|
|
4095
4109
|
const leaf = this.vtxoScript.leaves[0];
|
|
4096
4110
|
this.txid = base.hex.encode(new Uint8Array(preimageHash).reverse());
|
|
4097
4111
|
this.tapTree = this.vtxoScript.encode();
|
|
@@ -4101,6 +4115,9 @@ var ArkNote = class _ArkNote {
|
|
|
4101
4115
|
this.status = { confirmed: true };
|
|
4102
4116
|
this.extraWitness = [this.preimage];
|
|
4103
4117
|
}
|
|
4118
|
+
preimage;
|
|
4119
|
+
value;
|
|
4120
|
+
HRP;
|
|
4104
4121
|
static DefaultHRP = "arknote";
|
|
4105
4122
|
static PreimageLength = 32;
|
|
4106
4123
|
// 32 bytes for the preimage
|
|
@@ -4309,11 +4326,603 @@ function wrapHandlerWithIntentPersistence(base, deps) {
|
|
|
4309
4326
|
}
|
|
4310
4327
|
};
|
|
4311
4328
|
}
|
|
4329
|
+
|
|
4330
|
+
// src/repositories/virtualTxRepository.ts
|
|
4331
|
+
var ChainedTxType = /* @__PURE__ */ ((ChainedTxType2) => {
|
|
4332
|
+
ChainedTxType2[ChainedTxType2["Unspecified"] = 0] = "Unspecified";
|
|
4333
|
+
ChainedTxType2[ChainedTxType2["Commitment"] = 1] = "Commitment";
|
|
4334
|
+
ChainedTxType2[ChainedTxType2["Ark"] = 2] = "Ark";
|
|
4335
|
+
ChainedTxType2[ChainedTxType2["Tree"] = 3] = "Tree";
|
|
4336
|
+
ChainedTxType2[ChainedTxType2["Checkpoint"] = 4] = "Checkpoint";
|
|
4337
|
+
return ChainedTxType2;
|
|
4338
|
+
})(ChainedTxType || {});
|
|
4339
|
+
function mergeChainedTxType(incoming, prev) {
|
|
4340
|
+
if (incoming !== 0 /* Unspecified */) return incoming;
|
|
4341
|
+
return prev ?? 0 /* Unspecified */;
|
|
4342
|
+
}
|
|
4343
|
+
|
|
4344
|
+
// src/wallet/exit/chain.ts
|
|
4345
|
+
var isCommitment = (t) => t === "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */ || t === "INDEXER_CHAINED_TX_TYPE_UNSPECIFIED" /* UNSPECIFIED */;
|
|
4346
|
+
async function buildExitDag(params) {
|
|
4347
|
+
const byTxid = /* @__PURE__ */ new Map();
|
|
4348
|
+
for (const vtxo of params.vtxos) {
|
|
4349
|
+
const outpoint = `${vtxo.txid}:${vtxo.vout}`;
|
|
4350
|
+
const chain = await params.chain.getVtxoChain({ txid: vtxo.txid, vout: vtxo.vout });
|
|
4351
|
+
for (const chainTx of chain) {
|
|
4352
|
+
const existing = byTxid.get(chainTx.txid);
|
|
4353
|
+
if (existing) {
|
|
4354
|
+
existing.forVtxos.add(outpoint);
|
|
4355
|
+
} else {
|
|
4356
|
+
byTxid.set(chainTx.txid, { ...chainTx, forVtxos: /* @__PURE__ */ new Set([outpoint]) });
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
}
|
|
4360
|
+
const pending = new Map(
|
|
4361
|
+
[...byTxid.values()].filter((tx) => !isCommitment(tx.type)).map((tx) => [tx.txid, tx])
|
|
4362
|
+
);
|
|
4363
|
+
const inDegree = /* @__PURE__ */ new Map();
|
|
4364
|
+
for (const tx of pending.values()) {
|
|
4365
|
+
const parents = tx.spends.filter((p) => pending.has(p));
|
|
4366
|
+
inDegree.set(tx.txid, parents.length);
|
|
4367
|
+
}
|
|
4368
|
+
const order = [];
|
|
4369
|
+
const queue = [...pending.values()].filter((tx) => inDegree.get(tx.txid) === 0).sort((a, b) => a.txid.localeCompare(b.txid));
|
|
4370
|
+
while (queue.length > 0) {
|
|
4371
|
+
const tx = queue.shift();
|
|
4372
|
+
order.push(tx);
|
|
4373
|
+
const children = [...pending.values()].filter((c) => c.spends.includes(tx.txid)).sort((a, b) => a.txid.localeCompare(b.txid));
|
|
4374
|
+
for (const child of children) {
|
|
4375
|
+
const deg = inDegree.get(child.txid) - 1;
|
|
4376
|
+
inDegree.set(child.txid, deg);
|
|
4377
|
+
if (deg === 0) queue.push(child);
|
|
4378
|
+
}
|
|
4379
|
+
}
|
|
4380
|
+
if (order.length !== pending.size) {
|
|
4381
|
+
throw new Error("inconsistent vtxo chain from indexer (cycle detected)");
|
|
4382
|
+
}
|
|
4383
|
+
const nodes = [];
|
|
4384
|
+
for (const tx of order) {
|
|
4385
|
+
let confirmed = false;
|
|
4386
|
+
try {
|
|
4387
|
+
const status = await params.onchain.getTxStatus(tx.txid);
|
|
4388
|
+
confirmed = status.confirmed;
|
|
4389
|
+
} catch {
|
|
4390
|
+
confirmed = false;
|
|
4391
|
+
}
|
|
4392
|
+
const expires = Number(tx.expiresAt);
|
|
4393
|
+
nodes.push({
|
|
4394
|
+
txid: tx.txid,
|
|
4395
|
+
type: tx.type,
|
|
4396
|
+
expiresAt: Number.isFinite(expires) && expires > 0 ? expires : void 0,
|
|
4397
|
+
forVtxos: [...tx.forVtxos].sort(),
|
|
4398
|
+
confirmed
|
|
4399
|
+
});
|
|
4400
|
+
}
|
|
4401
|
+
return nodes;
|
|
4402
|
+
}
|
|
4403
|
+
function topoSortByDeps(items, idOf, depsOf) {
|
|
4404
|
+
const produced = new Set(items.map(idOf));
|
|
4405
|
+
const emitted = /* @__PURE__ */ new Set();
|
|
4406
|
+
const ordered = [];
|
|
4407
|
+
let remaining = items;
|
|
4408
|
+
while (remaining.length > 0) {
|
|
4409
|
+
const next = [];
|
|
4410
|
+
let progress = false;
|
|
4411
|
+
for (const item of remaining) {
|
|
4412
|
+
if (depsOf(item).every((d) => !produced.has(d) || emitted.has(d))) {
|
|
4413
|
+
ordered.push(item);
|
|
4414
|
+
emitted.add(idOf(item));
|
|
4415
|
+
progress = true;
|
|
4416
|
+
} else {
|
|
4417
|
+
next.push(item);
|
|
4418
|
+
}
|
|
4419
|
+
}
|
|
4420
|
+
if (!progress) {
|
|
4421
|
+
throw new Error("topological sort: cycle or unsatisfiable dependency");
|
|
4422
|
+
}
|
|
4423
|
+
remaining = next;
|
|
4424
|
+
}
|
|
4425
|
+
return ordered;
|
|
4426
|
+
}
|
|
4427
|
+
|
|
4428
|
+
// src/wallet/exit/capture.ts
|
|
4429
|
+
var DEFAULT_MIN_EXIT_WORTH_SATS = 1e3;
|
|
4430
|
+
var DEFAULT_EXIT_CAPTURE_MODE = "lite";
|
|
4431
|
+
function chainTxTypeToChainedExit(t) {
|
|
4432
|
+
switch (t) {
|
|
4433
|
+
case "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */:
|
|
4434
|
+
return 1 /* Commitment */;
|
|
4435
|
+
case "INDEXER_CHAINED_TX_TYPE_ARK" /* ARK */:
|
|
4436
|
+
return 2 /* Ark */;
|
|
4437
|
+
case "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */:
|
|
4438
|
+
return 3 /* Tree */;
|
|
4439
|
+
case "INDEXER_CHAINED_TX_TYPE_CHECKPOINT" /* CHECKPOINT */:
|
|
4440
|
+
return 4 /* Checkpoint */;
|
|
4441
|
+
default:
|
|
4442
|
+
return 0 /* Unspecified */;
|
|
4443
|
+
}
|
|
4444
|
+
}
|
|
4445
|
+
function orderAncestryFirst(chain) {
|
|
4446
|
+
const ids = new Set(chain.map((c) => c.txid));
|
|
4447
|
+
return topoSortByDeps(
|
|
4448
|
+
chain,
|
|
4449
|
+
(c) => c.txid,
|
|
4450
|
+
(c) => c.spends.filter((s) => ids.has(s))
|
|
4451
|
+
);
|
|
4452
|
+
}
|
|
4453
|
+
async function captureExitBranch(params) {
|
|
4454
|
+
const { resolver, repository, vtxo, value, mode, minExitWorthSats } = params;
|
|
4455
|
+
if (value < minExitWorthSats) return;
|
|
4456
|
+
if (await repository.hasBranch(vtxo)) return;
|
|
4457
|
+
const ordered = orderAncestryFirst(await resolver.getVtxoChain(vtxo));
|
|
4458
|
+
const psbtByTxid = /* @__PURE__ */ new Map();
|
|
4459
|
+
if (mode === "full") {
|
|
4460
|
+
const nonCommitment = ordered.filter((c) => chainTxTypeToChainedExit(c.type) !== 1 /* Commitment */).map((c) => c.txid);
|
|
4461
|
+
if (nonCommitment.length > 0) {
|
|
4462
|
+
for (const psbt of await resolver.getVirtualTxs(nonCommitment)) {
|
|
4463
|
+
psbtByTxid.set(chunk7IYIFMF4_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
4464
|
+
}
|
|
4465
|
+
}
|
|
4466
|
+
}
|
|
4467
|
+
const virtualTxs = ordered.map((c) => {
|
|
4468
|
+
const expires = Number(c.expiresAt);
|
|
4469
|
+
return {
|
|
4470
|
+
txid: c.txid,
|
|
4471
|
+
psbt: psbtByTxid.get(c.txid) ?? null,
|
|
4472
|
+
expiresAt: Number.isFinite(expires) && expires > 0 ? expires : null,
|
|
4473
|
+
type: chainTxTypeToChainedExit(c.type)
|
|
4474
|
+
};
|
|
4475
|
+
});
|
|
4476
|
+
const branch = ordered.map((c, i) => ({
|
|
4477
|
+
vtxoTxid: vtxo.txid,
|
|
4478
|
+
vtxoVout: vtxo.vout,
|
|
4479
|
+
virtualTxid: c.txid,
|
|
4480
|
+
position: i
|
|
4481
|
+
}));
|
|
4482
|
+
await repository.upsertVirtualTxs(virtualTxs);
|
|
4483
|
+
await repository.setBranch(vtxo, branch);
|
|
4484
|
+
}
|
|
4485
|
+
async function pruneExitBranches(repository, outpoints) {
|
|
4486
|
+
for (const outpoint of outpoints) {
|
|
4487
|
+
try {
|
|
4488
|
+
await repository.pruneForSpentVtxo(outpoint);
|
|
4489
|
+
} catch {
|
|
4490
|
+
}
|
|
4491
|
+
}
|
|
4492
|
+
}
|
|
4493
|
+
var IndexerExitDataSource = class {
|
|
4494
|
+
constructor(indexer) {
|
|
4495
|
+
this.indexer = indexer;
|
|
4496
|
+
}
|
|
4497
|
+
indexer;
|
|
4498
|
+
name = "indexer";
|
|
4499
|
+
async getVtxoChain(vtxo) {
|
|
4500
|
+
const chain = [];
|
|
4501
|
+
let pageIndex = 0;
|
|
4502
|
+
let hasMore = true;
|
|
4503
|
+
while (hasMore) {
|
|
4504
|
+
const { chain: page, page: meta } = await this.indexer.getVtxoChain(
|
|
4505
|
+
{ txid: vtxo.txid, vout: vtxo.vout },
|
|
4506
|
+
{ pageIndex, pageSize: chunk4KXOCVXP_cjs.DEFAULT_PAGE_SIZE }
|
|
4507
|
+
);
|
|
4508
|
+
chain.push(...page);
|
|
4509
|
+
hasMore = meta ? page.length === chunk4KXOCVXP_cjs.DEFAULT_PAGE_SIZE : false;
|
|
4510
|
+
pageIndex++;
|
|
4511
|
+
}
|
|
4512
|
+
return chain;
|
|
4513
|
+
}
|
|
4514
|
+
async getVirtualTxs(txids) {
|
|
4515
|
+
const out = /* @__PURE__ */ new Map();
|
|
4516
|
+
let pageIndex = 0;
|
|
4517
|
+
let hasMore = true;
|
|
4518
|
+
while (hasMore) {
|
|
4519
|
+
const { txs, page } = await this.indexer.getVirtualTxs(txids, {
|
|
4520
|
+
pageIndex,
|
|
4521
|
+
pageSize: chunk4KXOCVXP_cjs.DEFAULT_PAGE_SIZE
|
|
4522
|
+
});
|
|
4523
|
+
for (const psbt of txs) {
|
|
4524
|
+
out.set(chunk7IYIFMF4_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
4525
|
+
}
|
|
4526
|
+
hasMore = page ? txs.length === chunk4KXOCVXP_cjs.DEFAULT_PAGE_SIZE : false;
|
|
4527
|
+
pageIndex++;
|
|
4528
|
+
}
|
|
4529
|
+
return out;
|
|
4530
|
+
}
|
|
4531
|
+
};
|
|
4532
|
+
function chainedTxTypeToChainTxType(t) {
|
|
4533
|
+
switch (t) {
|
|
4534
|
+
case 1 /* Commitment */:
|
|
4535
|
+
return "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */;
|
|
4536
|
+
case 2 /* Ark */:
|
|
4537
|
+
return "INDEXER_CHAINED_TX_TYPE_ARK" /* ARK */;
|
|
4538
|
+
case 3 /* Tree */:
|
|
4539
|
+
return "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */;
|
|
4540
|
+
case 4 /* Checkpoint */:
|
|
4541
|
+
return "INDEXER_CHAINED_TX_TYPE_CHECKPOINT" /* CHECKPOINT */;
|
|
4542
|
+
default:
|
|
4543
|
+
return "INDEXER_CHAINED_TX_TYPE_UNSPECIFIED" /* UNSPECIFIED */;
|
|
4544
|
+
}
|
|
4545
|
+
}
|
|
4546
|
+
function psbtInputTxids(psbtBase64) {
|
|
4547
|
+
const tx = chunk7IYIFMF4_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
|
|
4548
|
+
const ids = [];
|
|
4549
|
+
for (let i = 0; i < tx.inputsLength; i++) {
|
|
4550
|
+
const txid = tx.getInput(i).txid;
|
|
4551
|
+
if (txid) ids.push(base.hex.encode(txid));
|
|
4552
|
+
}
|
|
4553
|
+
return ids;
|
|
4554
|
+
}
|
|
4555
|
+
var RepositoryExitDataSource = class {
|
|
4556
|
+
constructor(repo) {
|
|
4557
|
+
this.repo = repo;
|
|
4558
|
+
}
|
|
4559
|
+
repo;
|
|
4560
|
+
name = "repository";
|
|
4561
|
+
async getVtxoChain(vtxo) {
|
|
4562
|
+
const branch = await this.repo.getBranch(vtxo);
|
|
4563
|
+
if (branch.length === 0) return null;
|
|
4564
|
+
const chain = [];
|
|
4565
|
+
for (const v of branch) {
|
|
4566
|
+
const type = chainedTxTypeToChainTxType(v.type);
|
|
4567
|
+
let spends = [];
|
|
4568
|
+
if (v.type !== 1 /* Commitment */) {
|
|
4569
|
+
if (!v.psbt) return null;
|
|
4570
|
+
spends = psbtInputTxids(v.psbt);
|
|
4571
|
+
}
|
|
4572
|
+
chain.push({
|
|
4573
|
+
txid: v.txid,
|
|
4574
|
+
type,
|
|
4575
|
+
expiresAt: v.expiresAt != null ? String(v.expiresAt) : "",
|
|
4576
|
+
spends
|
|
4577
|
+
});
|
|
4578
|
+
}
|
|
4579
|
+
return chain;
|
|
4580
|
+
}
|
|
4581
|
+
async getVirtualTxs(txids) {
|
|
4582
|
+
const out = /* @__PURE__ */ new Map();
|
|
4583
|
+
for (const txid of txids) {
|
|
4584
|
+
const stored = await this.repo.getVirtualTx(txid);
|
|
4585
|
+
if (stored?.psbt) out.set(txid, stored.psbt);
|
|
4586
|
+
}
|
|
4587
|
+
return out;
|
|
4588
|
+
}
|
|
4589
|
+
};
|
|
4590
|
+
|
|
4591
|
+
// src/wallet/exit/resolver.ts
|
|
4592
|
+
var OrderedExitChainResolver = class {
|
|
4593
|
+
constructor(sources, persist) {
|
|
4594
|
+
this.sources = sources;
|
|
4595
|
+
this.persist = persist;
|
|
4596
|
+
}
|
|
4597
|
+
sources;
|
|
4598
|
+
persist;
|
|
4599
|
+
async getVtxoChain(vtxo) {
|
|
4600
|
+
let lastErr;
|
|
4601
|
+
for (const source of this.sources) {
|
|
4602
|
+
try {
|
|
4603
|
+
const chain = await source.getVtxoChain(vtxo);
|
|
4604
|
+
if (chain) return chain;
|
|
4605
|
+
} catch (e) {
|
|
4606
|
+
lastErr = e;
|
|
4607
|
+
}
|
|
4608
|
+
}
|
|
4609
|
+
if (lastErr) throw lastErr;
|
|
4610
|
+
throw new Error(`no exit-data source resolved the chain for ${vtxo.txid}:${vtxo.vout}`);
|
|
4611
|
+
}
|
|
4612
|
+
async getVirtualTxs(txids) {
|
|
4613
|
+
const found = /* @__PURE__ */ new Map();
|
|
4614
|
+
let remaining = txids;
|
|
4615
|
+
for (const [i, source] of this.sources.entries()) {
|
|
4616
|
+
if (remaining.length === 0) break;
|
|
4617
|
+
let got;
|
|
4618
|
+
try {
|
|
4619
|
+
got = await source.getVirtualTxs(remaining);
|
|
4620
|
+
} catch {
|
|
4621
|
+
continue;
|
|
4622
|
+
}
|
|
4623
|
+
const fresh = [];
|
|
4624
|
+
for (const [txid, psbt] of got) {
|
|
4625
|
+
if (found.has(txid)) continue;
|
|
4626
|
+
found.set(txid, psbt);
|
|
4627
|
+
fresh.push({ txid, psbt, expiresAt: null, type: 0 /* Unspecified */ });
|
|
4628
|
+
}
|
|
4629
|
+
if (i > 0 && this.persist && fresh.length > 0) {
|
|
4630
|
+
try {
|
|
4631
|
+
await this.persist.upsertVirtualTxs(fresh);
|
|
4632
|
+
} catch {
|
|
4633
|
+
}
|
|
4634
|
+
}
|
|
4635
|
+
remaining = txids.filter((t) => !found.has(t));
|
|
4636
|
+
}
|
|
4637
|
+
return [...found.values()];
|
|
4638
|
+
}
|
|
4639
|
+
};
|
|
4640
|
+
function createExitChainResolver(params) {
|
|
4641
|
+
const sources = [];
|
|
4642
|
+
if (params.repository) sources.push(new RepositoryExitDataSource(params.repository));
|
|
4643
|
+
if (params.extraSources) sources.push(...params.extraSources);
|
|
4644
|
+
sources.push(new IndexerExitDataSource(params.indexer));
|
|
4645
|
+
return new OrderedExitChainResolver(sources, params.repository);
|
|
4646
|
+
}
|
|
4647
|
+
|
|
4648
|
+
// src/providers/availability.ts
|
|
4649
|
+
function isRetryableProviderError(error) {
|
|
4650
|
+
return error instanceof chunk7IYIFMF4_cjs.ProviderUnavailableError || error instanceof chunk7IYIFMF4_cjs.FetchError || chunk7IYIFMF4_cjs.isFetchTimeoutError(error);
|
|
4651
|
+
}
|
|
4652
|
+
|
|
4653
|
+
// src/utils/syncCursors.ts
|
|
4654
|
+
var SAFETY_LAG_MS = 3e4;
|
|
4655
|
+
var OVERLAP_MS = 24 * 60 * 60 * 1e3;
|
|
4656
|
+
var walletStateLocks = /* @__PURE__ */ new WeakMap();
|
|
4657
|
+
async function updateWalletState(repo, updater) {
|
|
4658
|
+
const prev = walletStateLocks.get(repo) ?? Promise.resolve();
|
|
4659
|
+
const op = prev.then(async () => {
|
|
4660
|
+
const state = await repo.getWalletState() ?? {};
|
|
4661
|
+
await repo.saveWalletState(updater(state));
|
|
4662
|
+
});
|
|
4663
|
+
walletStateLocks.set(
|
|
4664
|
+
repo,
|
|
4665
|
+
op.catch(() => {
|
|
4666
|
+
})
|
|
4667
|
+
);
|
|
4668
|
+
return op;
|
|
4669
|
+
}
|
|
4670
|
+
var CURSOR_MIGRATED_KEY = "vtxoCursorMigrated";
|
|
4671
|
+
function hasMigrationMarker(state) {
|
|
4672
|
+
return state?.settings?.[CURSOR_MIGRATED_KEY] === true;
|
|
4673
|
+
}
|
|
4674
|
+
async function getSyncCursor(repo) {
|
|
4675
|
+
const state = await repo.getWalletState();
|
|
4676
|
+
if (!hasMigrationMarker(state)) return 0;
|
|
4677
|
+
return state?.lastSyncTime ?? 0;
|
|
4678
|
+
}
|
|
4679
|
+
async function advanceSyncCursor(repo, lastUpdatedAt) {
|
|
4680
|
+
await updateWalletState(repo, (state) => {
|
|
4681
|
+
const current = hasMigrationMarker(state) ? state.lastSyncTime ?? 0 : 0;
|
|
4682
|
+
return {
|
|
4683
|
+
...state,
|
|
4684
|
+
lastSyncTime: Math.max(current, lastUpdatedAt),
|
|
4685
|
+
settings: {
|
|
4686
|
+
...state.settings ?? {},
|
|
4687
|
+
[CURSOR_MIGRATED_KEY]: true
|
|
4688
|
+
}
|
|
4689
|
+
};
|
|
4690
|
+
});
|
|
4691
|
+
}
|
|
4692
|
+
async function clearSyncCursor(repo) {
|
|
4693
|
+
await updateWalletState(repo, (state) => {
|
|
4694
|
+
const { [CURSOR_MIGRATED_KEY]: _, ...restSettings } = state.settings ?? {};
|
|
4695
|
+
return {
|
|
4696
|
+
...state,
|
|
4697
|
+
lastSyncTime: void 0,
|
|
4698
|
+
settings: restSettings
|
|
4699
|
+
};
|
|
4700
|
+
});
|
|
4701
|
+
}
|
|
4702
|
+
function computeSyncWindow(cursor) {
|
|
4703
|
+
const after = Math.max(0, cursor - OVERLAP_MS);
|
|
4704
|
+
return { after };
|
|
4705
|
+
}
|
|
4706
|
+
function cursorCutoff(requestStartedAt) {
|
|
4707
|
+
return (requestStartedAt ?? Date.now()) - SAFETY_LAG_MS;
|
|
4708
|
+
}
|
|
4709
|
+
|
|
4710
|
+
// src/wallet/arkInfoSnapshot.ts
|
|
4711
|
+
var ARK_INFO_SNAPSHOT_KEY = "arkInfoSnapshot";
|
|
4712
|
+
var MalformedArkInfoSnapshotError = class extends Error {
|
|
4713
|
+
constructor(message, options) {
|
|
4714
|
+
super(message, { cause: options?.cause });
|
|
4715
|
+
this.name = "MalformedArkInfoSnapshotError";
|
|
4716
|
+
}
|
|
4717
|
+
};
|
|
4718
|
+
var CURRENT_VERSION = 1;
|
|
4719
|
+
function serializeArkInfoSnapshot(info, savedAt) {
|
|
4720
|
+
return {
|
|
4721
|
+
version: CURRENT_VERSION,
|
|
4722
|
+
savedAt,
|
|
4723
|
+
source: "arkade.getInfo",
|
|
4724
|
+
arkInfo: {
|
|
4725
|
+
network: info.network,
|
|
4726
|
+
signerPubkey: info.signerPubkey,
|
|
4727
|
+
checkpointTapscript: info.checkpointTapscript,
|
|
4728
|
+
forfeitAddress: info.forfeitAddress,
|
|
4729
|
+
forfeitPubkey: info.forfeitPubkey,
|
|
4730
|
+
unilateralExitDelay: info.unilateralExitDelay.toString(),
|
|
4731
|
+
boardingExitDelay: info.boardingExitDelay.toString(),
|
|
4732
|
+
sessionDuration: info.sessionDuration.toString(),
|
|
4733
|
+
dust: info.dust.toString(),
|
|
4734
|
+
fees: info.fees,
|
|
4735
|
+
digest: info.digest,
|
|
4736
|
+
version: info.version,
|
|
4737
|
+
vtxoMinAmount: info.vtxoMinAmount.toString(),
|
|
4738
|
+
vtxoMaxAmount: info.vtxoMaxAmount.toString(),
|
|
4739
|
+
utxoMinAmount: info.utxoMinAmount.toString(),
|
|
4740
|
+
utxoMaxAmount: info.utxoMaxAmount.toString(),
|
|
4741
|
+
deprecatedSigners: info.deprecatedSigners.map((s) => ({
|
|
4742
|
+
pubkey: s.pubkey,
|
|
4743
|
+
cutoffDate: s.cutoffDate.toString()
|
|
4744
|
+
})),
|
|
4745
|
+
scheduledSession: info.scheduledSession ? {
|
|
4746
|
+
duration: info.scheduledSession.duration.toString(),
|
|
4747
|
+
fees: info.scheduledSession.fees,
|
|
4748
|
+
nextEndTime: info.scheduledSession.nextEndTime.toString(),
|
|
4749
|
+
nextStartTime: info.scheduledSession.nextStartTime.toString(),
|
|
4750
|
+
period: info.scheduledSession.period.toString()
|
|
4751
|
+
} : void 0
|
|
4752
|
+
}
|
|
4753
|
+
};
|
|
4754
|
+
}
|
|
4755
|
+
function hydrateArkInfo(snapshot) {
|
|
4756
|
+
const a = snapshot.arkInfo;
|
|
4757
|
+
return {
|
|
4758
|
+
boardingExitDelay: BigInt(a.boardingExitDelay),
|
|
4759
|
+
checkpointTapscript: a.checkpointTapscript,
|
|
4760
|
+
deprecatedSigners: a.deprecatedSigners.map((s) => ({
|
|
4761
|
+
cutoffDate: BigInt(s.cutoffDate),
|
|
4762
|
+
pubkey: s.pubkey
|
|
4763
|
+
})),
|
|
4764
|
+
digest: a.digest,
|
|
4765
|
+
dust: BigInt(a.dust),
|
|
4766
|
+
fees: a.fees,
|
|
4767
|
+
forfeitAddress: a.forfeitAddress,
|
|
4768
|
+
forfeitPubkey: a.forfeitPubkey,
|
|
4769
|
+
network: a.network,
|
|
4770
|
+
scheduledSession: a.scheduledSession ? {
|
|
4771
|
+
duration: BigInt(a.scheduledSession.duration),
|
|
4772
|
+
fees: a.scheduledSession.fees,
|
|
4773
|
+
nextEndTime: BigInt(a.scheduledSession.nextEndTime),
|
|
4774
|
+
nextStartTime: BigInt(a.scheduledSession.nextStartTime),
|
|
4775
|
+
period: BigInt(a.scheduledSession.period)
|
|
4776
|
+
} : void 0,
|
|
4777
|
+
serviceStatus: {},
|
|
4778
|
+
sessionDuration: BigInt(a.sessionDuration),
|
|
4779
|
+
signerPubkey: a.signerPubkey,
|
|
4780
|
+
unilateralExitDelay: BigInt(a.unilateralExitDelay),
|
|
4781
|
+
utxoMaxAmount: BigInt(a.utxoMaxAmount),
|
|
4782
|
+
utxoMinAmount: BigInt(a.utxoMinAmount),
|
|
4783
|
+
version: a.version,
|
|
4784
|
+
vtxoMaxAmount: BigInt(a.vtxoMaxAmount),
|
|
4785
|
+
vtxoMinAmount: BigInt(a.vtxoMinAmount)
|
|
4786
|
+
};
|
|
4787
|
+
}
|
|
4788
|
+
var DECIMAL_STRING = /^-?\d+$/;
|
|
4789
|
+
function assertString(value, path) {
|
|
4790
|
+
if (typeof value !== "string") {
|
|
4791
|
+
throw new MalformedArkInfoSnapshotError(`${path} must be a string`);
|
|
4792
|
+
}
|
|
4793
|
+
}
|
|
4794
|
+
function assertDecimalString(value, path) {
|
|
4795
|
+
assertString(value, path);
|
|
4796
|
+
if (!DECIMAL_STRING.test(value)) {
|
|
4797
|
+
throw new MalformedArkInfoSnapshotError(`${path} must be a decimal integer string`);
|
|
4798
|
+
}
|
|
4799
|
+
}
|
|
4800
|
+
function assertFeeInfo(value, path) {
|
|
4801
|
+
if (typeof value !== "object" || value === null) {
|
|
4802
|
+
throw new MalformedArkInfoSnapshotError(`${path} must be an object`);
|
|
4803
|
+
}
|
|
4804
|
+
const fees = value;
|
|
4805
|
+
assertString(fees.txFeeRate, `${path}.txFeeRate`);
|
|
4806
|
+
if (typeof fees.intentFee !== "object" || fees.intentFee === null) {
|
|
4807
|
+
throw new MalformedArkInfoSnapshotError(`${path}.intentFee must be an object`);
|
|
4808
|
+
}
|
|
4809
|
+
}
|
|
4810
|
+
function parseStoredArkInfoSnapshot(raw) {
|
|
4811
|
+
if (typeof raw !== "object" || raw === null) {
|
|
4812
|
+
throw new MalformedArkInfoSnapshotError("snapshot must be an object");
|
|
4813
|
+
}
|
|
4814
|
+
const snap = raw;
|
|
4815
|
+
if (snap.version !== CURRENT_VERSION) {
|
|
4816
|
+
throw new MalformedArkInfoSnapshotError(
|
|
4817
|
+
`unsupported snapshot version: ${String(snap.version)}`
|
|
4818
|
+
);
|
|
4819
|
+
}
|
|
4820
|
+
if (typeof snap.savedAt !== "number") {
|
|
4821
|
+
throw new MalformedArkInfoSnapshotError("savedAt must be a number");
|
|
4822
|
+
}
|
|
4823
|
+
if (snap.source !== "arkade.getInfo") {
|
|
4824
|
+
throw new MalformedArkInfoSnapshotError(`unexpected source: ${String(snap.source)}`);
|
|
4825
|
+
}
|
|
4826
|
+
if (typeof snap.arkInfo !== "object" || snap.arkInfo === null) {
|
|
4827
|
+
throw new MalformedArkInfoSnapshotError("arkInfo must be an object");
|
|
4828
|
+
}
|
|
4829
|
+
const a = snap.arkInfo;
|
|
4830
|
+
for (const field of [
|
|
4831
|
+
"network",
|
|
4832
|
+
"signerPubkey",
|
|
4833
|
+
"checkpointTapscript",
|
|
4834
|
+
"forfeitAddress",
|
|
4835
|
+
"forfeitPubkey",
|
|
4836
|
+
"digest",
|
|
4837
|
+
"version"
|
|
4838
|
+
]) {
|
|
4839
|
+
assertString(a[field], `arkInfo.${field}`);
|
|
4840
|
+
}
|
|
4841
|
+
for (const field of [
|
|
4842
|
+
"unilateralExitDelay",
|
|
4843
|
+
"boardingExitDelay",
|
|
4844
|
+
"sessionDuration",
|
|
4845
|
+
"dust",
|
|
4846
|
+
"vtxoMinAmount",
|
|
4847
|
+
"vtxoMaxAmount",
|
|
4848
|
+
"utxoMinAmount",
|
|
4849
|
+
"utxoMaxAmount"
|
|
4850
|
+
]) {
|
|
4851
|
+
assertDecimalString(a[field], `arkInfo.${field}`);
|
|
4852
|
+
}
|
|
4853
|
+
assertFeeInfo(a.fees, "arkInfo.fees");
|
|
4854
|
+
if (!Array.isArray(a.deprecatedSigners)) {
|
|
4855
|
+
throw new MalformedArkInfoSnapshotError("arkInfo.deprecatedSigners must be an array");
|
|
4856
|
+
}
|
|
4857
|
+
a.deprecatedSigners.forEach((s, i) => {
|
|
4858
|
+
if (typeof s !== "object" || s === null) {
|
|
4859
|
+
throw new MalformedArkInfoSnapshotError(
|
|
4860
|
+
`arkInfo.deprecatedSigners[${i}] must be an object`
|
|
4861
|
+
);
|
|
4862
|
+
}
|
|
4863
|
+
const signer = s;
|
|
4864
|
+
assertString(signer.pubkey, `arkInfo.deprecatedSigners[${i}].pubkey`);
|
|
4865
|
+
assertDecimalString(signer.cutoffDate, `arkInfo.deprecatedSigners[${i}].cutoffDate`);
|
|
4866
|
+
});
|
|
4867
|
+
if (a.scheduledSession !== void 0) {
|
|
4868
|
+
if (typeof a.scheduledSession !== "object" || a.scheduledSession === null) {
|
|
4869
|
+
throw new MalformedArkInfoSnapshotError("arkInfo.scheduledSession must be an object");
|
|
4870
|
+
}
|
|
4871
|
+
const s = a.scheduledSession;
|
|
4872
|
+
for (const field of ["duration", "nextEndTime", "nextStartTime", "period"]) {
|
|
4873
|
+
assertDecimalString(s[field], `arkInfo.scheduledSession.${field}`);
|
|
4874
|
+
}
|
|
4875
|
+
assertFeeInfo(s.fees, "arkInfo.scheduledSession.fees");
|
|
4876
|
+
}
|
|
4877
|
+
return raw;
|
|
4878
|
+
}
|
|
4879
|
+
async function loadArkInfoSnapshot(repo) {
|
|
4880
|
+
const state = await repo.getWalletState();
|
|
4881
|
+
const raw = state?.settings?.[ARK_INFO_SNAPSHOT_KEY];
|
|
4882
|
+
if (raw === void 0 || raw === null) return null;
|
|
4883
|
+
return parseStoredArkInfoSnapshot(raw);
|
|
4884
|
+
}
|
|
4885
|
+
async function saveArkInfoSnapshot(repo, info, savedAt) {
|
|
4886
|
+
const snapshot = serializeArkInfoSnapshot(info, savedAt);
|
|
4887
|
+
await updateWalletState(repo, (state) => ({
|
|
4888
|
+
...state,
|
|
4889
|
+
settings: {
|
|
4890
|
+
...state.settings ?? {},
|
|
4891
|
+
[ARK_INFO_SNAPSHOT_KEY]: snapshot
|
|
4892
|
+
}
|
|
4893
|
+
}));
|
|
4894
|
+
}
|
|
4895
|
+
async function resolveArkInfo(arkProvider, walletRepository) {
|
|
4896
|
+
let info;
|
|
4897
|
+
try {
|
|
4898
|
+
info = await arkProvider.getInfo();
|
|
4899
|
+
} catch (err) {
|
|
4900
|
+
if (!isRetryableProviderError(err)) throw err;
|
|
4901
|
+
const snapshot = await loadArkInfoSnapshot(walletRepository);
|
|
4902
|
+
if (!snapshot) {
|
|
4903
|
+
throw new chunk7IYIFMF4_cjs.ProviderUnavailableError(
|
|
4904
|
+
"Arkade server info is unavailable and no cached snapshot exists",
|
|
4905
|
+
{ cause: err }
|
|
4906
|
+
);
|
|
4907
|
+
}
|
|
4908
|
+
return { info: hydrateArkInfo(snapshot), source: "cache", lastOnlineAt: snapshot.savedAt };
|
|
4909
|
+
}
|
|
4910
|
+
return { info, source: "live" };
|
|
4911
|
+
}
|
|
4912
|
+
async function saveValidatedArkInfoSnapshot(repo, info, savedAt) {
|
|
4913
|
+
try {
|
|
4914
|
+
await saveArkInfoSnapshot(repo, info, savedAt);
|
|
4915
|
+
} catch (err) {
|
|
4916
|
+
console.warn("Failed to persist Ark info snapshot", err);
|
|
4917
|
+
}
|
|
4918
|
+
}
|
|
4312
4919
|
var TxTree = class {
|
|
4313
4920
|
constructor(root, children = /* @__PURE__ */ new Map()) {
|
|
4314
4921
|
this.root = root;
|
|
4315
4922
|
this.children = children;
|
|
4316
4923
|
}
|
|
4924
|
+
root;
|
|
4925
|
+
children;
|
|
4317
4926
|
static create(chunks) {
|
|
4318
4927
|
if (chunks.length === 0) {
|
|
4319
4928
|
throw new Error("empty chunks");
|
|
@@ -4785,6 +5394,7 @@ var ReadonlyAssetManager = class {
|
|
|
4785
5394
|
constructor(indexer) {
|
|
4786
5395
|
this.indexer = indexer;
|
|
4787
5396
|
}
|
|
5397
|
+
indexer;
|
|
4788
5398
|
async getAssetDetails(assetId) {
|
|
4789
5399
|
return this.indexer.getAssetDetails(assetId);
|
|
4790
5400
|
}
|
|
@@ -4794,6 +5404,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4794
5404
|
super(wallet.indexerProvider);
|
|
4795
5405
|
this.wallet = wallet;
|
|
4796
5406
|
}
|
|
5407
|
+
wallet;
|
|
4797
5408
|
/**
|
|
4798
5409
|
* Issue a new asset.
|
|
4799
5410
|
* @param params - Parameters for asset issuance
|
|
@@ -4824,7 +5435,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4824
5435
|
const virtualCoins = await this.wallet.getVtxos({
|
|
4825
5436
|
withRecoverable: false
|
|
4826
5437
|
});
|
|
4827
|
-
const controlAssetRef = params.controlAssetId ?
|
|
5438
|
+
const controlAssetRef = params.controlAssetId ? chunk7IYIFMF4_cjs.AssetRef.fromId(chunk7IYIFMF4_cjs.AssetId.fromString(params.controlAssetId)) : null;
|
|
4828
5439
|
const coinSelection = selectVirtualCoins(virtualCoins, Number(this.wallet.dustAmount));
|
|
4829
5440
|
let totalBtcSelected = 0n;
|
|
4830
5441
|
const assetChanges = /* @__PURE__ */ new Map();
|
|
@@ -4837,8 +5448,8 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4837
5448
|
}
|
|
4838
5449
|
}
|
|
4839
5450
|
const groups = [];
|
|
4840
|
-
const issuedAssetOutput =
|
|
4841
|
-
const issuedAssetGroup =
|
|
5451
|
+
const issuedAssetOutput = chunk7IYIFMF4_cjs.AssetOutput.create(0, params.amount);
|
|
5452
|
+
const issuedAssetGroup = chunk7IYIFMF4_cjs.AssetGroup.create(
|
|
4842
5453
|
null,
|
|
4843
5454
|
controlAssetRef,
|
|
4844
5455
|
[],
|
|
@@ -4853,28 +5464,28 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4853
5464
|
for (const [inputIndex, assets] of assetInputs) {
|
|
4854
5465
|
for (const asset of assets) {
|
|
4855
5466
|
if (asset.assetId !== assetId) continue;
|
|
4856
|
-
changeInputs.push(
|
|
5467
|
+
changeInputs.push(chunk7IYIFMF4_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
4857
5468
|
}
|
|
4858
5469
|
}
|
|
4859
5470
|
groups.push(
|
|
4860
|
-
|
|
4861
|
-
|
|
5471
|
+
chunk7IYIFMF4_cjs.AssetGroup.create(
|
|
5472
|
+
chunk7IYIFMF4_cjs.AssetId.fromString(assetId),
|
|
4862
5473
|
null,
|
|
4863
5474
|
changeInputs,
|
|
4864
|
-
[
|
|
5475
|
+
[chunk7IYIFMF4_cjs.AssetOutput.create(0, amount)],
|
|
4865
5476
|
[]
|
|
4866
5477
|
)
|
|
4867
5478
|
);
|
|
4868
5479
|
}
|
|
4869
5480
|
}
|
|
4870
5481
|
const address = await this.wallet.getAddress();
|
|
4871
|
-
const outputAddress =
|
|
5482
|
+
const outputAddress = chunkMQB5H4X5_cjs.ArkAddress.decode(address);
|
|
4872
5483
|
const outputs = [
|
|
4873
5484
|
{
|
|
4874
5485
|
script: outputAddress.pkScript,
|
|
4875
5486
|
amount: BigInt(totalBtcSelected)
|
|
4876
5487
|
},
|
|
4877
|
-
Extension.create([
|
|
5488
|
+
Extension.create([chunk7IYIFMF4_cjs.Packet.create(groups)]).txOut()
|
|
4878
5489
|
];
|
|
4879
5490
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(
|
|
4880
5491
|
coinSelection.inputs,
|
|
@@ -4882,7 +5493,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4882
5493
|
);
|
|
4883
5494
|
return {
|
|
4884
5495
|
arkTxId: arkTxid,
|
|
4885
|
-
assetId:
|
|
5496
|
+
assetId: chunk7IYIFMF4_cjs.AssetId.create(arkTxid, 0).toString()
|
|
4886
5497
|
};
|
|
4887
5498
|
}
|
|
4888
5499
|
/**
|
|
@@ -4954,16 +5565,16 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4954
5565
|
for (const [inputIndex, assets] of assetInputs) {
|
|
4955
5566
|
for (const asset of assets) {
|
|
4956
5567
|
if (asset.assetId !== params.assetId) continue;
|
|
4957
|
-
reissueInputs.push(
|
|
5568
|
+
reissueInputs.push(chunk7IYIFMF4_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
4958
5569
|
}
|
|
4959
5570
|
}
|
|
4960
5571
|
const totalAssetAmount = assetToReissueAmount + params.amount;
|
|
4961
|
-
const reissueAssetIdObj =
|
|
4962
|
-
const reissueAssetGroup =
|
|
5572
|
+
const reissueAssetIdObj = chunk7IYIFMF4_cjs.AssetId.fromString(params.assetId);
|
|
5573
|
+
const reissueAssetGroup = chunk7IYIFMF4_cjs.AssetGroup.create(
|
|
4963
5574
|
reissueAssetIdObj,
|
|
4964
5575
|
null,
|
|
4965
5576
|
reissueInputs,
|
|
4966
|
-
[
|
|
5577
|
+
[chunk7IYIFMF4_cjs.AssetOutput.create(0, totalAssetAmount)],
|
|
4967
5578
|
[]
|
|
4968
5579
|
);
|
|
4969
5580
|
const groups = [reissueAssetGroup];
|
|
@@ -4972,27 +5583,27 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4972
5583
|
for (const [inputIndex, assets] of assetInputs) {
|
|
4973
5584
|
for (const asset of assets) {
|
|
4974
5585
|
if (asset.assetId !== assetId) continue;
|
|
4975
|
-
changeInputs.push(
|
|
5586
|
+
changeInputs.push(chunk7IYIFMF4_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
4976
5587
|
}
|
|
4977
5588
|
}
|
|
4978
5589
|
groups.push(
|
|
4979
|
-
|
|
4980
|
-
|
|
5590
|
+
chunk7IYIFMF4_cjs.AssetGroup.create(
|
|
5591
|
+
chunk7IYIFMF4_cjs.AssetId.fromString(assetId),
|
|
4981
5592
|
null,
|
|
4982
5593
|
changeInputs,
|
|
4983
|
-
[
|
|
5594
|
+
[chunk7IYIFMF4_cjs.AssetOutput.create(0, amount)],
|
|
4984
5595
|
[]
|
|
4985
5596
|
)
|
|
4986
5597
|
);
|
|
4987
5598
|
}
|
|
4988
5599
|
const address = await this.wallet.getAddress();
|
|
4989
|
-
const outputAddress =
|
|
5600
|
+
const outputAddress = chunkMQB5H4X5_cjs.ArkAddress.decode(address);
|
|
4990
5601
|
const outputs = [
|
|
4991
5602
|
{
|
|
4992
5603
|
script: outputAddress.pkScript,
|
|
4993
5604
|
amount: BigInt(totalBtcSelected)
|
|
4994
5605
|
},
|
|
4995
|
-
Extension.create([
|
|
5606
|
+
Extension.create([chunk7IYIFMF4_cjs.Packet.create(groups)]).txOut()
|
|
4996
5607
|
];
|
|
4997
5608
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
|
|
4998
5609
|
return arkTxid;
|
|
@@ -5059,27 +5670,27 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
5059
5670
|
for (const [inputIndex, assets] of assetInputs) {
|
|
5060
5671
|
for (const asset of assets) {
|
|
5061
5672
|
if (asset.assetId !== assetId) continue;
|
|
5062
|
-
changeInputs.push(
|
|
5673
|
+
changeInputs.push(chunk7IYIFMF4_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
5063
5674
|
}
|
|
5064
5675
|
}
|
|
5065
5676
|
groups.push(
|
|
5066
|
-
|
|
5067
|
-
|
|
5677
|
+
chunk7IYIFMF4_cjs.AssetGroup.create(
|
|
5678
|
+
chunk7IYIFMF4_cjs.AssetId.fromString(assetId),
|
|
5068
5679
|
null,
|
|
5069
5680
|
changeInputs,
|
|
5070
|
-
amount > 0n ? [
|
|
5681
|
+
amount > 0n ? [chunk7IYIFMF4_cjs.AssetOutput.create(0, amount)] : [],
|
|
5071
5682
|
[]
|
|
5072
5683
|
)
|
|
5073
5684
|
);
|
|
5074
5685
|
}
|
|
5075
5686
|
const address = await this.wallet.getAddress();
|
|
5076
|
-
const outputAddress =
|
|
5687
|
+
const outputAddress = chunkMQB5H4X5_cjs.ArkAddress.decode(address);
|
|
5077
5688
|
const outputs = [
|
|
5078
5689
|
{
|
|
5079
5690
|
script: outputAddress.pkScript,
|
|
5080
5691
|
amount: BigInt(totalBtcSelected)
|
|
5081
5692
|
},
|
|
5082
|
-
Extension.create([
|
|
5693
|
+
Extension.create([chunk7IYIFMF4_cjs.Packet.create(groups)]).txOut()
|
|
5083
5694
|
];
|
|
5084
5695
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
|
|
5085
5696
|
return arkTxid;
|
|
@@ -5104,7 +5715,7 @@ function castMetadata(metadata) {
|
|
|
5104
5715
|
} else {
|
|
5105
5716
|
throw new Error("Invalid metadata value type");
|
|
5106
5717
|
}
|
|
5107
|
-
md.push(
|
|
5718
|
+
md.push(chunk7IYIFMF4_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
|
|
5108
5719
|
}
|
|
5109
5720
|
return md;
|
|
5110
5721
|
}
|
|
@@ -5115,6 +5726,9 @@ var DelegateManagerImpl = class {
|
|
|
5115
5726
|
this.arkInfoProvider = arkInfoProvider;
|
|
5116
5727
|
this.identity = identity;
|
|
5117
5728
|
}
|
|
5729
|
+
delegateProvider;
|
|
5730
|
+
arkInfoProvider;
|
|
5731
|
+
identity;
|
|
5118
5732
|
async getDelegateInfo() {
|
|
5119
5733
|
return this.delegateProvider.getDelegateInfo();
|
|
5120
5734
|
}
|
|
@@ -5122,7 +5736,7 @@ var DelegateManagerImpl = class {
|
|
|
5122
5736
|
if (vtxos.length === 0) {
|
|
5123
5737
|
return { delegated: [], failed: [] };
|
|
5124
5738
|
}
|
|
5125
|
-
const destinationScript =
|
|
5739
|
+
const destinationScript = chunkMQB5H4X5_cjs.ArkAddress.decode(destination).pkScript;
|
|
5126
5740
|
const arkInfo = await this.arkInfoProvider.getInfo();
|
|
5127
5741
|
const delegateInfo = await this.delegateProvider.getDelegateInfo();
|
|
5128
5742
|
const eligible = vtxos.filter(
|
|
@@ -5270,7 +5884,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
5270
5884
|
const delegateFee = BigInt(Number(fee));
|
|
5271
5885
|
if (delegateFee > 0n) {
|
|
5272
5886
|
outputs.push({
|
|
5273
|
-
script:
|
|
5887
|
+
script: chunkMQB5H4X5_cjs.ArkAddress.decode(delegateAddress).pkScript,
|
|
5274
5888
|
amount: delegateFee
|
|
5275
5889
|
});
|
|
5276
5890
|
}
|
|
@@ -5281,12 +5895,12 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
5281
5895
|
script: base.hex.encode(output.script)
|
|
5282
5896
|
}).satoshis;
|
|
5283
5897
|
}, 0);
|
|
5284
|
-
if (amount - BigInt(outputFee)
|
|
5898
|
+
if (isSubdust(amount - BigInt(outputFee), dust)) {
|
|
5285
5899
|
throw new Error("Amount is below dust limit, cannot delegate");
|
|
5286
5900
|
}
|
|
5287
5901
|
amount -= BigInt(outputFee);
|
|
5288
5902
|
amount -= delegateFee;
|
|
5289
|
-
if (amount
|
|
5903
|
+
if (isSubdust(amount, dust)) {
|
|
5290
5904
|
throw new Error("Amount is below dust limit, cannot delegate");
|
|
5291
5905
|
}
|
|
5292
5906
|
outputs.push({
|
|
@@ -5303,7 +5917,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
5303
5917
|
destinationScript
|
|
5304
5918
|
);
|
|
5305
5919
|
const forfeitOutputScript = btcSigner.OutScript.encode(
|
|
5306
|
-
btcSigner.Address(
|
|
5920
|
+
btcSigner.Address(chunkMQB5H4X5_cjs.getNetwork(network)).decode(forfeitAddress)
|
|
5307
5921
|
);
|
|
5308
5922
|
const forfeits = await Promise.all(
|
|
5309
5923
|
vtxos.filter((v) => !isRecoverable(v)).map(async (coin) => {
|
|
@@ -5331,7 +5945,7 @@ async function makeDelegateForfeitTx(input, connectorAmount, delegatePubkey, for
|
|
|
5331
5945
|
index: input.vout,
|
|
5332
5946
|
witnessUtxo: {
|
|
5333
5947
|
amount: BigInt(input.value),
|
|
5334
|
-
script:
|
|
5948
|
+
script: chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
5335
5949
|
},
|
|
5336
5950
|
sighashType: btcSigner.SigHash.ALL_ANYONECANPAY,
|
|
5337
5951
|
tapLeafScript: [delegateTapLeaf]
|
|
@@ -5389,7 +6003,7 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
5389
6003
|
expire_at: 0,
|
|
5390
6004
|
cosigners_public_keys: cosignerPubKeys
|
|
5391
6005
|
};
|
|
5392
|
-
const proof =
|
|
6006
|
+
const proof = chunk7IYIFMF4_cjs.Intent.create(message, coins, outputs);
|
|
5393
6007
|
const signedProof = await identity.sign(proof);
|
|
5394
6008
|
return {
|
|
5395
6009
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -5407,10 +6021,10 @@ function getDayTimestamp(timestamp) {
|
|
|
5407
6021
|
function findDelegateTapLeaf(vtxo, delegatePubkey) {
|
|
5408
6022
|
if (!vtxo.tapTree) return void 0;
|
|
5409
6023
|
const pk = delegatePubkey.length === 66 ? delegatePubkey.slice(2) : delegatePubkey;
|
|
5410
|
-
const vtxoScript =
|
|
6024
|
+
const vtxoScript = chunkMQB5H4X5_cjs.VtxoScript.decode(vtxo.tapTree);
|
|
5411
6025
|
return vtxoScript.leaves.find((tapLeaf) => {
|
|
5412
|
-
const arkTapscript =
|
|
5413
|
-
if (!
|
|
6026
|
+
const arkTapscript = chunkMQB5H4X5_cjs.decodeTapscript(chunkMQB5H4X5_cjs.scriptFromTapLeafScript(tapLeaf));
|
|
6027
|
+
if (!chunkMQB5H4X5_cjs.MultisigTapscript.is(arkTapscript)) return false;
|
|
5414
6028
|
return arkTapscript.params.pubkeys.map(base.hex.encode).includes(pk);
|
|
5415
6029
|
});
|
|
5416
6030
|
}
|
|
@@ -5418,20 +6032,6 @@ function isAnnotated(v) {
|
|
|
5418
6032
|
return v.tapTree !== void 0 && v.forfeitTapLeafScript !== void 0 && v.intentTapLeafScript !== void 0;
|
|
5419
6033
|
}
|
|
5420
6034
|
|
|
5421
|
-
// src/repositories/virtualTxRepository.ts
|
|
5422
|
-
var ChainedTxType = /* @__PURE__ */ ((ChainedTxType2) => {
|
|
5423
|
-
ChainedTxType2[ChainedTxType2["Unspecified"] = 0] = "Unspecified";
|
|
5424
|
-
ChainedTxType2[ChainedTxType2["Commitment"] = 1] = "Commitment";
|
|
5425
|
-
ChainedTxType2[ChainedTxType2["Ark"] = 2] = "Ark";
|
|
5426
|
-
ChainedTxType2[ChainedTxType2["Tree"] = 3] = "Tree";
|
|
5427
|
-
ChainedTxType2[ChainedTxType2["Checkpoint"] = 4] = "Checkpoint";
|
|
5428
|
-
return ChainedTxType2;
|
|
5429
|
-
})(ChainedTxType || {});
|
|
5430
|
-
function mergeChainedTxType(incoming, prev) {
|
|
5431
|
-
if (incoming !== 0 /* Unspecified */) return incoming;
|
|
5432
|
-
return prev ?? 0 /* Unspecified */;
|
|
5433
|
-
}
|
|
5434
|
-
|
|
5435
6035
|
// src/repositories/inMemory/intentRepository.ts
|
|
5436
6036
|
var InMemoryIntentRepository = class {
|
|
5437
6037
|
version = 1;
|
|
@@ -5612,7 +6212,7 @@ async function closeDatabase(dbName) {
|
|
|
5612
6212
|
return true;
|
|
5613
6213
|
}
|
|
5614
6214
|
function scriptFromArkAddress(address) {
|
|
5615
|
-
return base.hex.encode(
|
|
6215
|
+
return base.hex.encode(chunkMQB5H4X5_cjs.ArkAddress.decode(address).pkScript);
|
|
5616
6216
|
}
|
|
5617
6217
|
|
|
5618
6218
|
// src/repositories/indexedDB/schema.ts
|
|
@@ -5897,6 +6497,7 @@ var IndexedDBVirtualTxRepository = class {
|
|
|
5897
6497
|
constructor(dbName = DEFAULT_DB_NAME) {
|
|
5898
6498
|
this.dbName = dbName;
|
|
5899
6499
|
}
|
|
6500
|
+
dbName;
|
|
5900
6501
|
version = 1;
|
|
5901
6502
|
db = null;
|
|
5902
6503
|
async getDB() {
|
|
@@ -6026,6 +6627,7 @@ var IndexedDBIntentRepository = class {
|
|
|
6026
6627
|
constructor(dbName = DEFAULT_DB_NAME) {
|
|
6027
6628
|
this.dbName = dbName;
|
|
6028
6629
|
}
|
|
6630
|
+
dbName;
|
|
6029
6631
|
version = 1;
|
|
6030
6632
|
db = null;
|
|
6031
6633
|
async getDB() {
|
|
@@ -6336,6 +6938,7 @@ var IndexedDBContractRepository = class {
|
|
|
6336
6938
|
constructor(dbName = DEFAULT_DB_NAME) {
|
|
6337
6939
|
this.dbName = dbName;
|
|
6338
6940
|
}
|
|
6941
|
+
dbName;
|
|
6339
6942
|
version = 1;
|
|
6340
6943
|
db = null;
|
|
6341
6944
|
async clear() {
|
|
@@ -6502,6 +7105,7 @@ var IndexedDBWalletRepository = class {
|
|
|
6502
7105
|
constructor(dbName = DEFAULT_DB_NAME) {
|
|
6503
7106
|
this.dbName = dbName;
|
|
6504
7107
|
}
|
|
7108
|
+
dbName;
|
|
6505
7109
|
version = 1;
|
|
6506
7110
|
db = null;
|
|
6507
7111
|
async clear() {
|
|
@@ -7487,7 +8091,7 @@ var ContractWatcher = class {
|
|
|
7487
8091
|
this.connectionState = "connected";
|
|
7488
8092
|
this.reconnectAttempts = 0;
|
|
7489
8093
|
this.listenLoop().catch((e) => {
|
|
7490
|
-
if (
|
|
8094
|
+
if (chunk7IYIFMF4_cjs.isEventSourceError(e)) {
|
|
7491
8095
|
console.debug("ContractWatcher subscription disconnected; reconnecting");
|
|
7492
8096
|
} else {
|
|
7493
8097
|
console.error(e);
|
|
@@ -7822,90 +8426,33 @@ async function reconcileIntents(deps) {
|
|
|
7822
8426
|
for (const intent of intents) {
|
|
7823
8427
|
try {
|
|
7824
8428
|
const next = await classifyIntent(intent, vtxosByOutpoint, nowMs);
|
|
7825
|
-
if (!next) continue;
|
|
7826
|
-
const [fresh] = await deps.intentRepository.getIntents({
|
|
7827
|
-
intentTxIds: [intent.intentTxId]
|
|
7828
|
-
});
|
|
7829
|
-
if (!fresh || fresh.state !== intent.state) continue;
|
|
7830
|
-
await deps.intentRepository.saveIntent(next);
|
|
7831
|
-
} catch (e) {
|
|
7832
|
-
console.error(`reconcileIntents: failed to reconcile intent ${intent.intentTxId}`, e);
|
|
7833
|
-
}
|
|
7834
|
-
}
|
|
7835
|
-
}
|
|
7836
|
-
function terminal(intent, state, now, patch) {
|
|
7837
|
-
return { ...intent, ...patch, state, updatedAt: now };
|
|
7838
|
-
}
|
|
7839
|
-
function outpointKey(o) {
|
|
7840
|
-
return `${o.txid}:${o.vout}`;
|
|
7841
|
-
}
|
|
7842
|
-
function dedupeOutpoints(outpoints) {
|
|
7843
|
-
const seen = /* @__PURE__ */ new Set();
|
|
7844
|
-
const out = [];
|
|
7845
|
-
for (const o of outpoints) {
|
|
7846
|
-
const k = outpointKey(o);
|
|
7847
|
-
if (seen.has(k)) continue;
|
|
7848
|
-
seen.add(k);
|
|
7849
|
-
out.push(o);
|
|
7850
|
-
}
|
|
7851
|
-
return out;
|
|
7852
|
-
}
|
|
7853
|
-
|
|
7854
|
-
// src/utils/syncCursors.ts
|
|
7855
|
-
var SAFETY_LAG_MS = 3e4;
|
|
7856
|
-
var OVERLAP_MS = 24 * 60 * 60 * 1e3;
|
|
7857
|
-
var walletStateLocks = /* @__PURE__ */ new WeakMap();
|
|
7858
|
-
async function updateWalletState(repo, updater) {
|
|
7859
|
-
const prev = walletStateLocks.get(repo) ?? Promise.resolve();
|
|
7860
|
-
const op = prev.then(async () => {
|
|
7861
|
-
const state = await repo.getWalletState() ?? {};
|
|
7862
|
-
await repo.saveWalletState(updater(state));
|
|
7863
|
-
});
|
|
7864
|
-
walletStateLocks.set(
|
|
7865
|
-
repo,
|
|
7866
|
-
op.catch(() => {
|
|
7867
|
-
})
|
|
7868
|
-
);
|
|
7869
|
-
return op;
|
|
7870
|
-
}
|
|
7871
|
-
var CURSOR_MIGRATED_KEY = "vtxoCursorMigrated";
|
|
7872
|
-
function hasMigrationMarker(state) {
|
|
7873
|
-
return state?.settings?.[CURSOR_MIGRATED_KEY] === true;
|
|
7874
|
-
}
|
|
7875
|
-
async function getSyncCursor(repo) {
|
|
7876
|
-
const state = await repo.getWalletState();
|
|
7877
|
-
if (!hasMigrationMarker(state)) return 0;
|
|
7878
|
-
return state?.lastSyncTime ?? 0;
|
|
7879
|
-
}
|
|
7880
|
-
async function advanceSyncCursor(repo, lastUpdatedAt) {
|
|
7881
|
-
await updateWalletState(repo, (state) => {
|
|
7882
|
-
const current = hasMigrationMarker(state) ? state.lastSyncTime ?? 0 : 0;
|
|
7883
|
-
return {
|
|
7884
|
-
...state,
|
|
7885
|
-
lastSyncTime: Math.max(current, lastUpdatedAt),
|
|
7886
|
-
settings: {
|
|
7887
|
-
...state.settings ?? {},
|
|
7888
|
-
[CURSOR_MIGRATED_KEY]: true
|
|
7889
|
-
}
|
|
7890
|
-
};
|
|
7891
|
-
});
|
|
8429
|
+
if (!next) continue;
|
|
8430
|
+
const [fresh] = await deps.intentRepository.getIntents({
|
|
8431
|
+
intentTxIds: [intent.intentTxId]
|
|
8432
|
+
});
|
|
8433
|
+
if (!fresh || fresh.state !== intent.state) continue;
|
|
8434
|
+
await deps.intentRepository.saveIntent(next);
|
|
8435
|
+
} catch (e) {
|
|
8436
|
+
console.error(`reconcileIntents: failed to reconcile intent ${intent.intentTxId}`, e);
|
|
8437
|
+
}
|
|
8438
|
+
}
|
|
7892
8439
|
}
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
const { [CURSOR_MIGRATED_KEY]: _, ...restSettings } = state.settings ?? {};
|
|
7896
|
-
return {
|
|
7897
|
-
...state,
|
|
7898
|
-
lastSyncTime: void 0,
|
|
7899
|
-
settings: restSettings
|
|
7900
|
-
};
|
|
7901
|
-
});
|
|
8440
|
+
function terminal(intent, state, now, patch) {
|
|
8441
|
+
return { ...intent, ...patch, state, updatedAt: now };
|
|
7902
8442
|
}
|
|
7903
|
-
function
|
|
7904
|
-
|
|
7905
|
-
return { after };
|
|
8443
|
+
function outpointKey(o) {
|
|
8444
|
+
return `${o.txid}:${o.vout}`;
|
|
7906
8445
|
}
|
|
7907
|
-
function
|
|
7908
|
-
|
|
8446
|
+
function dedupeOutpoints(outpoints) {
|
|
8447
|
+
const seen = /* @__PURE__ */ new Set();
|
|
8448
|
+
const out = [];
|
|
8449
|
+
for (const o of outpoints) {
|
|
8450
|
+
const k = outpointKey(o);
|
|
8451
|
+
if (seen.has(k)) continue;
|
|
8452
|
+
seen.add(k);
|
|
8453
|
+
out.push(o);
|
|
8454
|
+
}
|
|
8455
|
+
return out;
|
|
7909
8456
|
}
|
|
7910
8457
|
|
|
7911
8458
|
// src/contracts/contractManager.ts
|
|
@@ -7920,6 +8467,10 @@ var ContractManager = class _ContractManager {
|
|
|
7920
8467
|
initialized = false;
|
|
7921
8468
|
eventCallbacks = /* @__PURE__ */ new Set();
|
|
7922
8469
|
stopWatcherFn;
|
|
8470
|
+
/** `undefined` while online; the failure reason once a sync degrades. */
|
|
8471
|
+
syncDegradedReason;
|
|
8472
|
+
/** Epoch-ms of the last successful provider sync, if any. */
|
|
8473
|
+
lastSyncedAt;
|
|
7923
8474
|
constructor(config) {
|
|
7924
8475
|
this.config = config;
|
|
7925
8476
|
this.watcher = new ContractWatcher({
|
|
@@ -7942,6 +8493,26 @@ var ContractManager = class _ContractManager {
|
|
|
7942
8493
|
await cm.initialize();
|
|
7943
8494
|
return cm;
|
|
7944
8495
|
}
|
|
8496
|
+
/**
|
|
8497
|
+
* Latest provider-sync health. See {@link ContractSyncState}. Degradation is
|
|
8498
|
+
* recorded by {@link initialize}, {@link getContractsWithVtxos}, and
|
|
8499
|
+
* {@link createContract}; it flips back to `online` on the next successful
|
|
8500
|
+
* sync. Purely a freshness signal — not a source of truth for wallet data.
|
|
8501
|
+
*/
|
|
8502
|
+
getSyncState() {
|
|
8503
|
+
return this.syncDegradedReason === void 0 ? { mode: "online", lastSyncedAt: this.lastSyncedAt } : {
|
|
8504
|
+
mode: "degraded",
|
|
8505
|
+
reason: this.syncDegradedReason,
|
|
8506
|
+
lastSyncedAt: this.lastSyncedAt
|
|
8507
|
+
};
|
|
8508
|
+
}
|
|
8509
|
+
markSyncOnline() {
|
|
8510
|
+
this.syncDegradedReason = void 0;
|
|
8511
|
+
this.lastSyncedAt = Date.now();
|
|
8512
|
+
}
|
|
8513
|
+
markSyncDegraded(err) {
|
|
8514
|
+
this.syncDegradedReason = err instanceof Error ? err.message : String(err);
|
|
8515
|
+
}
|
|
7945
8516
|
async initialize() {
|
|
7946
8517
|
if (this.initialized) {
|
|
7947
8518
|
return;
|
|
@@ -7950,7 +8521,13 @@ var ContractManager = class _ContractManager {
|
|
|
7950
8521
|
for (const contract of contracts) {
|
|
7951
8522
|
await this.watcher.addContract(contract);
|
|
7952
8523
|
}
|
|
7953
|
-
|
|
8524
|
+
try {
|
|
8525
|
+
await this.reconcileWatched();
|
|
8526
|
+
this.markSyncOnline();
|
|
8527
|
+
} catch (err) {
|
|
8528
|
+
if (!isRetryableProviderError(err)) throw err;
|
|
8529
|
+
this.markSyncDegraded(err);
|
|
8530
|
+
}
|
|
7954
8531
|
this.initialized = true;
|
|
7955
8532
|
this.stopWatcherFn = await this.watcher.startWatching((event) => {
|
|
7956
8533
|
this.handleContractEvent(event).catch((error) => {
|
|
@@ -8004,7 +8581,13 @@ var ContractManager = class _ContractManager {
|
|
|
8004
8581
|
async createContract(params) {
|
|
8005
8582
|
const { contract, persisted } = await this.upsertContract(params);
|
|
8006
8583
|
if (persisted) {
|
|
8007
|
-
|
|
8584
|
+
try {
|
|
8585
|
+
await this.fetchContractVxosFromIndexer([contract]);
|
|
8586
|
+
this.markSyncOnline();
|
|
8587
|
+
} catch (err) {
|
|
8588
|
+
if (!isRetryableProviderError(err)) throw err;
|
|
8589
|
+
this.markSyncDegraded(err);
|
|
8590
|
+
}
|
|
8008
8591
|
await this.watcher.addContract(contract);
|
|
8009
8592
|
}
|
|
8010
8593
|
return contract;
|
|
@@ -8034,7 +8617,7 @@ var ContractManager = class _ContractManager {
|
|
|
8034
8617
|
* `persisted` is `true`.
|
|
8035
8618
|
*/
|
|
8036
8619
|
async upsertContract(params) {
|
|
8037
|
-
const handler =
|
|
8620
|
+
const handler = chunk4KXOCVXP_cjs.contractHandlers.get(params.type);
|
|
8038
8621
|
if (!handler) {
|
|
8039
8622
|
throw new Error(`No handler registered for contract type '${params.type}'`);
|
|
8040
8623
|
}
|
|
@@ -8117,7 +8700,7 @@ var ContractManager = class _ContractManager {
|
|
|
8117
8700
|
`scanContracts: batchSize must be a positive integer (got ${String(opts.batchSize)})`
|
|
8118
8701
|
);
|
|
8119
8702
|
}
|
|
8120
|
-
const registered =
|
|
8703
|
+
const registered = chunk4KXOCVXP_cjs.contractHandlers.getRegisteredTypes().map((t) => chunk4KXOCVXP_cjs.contractHandlers.get(t)).filter(isDiscoverable);
|
|
8121
8704
|
const discoverables = [
|
|
8122
8705
|
...registered.filter((h) => h.type === "boarding"),
|
|
8123
8706
|
...registered.filter((h) => h.type !== "boarding")
|
|
@@ -8203,7 +8786,13 @@ var ContractManager = class _ContractManager {
|
|
|
8203
8786
|
}
|
|
8204
8787
|
async getContractsWithVtxos(filter, pageSize) {
|
|
8205
8788
|
const contracts = await this.getContracts(filter);
|
|
8206
|
-
|
|
8789
|
+
try {
|
|
8790
|
+
await this.syncContracts({ contracts, pageSize });
|
|
8791
|
+
this.markSyncOnline();
|
|
8792
|
+
} catch (err) {
|
|
8793
|
+
if (!isRetryableProviderError(err)) throw err;
|
|
8794
|
+
this.markSyncDegraded(err);
|
|
8795
|
+
}
|
|
8207
8796
|
const vtxos = await this.getVtxosForContracts(contracts);
|
|
8208
8797
|
return contracts.map((contract) => ({
|
|
8209
8798
|
contract,
|
|
@@ -8301,7 +8890,7 @@ var ContractManager = class _ContractManager {
|
|
|
8301
8890
|
const { contractScript, collaborative = true, walletPubKey, vtxo } = options;
|
|
8302
8891
|
const [contract] = await this.getContracts({ script: contractScript });
|
|
8303
8892
|
if (!contract) return [];
|
|
8304
|
-
const handler =
|
|
8893
|
+
const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
|
|
8305
8894
|
if (!handler) return [];
|
|
8306
8895
|
const script = handler.createScript(contract.params);
|
|
8307
8896
|
const context = {
|
|
@@ -8321,7 +8910,7 @@ var ContractManager = class _ContractManager {
|
|
|
8321
8910
|
const { contractScript, collaborative = true, walletPubKey } = options;
|
|
8322
8911
|
const [contract] = await this.getContracts({ script: contractScript });
|
|
8323
8912
|
if (!contract) return [];
|
|
8324
|
-
const handler =
|
|
8913
|
+
const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
|
|
8325
8914
|
if (!handler) return [];
|
|
8326
8915
|
const script = handler.createScript(contract.params);
|
|
8327
8916
|
const context = {
|
|
@@ -8441,15 +9030,33 @@ var ContractManager = class _ContractManager {
|
|
|
8441
9030
|
* Handle events from the watcher.
|
|
8442
9031
|
*/
|
|
8443
9032
|
async handleContractEvent(event) {
|
|
8444
|
-
|
|
8445
|
-
|
|
8446
|
-
|
|
8447
|
-
|
|
8448
|
-
|
|
8449
|
-
|
|
8450
|
-
|
|
8451
|
-
|
|
8452
|
-
|
|
9033
|
+
try {
|
|
9034
|
+
switch (event.type) {
|
|
9035
|
+
// Delta-sync only the changed virtual outputs for this contract.
|
|
9036
|
+
case "vtxo_received":
|
|
9037
|
+
await this.syncContracts({ contracts: [event.contract] });
|
|
9038
|
+
this.markSyncOnline();
|
|
9039
|
+
break;
|
|
9040
|
+
case "vtxo_spent":
|
|
9041
|
+
await this.syncContracts({ contracts: [event.contract] });
|
|
9042
|
+
this.markSyncOnline();
|
|
9043
|
+
if (this.config.onVtxosSpent) {
|
|
9044
|
+
try {
|
|
9045
|
+
await this.config.onVtxosSpent(
|
|
9046
|
+
event.vtxos.map((v) => ({ txid: v.txid, vout: v.vout }))
|
|
9047
|
+
);
|
|
9048
|
+
} catch {
|
|
9049
|
+
}
|
|
9050
|
+
}
|
|
9051
|
+
break;
|
|
9052
|
+
case "connection_reset":
|
|
9053
|
+
await this.reconcileWatched();
|
|
9054
|
+
this.markSyncOnline();
|
|
9055
|
+
break;
|
|
9056
|
+
}
|
|
9057
|
+
} catch (err) {
|
|
9058
|
+
if (!isRetryableProviderError(err)) throw err;
|
|
9059
|
+
this.markSyncDegraded(err);
|
|
8453
9060
|
}
|
|
8454
9061
|
this.emitEvent(event);
|
|
8455
9062
|
}
|
|
@@ -8531,6 +9138,12 @@ var ContractManager = class _ContractManager {
|
|
|
8531
9138
|
contract,
|
|
8532
9139
|
filtered
|
|
8533
9140
|
);
|
|
9141
|
+
if (this.config.onVtxosPersisted) {
|
|
9142
|
+
try {
|
|
9143
|
+
await this.config.onVtxosPersisted(contract, filtered);
|
|
9144
|
+
} catch {
|
|
9145
|
+
}
|
|
9146
|
+
}
|
|
8534
9147
|
}
|
|
8535
9148
|
}
|
|
8536
9149
|
async fetchContractVxosFromIndexer(contracts, pageSize, syncWindow) {
|
|
@@ -8551,11 +9164,20 @@ var ContractManager = class _ContractManager {
|
|
|
8551
9164
|
contract,
|
|
8552
9165
|
filtered
|
|
8553
9166
|
);
|
|
9167
|
+
if (this.config.onVtxosPersisted) {
|
|
9168
|
+
try {
|
|
9169
|
+
await this.config.onVtxosPersisted(
|
|
9170
|
+
contract,
|
|
9171
|
+
filtered
|
|
9172
|
+
);
|
|
9173
|
+
} catch {
|
|
9174
|
+
}
|
|
9175
|
+
}
|
|
8554
9176
|
}
|
|
8555
9177
|
}
|
|
8556
9178
|
return result;
|
|
8557
9179
|
}
|
|
8558
|
-
async fetchContractVtxosBulk(contracts, pageSize =
|
|
9180
|
+
async fetchContractVtxosBulk(contracts, pageSize = chunk4KXOCVXP_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
|
|
8559
9181
|
if (contracts.length === 0) {
|
|
8560
9182
|
return /* @__PURE__ */ new Map();
|
|
8561
9183
|
}
|
|
@@ -8629,6 +9251,8 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
|
|
|
8629
9251
|
this.identity = identity;
|
|
8630
9252
|
this.walletRepository = walletRepository;
|
|
8631
9253
|
}
|
|
9254
|
+
identity;
|
|
9255
|
+
walletRepository;
|
|
8632
9256
|
/**
|
|
8633
9257
|
* Construct an HDDescriptorProvider. No I/O is performed here;
|
|
8634
9258
|
* persisted state is read lazily on the first call to
|
|
@@ -8731,7 +9355,7 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
|
|
|
8731
9355
|
*/
|
|
8732
9356
|
materializeDescriptorAt(index) {
|
|
8733
9357
|
const descriptor = this.identity.descriptor;
|
|
8734
|
-
const network =
|
|
9358
|
+
const network = chunk4KXOCVXP_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
8735
9359
|
const expansion = descriptorsScure.expand({ descriptor, network, index });
|
|
8736
9360
|
const keyInfo = expansion.expansionMap?.["@0"];
|
|
8737
9361
|
if (!keyInfo?.keyExpression) {
|
|
@@ -8821,6 +9445,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
8821
9445
|
this.currentTaggedScript = priorTaggedScript;
|
|
8822
9446
|
this.logger = logger ?? console;
|
|
8823
9447
|
}
|
|
9448
|
+
provider;
|
|
8824
9449
|
unsubscribe;
|
|
8825
9450
|
chain = Promise.resolve();
|
|
8826
9451
|
/**
|
|
@@ -8874,7 +9499,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
8874
9499
|
const provider = await resolveDescriptorProvider(config, setup.walletRepository);
|
|
8875
9500
|
if (!provider) return void 0;
|
|
8876
9501
|
const allowSilentFallback = (config.walletMode ?? "auto") === "auto";
|
|
8877
|
-
const expectedContractType = setup.offchainTapscript instanceof
|
|
9502
|
+
const expectedContractType = setup.offchainTapscript instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script ? "delegate" : "default";
|
|
8878
9503
|
const factoryOpts = {
|
|
8879
9504
|
walletRepository: setup.walletRepository,
|
|
8880
9505
|
contractRepository: setup.contractRepository,
|
|
@@ -9057,7 +9682,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
9057
9682
|
const newAddress = newTapscript.address(wallet.network.hrp, wallet.arkServerPublicKey).encode();
|
|
9058
9683
|
const manager = await wallet.getContractManager();
|
|
9059
9684
|
const csvTimelock = newTapscript.options.csvTimelock;
|
|
9060
|
-
const csvTimelockStr =
|
|
9685
|
+
const csvTimelockStr = chunkMQB5H4X5_cjs.timelockToSequence(csvTimelock).toString();
|
|
9061
9686
|
const serverPubKeyHex = base.hex.encode(newTapscript.options.serverPubKey);
|
|
9062
9687
|
const baseParams = {
|
|
9063
9688
|
script: newScript,
|
|
@@ -9071,11 +9696,11 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
9071
9696
|
// produce unsigned PSBTs that the server rejects with
|
|
9072
9697
|
// `INVALID_PSBT_INPUT (5): missing tapscript spend sig`.
|
|
9073
9698
|
metadata: {
|
|
9074
|
-
source:
|
|
9699
|
+
source: chunk4KXOCVXP_cjs.WALLET_RECEIVE_SOURCE,
|
|
9075
9700
|
signingDescriptor: descriptor
|
|
9076
9701
|
}
|
|
9077
9702
|
};
|
|
9078
|
-
if (newTapscript instanceof
|
|
9703
|
+
if (newTapscript instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script) {
|
|
9079
9704
|
await manager.createContract({
|
|
9080
9705
|
...baseParams,
|
|
9081
9706
|
type: "delegate",
|
|
@@ -9107,7 +9732,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
9107
9732
|
};
|
|
9108
9733
|
function deriveLeafPubkey(descriptor) {
|
|
9109
9734
|
try {
|
|
9110
|
-
return
|
|
9735
|
+
return chunk4KXOCVXP_cjs.deriveDescriptorLeafPubKey(descriptor);
|
|
9111
9736
|
} catch (e) {
|
|
9112
9737
|
throw new NonRangeableDescriptorError(
|
|
9113
9738
|
"Cannot derive leaf pubkey: descriptor is not a materialized, parsable tr(...) shape.",
|
|
@@ -9116,10 +9741,10 @@ function deriveLeafPubkey(descriptor) {
|
|
|
9116
9741
|
}
|
|
9117
9742
|
}
|
|
9118
9743
|
function rebuildTapscript(current, pubKey) {
|
|
9119
|
-
if (current instanceof
|
|
9120
|
-
return new
|
|
9744
|
+
if (current instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script) {
|
|
9745
|
+
return new chunk4KXOCVXP_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
|
|
9121
9746
|
}
|
|
9122
|
-
return new
|
|
9747
|
+
return new chunk4KXOCVXP_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
|
|
9123
9748
|
}
|
|
9124
9749
|
async function pickActiveReceive(contractRepository, serverPubKey, expectedType) {
|
|
9125
9750
|
const candidates = await contractRepository.getContracts({
|
|
@@ -9128,7 +9753,7 @@ async function pickActiveReceive(contractRepository, serverPubKey, expectedType)
|
|
|
9128
9753
|
});
|
|
9129
9754
|
const serverPubKeyHex = base.hex.encode(serverPubKey);
|
|
9130
9755
|
const matching = candidates.filter(
|
|
9131
|
-
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source ===
|
|
9756
|
+
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunk4KXOCVXP_cjs.WALLET_RECEIVE_SOURCE
|
|
9132
9757
|
).sort((a, b) => {
|
|
9133
9758
|
if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
|
|
9134
9759
|
return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
|
|
@@ -9174,6 +9799,8 @@ var MissingSigningDescriptorError = class extends Error {
|
|
|
9174
9799
|
this.contractScript = contractScript;
|
|
9175
9800
|
this.contractType = contractType;
|
|
9176
9801
|
}
|
|
9802
|
+
contractScript;
|
|
9803
|
+
contractType;
|
|
9177
9804
|
name = "MissingSigningDescriptorError";
|
|
9178
9805
|
};
|
|
9179
9806
|
var DescriptorSigningProviderMissingError = class extends Error {
|
|
@@ -9189,6 +9816,7 @@ var InputSignerRouter = class {
|
|
|
9189
9816
|
constructor(deps) {
|
|
9190
9817
|
this.deps = deps;
|
|
9191
9818
|
}
|
|
9819
|
+
deps;
|
|
9192
9820
|
/**
|
|
9193
9821
|
* Resolve each job to its target signer without invoking signing. The
|
|
9194
9822
|
* returned plan is the single source of truth for both {@link sign} and
|
|
@@ -9301,12 +9929,12 @@ var InputSignerRouter = class {
|
|
|
9301
9929
|
};
|
|
9302
9930
|
|
|
9303
9931
|
// src/wallet/wallet.ts
|
|
9304
|
-
var getArkadeServerUrl = ({ arkServerUrl }) => arkServerUrl ||
|
|
9932
|
+
var getArkadeServerUrl = ({ arkServerUrl }) => arkServerUrl || chunkMQB5H4X5_cjs.DEFAULT_ARKADE_SERVER_URL;
|
|
9305
9933
|
function intentProofJobs(coins) {
|
|
9306
9934
|
if (coins.length === 0) return [];
|
|
9307
9935
|
const coinJobs = coins.map((coin, i) => ({
|
|
9308
9936
|
index: i + 1,
|
|
9309
|
-
lookupScript:
|
|
9937
|
+
lookupScript: chunkMQB5H4X5_cjs.VtxoScript.decode(coin.tapTree).pkScript
|
|
9310
9938
|
}));
|
|
9311
9939
|
return [{ index: 0, lookupScript: coinJobs[0].lookupScript }, ...coinJobs];
|
|
9312
9940
|
}
|
|
@@ -9330,7 +9958,7 @@ function dedupeTimelocks(timelocks) {
|
|
|
9330
9958
|
const seen = /* @__PURE__ */ new Set();
|
|
9331
9959
|
const deduped = [];
|
|
9332
9960
|
for (const timelock of timelocks) {
|
|
9333
|
-
const sequence =
|
|
9961
|
+
const sequence = chunkMQB5H4X5_cjs.timelockToSequence(timelock).toString();
|
|
9334
9962
|
if (seen.has(sequence)) continue;
|
|
9335
9963
|
seen.add(sequence);
|
|
9336
9964
|
deduped.push(timelock);
|
|
@@ -9347,7 +9975,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
|
|
|
9347
9975
|
state: "active"
|
|
9348
9976
|
});
|
|
9349
9977
|
const newest = candidates.filter(
|
|
9350
|
-
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source ===
|
|
9978
|
+
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunk4KXOCVXP_cjs.WALLET_RECEIVE_SOURCE
|
|
9351
9979
|
).sort((a, b) => {
|
|
9352
9980
|
if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
|
|
9353
9981
|
return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
|
|
@@ -9355,7 +9983,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
|
|
|
9355
9983
|
if (!newest?.params.pubKey) return baseline;
|
|
9356
9984
|
try {
|
|
9357
9985
|
const pubKey = base.hex.decode(newest.params.pubKey);
|
|
9358
|
-
return new
|
|
9986
|
+
return new chunk4KXOCVXP_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
|
|
9359
9987
|
} catch (e) {
|
|
9360
9988
|
console.warn("Skipping malformed boarding contract at boot", newest.script, e);
|
|
9361
9989
|
return baseline;
|
|
@@ -9407,6 +10035,14 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9407
10035
|
this._assetManager = new ReadonlyAssetManager(this.indexerProvider);
|
|
9408
10036
|
this.walletContractTimelocks = walletContractTimelocks && walletContractTimelocks.length > 0 ? dedupeTimelocks(walletContractTimelocks) : [this.offchainTapscript.options.csvTimelock];
|
|
9409
10037
|
}
|
|
10038
|
+
identity;
|
|
10039
|
+
network;
|
|
10040
|
+
onchainProvider;
|
|
10041
|
+
indexerProvider;
|
|
10042
|
+
dustAmount;
|
|
10043
|
+
walletRepository;
|
|
10044
|
+
contractRepository;
|
|
10045
|
+
delegateProvider;
|
|
9410
10046
|
_contractManager;
|
|
9411
10047
|
_contractManagerInitializing;
|
|
9412
10048
|
watcherConfig;
|
|
@@ -9424,6 +10060,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9424
10060
|
* (ContractManager isn't given it); `undefined` ⇒ no-op.
|
|
9425
10061
|
*/
|
|
9426
10062
|
virtualTxRepository;
|
|
10063
|
+
/** Opt-in exit-data capture settings; see {@link StorageConfig.exitDataCapture}. */
|
|
10064
|
+
exitDataCapture;
|
|
9427
10065
|
_assetManager;
|
|
9428
10066
|
walletContractTimelocks;
|
|
9429
10067
|
// Outpoints ("txid:vout") committed to an in-flight settle/send. Filtered
|
|
@@ -9466,6 +10104,72 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9466
10104
|
* construction-time snapshot for their lifetime.
|
|
9467
10105
|
*/
|
|
9468
10106
|
_arkServerPublicKey;
|
|
10107
|
+
/**
|
|
10108
|
+
* Whether this wallet was constructed from live operator server-info
|
|
10109
|
+
* (`"live"`) or from a cached snapshot because the operator was unreachable
|
|
10110
|
+
* (`"cache"`). Freshness signal for {@link getProviderConnectionState}.
|
|
10111
|
+
*/
|
|
10112
|
+
_serverInfoSource = "live";
|
|
10113
|
+
/**
|
|
10114
|
+
* Epoch-ms of the last known live operator contact: construction time on the
|
|
10115
|
+
* `live` boot path, the cached snapshot's `savedAt` on the `cache` path.
|
|
10116
|
+
*/
|
|
10117
|
+
_serverInfoLastOnlineAt;
|
|
10118
|
+
/** @see {@link _serverInfoSource} */
|
|
10119
|
+
get serverInfoSource() {
|
|
10120
|
+
return this._serverInfoSource;
|
|
10121
|
+
}
|
|
10122
|
+
/**
|
|
10123
|
+
* Composed provider-connection freshness: the boot server-info source
|
|
10124
|
+
* (Arkade) combined with the contract-manager's indexer-sync health, if the
|
|
10125
|
+
* manager has been initialized. Reads no live provider state — it never
|
|
10126
|
+
* forces a `ContractManager` to construct — so it is safe for readonly
|
|
10127
|
+
* callers that only use address/balance APIs.
|
|
10128
|
+
*
|
|
10129
|
+
* - Boot fell back to a cached snapshot → degraded on `arkade` (`cache`).
|
|
10130
|
+
* - Otherwise, if the contract manager has degraded to repository data →
|
|
10131
|
+
* degraded on `indexer` (`repository`).
|
|
10132
|
+
* - Otherwise online.
|
|
10133
|
+
*
|
|
10134
|
+
* This only describes sync freshness; wallet balances/VTXOs are always read
|
|
10135
|
+
* from the repository regardless of this state.
|
|
10136
|
+
*/
|
|
10137
|
+
getProviderConnectionState() {
|
|
10138
|
+
if (this._serverInfoSource === "cache") {
|
|
10139
|
+
return {
|
|
10140
|
+
mode: "degraded",
|
|
10141
|
+
source: "cache",
|
|
10142
|
+
provider: "arkade",
|
|
10143
|
+
reason: "constructed from cached server-info; operator was unreachable at boot",
|
|
10144
|
+
lastOnlineAt: this._serverInfoLastOnlineAt
|
|
10145
|
+
};
|
|
10146
|
+
}
|
|
10147
|
+
const sync = this._contractManager?.getSyncState();
|
|
10148
|
+
if (sync?.mode === "degraded") {
|
|
10149
|
+
return {
|
|
10150
|
+
mode: "degraded",
|
|
10151
|
+
source: "repository",
|
|
10152
|
+
provider: "indexer",
|
|
10153
|
+
reason: sync.reason,
|
|
10154
|
+
lastOnlineAt: sync.lastSyncedAt ?? this._serverInfoLastOnlineAt
|
|
10155
|
+
};
|
|
10156
|
+
}
|
|
10157
|
+
return {
|
|
10158
|
+
mode: "online",
|
|
10159
|
+
source: "live",
|
|
10160
|
+
lastOnlineAt: sync?.lastSyncedAt ?? this._serverInfoLastOnlineAt ?? 0
|
|
10161
|
+
};
|
|
10162
|
+
}
|
|
10163
|
+
/**
|
|
10164
|
+
* The contract-manager's current provider-sync health **without forcing it
|
|
10165
|
+
* to initialize** — reads the already-constructed manager, or reports
|
|
10166
|
+
* `online` when none exists yet. Unlike {@link getContractManager}, this
|
|
10167
|
+
* never triggers a remote sync, so it is safe on a pure diagnostics path
|
|
10168
|
+
* (e.g. the service-worker sync-state message).
|
|
10169
|
+
*/
|
|
10170
|
+
getContractSyncState() {
|
|
10171
|
+
return this._contractManager?.getSyncState() ?? { mode: "online" };
|
|
10172
|
+
}
|
|
9469
10173
|
/**
|
|
9470
10174
|
* x-only hex of the operator's deprecated signer keys (from
|
|
9471
10175
|
* `ArkInfo.deprecatedSigners`), cached for the OFFLINE read/watch paths.
|
|
@@ -9581,7 +10285,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9581
10285
|
*/
|
|
9582
10286
|
static async setupWalletConfig(config, pubKey) {
|
|
9583
10287
|
const arkadeServerUrl = getArkadeServerUrl(config);
|
|
9584
|
-
const arkProvider = config.arkProvider || new
|
|
10288
|
+
const arkProvider = config.arkProvider || new chunk7IYIFMF4_cjs.RestArkProvider(arkadeServerUrl);
|
|
9585
10289
|
let indexerProvider = config.indexerProvider;
|
|
9586
10290
|
if (!indexerProvider) {
|
|
9587
10291
|
let indexerUrl = config.indexerUrl;
|
|
@@ -9598,10 +10302,16 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9598
10302
|
indexerUrl = arkadeServerUrl;
|
|
9599
10303
|
}
|
|
9600
10304
|
}
|
|
9601
|
-
indexerProvider = new
|
|
10305
|
+
indexerProvider = new chunk7IYIFMF4_cjs.RestIndexerProvider(indexerUrl);
|
|
9602
10306
|
}
|
|
9603
|
-
const
|
|
9604
|
-
const
|
|
10307
|
+
const walletRepository = config.storage?.walletRepository ?? new IndexedDBWalletRepository();
|
|
10308
|
+
const contractRepository = config.storage?.contractRepository ?? new IndexedDBContractRepository();
|
|
10309
|
+
const {
|
|
10310
|
+
info,
|
|
10311
|
+
source: serverInfoSource,
|
|
10312
|
+
lastOnlineAt: serverInfoLastOnlineAt
|
|
10313
|
+
} = await resolveArkInfo(arkProvider, walletRepository);
|
|
10314
|
+
const network = chunkMQB5H4X5_cjs.getNetwork(info.network);
|
|
9605
10315
|
if ("descriptor" in config.identity) {
|
|
9606
10316
|
const descriptor = config.identity.descriptor;
|
|
9607
10317
|
const identityIsMainnet = !descriptor.includes("tpub");
|
|
@@ -9648,14 +10358,12 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9648
10358
|
serverPubKey,
|
|
9649
10359
|
csvTimelock: exitTimelock
|
|
9650
10360
|
};
|
|
9651
|
-
const offchainTapscript = !delegatePubKey ? new
|
|
9652
|
-
const boardingTapscript =
|
|
10361
|
+
const offchainTapscript = !delegatePubKey ? new chunk4KXOCVXP_cjs.DefaultVtxo.Script(offchainOptions) : new chunk4KXOCVXP_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
|
|
10362
|
+
const boardingTapscript = chunk4KXOCVXP_cjs.BoardingContractHandler.createScript({
|
|
9653
10363
|
pubKey: base.hex.encode(pubKey),
|
|
9654
10364
|
serverPubKey: base.hex.encode(serverPubKey),
|
|
9655
|
-
csvTimelock:
|
|
10365
|
+
csvTimelock: chunkMQB5H4X5_cjs.timelockToSequence(boardingTimelock).toString()
|
|
9656
10366
|
});
|
|
9657
|
-
const walletRepository = config.storage?.walletRepository ?? new IndexedDBWalletRepository();
|
|
9658
|
-
const contractRepository = config.storage?.contractRepository ?? new IndexedDBContractRepository();
|
|
9659
10367
|
return {
|
|
9660
10368
|
arkProvider,
|
|
9661
10369
|
indexerProvider,
|
|
@@ -9669,6 +10377,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9669
10377
|
walletRepository,
|
|
9670
10378
|
contractRepository,
|
|
9671
10379
|
info,
|
|
10380
|
+
serverInfoSource,
|
|
10381
|
+
serverInfoLastOnlineAt,
|
|
9672
10382
|
delegateProvider: config.delegateProvider || config.delegatorProvider,
|
|
9673
10383
|
/** @deprecated alias for `delegateProvider` */
|
|
9674
10384
|
delegatorProvider: config.delegateProvider || config.delegatorProvider,
|
|
@@ -9704,6 +10414,15 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9704
10414
|
);
|
|
9705
10415
|
wallet.intentRepository = config.storage?.intentRepository;
|
|
9706
10416
|
wallet.virtualTxRepository = config.storage?.virtualTxRepository;
|
|
10417
|
+
wallet.exitDataCapture = config.storage?.exitDataCapture;
|
|
10418
|
+
wallet._serverInfoSource = setup.serverInfoSource;
|
|
10419
|
+
if (setup.serverInfoSource === "live") {
|
|
10420
|
+
const now = Date.now();
|
|
10421
|
+
await saveValidatedArkInfoSnapshot(setup.walletRepository, setup.info, now);
|
|
10422
|
+
wallet._serverInfoLastOnlineAt = now;
|
|
10423
|
+
} else {
|
|
10424
|
+
wallet._serverInfoLastOnlineAt = setup.serverInfoLastOnlineAt;
|
|
10425
|
+
}
|
|
9707
10426
|
wallet.refreshDeprecatedSigners(setup.info);
|
|
9708
10427
|
return wallet;
|
|
9709
10428
|
}
|
|
@@ -9834,7 +10553,10 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9834
10553
|
const response = await contractManager.getContractsWithVtxos();
|
|
9835
10554
|
const allVtxos = response.flatMap((_) => _.vtxos);
|
|
9836
10555
|
const { boardingTxs, commitmentsToIgnore } = await this.getBoardingTxs();
|
|
9837
|
-
const getTxCreatedAt = (txid) => this.indexerProvider.getVtxos({ outpoints: [{ txid, vout: 0 }] }).then((res) => res.vtxos[0]?.createdAt.getTime())
|
|
10556
|
+
const getTxCreatedAt = (txid) => this.indexerProvider.getVtxos({ outpoints: [{ txid, vout: 0 }] }).then((res) => res.vtxos[0]?.createdAt.getTime()).catch((err) => {
|
|
10557
|
+
if (isRetryableProviderError(err)) return void 0;
|
|
10558
|
+
throw err;
|
|
10559
|
+
});
|
|
9838
10560
|
return buildTransactionHistory(allVtxos, boardingTxs, commitmentsToIgnore, getTxCreatedAt);
|
|
9839
10561
|
}
|
|
9840
10562
|
/**
|
|
@@ -9974,9 +10696,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9974
10696
|
async getBoardingTapscripts(allowedSigners) {
|
|
9975
10697
|
const byScript = /* @__PURE__ */ new Map();
|
|
9976
10698
|
const add = (s) => byScript.set(base.hex.encode(s.pkScript), s);
|
|
9977
|
-
const boardingCsv = this.boardingTapscript.options.csvTimelock ??
|
|
10699
|
+
const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunk4KXOCVXP_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
9978
10700
|
add(
|
|
9979
|
-
new
|
|
10701
|
+
new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
|
|
9980
10702
|
pubKey: await this.identity.xOnlyPublicKey(),
|
|
9981
10703
|
serverPubKey: this.boardingTapscript.options.serverPubKey,
|
|
9982
10704
|
csvTimelock: boardingCsv
|
|
@@ -9991,7 +10713,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9991
10713
|
for (const c of boardingContracts) {
|
|
9992
10714
|
if (!allowed.has(toXOnlySignerHex(c.params.serverPubKey))) continue;
|
|
9993
10715
|
try {
|
|
9994
|
-
add(
|
|
10716
|
+
add(chunk4KXOCVXP_cjs.BoardingContractHandler.createScript(c.params));
|
|
9995
10717
|
} catch (e) {
|
|
9996
10718
|
console.warn("Skipping malformed boarding contract", c.script, e);
|
|
9997
10719
|
}
|
|
@@ -10029,7 +10751,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10029
10751
|
// Per-row CSV delay decoded from THIS tapscript's exit leaf —
|
|
10030
10752
|
// not the wallet's current boarding timelock, which a signer
|
|
10031
10753
|
// rotation may have changed.
|
|
10032
|
-
csvTimelock:
|
|
10754
|
+
csvTimelock: chunkMQB5H4X5_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
|
|
10033
10755
|
coins: utxos
|
|
10034
10756
|
});
|
|
10035
10757
|
}
|
|
@@ -10195,7 +10917,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10195
10917
|
});
|
|
10196
10918
|
for (const contract of contracts) {
|
|
10197
10919
|
if (map.has(contract.script)) continue;
|
|
10198
|
-
const handler =
|
|
10920
|
+
const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
|
|
10199
10921
|
if (handler) {
|
|
10200
10922
|
const script = handler.createScript(contract.params);
|
|
10201
10923
|
map.set(contract.script, script);
|
|
@@ -10253,15 +10975,43 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10253
10975
|
}
|
|
10254
10976
|
}
|
|
10255
10977
|
async initializeContractManager() {
|
|
10978
|
+
const virtualTxRepository = this.virtualTxRepository;
|
|
10979
|
+
let onVtxosPersisted;
|
|
10980
|
+
let onVtxosSpent;
|
|
10981
|
+
if (virtualTxRepository) {
|
|
10982
|
+
const capture = this.exitDataCapture;
|
|
10983
|
+
const resolver = createExitChainResolver({
|
|
10984
|
+
indexer: this.indexerProvider,
|
|
10985
|
+
repository: virtualTxRepository,
|
|
10986
|
+
extraSources: capture?.sources
|
|
10987
|
+
});
|
|
10988
|
+
onVtxosPersisted = async (_contract, vtxos) => {
|
|
10989
|
+
for (const v of vtxos) {
|
|
10990
|
+
if (v.virtualStatus.state === "spent") continue;
|
|
10991
|
+
await captureExitBranch({
|
|
10992
|
+
resolver,
|
|
10993
|
+
repository: virtualTxRepository,
|
|
10994
|
+
vtxo: { txid: v.txid, vout: v.vout },
|
|
10995
|
+
value: v.value,
|
|
10996
|
+
mode: capture?.mode ?? DEFAULT_EXIT_CAPTURE_MODE,
|
|
10997
|
+
minExitWorthSats: capture?.minExitWorthSats ?? DEFAULT_MIN_EXIT_WORTH_SATS
|
|
10998
|
+
}).catch(() => {
|
|
10999
|
+
});
|
|
11000
|
+
}
|
|
11001
|
+
};
|
|
11002
|
+
onVtxosSpent = (vtxos) => pruneExitBranches(virtualTxRepository, vtxos);
|
|
11003
|
+
}
|
|
10256
11004
|
const manager = await ContractManager.create({
|
|
10257
11005
|
indexerProvider: this.indexerProvider,
|
|
10258
11006
|
contractRepository: this.contractRepository,
|
|
10259
11007
|
walletRepository: this.walletRepository,
|
|
10260
11008
|
intentRepository: this.intentRepository,
|
|
11009
|
+
onVtxosPersisted,
|
|
11010
|
+
onVtxosSpent,
|
|
10261
11011
|
watcherConfig: this.watcherConfig
|
|
10262
11012
|
});
|
|
10263
11013
|
const baselinePubkey = await this.identity.xOnlyPublicKey();
|
|
10264
|
-
const delegatePubKey = this.offchainTapscript instanceof
|
|
11014
|
+
const delegatePubKey = this.offchainTapscript instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
|
|
10265
11015
|
const baselineSigners = [
|
|
10266
11016
|
this.offchainTapscript.options.serverPubKey,
|
|
10267
11017
|
...[...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h))
|
|
@@ -10269,8 +11019,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10269
11019
|
const seenBaselineScripts = /* @__PURE__ */ new Set();
|
|
10270
11020
|
for (const serverPubKey of baselineSigners) {
|
|
10271
11021
|
for (const csvTimelock of this.walletContractTimelocks) {
|
|
10272
|
-
const csvTimelockStr =
|
|
10273
|
-
const defaultScript = new
|
|
11022
|
+
const csvTimelockStr = chunkMQB5H4X5_cjs.timelockToSequence(csvTimelock).toString();
|
|
11023
|
+
const defaultScript = new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
|
|
10274
11024
|
pubKey: baselinePubkey,
|
|
10275
11025
|
serverPubKey,
|
|
10276
11026
|
csvTimelock
|
|
@@ -10291,7 +11041,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10291
11041
|
});
|
|
10292
11042
|
}
|
|
10293
11043
|
if (delegatePubKey) {
|
|
10294
|
-
const delegateScript = new
|
|
11044
|
+
const delegateScript = new chunk4KXOCVXP_cjs.DelegateVtxo.Script({
|
|
10295
11045
|
pubKey: baselinePubkey,
|
|
10296
11046
|
serverPubKey,
|
|
10297
11047
|
delegatePubKey,
|
|
@@ -10315,9 +11065,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10315
11065
|
}
|
|
10316
11066
|
}
|
|
10317
11067
|
}
|
|
10318
|
-
const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ??
|
|
11068
|
+
const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunk4KXOCVXP_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
10319
11069
|
for (const serverPubKey of baselineSigners) {
|
|
10320
|
-
const baselineBoarding = new
|
|
11070
|
+
const baselineBoarding = new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
|
|
10321
11071
|
pubKey: baselinePubkey,
|
|
10322
11072
|
serverPubKey,
|
|
10323
11073
|
csvTimelock: boardingCsvTimelock
|
|
@@ -10330,7 +11080,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10330
11080
|
params: {
|
|
10331
11081
|
pubKey: base.hex.encode(baselineBoarding.options.pubKey),
|
|
10332
11082
|
serverPubKey: base.hex.encode(serverPubKey),
|
|
10333
|
-
csvTimelock:
|
|
11083
|
+
csvTimelock: chunkMQB5H4X5_cjs.timelockToSequence(boardingCsvTimelock).toString()
|
|
10334
11084
|
},
|
|
10335
11085
|
script: boardingScriptHex,
|
|
10336
11086
|
address: baselineBoarding.address(this.network.hrp, serverPubKey).encode(),
|
|
@@ -10399,6 +11149,9 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10399
11149
|
boardingPkScript: boardingTapscript.pkScript
|
|
10400
11150
|
});
|
|
10401
11151
|
}
|
|
11152
|
+
arkProvider;
|
|
11153
|
+
forfeitOutputScript;
|
|
11154
|
+
forfeitPubkey;
|
|
10402
11155
|
static MIN_FEE_RATE = 1;
|
|
10403
11156
|
// sats/vbyte
|
|
10404
11157
|
identity;
|
|
@@ -10550,25 +11303,25 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10550
11303
|
return this.getBoardingAddress();
|
|
10551
11304
|
}
|
|
10552
11305
|
const descriptor = await provider.getNextSigningDescriptor();
|
|
10553
|
-
const pubKey =
|
|
10554
|
-
const newBoarding = new
|
|
11306
|
+
const pubKey = chunk4KXOCVXP_cjs.deriveDescriptorLeafPubKey(descriptor);
|
|
11307
|
+
const newBoarding = new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
|
|
10555
11308
|
...this._boardingTapscript.options,
|
|
10556
11309
|
pubKey
|
|
10557
11310
|
});
|
|
10558
|
-
const csvTimelock = newBoarding.options.csvTimelock ??
|
|
11311
|
+
const csvTimelock = newBoarding.options.csvTimelock ?? chunk4KXOCVXP_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
10559
11312
|
const manager = await this.getContractManager();
|
|
10560
11313
|
await manager.createContract({
|
|
10561
11314
|
type: "boarding",
|
|
10562
11315
|
params: {
|
|
10563
11316
|
pubKey: base.hex.encode(pubKey),
|
|
10564
11317
|
serverPubKey: base.hex.encode(newBoarding.options.serverPubKey),
|
|
10565
|
-
csvTimelock:
|
|
11318
|
+
csvTimelock: chunkMQB5H4X5_cjs.timelockToSequence(csvTimelock).toString()
|
|
10566
11319
|
},
|
|
10567
11320
|
script: base.hex.encode(newBoarding.pkScript),
|
|
10568
11321
|
address: newBoarding.address(this.network.hrp, this.arkServerPublicKey).encode(),
|
|
10569
11322
|
state: "active",
|
|
10570
11323
|
metadata: {
|
|
10571
|
-
source:
|
|
11324
|
+
source: chunk4KXOCVXP_cjs.WALLET_RECEIVE_SOURCE,
|
|
10572
11325
|
signingDescriptor: descriptor
|
|
10573
11326
|
}
|
|
10574
11327
|
});
|
|
@@ -10607,7 +11360,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10607
11360
|
const xonly = toXOnlyPubKey(newServerPubKey);
|
|
10608
11361
|
let newServerUnrollScript;
|
|
10609
11362
|
try {
|
|
10610
|
-
newServerUnrollScript =
|
|
11363
|
+
newServerUnrollScript = chunkMQB5H4X5_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
|
|
10611
11364
|
} catch (e) {
|
|
10612
11365
|
throw new Error("Invalid checkpointTapscript from server");
|
|
10613
11366
|
}
|
|
@@ -10635,21 +11388,21 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10635
11388
|
const [currentBoardingRow] = await manager.getContracts({
|
|
10636
11389
|
script: currentBoardingScript
|
|
10637
11390
|
});
|
|
10638
|
-
const newOffchain = this.offchainTapscript instanceof
|
|
11391
|
+
const newOffchain = this.offchainTapscript instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script ? new chunk4KXOCVXP_cjs.DelegateVtxo.Script({
|
|
10639
11392
|
...this.offchainTapscript.options,
|
|
10640
11393
|
serverPubKey: xonly
|
|
10641
|
-
}) : new
|
|
11394
|
+
}) : new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
|
|
10642
11395
|
...this.offchainTapscript.options,
|
|
10643
11396
|
serverPubKey: xonly
|
|
10644
11397
|
});
|
|
10645
|
-
const newBoarding = new
|
|
11398
|
+
const newBoarding = new chunk4KXOCVXP_cjs.DefaultVtxo.Script({
|
|
10646
11399
|
...this._boardingTapscript.options,
|
|
10647
11400
|
serverPubKey: xonly
|
|
10648
11401
|
});
|
|
10649
|
-
const offchainCsv =
|
|
11402
|
+
const offchainCsv = chunkMQB5H4X5_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
|
|
10650
11403
|
const newOffchainScript = base.hex.encode(newOffchain.pkScript);
|
|
10651
11404
|
const newOffchainAddress = newOffchain.address(this.network.hrp, xonly).encode();
|
|
10652
|
-
if (newOffchain instanceof
|
|
11405
|
+
if (newOffchain instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script) {
|
|
10653
11406
|
await manager.createContract({
|
|
10654
11407
|
type: "delegate",
|
|
10655
11408
|
params: {
|
|
@@ -10677,13 +11430,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10677
11430
|
metadata: currentOffchainRow?.metadata
|
|
10678
11431
|
});
|
|
10679
11432
|
}
|
|
10680
|
-
const boardingCsv = newBoarding.options.csvTimelock ??
|
|
11433
|
+
const boardingCsv = newBoarding.options.csvTimelock ?? chunk4KXOCVXP_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
10681
11434
|
await manager.createContract({
|
|
10682
11435
|
type: "boarding",
|
|
10683
11436
|
params: {
|
|
10684
11437
|
pubKey: base.hex.encode(newBoarding.options.pubKey),
|
|
10685
11438
|
serverPubKey: base.hex.encode(xonly),
|
|
10686
|
-
csvTimelock:
|
|
11439
|
+
csvTimelock: chunkMQB5H4X5_cjs.timelockToSequence(boardingCsv).toString()
|
|
10687
11440
|
},
|
|
10688
11441
|
script: base.hex.encode(newBoarding.pkScript),
|
|
10689
11442
|
address: newBoarding.address(this.network.hrp, xonly).encode(),
|
|
@@ -10778,7 +11531,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10778
11531
|
const hd = provider instanceof HDDescriptorProvider;
|
|
10779
11532
|
const staticDescriptor = hd ? void 0 : `tr(${base.hex.encode(await this.identity.xOnlyPublicKey())})`;
|
|
10780
11533
|
const materialize = (index) => hd ? provider.materializeDescriptorAt(index) : staticDescriptor;
|
|
10781
|
-
const delegatePubKey = this.offchainTapscript instanceof
|
|
11534
|
+
const delegatePubKey = this.offchainTapscript instanceof chunk4KXOCVXP_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
|
|
10782
11535
|
const arkInfo = await this.arkProvider.getInfo();
|
|
10783
11536
|
const currentSignerPubKey = toXOnlyPubKey(base.hex.decode(arkInfo.signerPubkey));
|
|
10784
11537
|
const deprecatedSignerPubKeys = arkInfo.deprecatedSigners.map(
|
|
@@ -10797,7 +11550,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10797
11550
|
csvTimelocks: this.walletContractTimelocks,
|
|
10798
11551
|
// Boarding-exit CSV so the boarding handler can build its
|
|
10799
11552
|
// candidate script (distinct from the unilateral-exit matrix).
|
|
10800
|
-
boardingTimelock: this.boardingTapscript.options.csvTimelock ??
|
|
11553
|
+
boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunk4KXOCVXP_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
|
|
10801
11554
|
delegatePubKey
|
|
10802
11555
|
};
|
|
10803
11556
|
const result = await manager.scanContracts({
|
|
@@ -10901,7 +11654,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10901
11654
|
let serverUnrollScript;
|
|
10902
11655
|
try {
|
|
10903
11656
|
const raw = base.hex.decode(setup.info.checkpointTapscript);
|
|
10904
|
-
serverUnrollScript =
|
|
11657
|
+
serverUnrollScript = chunkMQB5H4X5_cjs.CSVMultisigTapscript.decode(raw);
|
|
10905
11658
|
} catch (e) {
|
|
10906
11659
|
throw new Error("Invalid checkpointTapscript from server");
|
|
10907
11660
|
}
|
|
@@ -10932,6 +11685,14 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10932
11685
|
boot?.rotator,
|
|
10933
11686
|
boot?.provider
|
|
10934
11687
|
);
|
|
11688
|
+
wallet._serverInfoSource = setup.serverInfoSource;
|
|
11689
|
+
if (setup.serverInfoSource === "live") {
|
|
11690
|
+
const now = Date.now();
|
|
11691
|
+
await saveValidatedArkInfoSnapshot(setup.walletRepository, setup.info, now);
|
|
11692
|
+
wallet._serverInfoLastOnlineAt = now;
|
|
11693
|
+
} else {
|
|
11694
|
+
wallet._serverInfoLastOnlineAt = setup.serverInfoLastOnlineAt;
|
|
11695
|
+
}
|
|
10935
11696
|
wallet.refreshDeprecatedSigners(setup.info);
|
|
10936
11697
|
{
|
|
10937
11698
|
const ap = setup.arkProvider;
|
|
@@ -10953,6 +11714,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10953
11714
|
}
|
|
10954
11715
|
wallet.intentRepository = config.storage?.intentRepository;
|
|
10955
11716
|
wallet.virtualTxRepository = config.storage?.virtualTxRepository;
|
|
11717
|
+
wallet.exitDataCapture = config.storage?.exitDataCapture;
|
|
10956
11718
|
await wallet.getVtxoManager();
|
|
10957
11719
|
return wallet;
|
|
10958
11720
|
}
|
|
@@ -11029,7 +11791,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11029
11791
|
inputs: params.selectedVtxos,
|
|
11030
11792
|
changeAmount: BigInt(changeAmount)
|
|
11031
11793
|
};
|
|
11032
|
-
const outputAddress =
|
|
11794
|
+
const outputAddress = chunkMQB5H4X5_cjs.ArkAddress.decode(params.address);
|
|
11033
11795
|
const outputScript = BigInt(params.amount) < this.dustAmount ? outputAddress.subdustPkScript : outputAddress.pkScript;
|
|
11034
11796
|
const outputs = [
|
|
11035
11797
|
{
|
|
@@ -11082,13 +11844,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11082
11844
|
}
|
|
11083
11845
|
}
|
|
11084
11846
|
const offchainAddress = await this.getAddress();
|
|
11085
|
-
const offchainPkScript =
|
|
11847
|
+
const offchainPkScript = chunkMQB5H4X5_cjs.ArkAddress.decode(offchainAddress).pkScript;
|
|
11086
11848
|
const offchainOutputScript = base.hex.encode(offchainPkScript);
|
|
11087
11849
|
if (!params) {
|
|
11088
11850
|
const { fees, vtxoMaxAmount } = await this.arkProvider.getInfo();
|
|
11089
11851
|
const estimator = new Estimator(fees.intentFee);
|
|
11090
11852
|
let amount = 0;
|
|
11091
|
-
const exitScript =
|
|
11853
|
+
const exitScript = chunkMQB5H4X5_cjs.CSVMultisigTapscript.decode(
|
|
11092
11854
|
base.hex.decode(this.boardingTapscript.exitScript)
|
|
11093
11855
|
);
|
|
11094
11856
|
const boardingTimelock = exitScript.params.timelock;
|
|
@@ -11154,7 +11916,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11154
11916
|
script: offchainOutputScript
|
|
11155
11917
|
});
|
|
11156
11918
|
output.amount -= BigInt(outputFee.satoshis);
|
|
11157
|
-
if (output.amount
|
|
11919
|
+
if (isSubdust(output.amount, this.dustAmount)) {
|
|
11158
11920
|
throw new Error("Output amount is below dust limit");
|
|
11159
11921
|
}
|
|
11160
11922
|
params = {
|
|
@@ -11168,7 +11930,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11168
11930
|
for (const [index, output] of params.outputs.entries()) {
|
|
11169
11931
|
let script;
|
|
11170
11932
|
try {
|
|
11171
|
-
const addr =
|
|
11933
|
+
const addr = chunkMQB5H4X5_cjs.ArkAddress.decode(output.address);
|
|
11172
11934
|
script = addr.pkScript;
|
|
11173
11935
|
hasOffchainOutputs = true;
|
|
11174
11936
|
} catch {
|
|
@@ -11402,7 +12164,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11402
12164
|
}
|
|
11403
12165
|
continue;
|
|
11404
12166
|
}
|
|
11405
|
-
if (isRecoverable(input) || isSubdust(input, this.dustAmount)) {
|
|
12167
|
+
if (isRecoverable(input) || isSubdust({ value: input.value }, this.dustAmount)) {
|
|
11406
12168
|
continue;
|
|
11407
12169
|
}
|
|
11408
12170
|
if (connectorsLeaves.length === 0) {
|
|
@@ -11430,7 +12192,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11430
12192
|
index: input.vout,
|
|
11431
12193
|
witnessUtxo: {
|
|
11432
12194
|
amount: BigInt(input.value),
|
|
11433
|
-
script:
|
|
12195
|
+
script: chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
11434
12196
|
},
|
|
11435
12197
|
sighashType: btcSigner.SigHash.DEFAULT,
|
|
11436
12198
|
tapLeafScript: [input.forfeitTapLeafScript]
|
|
@@ -11449,7 +12211,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11449
12211
|
forfeitTx = await this._signerRouter.sign(forfeitTx, [
|
|
11450
12212
|
{
|
|
11451
12213
|
index: 0,
|
|
11452
|
-
lookupScript:
|
|
12214
|
+
lookupScript: chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
11453
12215
|
}
|
|
11454
12216
|
]);
|
|
11455
12217
|
signedForfeits.push(base.base64.encode(forfeitTx.toPSBT()));
|
|
@@ -11507,7 +12269,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11507
12269
|
if (skip) {
|
|
11508
12270
|
return { skip };
|
|
11509
12271
|
}
|
|
11510
|
-
const sweepTapscript =
|
|
12272
|
+
const sweepTapscript = chunkMQB5H4X5_cjs.CSVMultisigTapscript.encode({
|
|
11511
12273
|
timelock: {
|
|
11512
12274
|
value: event.batchExpiry,
|
|
11513
12275
|
type: event.batchExpiry >= 512n ? "seconds" : "blocks"
|
|
@@ -11613,9 +12375,9 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11613
12375
|
...existing ?? {},
|
|
11614
12376
|
intentTxId,
|
|
11615
12377
|
registerProof: intent.proof,
|
|
11616
|
-
registerProofMessage:
|
|
12378
|
+
registerProofMessage: chunk7IYIFMF4_cjs.Intent.encodeMessage(intent.message),
|
|
11617
12379
|
deleteProof: deleteIntent.proof,
|
|
11618
|
-
deleteProofMessage:
|
|
12380
|
+
deleteProofMessage: chunk7IYIFMF4_cjs.Intent.encodeMessage(deleteIntent.message),
|
|
11619
12381
|
intentVtxos: inputs.map((i) => ({
|
|
11620
12382
|
txid: i.txid,
|
|
11621
12383
|
vout: i.vout
|
|
@@ -11647,7 +12409,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11647
12409
|
try {
|
|
11648
12410
|
return await this.arkProvider.registerIntent(intent);
|
|
11649
12411
|
} catch (error) {
|
|
11650
|
-
if (error instanceof
|
|
12412
|
+
if (error instanceof chunk7IYIFMF4_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
|
|
11651
12413
|
const deleteIntent = await this.makeDeleteIntentSignature(inputs);
|
|
11652
12414
|
await this.arkProvider.deleteIntent(deleteIntent);
|
|
11653
12415
|
return this.arkProvider.registerIntent(intent);
|
|
@@ -11663,7 +12425,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11663
12425
|
expire_at: 0,
|
|
11664
12426
|
cosigners_public_keys: cosignerPubKeys
|
|
11665
12427
|
};
|
|
11666
|
-
const proof =
|
|
12428
|
+
const proof = chunk7IYIFMF4_cjs.Intent.create(message, coins, outputs);
|
|
11667
12429
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
11668
12430
|
return {
|
|
11669
12431
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -11675,7 +12437,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11675
12437
|
type: "delete",
|
|
11676
12438
|
expire_at: 0
|
|
11677
12439
|
};
|
|
11678
|
-
const proof =
|
|
12440
|
+
const proof = chunk7IYIFMF4_cjs.Intent.create(message, coins, []);
|
|
11679
12441
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
11680
12442
|
return {
|
|
11681
12443
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -11687,7 +12449,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11687
12449
|
type: "get-pending-tx",
|
|
11688
12450
|
expire_at: 0
|
|
11689
12451
|
};
|
|
11690
|
-
const proof =
|
|
12452
|
+
const proof = chunk7IYIFMF4_cjs.Intent.create(message, coins, []);
|
|
11691
12453
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
11692
12454
|
return {
|
|
11693
12455
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -12103,7 +12865,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12103
12865
|
);
|
|
12104
12866
|
const arkTxJobs = inputs.map((input, index) => ({
|
|
12105
12867
|
index,
|
|
12106
|
-
lookupScript:
|
|
12868
|
+
lookupScript: chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
12107
12869
|
}));
|
|
12108
12870
|
const checkpointJobs = offchainTx.checkpoints.map(
|
|
12109
12871
|
(c) => this.inputSigningJobsFromWitnessUtxos(c)
|
|
@@ -12336,7 +13098,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12336
13098
|
} else {
|
|
12337
13099
|
let sourceAddress;
|
|
12338
13100
|
try {
|
|
12339
|
-
sourceAddress =
|
|
13101
|
+
sourceAddress = chunkMQB5H4X5_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
|
|
12340
13102
|
this.network
|
|
12341
13103
|
);
|
|
12342
13104
|
} catch {
|
|
@@ -12481,6 +13243,8 @@ var MessageBus = class {
|
|
|
12481
13243
|
this.debug = debug;
|
|
12482
13244
|
this.buildServicesFn = buildServices ?? this.buildServices.bind(this);
|
|
12483
13245
|
}
|
|
13246
|
+
walletRepository;
|
|
13247
|
+
contractRepository;
|
|
12484
13248
|
handlers;
|
|
12485
13249
|
tickIntervalMs;
|
|
12486
13250
|
messageTimeoutMs;
|
|
@@ -12645,7 +13409,7 @@ var MessageBus = class {
|
|
|
12645
13409
|
this.initialized = true;
|
|
12646
13410
|
}
|
|
12647
13411
|
async buildServices(config) {
|
|
12648
|
-
const arkProvider = new
|
|
13412
|
+
const arkProvider = new chunk7IYIFMF4_cjs.RestArkProvider(config.arkServer.url);
|
|
12649
13413
|
const storage = {
|
|
12650
13414
|
walletRepository: this.walletRepository,
|
|
12651
13415
|
contractRepository: this.contractRepository
|
|
@@ -12982,6 +13746,7 @@ var Ramps = class {
|
|
|
12982
13746
|
constructor(wallet) {
|
|
12983
13747
|
this.wallet = wallet;
|
|
12984
13748
|
}
|
|
13749
|
+
wallet;
|
|
12985
13750
|
/**
|
|
12986
13751
|
* Onboard boarding inputs.
|
|
12987
13752
|
*
|
|
@@ -13027,7 +13792,7 @@ var Ramps = class {
|
|
|
13027
13792
|
}
|
|
13028
13793
|
amount = amount ?? totalAmount;
|
|
13029
13794
|
const offchainAddress = await this.wallet.getAddress();
|
|
13030
|
-
const offchainAddr =
|
|
13795
|
+
const offchainAddr = chunkMQB5H4X5_cjs.ArkAddress.decode(offchainAddress);
|
|
13031
13796
|
const offchainScript = base.hex.encode(offchainAddr.pkScript);
|
|
13032
13797
|
const outputFee = estimator.evalOffchainOutput({
|
|
13033
13798
|
amount,
|
|
@@ -13125,7 +13890,7 @@ var Ramps = class {
|
|
|
13125
13890
|
let destinationScript;
|
|
13126
13891
|
for (const networkName of networkNames) {
|
|
13127
13892
|
try {
|
|
13128
|
-
const network =
|
|
13893
|
+
const network = chunkMQB5H4X5_cjs.networks[networkName];
|
|
13129
13894
|
const addr = btcSigner.Address(network).decode(destinationAddress);
|
|
13130
13895
|
destinationScript = btcSigner.OutScript.encode(addr);
|
|
13131
13896
|
break;
|
|
@@ -13470,10 +14235,18 @@ var WalletMessageHandler = class {
|
|
|
13470
14235
|
type: "WALLET_STATUS",
|
|
13471
14236
|
payload: {
|
|
13472
14237
|
walletInitialized: true,
|
|
13473
|
-
xOnlyPublicKey: pubKey
|
|
14238
|
+
xOnlyPublicKey: pubKey,
|
|
14239
|
+
providerConnectionState: this.readonlyWallet.getProviderConnectionState()
|
|
13474
14240
|
}
|
|
13475
14241
|
});
|
|
13476
14242
|
}
|
|
14243
|
+
case "GET_CONTRACT_SYNC_STATE": {
|
|
14244
|
+
return this.tagged({
|
|
14245
|
+
id,
|
|
14246
|
+
type: "CONTRACT_SYNC_STATE",
|
|
14247
|
+
payload: { syncState: this.readonlyWallet.getContractSyncState() }
|
|
14248
|
+
});
|
|
14249
|
+
}
|
|
13477
14250
|
case "CLEAR": {
|
|
13478
14251
|
await this.clear();
|
|
13479
14252
|
return this.tagged({
|
|
@@ -13802,7 +14575,7 @@ var WalletMessageHandler = class {
|
|
|
13802
14575
|
// Wallet methods
|
|
13803
14576
|
async handleInitWallet({ payload }) {
|
|
13804
14577
|
const { arkServerUrl } = payload;
|
|
13805
|
-
this.indexerProvider = new
|
|
14578
|
+
this.indexerProvider = new chunk7IYIFMF4_cjs.RestIndexerProvider(arkServerUrl);
|
|
13806
14579
|
await this.onWalletInitialized();
|
|
13807
14580
|
}
|
|
13808
14581
|
async handleGetBalance() {
|
|
@@ -14236,6 +15009,7 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
|
|
|
14236
15009
|
GET_BALANCE: 1e4,
|
|
14237
15010
|
GET_BOARDING_ADDRESS: 1e4,
|
|
14238
15011
|
GET_STATUS: 1e4,
|
|
15012
|
+
GET_CONTRACT_SYNC_STATE: 1e4,
|
|
14239
15013
|
GET_DELEGATE_INFO: 1e4,
|
|
14240
15014
|
IS_CONTRACT_MANAGER_WATCHING: 1e4,
|
|
14241
15015
|
// Medium reads — may involve indexer queries
|
|
@@ -14319,6 +15093,8 @@ var ServiceWorkerReadonlyAssetManager = class {
|
|
|
14319
15093
|
this.sendMessage = sendMessage;
|
|
14320
15094
|
this.messageTag = messageTag;
|
|
14321
15095
|
}
|
|
15096
|
+
sendMessage;
|
|
15097
|
+
messageTag;
|
|
14322
15098
|
async getAssetDetails(assetId) {
|
|
14323
15099
|
const message = {
|
|
14324
15100
|
tag: this.messageTag,
|
|
@@ -14403,6 +15179,8 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
14403
15179
|
messageTag
|
|
14404
15180
|
);
|
|
14405
15181
|
}
|
|
15182
|
+
serviceWorker;
|
|
15183
|
+
messageTag;
|
|
14406
15184
|
walletRepository;
|
|
14407
15185
|
contractRepository;
|
|
14408
15186
|
identity;
|
|
@@ -14844,6 +15622,19 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
14844
15622
|
throw new Error(`Failed to get status: ${error}`);
|
|
14845
15623
|
}
|
|
14846
15624
|
}
|
|
15625
|
+
/**
|
|
15626
|
+
* Wallet-level provider-connection freshness, delegated to the worker via
|
|
15627
|
+
* `GET_STATUS`. Async by necessity (the worker boundary is asynchronous); no
|
|
15628
|
+
* synchronous variant is offered because it would have the same transport
|
|
15629
|
+
* mismatch as the contract-manager proxy's cached `getSyncState()`.
|
|
15630
|
+
*/
|
|
15631
|
+
async getProviderConnectionState() {
|
|
15632
|
+
const { providerConnectionState } = await this.getStatus();
|
|
15633
|
+
if (!providerConnectionState) {
|
|
15634
|
+
throw new Error("Worker did not report provider connection state");
|
|
15635
|
+
}
|
|
15636
|
+
return providerConnectionState;
|
|
15637
|
+
}
|
|
14847
15638
|
async getActivityHistory() {
|
|
14848
15639
|
return buildActivities(await this.getTransactionHistory(), this.activity.all());
|
|
14849
15640
|
}
|
|
@@ -14898,6 +15689,32 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
14898
15689
|
return wallet.sendMessage(message);
|
|
14899
15690
|
};
|
|
14900
15691
|
const messageTag = this.messageTag;
|
|
15692
|
+
const fetchSyncState = async () => {
|
|
15693
|
+
const message = {
|
|
15694
|
+
type: "GET_CONTRACT_SYNC_STATE",
|
|
15695
|
+
id: getRandomId(),
|
|
15696
|
+
tag: messageTag
|
|
15697
|
+
};
|
|
15698
|
+
const response = await sendContractMessage(message);
|
|
15699
|
+
return response.payload.syncState;
|
|
15700
|
+
};
|
|
15701
|
+
const UNKNOWN_STATE = {
|
|
15702
|
+
mode: "degraded",
|
|
15703
|
+
reason: "contract sync state unavailable from the worker"
|
|
15704
|
+
};
|
|
15705
|
+
let syncState = UNKNOWN_STATE;
|
|
15706
|
+
let everProbed = false;
|
|
15707
|
+
const refreshSyncState = async () => {
|
|
15708
|
+
try {
|
|
15709
|
+
syncState = await fetchSyncState();
|
|
15710
|
+
everProbed = true;
|
|
15711
|
+
} catch {
|
|
15712
|
+
if (!everProbed) {
|
|
15713
|
+
syncState = UNKNOWN_STATE;
|
|
15714
|
+
}
|
|
15715
|
+
}
|
|
15716
|
+
};
|
|
15717
|
+
await refreshSyncState();
|
|
14901
15718
|
const manager = {
|
|
14902
15719
|
async createContract(params) {
|
|
14903
15720
|
const message = {
|
|
@@ -14908,6 +15725,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
14908
15725
|
};
|
|
14909
15726
|
try {
|
|
14910
15727
|
const response = await sendContractMessage(message);
|
|
15728
|
+
await refreshSyncState();
|
|
14911
15729
|
return response.payload.contract;
|
|
14912
15730
|
} catch (e) {
|
|
14913
15731
|
throw new Error("Failed to create contract");
|
|
@@ -14936,11 +15754,15 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
14936
15754
|
};
|
|
14937
15755
|
try {
|
|
14938
15756
|
const response = await sendContractMessage(message);
|
|
15757
|
+
await refreshSyncState();
|
|
14939
15758
|
return response.payload.contracts;
|
|
14940
15759
|
} catch (e) {
|
|
14941
15760
|
throw new Error("Failed to get contracts with vtxos");
|
|
14942
15761
|
}
|
|
14943
15762
|
},
|
|
15763
|
+
getSyncState() {
|
|
15764
|
+
return syncState;
|
|
15765
|
+
},
|
|
14944
15766
|
async annotateVtxos(vtxos) {
|
|
14945
15767
|
if (vtxos.length === 0) return [];
|
|
14946
15768
|
const message = {
|
|
@@ -15049,7 +15871,11 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
15049
15871
|
tag: messageTag,
|
|
15050
15872
|
payload: opts
|
|
15051
15873
|
};
|
|
15052
|
-
|
|
15874
|
+
try {
|
|
15875
|
+
await sendContractMessage(message);
|
|
15876
|
+
} finally {
|
|
15877
|
+
await refreshSyncState();
|
|
15878
|
+
}
|
|
15053
15879
|
},
|
|
15054
15880
|
async refreshOutpoints(outpoints) {
|
|
15055
15881
|
const message = {
|
|
@@ -15058,7 +15884,11 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
15058
15884
|
tag: messageTag,
|
|
15059
15885
|
payload: { outpoints }
|
|
15060
15886
|
};
|
|
15061
|
-
|
|
15887
|
+
try {
|
|
15888
|
+
await sendContractMessage(message);
|
|
15889
|
+
} finally {
|
|
15890
|
+
await refreshSyncState();
|
|
15891
|
+
}
|
|
15062
15892
|
},
|
|
15063
15893
|
scanContracts() {
|
|
15064
15894
|
return Promise.reject(
|
|
@@ -15103,6 +15933,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
|
|
|
15103
15933
|
);
|
|
15104
15934
|
this.hasDelegate = hasDelegate;
|
|
15105
15935
|
}
|
|
15936
|
+
serviceWorker;
|
|
15106
15937
|
walletRepository;
|
|
15107
15938
|
contractRepository;
|
|
15108
15939
|
identity;
|
|
@@ -15484,6 +16315,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
15484
16315
|
this.onchainP2TR = onchainP2TR;
|
|
15485
16316
|
this.provider = provider;
|
|
15486
16317
|
}
|
|
16318
|
+
identity;
|
|
15487
16319
|
static MIN_FEE_RATE = 1;
|
|
15488
16320
|
// sat/vbyte
|
|
15489
16321
|
onchainP2TR;
|
|
@@ -15498,12 +16330,12 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
15498
16330
|
* @returns Configured onchain wallet
|
|
15499
16331
|
* @throws Error if the configured identity cannot produce a valid x-only public key
|
|
15500
16332
|
*/
|
|
15501
|
-
static async create(identity, networkName =
|
|
16333
|
+
static async create(identity, networkName = chunkMQB5H4X5_cjs.DEFAULT_NETWORK_NAME, provider) {
|
|
15502
16334
|
const pubkey = await identity.xOnlyPublicKey();
|
|
15503
16335
|
if (!pubkey) {
|
|
15504
16336
|
throw new Error("Invalid configured public key");
|
|
15505
16337
|
}
|
|
15506
|
-
const network =
|
|
16338
|
+
const network = chunkMQB5H4X5_cjs.getNetwork(networkName);
|
|
15507
16339
|
const onchainProvider = provider || new EsploraProvider(ESPLORA_URL[networkName]);
|
|
15508
16340
|
const onchainP2TR = btcSigner.p2tr(pubkey, void 0, network);
|
|
15509
16341
|
return new _OnchainWallet(identity, network, onchainP2TR, onchainProvider);
|
|
@@ -15609,7 +16441,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
15609
16441
|
if (!inputs) {
|
|
15610
16442
|
throw new Error("Fee estimation failed");
|
|
15611
16443
|
}
|
|
15612
|
-
let tx = new
|
|
16444
|
+
let tx = new chunk7IYIFMF4_cjs.Transaction();
|
|
15613
16445
|
for (const input of inputs) {
|
|
15614
16446
|
tx.addInput({
|
|
15615
16447
|
txid: input.txid,
|
|
@@ -15667,7 +16499,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
15667
16499
|
* @throws If the parent has no anchor, or funding cannot be selected/signed
|
|
15668
16500
|
*/
|
|
15669
16501
|
async bumpAnchor(parentHex, feeRate) {
|
|
15670
|
-
const parent =
|
|
16502
|
+
const parent = chunk7IYIFMF4_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
|
|
15671
16503
|
const coins = (await this.getCoins()).filter((c) => c.status.confirmed);
|
|
15672
16504
|
const child = await this.buildBumpPackage(parent, feeRate, coins);
|
|
15673
16505
|
return [parent.hex, child.hex];
|
|
@@ -15785,6 +16617,8 @@ var WsElectrumChainSource = class {
|
|
|
15785
16617
|
this.ws = ws;
|
|
15786
16618
|
this.network = network;
|
|
15787
16619
|
}
|
|
16620
|
+
ws;
|
|
16621
|
+
network;
|
|
15788
16622
|
// Cached chain tip kept fresh by the headers subscription. Initialized
|
|
15789
16623
|
// lazily on first call to subscribeHeaders().
|
|
15790
16624
|
cachedTip = null;
|
|
@@ -16067,6 +16901,8 @@ var ElectrumOnchainProvider = class {
|
|
|
16067
16901
|
this.network = network;
|
|
16068
16902
|
this.chain = new WsElectrumChainSource(ws, network);
|
|
16069
16903
|
}
|
|
16904
|
+
ws;
|
|
16905
|
+
network;
|
|
16070
16906
|
chain;
|
|
16071
16907
|
async getCoins(address) {
|
|
16072
16908
|
const script = this.encodeAddress(address);
|
|
@@ -16428,7 +17264,7 @@ exports.BIP322 = void 0;
|
|
|
16428
17264
|
async function sign2(message, identity, network) {
|
|
16429
17265
|
const xOnlyPubKey = await identity.xOnlyPublicKey();
|
|
16430
17266
|
const payment = btcSigner.p2tr(xOnlyPubKey, void 0, network);
|
|
16431
|
-
const toSpend =
|
|
17267
|
+
const toSpend = chunk7IYIFMF4_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
|
|
16432
17268
|
const toSign = craftBIP322ToSignP2TR(toSpend, payment.script, xOnlyPubKey);
|
|
16433
17269
|
const signed = await identity.sign(toSign, [0]);
|
|
16434
17270
|
signed.finalizeIdx(0);
|
|
@@ -16486,7 +17322,7 @@ function verifyP2TR(message, witnessItems, pkScript, pubkey) {
|
|
|
16486
17322
|
if (sighashType !== btcSigner.SigHash.DEFAULT && sighashType !== btcSigner.SigHash.ALL) {
|
|
16487
17323
|
return false;
|
|
16488
17324
|
}
|
|
16489
|
-
const toSpend =
|
|
17325
|
+
const toSpend = chunk7IYIFMF4_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
|
|
16490
17326
|
const toSign = craftBIP322ToSignP2TR(toSpend, pkScript, pubkey);
|
|
16491
17327
|
const sighash = toSign.preimageWitnessV1(0, [pkScript], sighashType, [0n]);
|
|
16492
17328
|
const rawSig = sig.length === 65 ? sig.subarray(0, 64) : sig;
|
|
@@ -16507,7 +17343,7 @@ function verifyP2WPKH(message, witnessItems, pkScript, addressHash) {
|
|
|
16507
17343
|
}
|
|
16508
17344
|
const sighashType = sigWithHash[sigWithHash.length - 1];
|
|
16509
17345
|
const derSig = sigWithHash.subarray(0, sigWithHash.length - 1);
|
|
16510
|
-
const toSpend =
|
|
17346
|
+
const toSpend = chunk7IYIFMF4_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
|
|
16511
17347
|
const toSign = craftBIP322ToSignSimple(toSpend, pkScript);
|
|
16512
17348
|
const scriptCode = btcSigner.OutScript.encode({ type: "pkh", hash: addressHash });
|
|
16513
17349
|
const sighash = toSign.preimageWitnessV0(0, scriptCode, sighashType, 0n);
|
|
@@ -16560,7 +17396,7 @@ function encodeCompactSize(n) {
|
|
|
16560
17396
|
return buf;
|
|
16561
17397
|
}
|
|
16562
17398
|
function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
|
|
16563
|
-
const tx = new
|
|
17399
|
+
const tx = new chunk7IYIFMF4_cjs.Transaction({ version: 0 });
|
|
16564
17400
|
tx.addInput({
|
|
16565
17401
|
txid: toSpend.id,
|
|
16566
17402
|
index: 0,
|
|
@@ -16574,12 +17410,12 @@ function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
|
|
|
16574
17410
|
});
|
|
16575
17411
|
tx.addOutput({
|
|
16576
17412
|
amount: 0n,
|
|
16577
|
-
script:
|
|
17413
|
+
script: chunk7IYIFMF4_cjs.OP_RETURN_EMPTY_PKSCRIPT
|
|
16578
17414
|
});
|
|
16579
17415
|
return tx;
|
|
16580
17416
|
}
|
|
16581
17417
|
function craftBIP322ToSignSimple(toSpend, pkScript) {
|
|
16582
|
-
const tx = new
|
|
17418
|
+
const tx = new chunk7IYIFMF4_cjs.Transaction({ version: 0 });
|
|
16583
17419
|
tx.addInput({
|
|
16584
17420
|
txid: toSpend.id,
|
|
16585
17421
|
index: 0,
|
|
@@ -16591,12 +17427,12 @@ function craftBIP322ToSignSimple(toSpend, pkScript) {
|
|
|
16591
17427
|
});
|
|
16592
17428
|
tx.addOutput({
|
|
16593
17429
|
amount: 0n,
|
|
16594
|
-
script:
|
|
17430
|
+
script: chunk7IYIFMF4_cjs.OP_RETURN_EMPTY_PKSCRIPT
|
|
16595
17431
|
});
|
|
16596
17432
|
return tx;
|
|
16597
17433
|
}
|
|
16598
17434
|
function finalizeVirtualTx(type, psbtBase64) {
|
|
16599
|
-
const tx =
|
|
17435
|
+
const tx = chunk7IYIFMF4_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
|
|
16600
17436
|
if (type === "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */) {
|
|
16601
17437
|
const input = tx.getInput(0);
|
|
16602
17438
|
if (!input) {
|
|
@@ -16620,16 +17456,17 @@ var ExitPathError = class extends Error {
|
|
|
16620
17456
|
this.reason = reason;
|
|
16621
17457
|
this.name = "ExitPathError";
|
|
16622
17458
|
}
|
|
17459
|
+
reason;
|
|
16623
17460
|
};
|
|
16624
17461
|
function delayWeight(sequence) {
|
|
16625
|
-
const t =
|
|
17462
|
+
const t = chunkMQB5H4X5_cjs.sequenceToTimelock(sequence);
|
|
16626
17463
|
return t.type === "blocks" ? Number(t.value) : Number(t.value) / 600;
|
|
16627
17464
|
}
|
|
16628
17465
|
async function resolveUnilateralPath(params) {
|
|
16629
17466
|
const { vtxo, scriptHex, contractRepository } = params;
|
|
16630
17467
|
const contract = contractRepository ? (await contractRepository.getContracts({ script: scriptHex }))[0] : void 0;
|
|
16631
17468
|
if (contract) {
|
|
16632
|
-
const handler =
|
|
17469
|
+
const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
|
|
16633
17470
|
if (!handler) {
|
|
16634
17471
|
throw new ExitPathError(
|
|
16635
17472
|
"no-handler",
|
|
@@ -16652,12 +17489,12 @@ async function resolveUnilateralPath(params) {
|
|
|
16652
17489
|
paths.sort((a, b) => delayWeight(a.sequence) - delayWeight(b.sequence));
|
|
16653
17490
|
return { selection: paths[0], label: `${contract.type}:unilateral` };
|
|
16654
17491
|
}
|
|
16655
|
-
const decoded =
|
|
17492
|
+
const decoded = chunkMQB5H4X5_cjs.VtxoScript.decode(vtxo.tapTree);
|
|
16656
17493
|
let best;
|
|
16657
17494
|
for (const exit of decoded.exitPaths()) {
|
|
16658
17495
|
const leaf = decoded.findLeaf(base.hex.encode(exit.script));
|
|
16659
17496
|
if (!leaf) continue;
|
|
16660
|
-
const sequence =
|
|
17497
|
+
const sequence = chunkMQB5H4X5_cjs.timelockToSequence(exit.params.timelock);
|
|
16661
17498
|
const weight = delayWeight(sequence);
|
|
16662
17499
|
if (!best || weight < best.weight) {
|
|
16663
17500
|
best = { selection: { leaf, sequence }, weight };
|
|
@@ -16673,7 +17510,7 @@ async function resolveUnilateralPath(params) {
|
|
|
16673
17510
|
}
|
|
16674
17511
|
|
|
16675
17512
|
// src/wallet/unroll.ts
|
|
16676
|
-
function
|
|
17513
|
+
function chainTxTypeToChainedExit2(t) {
|
|
16677
17514
|
switch (t) {
|
|
16678
17515
|
case "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */:
|
|
16679
17516
|
return 1 /* Commitment */;
|
|
@@ -16703,6 +17540,11 @@ exports.Unroll = void 0;
|
|
|
16703
17540
|
this.indexer = indexer;
|
|
16704
17541
|
this.virtualTxRepository = virtualTxRepository;
|
|
16705
17542
|
}
|
|
17543
|
+
toUnroll;
|
|
17544
|
+
bumper;
|
|
17545
|
+
explorer;
|
|
17546
|
+
indexer;
|
|
17547
|
+
virtualTxRepository;
|
|
16706
17548
|
/** Create an unroll session by loading the virtual output chain from the indexer. */
|
|
16707
17549
|
static async create(toUnroll, bumper, explorer, indexer, virtualTxRepository) {
|
|
16708
17550
|
const { chain } = await indexer.getVtxoChain(toUnroll);
|
|
@@ -16736,7 +17578,7 @@ exports.Unroll = void 0;
|
|
|
16736
17578
|
txid: next.txid,
|
|
16737
17579
|
psbt,
|
|
16738
17580
|
expiresAt: null,
|
|
16739
|
-
type:
|
|
17581
|
+
type: chainTxTypeToChainedExit2(next.type)
|
|
16740
17582
|
};
|
|
16741
17583
|
try {
|
|
16742
17584
|
await repo.upsertVirtualTxs([cached]);
|
|
@@ -16838,14 +17680,14 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
16838
17680
|
}
|
|
16839
17681
|
const resolved = await resolveUnilateralPath({
|
|
16840
17682
|
vtxo,
|
|
16841
|
-
scriptHex: base.hex.encode(
|
|
17683
|
+
scriptHex: base.hex.encode(chunkMQB5H4X5_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
|
|
16842
17684
|
contractRepository: wallet.contractRepository,
|
|
16843
17685
|
walletPubKeyHex: base.hex.encode(await wallet.identity.xOnlyPublicKey()),
|
|
16844
17686
|
currentTime: Date.now()
|
|
16845
17687
|
});
|
|
16846
17688
|
const spendingLeaf = resolved.selection.leaf;
|
|
16847
17689
|
const sequence = resolved.selection.sequence;
|
|
16848
|
-
const timelock =
|
|
17690
|
+
const timelock = chunkMQB5H4X5_cjs.sequenceToTimelock(sequence);
|
|
16849
17691
|
const elapsed = timelock.type === "blocks" ? chainTip.height >= txStatus.blockHeight + Number(timelock.value) : chainTip.time >= txStatus.blockTime + Number(timelock.value);
|
|
16850
17692
|
if (!elapsed) {
|
|
16851
17693
|
throw new Error(`no available exit path found for vtxo ${vtxo.txid}:${vtxo.vout}`);
|
|
@@ -16858,7 +17700,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
16858
17700
|
sequence,
|
|
16859
17701
|
witnessUtxo: {
|
|
16860
17702
|
amount: BigInt(vtxo.value),
|
|
16861
|
-
script:
|
|
17703
|
+
script: chunkMQB5H4X5_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
|
|
16862
17704
|
},
|
|
16863
17705
|
sighashType: btcSigner.SigHash.DEFAULT
|
|
16864
17706
|
});
|
|
@@ -16868,7 +17710,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
16868
17710
|
btcSigner.TaprootControlBlock.encode(spendingLeaf[0]).length
|
|
16869
17711
|
);
|
|
16870
17712
|
}
|
|
16871
|
-
const tx = new
|
|
17713
|
+
const tx = new chunk7IYIFMF4_cjs.Transaction({ version: 2 });
|
|
16872
17714
|
for (const input of inputs) {
|
|
16873
17715
|
tx.addInput(input);
|
|
16874
17716
|
}
|
|
@@ -16914,99 +17756,6 @@ function doWait(onchainProvider, txid) {
|
|
|
16914
17756
|
});
|
|
16915
17757
|
};
|
|
16916
17758
|
}
|
|
16917
|
-
|
|
16918
|
-
// src/wallet/exit/chain.ts
|
|
16919
|
-
var isCommitment = (t) => t === "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */ || t === "INDEXER_CHAINED_TX_TYPE_UNSPECIFIED" /* UNSPECIFIED */;
|
|
16920
|
-
async function buildExitDag(params) {
|
|
16921
|
-
const byTxid = /* @__PURE__ */ new Map();
|
|
16922
|
-
for (const vtxo of params.vtxos) {
|
|
16923
|
-
const outpoint = `${vtxo.txid}:${vtxo.vout}`;
|
|
16924
|
-
let pageIndex = 0;
|
|
16925
|
-
let hasMore = true;
|
|
16926
|
-
while (hasMore) {
|
|
16927
|
-
const { chain, page } = await params.indexer.getVtxoChain(
|
|
16928
|
-
{ txid: vtxo.txid, vout: vtxo.vout },
|
|
16929
|
-
{ pageIndex, pageSize: chunk32YKLQPS_cjs.DEFAULT_PAGE_SIZE }
|
|
16930
|
-
);
|
|
16931
|
-
for (const chainTx of chain) {
|
|
16932
|
-
const existing = byTxid.get(chainTx.txid);
|
|
16933
|
-
if (existing) {
|
|
16934
|
-
existing.forVtxos.add(outpoint);
|
|
16935
|
-
} else {
|
|
16936
|
-
byTxid.set(chainTx.txid, { ...chainTx, forVtxos: /* @__PURE__ */ new Set([outpoint]) });
|
|
16937
|
-
}
|
|
16938
|
-
}
|
|
16939
|
-
hasMore = page ? chain.length === chunk32YKLQPS_cjs.DEFAULT_PAGE_SIZE : false;
|
|
16940
|
-
pageIndex++;
|
|
16941
|
-
}
|
|
16942
|
-
}
|
|
16943
|
-
const pending = new Map(
|
|
16944
|
-
[...byTxid.values()].filter((tx) => !isCommitment(tx.type)).map((tx) => [tx.txid, tx])
|
|
16945
|
-
);
|
|
16946
|
-
const inDegree = /* @__PURE__ */ new Map();
|
|
16947
|
-
for (const tx of pending.values()) {
|
|
16948
|
-
const parents = tx.spends.filter((p) => pending.has(p));
|
|
16949
|
-
inDegree.set(tx.txid, parents.length);
|
|
16950
|
-
}
|
|
16951
|
-
const order = [];
|
|
16952
|
-
const queue = [...pending.values()].filter((tx) => inDegree.get(tx.txid) === 0).sort((a, b) => a.txid.localeCompare(b.txid));
|
|
16953
|
-
while (queue.length > 0) {
|
|
16954
|
-
const tx = queue.shift();
|
|
16955
|
-
order.push(tx);
|
|
16956
|
-
const children = [...pending.values()].filter((c) => c.spends.includes(tx.txid)).sort((a, b) => a.txid.localeCompare(b.txid));
|
|
16957
|
-
for (const child of children) {
|
|
16958
|
-
const deg = inDegree.get(child.txid) - 1;
|
|
16959
|
-
inDegree.set(child.txid, deg);
|
|
16960
|
-
if (deg === 0) queue.push(child);
|
|
16961
|
-
}
|
|
16962
|
-
}
|
|
16963
|
-
if (order.length !== pending.size) {
|
|
16964
|
-
throw new Error("inconsistent vtxo chain from indexer (cycle detected)");
|
|
16965
|
-
}
|
|
16966
|
-
const nodes = [];
|
|
16967
|
-
for (const tx of order) {
|
|
16968
|
-
let confirmed = false;
|
|
16969
|
-
try {
|
|
16970
|
-
const status = await params.onchain.getTxStatus(tx.txid);
|
|
16971
|
-
confirmed = status.confirmed;
|
|
16972
|
-
} catch {
|
|
16973
|
-
confirmed = false;
|
|
16974
|
-
}
|
|
16975
|
-
const expires = Number(tx.expiresAt);
|
|
16976
|
-
nodes.push({
|
|
16977
|
-
txid: tx.txid,
|
|
16978
|
-
type: tx.type,
|
|
16979
|
-
expiresAt: Number.isFinite(expires) && expires > 0 ? expires : void 0,
|
|
16980
|
-
forVtxos: [...tx.forVtxos].sort(),
|
|
16981
|
-
confirmed
|
|
16982
|
-
});
|
|
16983
|
-
}
|
|
16984
|
-
return nodes;
|
|
16985
|
-
}
|
|
16986
|
-
function topoSortByDeps(items, idOf, depsOf) {
|
|
16987
|
-
const produced = new Set(items.map(idOf));
|
|
16988
|
-
const emitted = /* @__PURE__ */ new Set();
|
|
16989
|
-
const ordered = [];
|
|
16990
|
-
let remaining = items;
|
|
16991
|
-
while (remaining.length > 0) {
|
|
16992
|
-
const next = [];
|
|
16993
|
-
let progress = false;
|
|
16994
|
-
for (const item of remaining) {
|
|
16995
|
-
if (depsOf(item).every((d) => !produced.has(d) || emitted.has(d))) {
|
|
16996
|
-
ordered.push(item);
|
|
16997
|
-
emitted.add(idOf(item));
|
|
16998
|
-
progress = true;
|
|
16999
|
-
} else {
|
|
17000
|
-
next.push(item);
|
|
17001
|
-
}
|
|
17002
|
-
}
|
|
17003
|
-
if (!progress) {
|
|
17004
|
-
throw new Error("topological sort: cycle or unsatisfiable dependency");
|
|
17005
|
-
}
|
|
17006
|
-
remaining = next;
|
|
17007
|
-
}
|
|
17008
|
-
return ordered;
|
|
17009
|
-
}
|
|
17010
17759
|
function extraWitnessSize(path) {
|
|
17011
17760
|
return (path.extraWitness ?? []).reduce((sum, item) => sum + 1 + item.length, 0);
|
|
17012
17761
|
}
|
|
@@ -17028,7 +17777,7 @@ async function buildSignedSweep(params) {
|
|
|
17028
17777
|
`uneconomic vtxo ${vtxo.txid}:${vtxo.vout}: value ${vtxo.value} - fee ${fee} < dust`
|
|
17029
17778
|
);
|
|
17030
17779
|
}
|
|
17031
|
-
const tx = new
|
|
17780
|
+
const tx = new chunk7IYIFMF4_cjs.Transaction({ version: 2 });
|
|
17032
17781
|
tx.addInput({
|
|
17033
17782
|
txid: vtxo.txid,
|
|
17034
17783
|
index: vtxo.vout,
|
|
@@ -17053,7 +17802,7 @@ async function buildSignedSweep(params) {
|
|
|
17053
17802
|
finalScriptWitness: [
|
|
17054
17803
|
tapScriptSig[0][1],
|
|
17055
17804
|
...path.extraWitness,
|
|
17056
|
-
|
|
17805
|
+
chunkMQB5H4X5_cjs.scriptFromTapLeafScript(path.leaf),
|
|
17057
17806
|
btcSigner.TaprootControlBlock.encode(controlBlock)
|
|
17058
17807
|
]
|
|
17059
17808
|
});
|
|
@@ -17098,7 +17847,7 @@ async function selectExitVtxos(opts) {
|
|
|
17098
17847
|
`no contract registered for vtxo script ${vtxo.script} \u2014 register the contract before exiting`
|
|
17099
17848
|
);
|
|
17100
17849
|
}
|
|
17101
|
-
const handler =
|
|
17850
|
+
const handler = chunk4KXOCVXP_cjs.contractHandlers.get(contract.type);
|
|
17102
17851
|
if (!handler) {
|
|
17103
17852
|
throw new Error(`no contract handler registered for type '${contract.type}'`);
|
|
17104
17853
|
}
|
|
@@ -17113,27 +17862,22 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
17113
17862
|
const { wallet, onchainWallet } = opts;
|
|
17114
17863
|
const vtxos = await selectExitVtxos(opts);
|
|
17115
17864
|
if (vtxos.length === 0) throw new Error("no vtxos to exit");
|
|
17865
|
+
const resolver = createExitChainResolver({
|
|
17866
|
+
indexer: wallet.indexerProvider,
|
|
17867
|
+
repository: wallet.virtualTxRepository,
|
|
17868
|
+
extraSources: wallet.exitDataCapture?.sources
|
|
17869
|
+
});
|
|
17116
17870
|
const dag = await buildExitDag({
|
|
17117
17871
|
vtxos,
|
|
17118
|
-
|
|
17872
|
+
chain: resolver,
|
|
17119
17873
|
onchain: wallet.onchainProvider
|
|
17120
17874
|
});
|
|
17121
17875
|
const pendingNodes = dag.filter((n) => !n.confirmed);
|
|
17122
17876
|
const psbts = /* @__PURE__ */ new Map();
|
|
17123
17877
|
if (pendingNodes.length > 0) {
|
|
17124
|
-
const
|
|
17125
|
-
|
|
17126
|
-
|
|
17127
|
-
while (hasMore) {
|
|
17128
|
-
const { txs, page } = await wallet.indexerProvider.getVirtualTxs(txids, {
|
|
17129
|
-
pageIndex,
|
|
17130
|
-
pageSize: chunk32YKLQPS_cjs.DEFAULT_PAGE_SIZE
|
|
17131
|
-
});
|
|
17132
|
-
for (const psbt of txs) {
|
|
17133
|
-
psbts.set(chunkUBYY2TPK_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
17134
|
-
}
|
|
17135
|
-
hasMore = page ? txs.length === chunk32YKLQPS_cjs.DEFAULT_PAGE_SIZE : false;
|
|
17136
|
-
pageIndex++;
|
|
17878
|
+
const txs = await resolver.getVirtualTxs(pendingNodes.map((n) => n.txid));
|
|
17879
|
+
for (const psbt of txs) {
|
|
17880
|
+
psbts.set(chunk7IYIFMF4_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
17137
17881
|
}
|
|
17138
17882
|
}
|
|
17139
17883
|
const childVsize = Number(
|
|
@@ -17169,7 +17913,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
17169
17913
|
try {
|
|
17170
17914
|
const resolved = await resolveUnilateralPath({
|
|
17171
17915
|
vtxo,
|
|
17172
|
-
scriptHex: base.hex.encode(
|
|
17916
|
+
scriptHex: base.hex.encode(chunkMQB5H4X5_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
|
|
17173
17917
|
contractRepository: wallet.contractRepository,
|
|
17174
17918
|
walletPubKeyHex,
|
|
17175
17919
|
currentTime: Date.now()
|
|
@@ -17188,7 +17932,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
17188
17932
|
});
|
|
17189
17933
|
continue;
|
|
17190
17934
|
}
|
|
17191
|
-
const t =
|
|
17935
|
+
const t = chunkMQB5H4X5_cjs.sequenceToTimelock(resolved.selection.sequence);
|
|
17192
17936
|
const delay = { type: t.type, value: Number(t.value) };
|
|
17193
17937
|
infos.push({ outpoint, value: vtxo.value, sweepFee, path: resolved.label, delay });
|
|
17194
17938
|
sweeps.push({ vtxo, resolved, sweepFee, delay });
|
|
@@ -17281,6 +18025,8 @@ var Executor = class {
|
|
|
17281
18025
|
this.pollIntervalMs = opts?.pollIntervalMs ?? 5e3;
|
|
17282
18026
|
this.feeWallet = opts?.feeWallet;
|
|
17283
18027
|
}
|
|
18028
|
+
pkg;
|
|
18029
|
+
provider;
|
|
17284
18030
|
pollIntervalMs;
|
|
17285
18031
|
feeWallet;
|
|
17286
18032
|
sleep() {
|
|
@@ -17493,7 +18239,7 @@ async function prepare(opts) {
|
|
|
17493
18239
|
txid: sweep.vtxo.txid,
|
|
17494
18240
|
vout: sweep.vtxo.vout,
|
|
17495
18241
|
value: sweep.vtxo.value,
|
|
17496
|
-
pkScript:
|
|
18242
|
+
pkScript: chunkMQB5H4X5_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
|
|
17497
18243
|
},
|
|
17498
18244
|
path: sweep.resolved.selection,
|
|
17499
18245
|
outputAddress: opts.sweepAddress,
|
|
@@ -17578,7 +18324,7 @@ async function prepare(opts) {
|
|
|
17578
18324
|
if (newFee <= splitterFee) break;
|
|
17579
18325
|
splitterFee = newFee;
|
|
17580
18326
|
}
|
|
17581
|
-
const splitter = new
|
|
18327
|
+
const splitter = new chunk7IYIFMF4_cjs.Transaction({ version: 2 });
|
|
17582
18328
|
for (const coin of selected.inputs) {
|
|
17583
18329
|
splitter.addInput({
|
|
17584
18330
|
txid: coin.txid,
|
|
@@ -17742,7 +18488,7 @@ function decodeArkContract(encoded) {
|
|
|
17742
18488
|
}
|
|
17743
18489
|
function contractFromArkContract(encoded, options = {}) {
|
|
17744
18490
|
const parsed = decodeArkContract(encoded);
|
|
17745
|
-
const handler =
|
|
18491
|
+
const handler = chunk4KXOCVXP_cjs.contractHandlers.get(parsed.type);
|
|
17746
18492
|
if (!handler) {
|
|
17747
18493
|
throw new Error(`No handler registered for contract type '${parsed.type}'`);
|
|
17748
18494
|
}
|
|
@@ -17756,9 +18502,9 @@ function contractFromArkContract(encoded, options = {}) {
|
|
|
17756
18502
|
metadata: options.metadata
|
|
17757
18503
|
};
|
|
17758
18504
|
}
|
|
17759
|
-
function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix =
|
|
18505
|
+
function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunkMQB5H4X5_cjs.DEFAULT_NETWORK.hrp, options = {}) {
|
|
17760
18506
|
const parsed = decodeArkContract(encoded);
|
|
17761
|
-
const handler =
|
|
18507
|
+
const handler = chunk4KXOCVXP_cjs.contractHandlers.getOrThrow(parsed.type);
|
|
17762
18508
|
const params = parsed.data;
|
|
17763
18509
|
const vtxoScript = handler.createScript(params);
|
|
17764
18510
|
return {
|
|
@@ -17851,6 +18597,7 @@ exports.combineTapscriptSigs = combineTapscriptSigs;
|
|
|
17851
18597
|
exports.contractFromArkContract = contractFromArkContract;
|
|
17852
18598
|
exports.contractFromArkContractWithAddress = contractFromArkContractWithAddress;
|
|
17853
18599
|
exports.createDefaultActivityRegistry = createDefaultActivityRegistry;
|
|
18600
|
+
exports.createExitChainResolver = createExitChainResolver;
|
|
17854
18601
|
exports.decodeArkContract = decodeArkContract;
|
|
17855
18602
|
exports.deserializeAssets = deserializeAssets;
|
|
17856
18603
|
exports.deserializeExitPackage = deserializeExitPackage;
|
|
@@ -17869,6 +18616,7 @@ exports.isCooperativelyMigratable = isCooperativelyMigratable;
|
|
|
17869
18616
|
exports.isDiscoverable = isDiscoverable;
|
|
17870
18617
|
exports.isExpired = isExpired;
|
|
17871
18618
|
exports.isRecoverable = isRecoverable;
|
|
18619
|
+
exports.isRetryableProviderError = isRetryableProviderError;
|
|
17872
18620
|
exports.isSpendable = isSpendable;
|
|
17873
18621
|
exports.isSubdust = isSubdust;
|
|
17874
18622
|
exports.isTerminalIntentState = isTerminalIntentState;
|
|
@@ -17894,5 +18642,5 @@ exports.validateVtxoTxGraph = validateVtxoTxGraph;
|
|
|
17894
18642
|
exports.verifyTapscriptSignatures = verifyTapscriptSignatures;
|
|
17895
18643
|
exports.waitForIncomingFunds = waitForIncomingFunds;
|
|
17896
18644
|
exports.warnAndFilterVtxosForScript = warnAndFilterVtxosForScript;
|
|
17897
|
-
//# sourceMappingURL=chunk-
|
|
17898
|
-
//# sourceMappingURL=chunk-
|
|
18645
|
+
//# sourceMappingURL=chunk-D46YDM36.cjs.map
|
|
18646
|
+
//# sourceMappingURL=chunk-D46YDM36.cjs.map
|