@arkade-os/sdk 0.5.0-rc.24 → 0.5.0-rc.26
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 +65 -0
- package/dist/adapters/expo.cjs +5 -5
- package/dist/adapters/expo.d.cts +3 -3
- package/dist/adapters/expo.d.ts +3 -3
- package/dist/adapters/expo.js +3 -3
- package/dist/{asyncStorageTaskQueue-DeXfxJp5.d.cts → asyncStorageTaskQueue-CFWscYpG.d.cts} +2 -2
- package/dist/{asyncStorageTaskQueue-C4ESykOx.d.ts → asyncStorageTaskQueue-DrFapzPg.d.ts} +2 -2
- package/dist/{chunk-PD5CVWPT.js → chunk-5JQ5EOYE.js} +25 -6
- package/dist/chunk-5JQ5EOYE.js.map +1 -0
- package/dist/{chunk-OIYVDV2N.cjs → chunk-B2YMUJD5.cjs} +1116 -657
- package/dist/chunk-B2YMUJD5.cjs.map +1 -0
- package/dist/{chunk-UV3IM6BG.cjs → chunk-CFOIHLON.cjs} +48 -48
- package/dist/{chunk-UV3IM6BG.cjs.map → chunk-CFOIHLON.cjs.map} +1 -1
- package/dist/{chunk-PAD5V653.cjs → chunk-FEBAG2K2.cjs} +40 -21
- package/dist/chunk-FEBAG2K2.cjs.map +1 -0
- package/dist/{chunk-RDJIT7RA.js → chunk-HPUKFTZV.js} +4 -4
- package/dist/{chunk-RDJIT7RA.js.map → chunk-HPUKFTZV.js.map} +1 -1
- package/dist/{chunk-HGOERMAY.js → chunk-HTCIPDVW.js} +23 -7
- package/dist/chunk-HTCIPDVW.js.map +1 -0
- package/dist/{chunk-O2WE7RWU.cjs → chunk-K2YTDYQF.cjs} +17 -17
- package/dist/chunk-K2YTDYQF.cjs.map +1 -0
- package/dist/{chunk-RFI6RO25.js → chunk-N2VM6V6K.js} +3 -3
- package/dist/{chunk-RFI6RO25.js.map → chunk-N2VM6V6K.js.map} +1 -1
- package/dist/{chunk-MJG2O6PT.cjs → chunk-QCD3SJOL.cjs} +10 -10
- package/dist/{chunk-MJG2O6PT.cjs.map → chunk-QCD3SJOL.cjs.map} +1 -1
- package/dist/{chunk-WXHMXKPV.js → chunk-U5ZRDVVB.js} +637 -181
- package/dist/chunk-U5ZRDVVB.js.map +1 -0
- package/dist/{chunk-65CTZR2O.cjs → chunk-VVFCCNU2.cjs} +23 -6
- package/dist/chunk-VVFCCNU2.cjs.map +1 -0
- package/dist/{chunk-2YGYHUBW.js → chunk-Y5VSJURH.js} +6 -6
- package/dist/chunk-Y5VSJURH.js.map +1 -0
- package/dist/contracts/handlers/index.cjs +9 -9
- 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-CJ34lCIK.d.ts → delegate-Cz8FnLqi.d.ts} +1 -1
- package/dist/{delegate-C1wtM1NZ.d.cts → delegate-r3jh7UcH.d.cts} +1 -1
- package/dist/{index-CH0tbuRp.d.ts → index-BfvbSL0W.d.cts} +81 -11
- package/dist/{index-CH0tbuRp.d.cts → index-BfvbSL0W.d.ts} +81 -11
- package/dist/{index-iD05fKPX.d.ts → index-Chgwl4dO.d.ts} +2 -2
- package/dist/{index-DhVOLSJN.d.cts → index-DOION7Ta.d.cts} +2 -2
- package/dist/index.cjs +328 -312
- package/dist/index.d.cts +129 -87
- package/dist/index.d.ts +129 -87
- package/dist/index.js +4 -4
- package/dist/repositories/realm/index.cjs +35 -35
- package/dist/repositories/realm/index.d.cts +2 -2
- package/dist/repositories/realm/index.d.ts +2 -2
- package/dist/repositories/realm/index.js +5 -5
- package/dist/repositories/sqlite/index.cjs +33 -33
- package/dist/repositories/sqlite/index.d.cts +2 -2
- package/dist/repositories/sqlite/index.d.ts +2 -2
- package/dist/repositories/sqlite/index.js +5 -5
- package/dist/{taskRunner-Ox7fjm1O.d.cts → taskRunner-BO8a-SQh.d.cts} +2 -2
- package/dist/{taskRunner-DGSSHZ6e.d.ts → taskRunner-CXAcjtdU.d.ts} +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 +19 -15
- package/dist/wallet/expo/index.cjs.map +1 -1
- package/dist/wallet/expo/index.d.cts +6 -4
- package/dist/wallet/expo/index.d.ts +6 -4
- package/dist/wallet/expo/index.js +9 -5
- package/dist/wallet/expo/index.js.map +1 -1
- package/dist/{wallet-EWn1ivtK.d.cts → wallet-CFIfUlQP.d.ts} +72 -4
- package/dist/{wallet-DK71priz.d.ts → wallet-s90p-vIk.d.cts} +72 -4
- package/dist/worker/expo/index.cjs +9 -9
- package/dist/worker/expo/index.d.cts +4 -4
- package/dist/worker/expo/index.d.ts +4 -4
- package/dist/worker/expo/index.js +5 -5
- package/package.json +1 -1
- package/dist/chunk-2YGYHUBW.js.map +0 -1
- package/dist/chunk-65CTZR2O.cjs.map +0 -1
- package/dist/chunk-HGOERMAY.js.map +0 -1
- package/dist/chunk-O2WE7RWU.cjs.map +0 -1
- package/dist/chunk-OIYVDV2N.cjs.map +0 -1
- package/dist/chunk-PAD5V653.cjs.map +0 -1
- package/dist/chunk-PD5CVWPT.js.map +0 -1
- package/dist/chunk-WXHMXKPV.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunkFEBAG2K2_cjs = require('./chunk-FEBAG2K2.cjs');
|
|
4
|
+
var chunkCFOIHLON_cjs = require('./chunk-CFOIHLON.cjs');
|
|
5
|
+
var chunkVVFCCNU2_cjs = require('./chunk-VVFCCNU2.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');
|
|
@@ -187,7 +187,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
187
187
|
noncesByPubkey.set(base.hex.encode(myPublicKey.subarray(1)), myNonce);
|
|
188
188
|
const tx = this.graph.find(txid);
|
|
189
189
|
if (!tx) throw new Error(`missing tx for txid ${txid}`);
|
|
190
|
-
const cosigners =
|
|
190
|
+
const cosigners = chunkVVFCCNU2_cjs.getArkPsbtFields(tx.root, 0, chunkVVFCCNU2_cjs.CosignerPublicKey).map(
|
|
191
191
|
(c) => base.hex.encode(c.key.subarray(1))
|
|
192
192
|
// xonly pubkey
|
|
193
193
|
);
|
|
@@ -239,7 +239,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
239
239
|
if (!aggNonce) throw new Error("missing aggregate nonce");
|
|
240
240
|
const prevoutAmounts = [];
|
|
241
241
|
const prevoutScripts = [];
|
|
242
|
-
const cosigners =
|
|
242
|
+
const cosigners = chunkVVFCCNU2_cjs.getArkPsbtFields(g.root, 0, chunkVVFCCNU2_cjs.CosignerPublicKey).map((c) => c.key);
|
|
243
243
|
const { finalKey } = aggregateKeys(cosigners, true, {
|
|
244
244
|
taprootTweak: this.scriptRoot
|
|
245
245
|
});
|
|
@@ -322,7 +322,7 @@ var SingleKey = class _SingleKey {
|
|
|
322
322
|
async sign(tx, inputIndexes) {
|
|
323
323
|
const txCpy = tx.clone();
|
|
324
324
|
if (!inputIndexes) {
|
|
325
|
-
|
|
325
|
+
chunkVVFCCNU2_cjs.assertAllowedSighashTypes(txCpy, ALLOWED_SIGHASH);
|
|
326
326
|
try {
|
|
327
327
|
if (!txCpy.sign(this.key, ALLOWED_SIGHASH)) {
|
|
328
328
|
throw new Error("Failed to sign transaction");
|
|
@@ -422,7 +422,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
422
422
|
let network;
|
|
423
423
|
if ("descriptor" in opts && typeof opts.descriptor === "string") {
|
|
424
424
|
descriptor = opts.descriptor;
|
|
425
|
-
network =
|
|
425
|
+
network = chunkCFOIHLON_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
426
426
|
} else {
|
|
427
427
|
network = opts.isMainnet ?? true ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
428
428
|
descriptor = descriptorsScure.scriptExpressions.trBIP32({
|
|
@@ -499,7 +499,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
499
499
|
}
|
|
500
500
|
/** Returns true when `descriptor` is derived from this identity's seed. */
|
|
501
501
|
ownsDescriptor(descriptor) {
|
|
502
|
-
return
|
|
502
|
+
return chunkCFOIHLON_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
|
|
503
503
|
}
|
|
504
504
|
/**
|
|
505
505
|
* Signs each request with the key derived from its descriptor.
|
|
@@ -538,7 +538,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
538
538
|
}
|
|
539
539
|
// ── internal helpers ─────────────────────────────────────────────
|
|
540
540
|
derivePrivateKeyForDescriptor(descriptor) {
|
|
541
|
-
const network =
|
|
541
|
+
const network = chunkCFOIHLON_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
542
542
|
const expansion = descriptorsScure.expand({ descriptor, network });
|
|
543
543
|
if (expansion.isRanged) {
|
|
544
544
|
throw new Error(
|
|
@@ -563,7 +563,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
563
563
|
signTxWithKey(tx, key, inputIndexes) {
|
|
564
564
|
const txCpy = tx.clone();
|
|
565
565
|
if (!inputIndexes) {
|
|
566
|
-
|
|
566
|
+
chunkVVFCCNU2_cjs.assertAllowedSighashTypes(txCpy, ALLOWED_SIGHASH2);
|
|
567
567
|
try {
|
|
568
568
|
if (!txCpy.sign(key, ALLOWED_SIGHASH2)) {
|
|
569
569
|
throw new Error("Failed to sign transaction");
|
|
@@ -615,7 +615,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
|
|
|
615
615
|
/** Wildcard account-descriptor template (e.g. `tr([fp/86'/0'/0']xpub/0/*)`). */
|
|
616
616
|
descriptor;
|
|
617
617
|
constructor(descriptor) {
|
|
618
|
-
const network =
|
|
618
|
+
const network = chunkCFOIHLON_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
619
619
|
let expansion;
|
|
620
620
|
try {
|
|
621
621
|
expansion = descriptorsScure.expand({ descriptor, network, index: 0 });
|
|
@@ -650,7 +650,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
|
|
|
650
650
|
}
|
|
651
651
|
/** Returns true when `descriptor` derives from this identity's xpub. */
|
|
652
652
|
ownsDescriptor(descriptor) {
|
|
653
|
-
return
|
|
653
|
+
return chunkCFOIHLON_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
|
|
654
654
|
}
|
|
655
655
|
};
|
|
656
656
|
function serializeSeedOwnedSigningIdentity(identity) {
|
|
@@ -793,10 +793,10 @@ var DescriptorIdentity = class {
|
|
|
793
793
|
this.base = base;
|
|
794
794
|
}
|
|
795
795
|
async xOnlyPublicKey() {
|
|
796
|
-
return
|
|
796
|
+
return chunkCFOIHLON_cjs.deriveDescriptorLeafPubKey(this.descriptor);
|
|
797
797
|
}
|
|
798
798
|
async compressedPublicKey() {
|
|
799
|
-
return
|
|
799
|
+
return chunkCFOIHLON_cjs.deriveDescriptorLeafCompressedPubKey(this.descriptor);
|
|
800
800
|
}
|
|
801
801
|
async sign(tx, inputIndexes) {
|
|
802
802
|
const [signed] = await this.signer.signWithDescriptor([
|
|
@@ -856,8 +856,8 @@ var StaticDescriptorProvider = class _StaticDescriptorProvider {
|
|
|
856
856
|
}
|
|
857
857
|
isOurs(descriptor) {
|
|
858
858
|
try {
|
|
859
|
-
const normalized =
|
|
860
|
-
const pubKey =
|
|
859
|
+
const normalized = chunkCFOIHLON_cjs.normalizeToDescriptor(descriptor);
|
|
860
|
+
const pubKey = chunkCFOIHLON_cjs.extractPubKey(normalized);
|
|
861
861
|
return pubKey.toLowerCase() === this.pubKeyHex.toLowerCase();
|
|
862
862
|
} catch {
|
|
863
863
|
return false;
|
|
@@ -1194,7 +1194,7 @@ function unwrapKeyring(provider) {
|
|
|
1194
1194
|
}
|
|
1195
1195
|
function keyOf(descriptor) {
|
|
1196
1196
|
try {
|
|
1197
|
-
return
|
|
1197
|
+
return chunkCFOIHLON_cjs.extractPubKey(chunkCFOIHLON_cjs.normalizeToDescriptor(descriptor)).toLowerCase();
|
|
1198
1198
|
} catch {
|
|
1199
1199
|
return void 0;
|
|
1200
1200
|
}
|
|
@@ -1285,12 +1285,12 @@ async function resolveDescriptorSigner(descriptor, identity, provider) {
|
|
|
1285
1285
|
signMessageWithDescriptor: (ownedDescriptor, message, signatureType) => identity.signDescriptorMessage(ownedDescriptor, message, signatureType)
|
|
1286
1286
|
} : void 0;
|
|
1287
1287
|
const owner = providerOwner ?? identityOwner;
|
|
1288
|
-
if (owner &&
|
|
1288
|
+
if (owner && chunkCFOIHLON_cjs.parseHDDescriptor(descriptor)) {
|
|
1289
1289
|
return new DescriptorIdentity({ descriptor, signer: owner, base: identity });
|
|
1290
1290
|
}
|
|
1291
1291
|
let key;
|
|
1292
1292
|
try {
|
|
1293
|
-
key =
|
|
1293
|
+
key = chunkCFOIHLON_cjs.deriveDescriptorLeafPubKey(descriptor);
|
|
1294
1294
|
} catch {
|
|
1295
1295
|
throw new ForeignDescriptorError(descriptor);
|
|
1296
1296
|
}
|
|
@@ -1343,14 +1343,14 @@ function buildSaltedPreimageMessage(xonly, salt) {
|
|
|
1343
1343
|
}
|
|
1344
1344
|
var PREIMAGE_INDEX = 0;
|
|
1345
1345
|
function isPerArtifactDescriptor(descriptor) {
|
|
1346
|
-
return
|
|
1346
|
+
return chunkCFOIHLON_cjs.parseHDDescriptor(descriptor) !== null;
|
|
1347
1347
|
}
|
|
1348
1348
|
async function provisionDescriptor(wallet) {
|
|
1349
1349
|
const allocated = isHDAllocationCapable(wallet) ? await wallet.getNextSigningDescriptor() : void 0;
|
|
1350
|
-
return allocated ?? await
|
|
1350
|
+
return allocated ?? await chunkCFOIHLON_cjs.identityDescriptor(wallet.identity);
|
|
1351
1351
|
}
|
|
1352
1352
|
async function provisionRefundKey(wallet) {
|
|
1353
|
-
const descriptor = await
|
|
1353
|
+
const descriptor = await chunkCFOIHLON_cjs.identityDescriptor(wallet.identity);
|
|
1354
1354
|
const signer = await contractSigner(wallet, descriptor);
|
|
1355
1355
|
const pubkey = await signer.xOnlyPublicKey();
|
|
1356
1356
|
const identityPubkey = await wallet.identity.xOnlyPublicKey();
|
|
@@ -1360,7 +1360,7 @@ async function provisionRefundKey(wallet) {
|
|
|
1360
1360
|
);
|
|
1361
1361
|
}
|
|
1362
1362
|
const address = await wallet.getAddress();
|
|
1363
|
-
const { pkScript } =
|
|
1363
|
+
const { pkScript } = chunkVVFCCNU2_cjs.ArkAddress.decode(address);
|
|
1364
1364
|
return { descriptor, pubkey, pkScript, address };
|
|
1365
1365
|
}
|
|
1366
1366
|
async function provisionClaimSecret(wallet, opts = {}) {
|
|
@@ -1406,7 +1406,7 @@ async function contractSigner(wallet, descriptor) {
|
|
|
1406
1406
|
const signer = isHDWalletCapable(wallet) ? await wallet.signerForDescriptor(descriptor) : wallet.identity;
|
|
1407
1407
|
let expected;
|
|
1408
1408
|
try {
|
|
1409
|
-
expected =
|
|
1409
|
+
expected = chunkCFOIHLON_cjs.deriveDescriptorLeafPubKey(descriptor);
|
|
1410
1410
|
} catch (cause) {
|
|
1411
1411
|
throw new ForeignDescriptorError(descriptor, { cause });
|
|
1412
1412
|
}
|
|
@@ -1488,7 +1488,7 @@ function debugLog(debug, ...args) {
|
|
|
1488
1488
|
}
|
|
1489
1489
|
function normalizeOptions(pathOrOptions) {
|
|
1490
1490
|
const o = typeof pathOrOptions === "string" ? { path: pathOrOptions } : pathOrOptions;
|
|
1491
|
-
|
|
1491
|
+
chunkVVFCCNU2_cjs.assertTimerMs("activationTimeoutMs", o.activationTimeoutMs);
|
|
1492
1492
|
return {
|
|
1493
1493
|
path: o.path,
|
|
1494
1494
|
updateViaCache: o.updateViaCache ?? "none",
|
|
@@ -1611,14 +1611,14 @@ var RestDelegateProvider = class {
|
|
|
1611
1611
|
*/
|
|
1612
1612
|
async delegate(intent, forfeitTxs, options) {
|
|
1613
1613
|
const url = `${this.url}/v1/delegate`;
|
|
1614
|
-
const response = await
|
|
1614
|
+
const response = await chunkVVFCCNU2_cjs.baseFetch(url, {
|
|
1615
1615
|
method: "POST",
|
|
1616
1616
|
headers: {
|
|
1617
1617
|
"Content-Type": "application/json"
|
|
1618
1618
|
},
|
|
1619
1619
|
body: JSON.stringify({
|
|
1620
1620
|
intent: {
|
|
1621
|
-
message:
|
|
1621
|
+
message: chunkVVFCCNU2_cjs.Intent.encodeMessage(intent.message),
|
|
1622
1622
|
proof: intent.proof
|
|
1623
1623
|
},
|
|
1624
1624
|
forfeit_txs: forfeitTxs,
|
|
@@ -1637,7 +1637,7 @@ var RestDelegateProvider = class {
|
|
|
1637
1637
|
*/
|
|
1638
1638
|
async getDelegateInfo() {
|
|
1639
1639
|
const url = `${this.url}/v1/delegator/info`;
|
|
1640
|
-
const response = await
|
|
1640
|
+
const response = await chunkVVFCCNU2_cjs.rateGate.runHttp(url, () => chunkVVFCCNU2_cjs.baseFetch(url));
|
|
1641
1641
|
if (!response.ok) {
|
|
1642
1642
|
const errorText2 = await response.text();
|
|
1643
1643
|
throw new Error(`Failed to get delegate info: ${errorText2}`);
|
|
@@ -1693,7 +1693,7 @@ async function collectPages(read) {
|
|
|
1693
1693
|
return items;
|
|
1694
1694
|
}
|
|
1695
1695
|
function scriptFromArkAddress(address) {
|
|
1696
|
-
return base.hex.encode(
|
|
1696
|
+
return base.hex.encode(chunkVVFCCNU2_cjs.ArkAddress.decode(address).pkScript);
|
|
1697
1697
|
}
|
|
1698
1698
|
|
|
1699
1699
|
// src/repositories/walletRepository.ts
|
|
@@ -1755,9 +1755,9 @@ async function collectScriptVtxos(repository, script, options) {
|
|
|
1755
1755
|
return [...byOutpoint.values()].map((row) => row.vtxo);
|
|
1756
1756
|
}
|
|
1757
1757
|
function unspentScriptVtxos(rows, copies) {
|
|
1758
|
-
const spent = copies.filter((copy) =>
|
|
1758
|
+
const spent = copies.filter((copy) => chunkVVFCCNU2_cjs.isVtxoSpent(copy.vtxo));
|
|
1759
1759
|
return rows.filter(
|
|
1760
|
-
(row) => !
|
|
1760
|
+
(row) => !chunkVVFCCNU2_cjs.isVtxoSpent(row.vtxo) && !spent.some(
|
|
1761
1761
|
(copy) => copy.address !== row.address && copy.vtxo.txid === row.vtxo.txid && copy.vtxo.vout === row.vtxo.vout && shouldReplaceScriptVtxo(row, copy)
|
|
1762
1762
|
)
|
|
1763
1763
|
);
|
|
@@ -1840,7 +1840,7 @@ var ESPLORA_URL = {
|
|
|
1840
1840
|
regtest: "http://localhost:3000/api"
|
|
1841
1841
|
};
|
|
1842
1842
|
var EsploraProvider = class {
|
|
1843
|
-
constructor(baseUrl = ESPLORA_URL[
|
|
1843
|
+
constructor(baseUrl = ESPLORA_URL[chunkVVFCCNU2_cjs.DEFAULT_NETWORK_NAME], opts) {
|
|
1844
1844
|
this.baseUrl = baseUrl;
|
|
1845
1845
|
this.pollingInterval = opts?.pollingInterval ?? 15e3;
|
|
1846
1846
|
this.forcePolling = opts?.forcePolling ?? false;
|
|
@@ -1855,7 +1855,7 @@ var EsploraProvider = class {
|
|
|
1855
1855
|
*/
|
|
1856
1856
|
addressWatches = /* @__PURE__ */ new Map();
|
|
1857
1857
|
async getCoins(address) {
|
|
1858
|
-
const response = await
|
|
1858
|
+
const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
|
|
1859
1859
|
if (!response.ok) {
|
|
1860
1860
|
throw new Error(`Failed to fetch UTXOs: ${response.statusText}`);
|
|
1861
1861
|
}
|
|
@@ -1864,12 +1864,12 @@ var EsploraProvider = class {
|
|
|
1864
1864
|
async getFeeRate() {
|
|
1865
1865
|
let url = `${this.baseUrl}/fee-estimates`;
|
|
1866
1866
|
let key = "1";
|
|
1867
|
-
let response = await
|
|
1867
|
+
let response = await chunkVVFCCNU2_cjs.baseFetch(url);
|
|
1868
1868
|
if (response.status === 404) {
|
|
1869
1869
|
await response.body?.cancel();
|
|
1870
1870
|
url = `${this.baseUrl}/v1/fees/recommended`;
|
|
1871
1871
|
key = "fastestFee";
|
|
1872
|
-
response = await
|
|
1872
|
+
response = await chunkVVFCCNU2_cjs.baseFetch(url);
|
|
1873
1873
|
}
|
|
1874
1874
|
if (response.status === 404) {
|
|
1875
1875
|
await response.body?.cancel();
|
|
@@ -1906,7 +1906,7 @@ var EsploraProvider = class {
|
|
|
1906
1906
|
}
|
|
1907
1907
|
}
|
|
1908
1908
|
async getTxOutspends(txid) {
|
|
1909
|
-
const response = await
|
|
1909
|
+
const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
|
|
1910
1910
|
if (!response.ok) {
|
|
1911
1911
|
const error = await response.text();
|
|
1912
1912
|
throw new Error(`Failed to get transaction outspends: ${error}`);
|
|
@@ -1914,7 +1914,7 @@ var EsploraProvider = class {
|
|
|
1914
1914
|
return response.json();
|
|
1915
1915
|
}
|
|
1916
1916
|
async getTransactions(address) {
|
|
1917
|
-
const response = await
|
|
1917
|
+
const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
|
|
1918
1918
|
if (!response.ok) {
|
|
1919
1919
|
const error = await response.text();
|
|
1920
1920
|
throw new Error(`Failed to get transactions: ${error}`);
|
|
@@ -1923,14 +1923,14 @@ var EsploraProvider = class {
|
|
|
1923
1923
|
}
|
|
1924
1924
|
/** Orders of magnitude smaller than `/address/{addr}/txs`: the polling fallback's probe. */
|
|
1925
1925
|
async getAddressStats(address) {
|
|
1926
|
-
const response = await
|
|
1926
|
+
const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/address/${address}`);
|
|
1927
1927
|
if (!response.ok) {
|
|
1928
1928
|
throw new Error(`Failed to get address stats: ${response.statusText}`);
|
|
1929
1929
|
}
|
|
1930
1930
|
return response.json();
|
|
1931
1931
|
}
|
|
1932
1932
|
async getRawTransaction(txid) {
|
|
1933
|
-
const response = await
|
|
1933
|
+
const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/hex`);
|
|
1934
1934
|
if (!response.ok) {
|
|
1935
1935
|
const error = await response.text();
|
|
1936
1936
|
throw new Error(`Failed to get raw transaction ${txid}: ${error}`);
|
|
@@ -1938,7 +1938,7 @@ var EsploraProvider = class {
|
|
|
1938
1938
|
return base.hex.decode((await response.text()).trim());
|
|
1939
1939
|
}
|
|
1940
1940
|
async getTxStatus(txid) {
|
|
1941
|
-
const txresponse = await
|
|
1941
|
+
const txresponse = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
|
|
1942
1942
|
if (!txresponse.ok) {
|
|
1943
1943
|
throw new Error(txresponse.statusText);
|
|
1944
1944
|
}
|
|
@@ -1946,7 +1946,7 @@ var EsploraProvider = class {
|
|
|
1946
1946
|
if (!tx.status.confirmed) {
|
|
1947
1947
|
return { confirmed: false };
|
|
1948
1948
|
}
|
|
1949
|
-
const response = await
|
|
1949
|
+
const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
|
|
1950
1950
|
if (!response.ok) {
|
|
1951
1951
|
throw new Error(`Failed to get transaction status: ${response.statusText}`);
|
|
1952
1952
|
}
|
|
@@ -2220,9 +2220,9 @@ var EsploraProvider = class {
|
|
|
2220
2220
|
return { subscribers, teardown, started };
|
|
2221
2221
|
}
|
|
2222
2222
|
async getChainTip() {
|
|
2223
|
-
let tipBlocks = await
|
|
2223
|
+
let tipBlocks = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/blocks`);
|
|
2224
2224
|
if (tipBlocks.status === 404) {
|
|
2225
|
-
tipBlocks = await
|
|
2225
|
+
tipBlocks = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/v1/blocks`);
|
|
2226
2226
|
}
|
|
2227
2227
|
if (!tipBlocks.ok) {
|
|
2228
2228
|
throw new Error(`Failed to get chain tip: ${tipBlocks.statusText}`);
|
|
@@ -2243,7 +2243,7 @@ var EsploraProvider = class {
|
|
|
2243
2243
|
};
|
|
2244
2244
|
}
|
|
2245
2245
|
async broadcastPackage(parent, child) {
|
|
2246
|
-
const response = await
|
|
2246
|
+
const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
|
|
2247
2247
|
method: "POST",
|
|
2248
2248
|
headers: {
|
|
2249
2249
|
"Content-Type": "application/json"
|
|
@@ -2259,7 +2259,7 @@ var EsploraProvider = class {
|
|
|
2259
2259
|
return result;
|
|
2260
2260
|
}
|
|
2261
2261
|
async broadcastTx(tx) {
|
|
2262
|
-
const response = await
|
|
2262
|
+
const response = await chunkVVFCCNU2_cjs.baseFetch(`${this.baseUrl}/tx`, {
|
|
2263
2263
|
method: "POST",
|
|
2264
2264
|
headers: {
|
|
2265
2265
|
"Content-Type": "text/plain"
|
|
@@ -2431,7 +2431,7 @@ function findP2AOutput(tx) {
|
|
|
2431
2431
|
var CHILD_DUST_AMOUNT = 546;
|
|
2432
2432
|
function buildAnchorChild(params) {
|
|
2433
2433
|
const { parent, feeRate, fundingCoins, changeAddress, tapInternalKey, network } = params;
|
|
2434
|
-
const child = new
|
|
2434
|
+
const child = new chunkVVFCCNU2_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
|
|
2435
2435
|
const anchor = findP2AOutput(parent);
|
|
2436
2436
|
child.addInput(anchor);
|
|
2437
2437
|
const estimator = TxWeightEstimator.create().addP2AInput();
|
|
@@ -2480,7 +2480,7 @@ function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
|
|
|
2480
2480
|
);
|
|
2481
2481
|
}
|
|
2482
2482
|
function buildForfeitTxWithOutput(inputs, output, txLocktime) {
|
|
2483
|
-
const tx = new
|
|
2483
|
+
const tx = new chunkVVFCCNU2_cjs.Transaction({
|
|
2484
2484
|
version: 3,
|
|
2485
2485
|
lockTime: txLocktime
|
|
2486
2486
|
});
|
|
@@ -2507,7 +2507,7 @@ function validateConnectorsTxGraph(settlementTxB64, connectorsGraph) {
|
|
|
2507
2507
|
connectorsGraph.validate();
|
|
2508
2508
|
if (connectorsGraph.root.inputsLength !== 1) throw ErrNumberOfInputs;
|
|
2509
2509
|
const rootInput = connectorsGraph.root.getInput(0);
|
|
2510
|
-
const settlementTx =
|
|
2510
|
+
const settlementTx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(settlementTxB64));
|
|
2511
2511
|
if (settlementTx.outputsLength <= BATCH_OUTPUT_CONNECTORS_INDEX)
|
|
2512
2512
|
throw ErrInvalidSettlementTxOutputs;
|
|
2513
2513
|
const expectedRootTxid = settlementTx.id;
|
|
@@ -2556,7 +2556,7 @@ function validateVtxoTxGraph(graph, roundTransaction, sweepTapTreeRoot) {
|
|
|
2556
2556
|
if (previousScriptKey.length !== 32) {
|
|
2557
2557
|
throw new Error(`parent output ${childIndex} has invalid script`);
|
|
2558
2558
|
}
|
|
2559
|
-
const cosigners =
|
|
2559
|
+
const cosigners = chunkVVFCCNU2_cjs.getArkPsbtFields(child.root, 0, chunkVVFCCNU2_cjs.CosignerPublicKey);
|
|
2560
2560
|
if (cosigners.length === 0) {
|
|
2561
2561
|
throw ErrMissingCosignersPublicKeys;
|
|
2562
2562
|
}
|
|
@@ -2614,7 +2614,7 @@ var EmulatorPacket = class _EmulatorPacket {
|
|
|
2614
2614
|
return new _EmulatorPacket(entries);
|
|
2615
2615
|
}
|
|
2616
2616
|
static fromBytes(data) {
|
|
2617
|
-
const reader = new
|
|
2617
|
+
const reader = new chunkFEBAG2K2_cjs.BufferReader(data);
|
|
2618
2618
|
const entryCount = reader.readCompactSize();
|
|
2619
2619
|
const entries = [];
|
|
2620
2620
|
for (let i = 0; i < entryCount; i++) {
|
|
@@ -2632,7 +2632,7 @@ var EmulatorPacket = class _EmulatorPacket {
|
|
|
2632
2632
|
return _EmulatorPacket.PACKET_TYPE;
|
|
2633
2633
|
}
|
|
2634
2634
|
serialize() {
|
|
2635
|
-
const writer = new
|
|
2635
|
+
const writer = new chunkFEBAG2K2_cjs.BufferWriter();
|
|
2636
2636
|
writer.writeCompactSize(this.entries.length);
|
|
2637
2637
|
for (const entry of this.entries) {
|
|
2638
2638
|
writer.writeUint16LE(entry.vin);
|
|
@@ -2719,7 +2719,7 @@ var Extension = class _Extension {
|
|
|
2719
2719
|
`expected magic prefix ${base.hex.encode(ARKADE_MAGIC)}, got ${base.hex.encode(payload.slice(0, Math.min(payload.length, ARKADE_MAGIC.length)))}`
|
|
2720
2720
|
);
|
|
2721
2721
|
}
|
|
2722
|
-
const reader = new
|
|
2722
|
+
const reader = new chunkFEBAG2K2_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
|
|
2723
2723
|
const packets = [];
|
|
2724
2724
|
while (reader.remaining() > 0) {
|
|
2725
2725
|
const packetType = reader.readByte();
|
|
@@ -2792,7 +2792,7 @@ var Extension = class _Extension {
|
|
|
2792
2792
|
* getAssetPacket returns the embedded Packet, or null if not present.
|
|
2793
2793
|
*/
|
|
2794
2794
|
getAssetPacket() {
|
|
2795
|
-
return this.packets.find((p) => p instanceof
|
|
2795
|
+
return this.packets.find((p) => p instanceof chunkFEBAG2K2_cjs.Packet) ?? null;
|
|
2796
2796
|
}
|
|
2797
2797
|
/**
|
|
2798
2798
|
* getEmulatorPacket returns the embedded EmulatorPacket, or null if not present.
|
|
@@ -2816,8 +2816,8 @@ var Extension = class _Extension {
|
|
|
2816
2816
|
};
|
|
2817
2817
|
function parsePacket(packetType, data) {
|
|
2818
2818
|
switch (packetType) {
|
|
2819
|
-
case
|
|
2820
|
-
return
|
|
2819
|
+
case chunkFEBAG2K2_cjs.Packet.PACKET_TYPE:
|
|
2820
|
+
return chunkFEBAG2K2_cjs.Packet.fromBytes(data);
|
|
2821
2821
|
case EmulatorPacket.PACKET_TYPE:
|
|
2822
2822
|
return EmulatorPacket.fromBytes(data);
|
|
2823
2823
|
default:
|
|
@@ -2864,22 +2864,22 @@ function buildOpReturnScript(data) {
|
|
|
2864
2864
|
}
|
|
2865
2865
|
return script;
|
|
2866
2866
|
}
|
|
2867
|
-
var ErrOffchainOutputNotFound = (address) => new
|
|
2868
|
-
var ErrInvalidAssetOutputAmount = (got, want, assetId) => new
|
|
2867
|
+
var ErrOffchainOutputNotFound = (address) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(`offchain send output not found: ${address}`);
|
|
2868
|
+
var ErrInvalidAssetOutputAmount = (got, want, assetId) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
2869
2869
|
`invalid asset output amount for ${assetId}: got ${got}, want ${want}`
|
|
2870
2870
|
);
|
|
2871
|
-
var ErrAssetGroupNotFound = (assetId) => new
|
|
2872
|
-
var ErrAssetOutputNotFound = (assetId, outputIndex) => new
|
|
2871
|
+
var ErrAssetGroupNotFound = (assetId) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(`asset group not found in batch leaf: ${assetId}`);
|
|
2872
|
+
var ErrAssetOutputNotFound = (assetId, outputIndex) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
2873
2873
|
`asset output not found in asset group ${assetId} at index ${outputIndex}`
|
|
2874
2874
|
);
|
|
2875
|
-
var ErrOnchainOutputNotFound = (address) => new
|
|
2876
|
-
var ErrUnvalidatedOffchainOutput = (address) => new
|
|
2875
|
+
var ErrOnchainOutputNotFound = (address) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(`onchain output not found: ${address}`);
|
|
2876
|
+
var ErrUnvalidatedOffchainOutput = (address) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
2877
2877
|
`offchain output ${address} cannot be validated: virtual output tree signing did not run`
|
|
2878
2878
|
);
|
|
2879
|
-
var ErrIntentOutputNotFound = (index, kind) => new
|
|
2879
|
+
var ErrIntentOutputNotFound = (index, kind) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
2880
2880
|
`${kind} output ${index} of the intent proof is not present in what the server built`
|
|
2881
2881
|
);
|
|
2882
|
-
var ErrUnvalidatedIntentOutput = (index) => new
|
|
2882
|
+
var ErrUnvalidatedIntentOutput = (index) => new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
2883
2883
|
`offchain output ${index} of the intent proof cannot be validated: virtual output tree signing did not run`
|
|
2884
2884
|
);
|
|
2885
2885
|
var ErrInvalidOnchainOutputAmount = (address) => new Error(`invalid onchain output amount: ${address}`);
|
|
@@ -2888,7 +2888,7 @@ var ErrInvalidOffchainOutputAmount = (address) => new Error(`invalid offchain ou
|
|
|
2888
2888
|
function assertFinalCommitmentMatchesValidated(finalCommitmentTx, validatedCommitmentTxid, context) {
|
|
2889
2889
|
if (!validatedCommitmentTxid) return;
|
|
2890
2890
|
if (finalCommitmentTx.id === validatedCommitmentTxid) return;
|
|
2891
|
-
throw new
|
|
2891
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
2892
2892
|
`${context}: finalization commitment tx ${finalCommitmentTx.id} differs from the validated commitment tx ${validatedCommitmentTxid}`
|
|
2893
2893
|
);
|
|
2894
2894
|
}
|
|
@@ -2898,7 +2898,7 @@ function validateBatchRecipients(commitmentTx, vtxoTreeLeaves, recipients, netwo
|
|
|
2898
2898
|
for (const recipient of recipients) {
|
|
2899
2899
|
let arkAddress;
|
|
2900
2900
|
try {
|
|
2901
|
-
arkAddress =
|
|
2901
|
+
arkAddress = chunkVVFCCNU2_cjs.ArkAddress.decode(recipient.address);
|
|
2902
2902
|
} catch {
|
|
2903
2903
|
validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
|
|
2904
2904
|
continue;
|
|
@@ -2910,7 +2910,7 @@ function validateBatchRecipientsWithoutTree(commitmentTx, recipients, network) {
|
|
|
2910
2910
|
const usedOnchainOutputs = /* @__PURE__ */ new Set();
|
|
2911
2911
|
for (const recipient of recipients) {
|
|
2912
2912
|
try {
|
|
2913
|
-
|
|
2913
|
+
chunkVVFCCNU2_cjs.ArkAddress.decode(recipient.address);
|
|
2914
2914
|
} catch {
|
|
2915
2915
|
validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
|
|
2916
2916
|
continue;
|
|
@@ -2919,7 +2919,7 @@ function validateBatchRecipientsWithoutTree(commitmentTx, recipients, network) {
|
|
|
2919
2919
|
}
|
|
2920
2920
|
}
|
|
2921
2921
|
function declaredIntentOutputs(signedProof, onchainOutputIndexes) {
|
|
2922
|
-
const proof =
|
|
2922
|
+
const proof = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(signedProof));
|
|
2923
2923
|
const onchain = new Set(onchainOutputIndexes);
|
|
2924
2924
|
const declared = [];
|
|
2925
2925
|
for (let i = 0; i < proof.outputsLength; i++) {
|
|
@@ -3211,7 +3211,7 @@ function assetMintResolver() {
|
|
|
3211
3211
|
if (!tx.assets?.length || !tx.key.arkTxid) return void 0;
|
|
3212
3212
|
const minted = tx.assets.filter((a) => {
|
|
3213
3213
|
try {
|
|
3214
|
-
return base.hex.encode(
|
|
3214
|
+
return base.hex.encode(chunkFEBAG2K2_cjs.AssetId.fromString(a.assetId).txid) === tx.key.arkTxid;
|
|
3215
3215
|
} catch {
|
|
3216
3216
|
return false;
|
|
3217
3217
|
}
|
|
@@ -3288,7 +3288,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
3288
3288
|
const existing = inputsByAssetId.get(asset.assetId);
|
|
3289
3289
|
inputsByAssetId.set(asset.assetId, [
|
|
3290
3290
|
...existing ?? [],
|
|
3291
|
-
|
|
3291
|
+
chunkFEBAG2K2_cjs.AssetInput.create(inputIndex, asset.amount)
|
|
3292
3292
|
]);
|
|
3293
3293
|
}
|
|
3294
3294
|
}
|
|
@@ -3300,7 +3300,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
3300
3300
|
const existing = outputsByAssetId.get(asset.assetId);
|
|
3301
3301
|
outputsByAssetId.set(asset.assetId, [
|
|
3302
3302
|
...existing ?? [],
|
|
3303
|
-
|
|
3303
|
+
chunkFEBAG2K2_cjs.AssetOutput.create(outputIndex, asset.amount)
|
|
3304
3304
|
]);
|
|
3305
3305
|
}
|
|
3306
3306
|
}
|
|
@@ -3311,7 +3311,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
3311
3311
|
const existing = outputsByAssetId.get(asset.assetId);
|
|
3312
3312
|
outputsByAssetId.set(asset.assetId, [
|
|
3313
3313
|
...existing ?? [],
|
|
3314
|
-
|
|
3314
|
+
chunkFEBAG2K2_cjs.AssetOutput.create(outputIndex, asset.amount)
|
|
3315
3315
|
]);
|
|
3316
3316
|
}
|
|
3317
3317
|
}
|
|
@@ -3320,11 +3320,11 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
3320
3320
|
for (const assetIdStr of allAssetIds) {
|
|
3321
3321
|
const inputs = inputsByAssetId.get(assetIdStr);
|
|
3322
3322
|
const outputs = outputsByAssetId.get(assetIdStr);
|
|
3323
|
-
const assetId =
|
|
3324
|
-
const group =
|
|
3323
|
+
const assetId = chunkFEBAG2K2_cjs.AssetId.fromString(assetIdStr);
|
|
3324
|
+
const group = chunkFEBAG2K2_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
|
|
3325
3325
|
groups.push(group);
|
|
3326
3326
|
}
|
|
3327
|
-
return
|
|
3327
|
+
return chunkFEBAG2K2_cjs.Packet.create(groups);
|
|
3328
3328
|
}
|
|
3329
3329
|
function selectCoinsWithAsset(coins, assetId, requiredAmount) {
|
|
3330
3330
|
const coinsWithAsset = coins.filter((coin) => coin.assets?.some((a) => a.assetId === assetId));
|
|
@@ -3408,7 +3408,7 @@ function meetsInputExpiryFloor(coin, floor) {
|
|
|
3408
3408
|
}
|
|
3409
3409
|
function toXOnlySignerHex(pubkeyHex) {
|
|
3410
3410
|
const bytes = base.hex.decode(pubkeyHex);
|
|
3411
|
-
if (bytes.length === 32 || bytes.length === 33) return base.hex.encode(
|
|
3411
|
+
if (bytes.length === 32 || bytes.length === 33) return base.hex.encode(chunkCFOIHLON_cjs.toXOnly(bytes, "signer key"));
|
|
3412
3412
|
throw new Error(`invalid signer pubkey length: expected 32 or 33 bytes, got ${bytes.length}`);
|
|
3413
3413
|
}
|
|
3414
3414
|
function signerSetFromInfo(info) {
|
|
@@ -3455,13 +3455,13 @@ var toTimelock = (value) => ({
|
|
|
3455
3455
|
var toSeconds = (t) => t.type === "seconds" ? t.value : t.value * NOMINAL_BLOCK_SECONDS;
|
|
3456
3456
|
function assertTimelockInPolicy(timelock, policy, label, overrideOption) {
|
|
3457
3457
|
if (policy.requireSeconds && timelock.type === "blocks") {
|
|
3458
|
-
throw new
|
|
3458
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3459
3459
|
`${label} rejected: block-typed timelocks are not accepted (got ${timelock.value})`
|
|
3460
3460
|
);
|
|
3461
3461
|
}
|
|
3462
3462
|
const seconds = toSeconds(timelock);
|
|
3463
3463
|
if (seconds < policy.minSeconds) {
|
|
3464
|
-
throw new
|
|
3464
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3465
3465
|
`${label} rejected: ${timelock.value} ${timelock.type} is below the ${policy.minSeconds}s floor; pass ${overrideOption}: ${seconds}n to Wallet.create to lower it`
|
|
3466
3466
|
);
|
|
3467
3467
|
}
|
|
@@ -3482,7 +3482,7 @@ function resolveBatchExpiryPolicy(network, overrides) {
|
|
|
3482
3482
|
}
|
|
3483
3483
|
function assertValidBatchExpiry(batchExpiry, policy) {
|
|
3484
3484
|
if (policy.advertisedVtxoTreeExpiry !== void 0 && batchExpiry !== policy.advertisedVtxoTreeExpiry) {
|
|
3485
|
-
throw new
|
|
3485
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3486
3486
|
`batch expiry rejected: ${batchExpiry} does not match the advertised vtxoTreeExpiry ${policy.advertisedVtxoTreeExpiry}`
|
|
3487
3487
|
);
|
|
3488
3488
|
}
|
|
@@ -3512,21 +3512,21 @@ function resolveCheckpointExitDelayPolicy(network, overrides) {
|
|
|
3512
3512
|
function assertValidServerUnrollScript(checkpointTapscript, policy) {
|
|
3513
3513
|
let script;
|
|
3514
3514
|
try {
|
|
3515
|
-
script =
|
|
3515
|
+
script = chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
|
|
3516
3516
|
} catch (e) {
|
|
3517
|
-
throw new
|
|
3517
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3518
3518
|
`checkpoint exit delay rejected: invalid checkpointTapscript from server (${e instanceof Error ? e.message : String(e)})`
|
|
3519
3519
|
);
|
|
3520
3520
|
}
|
|
3521
3521
|
if (policy.advertisedForfeitPubkey !== void 0) {
|
|
3522
3522
|
const { pubkeys } = script.params;
|
|
3523
3523
|
if (pubkeys.length !== 1) {
|
|
3524
|
-
throw new
|
|
3524
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3525
3525
|
`checkpoint exit delay rejected: checkpointTapscript must commit to exactly one pubkey, got ${pubkeys.length} [${pubkeys.map(base.hex.encode).join(", ")}]`
|
|
3526
3526
|
);
|
|
3527
3527
|
}
|
|
3528
3528
|
if (!utils_js.equalBytes(pubkeys[0], policy.advertisedForfeitPubkey)) {
|
|
3529
|
-
throw new
|
|
3529
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3530
3530
|
`checkpoint exit delay rejected: checkpointTapscript pubkey ${base.hex.encode(pubkeys[0])} does not match the advertised forfeitPubkey ${base.hex.encode(policy.advertisedForfeitPubkey)}`
|
|
3531
3531
|
);
|
|
3532
3532
|
}
|
|
@@ -3570,8 +3570,8 @@ function buildOffchainTx(inputs, outputs, serverUnrollScript) {
|
|
|
3570
3570
|
function buildVirtualTx(inputs, outputs) {
|
|
3571
3571
|
let lockTime = 0n;
|
|
3572
3572
|
for (const input of inputs) {
|
|
3573
|
-
const tapscript =
|
|
3574
|
-
if (
|
|
3573
|
+
const tapscript = chunkVVFCCNU2_cjs.decodeTapscript(chunkVVFCCNU2_cjs.scriptFromTapLeafScript(input.tapLeafScript));
|
|
3574
|
+
if (chunkVVFCCNU2_cjs.CLTVMultisigTapscript.is(tapscript)) {
|
|
3575
3575
|
if (lockTime !== 0n) {
|
|
3576
3576
|
if (isSeconds(lockTime) !== isSeconds(tapscript.params.absoluteTimelock)) {
|
|
3577
3577
|
throw new Error("cannot mix seconds and blocks locktime");
|
|
@@ -3582,7 +3582,7 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
3582
3582
|
}
|
|
3583
3583
|
}
|
|
3584
3584
|
}
|
|
3585
|
-
const tx = new
|
|
3585
|
+
const tx = new chunkVVFCCNU2_cjs.Transaction({
|
|
3586
3586
|
version: 3,
|
|
3587
3587
|
lockTime: Number(lockTime)
|
|
3588
3588
|
});
|
|
@@ -3592,12 +3592,12 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
3592
3592
|
index: input.vout,
|
|
3593
3593
|
sequence: lockTime ? btcSigner.DEFAULT_SEQUENCE - 1 : void 0,
|
|
3594
3594
|
witnessUtxo: {
|
|
3595
|
-
script:
|
|
3595
|
+
script: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript,
|
|
3596
3596
|
amount: BigInt(input.value)
|
|
3597
3597
|
},
|
|
3598
3598
|
tapLeafScript: [input.tapLeafScript]
|
|
3599
3599
|
});
|
|
3600
|
-
|
|
3600
|
+
chunkVVFCCNU2_cjs.setArkPsbtField(tx, i, chunkVVFCCNU2_cjs.VtxoTaprootTree, input.tapTree);
|
|
3601
3601
|
}
|
|
3602
3602
|
for (const output of outputs) {
|
|
3603
3603
|
tx.addOutput(output);
|
|
@@ -3608,8 +3608,8 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
3608
3608
|
return tx;
|
|
3609
3609
|
}
|
|
3610
3610
|
function buildCheckpointTx(vtxo, serverUnrollScript) {
|
|
3611
|
-
const collaborativeClosure =
|
|
3612
|
-
const checkpointVtxoScript = new
|
|
3611
|
+
const collaborativeClosure = chunkVVFCCNU2_cjs.decodeTapscript(chunkVVFCCNU2_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
|
|
3612
|
+
const checkpointVtxoScript = new chunkVVFCCNU2_cjs.VtxoScript([
|
|
3613
3613
|
serverUnrollScript.script,
|
|
3614
3614
|
collaborativeClosure.script
|
|
3615
3615
|
]);
|
|
@@ -3685,7 +3685,7 @@ function verifyTapscriptSignatures(tx, inputIndex, requiredSigners, excludePubke
|
|
|
3685
3685
|
const sighashType = signature.length === 65 ? signature[64] : btcSigner.SigHash.DEFAULT;
|
|
3686
3686
|
const sig = signature.subarray(0, 64);
|
|
3687
3687
|
if (!allowedSighashTypes.includes(sighashType)) {
|
|
3688
|
-
const sighashName =
|
|
3688
|
+
const sighashName = chunkVVFCCNU2_cjs.formatSighash(sighashType);
|
|
3689
3689
|
throw new Error(
|
|
3690
3690
|
`Unallowed sighash type ${sighashName} for input ${inputIndex}, pubkey ${pubKeyHex}.`
|
|
3691
3691
|
);
|
|
@@ -3759,7 +3759,7 @@ function combineTapscriptSigs(signedTx, originalTx) {
|
|
|
3759
3759
|
}
|
|
3760
3760
|
function isValidArkAddress(address) {
|
|
3761
3761
|
try {
|
|
3762
|
-
|
|
3762
|
+
chunkVVFCCNU2_cjs.ArkAddress.decode(address);
|
|
3763
3763
|
return true;
|
|
3764
3764
|
} catch (e) {
|
|
3765
3765
|
return false;
|
|
@@ -3767,16 +3767,16 @@ function isValidArkAddress(address) {
|
|
|
3767
3767
|
}
|
|
3768
3768
|
function matchServerCheckpoints(serverCheckpointTxs, expectedCheckpoints, context) {
|
|
3769
3769
|
if (serverCheckpointTxs.length !== expectedCheckpoints.length) {
|
|
3770
|
-
throw new
|
|
3770
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3771
3771
|
`${context} returned ${serverCheckpointTxs.length} checkpoints, expected ${expectedCheckpoints.length}`
|
|
3772
3772
|
);
|
|
3773
3773
|
}
|
|
3774
3774
|
const byTxid = new Map(expectedCheckpoints.map((c) => [c.id, c]));
|
|
3775
3775
|
return serverCheckpointTxs.map((encoded, index) => {
|
|
3776
|
-
const server =
|
|
3776
|
+
const server = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
|
|
3777
3777
|
const local = byTxid.get(server.id);
|
|
3778
3778
|
if (!local) {
|
|
3779
|
-
throw new
|
|
3779
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3780
3780
|
`${context} checkpoint ${index} txid ${server.id} does not match any submitted checkpoint`
|
|
3781
3781
|
);
|
|
3782
3782
|
}
|
|
@@ -3786,14 +3786,14 @@ function matchServerCheckpoints(serverCheckpointTxs, expectedCheckpoints, contex
|
|
|
3786
3786
|
}
|
|
3787
3787
|
function assertSubmittedArkTxid(response, signedArkTx, context) {
|
|
3788
3788
|
if (response.arkTxid !== signedArkTx.id) {
|
|
3789
|
-
throw new
|
|
3789
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3790
3790
|
`${context} returned ark txid ${response.arkTxid}, expected ${signedArkTx.id}`
|
|
3791
3791
|
);
|
|
3792
3792
|
}
|
|
3793
3793
|
if (response.finalArkTx === void 0) return;
|
|
3794
|
-
const finalTxid =
|
|
3794
|
+
const finalTxid = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx)).id;
|
|
3795
3795
|
if (finalTxid !== signedArkTx.id) {
|
|
3796
|
-
throw new
|
|
3796
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3797
3797
|
`${context} returned final ark tx ${finalTxid}, expected ${signedArkTx.id}`
|
|
3798
3798
|
);
|
|
3799
3799
|
}
|
|
@@ -3805,20 +3805,20 @@ function assertServerSignedLeaf(serverTx, localTx, inputIndex, serverPubkeys, co
|
|
|
3805
3805
|
`${context}: input ${inputIndex} carries no spend leaf to verify the server signature against`
|
|
3806
3806
|
);
|
|
3807
3807
|
}
|
|
3808
|
-
const script =
|
|
3808
|
+
const script = chunkVVFCCNU2_cjs.scriptFromTapLeafScript(leaf);
|
|
3809
3809
|
let leafPubkeys;
|
|
3810
3810
|
try {
|
|
3811
|
-
leafPubkeys =
|
|
3812
|
-
(key) => base.hex.encode(
|
|
3811
|
+
leafPubkeys = chunkVVFCCNU2_cjs.decodeTapscript(script).params.pubkeys.map(
|
|
3812
|
+
(key) => base.hex.encode(chunkCFOIHLON_cjs.toXOnly(key, "leaf key"))
|
|
3813
3813
|
);
|
|
3814
3814
|
} catch (error) {
|
|
3815
|
-
throw new
|
|
3815
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3816
3816
|
`${context}: input ${inputIndex} spend leaf cannot be decoded (${error instanceof Error ? error.message : String(error)})`
|
|
3817
3817
|
);
|
|
3818
3818
|
}
|
|
3819
3819
|
const signer = leafPubkeys.find((key) => serverPubkeys.has(key));
|
|
3820
3820
|
if (!signer) {
|
|
3821
|
-
throw new
|
|
3821
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3822
3822
|
`${context}: input ${inputIndex} spend leaf names no signer key the server advertises`
|
|
3823
3823
|
);
|
|
3824
3824
|
}
|
|
@@ -3832,7 +3832,7 @@ function assertServerSignedLeaf(serverTx, localTx, inputIndex, serverPubkeys, co
|
|
|
3832
3832
|
payment_js.tapLeafHash(script)
|
|
3833
3833
|
);
|
|
3834
3834
|
} catch (error) {
|
|
3835
|
-
throw new
|
|
3835
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3836
3836
|
`${context}: input ${inputIndex} is not signed by the server on the leaf being spent (${error instanceof Error ? error.message : String(error)})`
|
|
3837
3837
|
);
|
|
3838
3838
|
}
|
|
@@ -3841,20 +3841,20 @@ function assertCheckpointsMatchInputs(checkpoints, inputs, unrollCandidates, con
|
|
|
3841
3841
|
const byOutpoint = new Map(inputs.map((input) => [`${input.txid}:${input.vout}`, input]));
|
|
3842
3842
|
for (const [index, checkpoint] of checkpoints.entries()) {
|
|
3843
3843
|
if (checkpoint.inputsLength !== 1) {
|
|
3844
|
-
throw new
|
|
3844
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3845
3845
|
`${context}: checkpoint ${index} spends ${checkpoint.inputsLength} inputs, expected 1`
|
|
3846
3846
|
);
|
|
3847
3847
|
}
|
|
3848
3848
|
const spent = checkpoint.getInput(0);
|
|
3849
3849
|
if (!spent.txid || spent.index === void 0) {
|
|
3850
|
-
throw new
|
|
3850
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3851
3851
|
`${context}: checkpoint ${index} has no input outpoint`
|
|
3852
3852
|
);
|
|
3853
3853
|
}
|
|
3854
3854
|
const outpoint = `${base.hex.encode(spent.txid)}:${spent.index}`;
|
|
3855
3855
|
const input = byOutpoint.get(outpoint);
|
|
3856
3856
|
if (!input) {
|
|
3857
|
-
throw new
|
|
3857
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3858
3858
|
`${context}: checkpoint ${index} spends ${outpoint}, which is not one of the requested virtual outputs`
|
|
3859
3859
|
);
|
|
3860
3860
|
}
|
|
@@ -3862,7 +3862,7 @@ function assertCheckpointsMatchInputs(checkpoints, inputs, unrollCandidates, con
|
|
|
3862
3862
|
(unroll) => buildCheckpointTx(input, unroll).tx.id === checkpoint.id
|
|
3863
3863
|
);
|
|
3864
3864
|
if (!rebuilt) {
|
|
3865
|
-
throw new
|
|
3865
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3866
3866
|
`${context}: checkpoint ${index} txid ${checkpoint.id} differs from the checkpoint built locally for ${outpoint}`
|
|
3867
3867
|
);
|
|
3868
3868
|
}
|
|
@@ -3888,9 +3888,9 @@ async function submitOffchainTx(provider, offchainTx, signer, hooks, options) {
|
|
|
3888
3888
|
const matched = matchServerCheckpoints(signedCheckpointTxs, offchainTx.checkpoints, "submitTx");
|
|
3889
3889
|
matched.forEach(({ server }, index) => {
|
|
3890
3890
|
try {
|
|
3891
|
-
|
|
3891
|
+
chunkVVFCCNU2_cjs.assertAllowedSighashTypes(server);
|
|
3892
3892
|
} catch (error) {
|
|
3893
|
-
throw new
|
|
3893
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3894
3894
|
`submitTx checkpoint ${index}: ${error instanceof Error ? error.message : String(error)}`
|
|
3895
3895
|
);
|
|
3896
3896
|
}
|
|
@@ -3898,14 +3898,14 @@ async function submitOffchainTx(provider, offchainTx, signer, hooks, options) {
|
|
|
3898
3898
|
const verify = options?.verifyServerSignatures;
|
|
3899
3899
|
if (verify) {
|
|
3900
3900
|
if (response.finalArkTx === void 0) {
|
|
3901
|
-
throw new
|
|
3901
|
+
throw new chunkVVFCCNU2_cjs.ServerResponseMismatchError(
|
|
3902
3902
|
"submitTx: server returned no final ark tx to verify its signatures against"
|
|
3903
3903
|
);
|
|
3904
3904
|
}
|
|
3905
|
-
const finalArkTx =
|
|
3905
|
+
const finalArkTx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx));
|
|
3906
3906
|
const serverPubkeys = new Set(
|
|
3907
3907
|
[verify.serverPubkey, ...verify.deprecatedServerPubkeys ?? []].map(
|
|
3908
|
-
(key) => base.hex.encode(
|
|
3908
|
+
(key) => base.hex.encode(chunkCFOIHLON_cjs.toXOnly(key, "server key"))
|
|
3909
3909
|
)
|
|
3910
3910
|
);
|
|
3911
3911
|
for (let i = 0; i < offchainTx.arkTx.inputsLength; i++) {
|
|
@@ -3953,16 +3953,36 @@ async function signAndSubmitOffchainTx(params) {
|
|
|
3953
3953
|
});
|
|
3954
3954
|
return arkTxid;
|
|
3955
3955
|
}
|
|
3956
|
+
async function submitViaEmulator(emulator, offchainTx, signer, opts) {
|
|
3957
|
+
const { inputIndexes } = opts;
|
|
3958
|
+
let { arkTx, checkpoints } = offchainTx;
|
|
3959
|
+
if (inputIndexes.length > 0) {
|
|
3960
|
+
if (!signer) {
|
|
3961
|
+
throw new Error(`this spend requires an \`identity\` to sign inputs ${inputIndexes}`);
|
|
3962
|
+
}
|
|
3963
|
+
arkTx = await signer.sign(arkTx, inputIndexes);
|
|
3964
|
+
checkpoints = await Promise.all(
|
|
3965
|
+
checkpoints.map((c, i) => inputIndexes.includes(i) ? signer.sign(c, [0]) : c)
|
|
3966
|
+
);
|
|
3967
|
+
}
|
|
3968
|
+
const res = await emulator.submitTx(
|
|
3969
|
+
base.base64.encode(arkTx.toPSBT()),
|
|
3970
|
+
checkpoints.map((c) => base.base64.encode(c.toPSBT()))
|
|
3971
|
+
);
|
|
3972
|
+
const txid = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(res.signedArkTx)).id;
|
|
3973
|
+
assertSubmittedArkTxid({ arkTxid: txid }, arkTx, "emulator submitTx");
|
|
3974
|
+
return { txid, signedArkTx: res.signedArkTx, signedCheckpointTxs: res.signedCheckpointTxs };
|
|
3975
|
+
}
|
|
3956
3976
|
function claimWithPreimageIdentity(identity, preimage) {
|
|
3957
3977
|
return {
|
|
3958
3978
|
...identity,
|
|
3959
3979
|
sign: async (tx, inputIndexes) => {
|
|
3960
|
-
const signed =
|
|
3980
|
+
const signed = chunkVVFCCNU2_cjs.Transaction.fromPSBT(
|
|
3961
3981
|
(await identity.sign(tx.clone(), inputIndexes)).toPSBT()
|
|
3962
3982
|
);
|
|
3963
3983
|
const indexes = inputIndexes ?? Array.from({ length: signed.inputsLength }, (_, i) => i);
|
|
3964
3984
|
for (const index of indexes) {
|
|
3965
|
-
|
|
3985
|
+
chunkVVFCCNU2_cjs.setArkPsbtField(signed, index, chunkVVFCCNU2_cjs.ConditionWitness, [preimage]);
|
|
3966
3986
|
}
|
|
3967
3987
|
return signed;
|
|
3968
3988
|
}
|
|
@@ -4145,7 +4165,7 @@ function extendCoinWithTapscript(boardingTapscript, utxo) {
|
|
|
4145
4165
|
};
|
|
4146
4166
|
}
|
|
4147
4167
|
function deriveContractTapscripts(contract) {
|
|
4148
|
-
const handler =
|
|
4168
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
|
|
4149
4169
|
if (!handler) {
|
|
4150
4170
|
throw new Error(`No handler for contract type '${contract.type}'`);
|
|
4151
4171
|
}
|
|
@@ -4214,6 +4234,18 @@ function getRandomId() {
|
|
|
4214
4234
|
const randomValue = crypto.getRandomValues(new Uint8Array(16));
|
|
4215
4235
|
return base.hex.encode(randomValue);
|
|
4216
4236
|
}
|
|
4237
|
+
var sdkPicked = /* @__PURE__ */ new WeakSet();
|
|
4238
|
+
function markSdkPicked(params) {
|
|
4239
|
+
sdkPicked.add(params);
|
|
4240
|
+
return params;
|
|
4241
|
+
}
|
|
4242
|
+
function isSdkPicked(params) {
|
|
4243
|
+
return params !== void 0 && sdkPicked.has(params);
|
|
4244
|
+
}
|
|
4245
|
+
function getSelectableBoardingUtxos(wallet) {
|
|
4246
|
+
const selectable = wallet.getSelectableBoardingUtxos;
|
|
4247
|
+
return typeof selectable === "function" ? selectable.call(wallet) : wallet.getBoardingUtxos();
|
|
4248
|
+
}
|
|
4217
4249
|
function assertRecipientArkadeAddress(encoded, address, context) {
|
|
4218
4250
|
if (address.hrp !== context.hrp) {
|
|
4219
4251
|
throw new Error(
|
|
@@ -4236,7 +4268,7 @@ function assertRecipientArkadeAddress(encoded, address, context) {
|
|
|
4236
4268
|
function assertTapTreeDerivesAddress(encoded, tapTree, address) {
|
|
4237
4269
|
let derived;
|
|
4238
4270
|
try {
|
|
4239
|
-
derived =
|
|
4271
|
+
derived = chunkVVFCCNU2_cjs.VtxoScript.decode(tapTree).pkScript;
|
|
4240
4272
|
} catch (e) {
|
|
4241
4273
|
throw new Error(
|
|
4242
4274
|
`Invalid tapTree for ${encoded}: ${e instanceof Error ? e.message : String(e)}`
|
|
@@ -4253,7 +4285,7 @@ function validateRecipients(recipients, dustAmount, context) {
|
|
|
4253
4285
|
for (const recipient of recipients) {
|
|
4254
4286
|
let address;
|
|
4255
4287
|
try {
|
|
4256
|
-
address =
|
|
4288
|
+
address = chunkVVFCCNU2_cjs.ArkAddress.decode(recipient.address);
|
|
4257
4289
|
} catch (e) {
|
|
4258
4290
|
throw new Error(`Invalid Arkade address: ${recipient.address}`);
|
|
4259
4291
|
}
|
|
@@ -4278,7 +4310,7 @@ function validateRecipients(recipients, dustAmount, context) {
|
|
|
4278
4310
|
|
|
4279
4311
|
// src/contracts/spendability.ts
|
|
4280
4312
|
function isContractGenericallySpendable(contract) {
|
|
4281
|
-
return
|
|
4313
|
+
return chunkCFOIHLON_cjs.contractHandlers.get(contract.type)?.isGenericallySpendable?.(contract) === true;
|
|
4282
4314
|
}
|
|
4283
4315
|
function gatedContracts(contracts) {
|
|
4284
4316
|
const gated = /* @__PURE__ */ new Map();
|
|
@@ -4300,7 +4332,7 @@ function gateExclusion(gated) {
|
|
|
4300
4332
|
return (vtxo) => {
|
|
4301
4333
|
const type = gatedTypeOf(vtxo, gated);
|
|
4302
4334
|
if (type === void 0) return void 0;
|
|
4303
|
-
if (!
|
|
4335
|
+
if (!chunkCFOIHLON_cjs.contractHandlers.has(type)) {
|
|
4304
4336
|
return `at ${vtxo.script} (contract type '${type}') has no handler registered in this build`;
|
|
4305
4337
|
}
|
|
4306
4338
|
return `at ${vtxo.script} (contract type '${type}') is not generically spendable`;
|
|
@@ -4336,7 +4368,7 @@ function selectPendingRecoveryOutpoints(contractsWithVtxos, signerSet, nowSecond
|
|
|
4336
4368
|
continue;
|
|
4337
4369
|
}
|
|
4338
4370
|
for (const v of vtxos) {
|
|
4339
|
-
if (!
|
|
4371
|
+
if (!chunkVVFCCNU2_cjs.isVtxoSpent(v) && !v.isSwept && !v.isUnrolled) {
|
|
4340
4372
|
out.add(`${v.txid}:${v.vout}`);
|
|
4341
4373
|
}
|
|
4342
4374
|
}
|
|
@@ -4372,10 +4404,14 @@ function byValueDescending(vtxos) {
|
|
|
4372
4404
|
return [...vtxos].sort((a, b) => b.value - a.value);
|
|
4373
4405
|
}
|
|
4374
4406
|
async function fetchTimeHeight(wallet) {
|
|
4375
|
-
return
|
|
4407
|
+
return chunkVVFCCNU2_cjs.resolveTimeHeight(wallet.onchainProvider);
|
|
4408
|
+
}
|
|
4409
|
+
function heldVtxosOf(wallet) {
|
|
4410
|
+
const held = wallet.getHeldVtxos;
|
|
4411
|
+
return typeof held === "function" ? held.call(wallet) : Promise.resolve([]);
|
|
4376
4412
|
}
|
|
4377
4413
|
function canMigrateBySend(vtxo, now) {
|
|
4378
|
-
if (!
|
|
4414
|
+
if (!chunkVVFCCNU2_cjs.canSpendOffchain(vtxo, now)) return false;
|
|
4379
4415
|
return vtxo.expiresAt !== void 0 || vtxo.expiresAtHeight !== void 0;
|
|
4380
4416
|
}
|
|
4381
4417
|
function byExpiryAscending(vtxos, now) {
|
|
@@ -4383,7 +4419,7 @@ function byExpiryAscending(vtxos, now) {
|
|
|
4383
4419
|
if (vtxo.isSwept) return -Infinity;
|
|
4384
4420
|
if (vtxo.expiresAt !== void 0) return vtxo.expiresAt.getTime();
|
|
4385
4421
|
if (vtxo.expiresAtHeight !== void 0) {
|
|
4386
|
-
return
|
|
4422
|
+
return chunkVVFCCNU2_cjs.isPastExpiry(vtxo, now) ? -Infinity : Infinity;
|
|
4387
4423
|
}
|
|
4388
4424
|
return Infinity;
|
|
4389
4425
|
};
|
|
@@ -4410,7 +4446,7 @@ function priceSettlementInputs(vtxos, estimator) {
|
|
|
4410
4446
|
const payable = [];
|
|
4411
4447
|
const net = /* @__PURE__ */ new Map();
|
|
4412
4448
|
for (const vtxo of vtxos) {
|
|
4413
|
-
const inputFee = estimator.evalOffchainInput(
|
|
4449
|
+
const inputFee = estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(vtxo));
|
|
4414
4450
|
if (inputFee.satoshis >= vtxo.value) {
|
|
4415
4451
|
continue;
|
|
4416
4452
|
}
|
|
@@ -4439,7 +4475,7 @@ function offchainOutputFee(amount, estimator, arkAddress) {
|
|
|
4439
4475
|
}
|
|
4440
4476
|
const outputFee = estimator.evalOffchainOutput({
|
|
4441
4477
|
amount,
|
|
4442
|
-
script: base.hex.encode(
|
|
4478
|
+
script: base.hex.encode(chunkVVFCCNU2_cjs.ArkAddress.decode(arkAddress).pkScript)
|
|
4443
4479
|
});
|
|
4444
4480
|
return BigInt(outputFee.satoshis);
|
|
4445
4481
|
}
|
|
@@ -4490,10 +4526,10 @@ var DEFAULT_SETTLEMENT_CONFIG = {
|
|
|
4490
4526
|
};
|
|
4491
4527
|
function getRecoverableVtxos(vtxos, dustAmount, now) {
|
|
4492
4528
|
return vtxos.filter((vtxo) => {
|
|
4493
|
-
if (
|
|
4529
|
+
if (chunkVVFCCNU2_cjs.canRecoverOnchain(vtxo, now)) {
|
|
4494
4530
|
return true;
|
|
4495
4531
|
}
|
|
4496
|
-
if (
|
|
4532
|
+
if (chunkVVFCCNU2_cjs.canSpendOffchain(vtxo, now) && vtxo.isPreconfirmed && isSubdust(vtxo, dustAmount)) {
|
|
4497
4533
|
return true;
|
|
4498
4534
|
}
|
|
4499
4535
|
return false;
|
|
@@ -4525,7 +4561,7 @@ function getRecoverableWithSubdust(vtxos, dustAmount, now) {
|
|
|
4525
4561
|
function isVtxoExpiringSoon(vtxo, thresholdMs) {
|
|
4526
4562
|
if (vtxo.isUnrolled) return false;
|
|
4527
4563
|
const realThresholdMs = thresholdMs <= 100 ? DEFAULT_THRESHOLD_MS : thresholdMs;
|
|
4528
|
-
const expiresAt =
|
|
4564
|
+
const expiresAt = chunkVVFCCNU2_cjs.normalizeVtxo(vtxo).expiresAt;
|
|
4529
4565
|
if (expiresAt === void 0) return false;
|
|
4530
4566
|
const now = Date.now();
|
|
4531
4567
|
const batchExpiry = expiresAt.getTime();
|
|
@@ -4536,7 +4572,7 @@ function getExpiringAndRecoverableVtxos(vtxos, thresholdMs, dustAmount, now) {
|
|
|
4536
4572
|
return vtxos.filter(
|
|
4537
4573
|
// The leading exclusion covers the `isSubdust` arm too, which is a value
|
|
4538
4574
|
// property and would otherwise re-admit an exited coin on its own.
|
|
4539
|
-
(vtxo) => !vtxo.isUnrolled && (isVtxoExpiringSoon(vtxo, thresholdMs) ||
|
|
4575
|
+
(vtxo) => !vtxo.isUnrolled && (isVtxoExpiringSoon(vtxo, thresholdMs) || chunkVVFCCNU2_cjs.canRecoverOnchain(vtxo, now) || isSubdust(vtxo, dustAmount))
|
|
4540
4576
|
);
|
|
4541
4577
|
}
|
|
4542
4578
|
function isMigrationCapable(wallet) {
|
|
@@ -4596,7 +4632,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
4596
4632
|
constructor(wallet, settlementConfig) {
|
|
4597
4633
|
this.wallet = wallet;
|
|
4598
4634
|
if (settlementConfig !== false) {
|
|
4599
|
-
|
|
4635
|
+
chunkVVFCCNU2_cjs.assertTimerMs("pollIntervalMs", settlementConfig?.pollIntervalMs);
|
|
4600
4636
|
}
|
|
4601
4637
|
this.settlementConfig = settlementConfig !== void 0 ? settlementConfig : { ...DEFAULT_SETTLEMENT_CONFIG };
|
|
4602
4638
|
this.contractEventsSubscriptionReady = this.initializeSubscription();
|
|
@@ -4903,7 +4939,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
4903
4939
|
* {@link recoverImportedContracts}).
|
|
4904
4940
|
*/
|
|
4905
4941
|
async recoverOneImportedContract(wallet, contract, vtxos, info, dustAmount) {
|
|
4906
|
-
const recoverable = vtxos.filter((vtxo) => vtxo.isSwept && !
|
|
4942
|
+
const recoverable = vtxos.filter((vtxo) => vtxo.isSwept && !chunkVVFCCNU2_cjs.isVtxoSpent(vtxo));
|
|
4907
4943
|
const estimator = new Estimator(info?.fees.intentFee ?? {});
|
|
4908
4944
|
const { payable, net } = priceSettlementInputs(recoverable, estimator);
|
|
4909
4945
|
const vtxoMaxAmount = info?.vtxoMaxAmount ?? -1n;
|
|
@@ -4925,7 +4961,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
4925
4961
|
if (vtxos.length === 0) return;
|
|
4926
4962
|
const spent = new Set(batch.map((vtxo) => `${vtxo.txid}:${vtxo.vout}`));
|
|
4927
4963
|
const stillSpendable = vtxos.some(
|
|
4928
|
-
(vtxo) => !
|
|
4964
|
+
(vtxo) => !chunkVVFCCNU2_cjs.isVtxoSpent(vtxo) && !spent.has(`${vtxo.txid}:${vtxo.vout}`)
|
|
4929
4965
|
);
|
|
4930
4966
|
if (!stillSpendable) {
|
|
4931
4967
|
await wallet.removeRecoveryContract(contract.script);
|
|
@@ -4974,12 +5010,37 @@ var VtxoManager = class _VtxoManager {
|
|
|
4974
5010
|
genericallySpendableOnly: true
|
|
4975
5011
|
});
|
|
4976
5012
|
const threshold = thresholdMs !== void 0 ? thresholdMs : this.configuredThresholdMs();
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
5013
|
+
const tip = now ?? await fetchTimeHeight(this.wallet);
|
|
5014
|
+
await this.warnHeldExpiring(threshold, tip);
|
|
5015
|
+
return getExpiringAndRecoverableVtxos(vtxos, threshold, getDustAmount(this.wallet), tip);
|
|
5016
|
+
}
|
|
5017
|
+
/** Outpoints {@link warnHeldExpiring} last reported, so each is reported once while held. */
|
|
5018
|
+
heldExpiringWarned = /* @__PURE__ */ new Set();
|
|
5019
|
+
/**
|
|
5020
|
+
* A hold outranks renewal: renewing would change the outpoint under the holder, whose spend
|
|
5021
|
+
* by name would then fail. So the VTXO is skipped, and only this warning says it is drifting
|
|
5022
|
+
* toward a sweep. Best-effort: a failed read never blocks renewal.
|
|
5023
|
+
*/
|
|
5024
|
+
async warnHeldExpiring(threshold, now) {
|
|
5025
|
+
let keys;
|
|
5026
|
+
try {
|
|
5027
|
+
const held = await heldVtxosOf(this.wallet);
|
|
5028
|
+
keys = getExpiringAndRecoverableVtxos(
|
|
5029
|
+
held,
|
|
5030
|
+
threshold,
|
|
5031
|
+
getDustAmount(this.wallet),
|
|
5032
|
+
now
|
|
5033
|
+
).map((vtxo) => `${vtxo.txid}:${vtxo.vout}`);
|
|
5034
|
+
} catch {
|
|
5035
|
+
return;
|
|
5036
|
+
}
|
|
5037
|
+
const fresh = keys.filter((key) => !this.heldExpiringWarned.has(key));
|
|
5038
|
+
this.heldExpiringWarned = new Set(keys);
|
|
5039
|
+
if (fresh.length > 0) {
|
|
5040
|
+
console.warn(
|
|
5041
|
+
`Renewal: ${fresh.length} VTXO(s) due for renewal are held by reserveVtxos and will not be renewed; spend or release them before they expire: ${fresh.join(", ")}`
|
|
5042
|
+
);
|
|
5043
|
+
}
|
|
4983
5044
|
}
|
|
4984
5045
|
/**
|
|
4985
5046
|
* Renew expiring virtual outputs (including recoverable ones) by settling them back to the
|
|
@@ -5089,10 +5150,10 @@ var VtxoManager = class _VtxoManager {
|
|
|
5089
5150
|
}
|
|
5090
5151
|
}
|
|
5091
5152
|
const txid = await this.wallet.settle(
|
|
5092
|
-
{
|
|
5153
|
+
markSdkPicked({
|
|
5093
5154
|
inputs: vtxos,
|
|
5094
5155
|
outputs: amounts.map((amount) => ({ address: arkAddress, amount }))
|
|
5095
|
-
},
|
|
5156
|
+
}),
|
|
5096
5157
|
eventCallback
|
|
5097
5158
|
);
|
|
5098
5159
|
return txid;
|
|
@@ -5192,11 +5253,11 @@ var VtxoManager = class _VtxoManager {
|
|
|
5192
5253
|
`Sweep not economical: output ${outputAmount} sats after ${fee} sats fee is below dust (${dustAmount} sats)`
|
|
5193
5254
|
);
|
|
5194
5255
|
}
|
|
5195
|
-
const tx = new
|
|
5256
|
+
const tx = new chunkVVFCCNU2_cjs.Transaction();
|
|
5196
5257
|
for (const utxo of expiredUtxos) {
|
|
5197
|
-
const utxoScript =
|
|
5258
|
+
const utxoScript = chunkVVFCCNU2_cjs.VtxoScript.decode(utxo.tapTree);
|
|
5198
5259
|
const utxoExitLeaf = utxoScript.leaves.find(
|
|
5199
|
-
(leaf) =>
|
|
5260
|
+
(leaf) => chunkVVFCCNU2_cjs.CSVMultisigTapscript.isScriptValid(chunkVVFCCNU2_cjs.scriptFromTapLeafScript(leaf)) === true
|
|
5200
5261
|
);
|
|
5201
5262
|
if (!utxoExitLeaf) {
|
|
5202
5263
|
throw new Error(
|
|
@@ -5211,7 +5272,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
5211
5272
|
amount: BigInt(utxo.value)
|
|
5212
5273
|
},
|
|
5213
5274
|
tapLeafScript: [utxoExitLeaf],
|
|
5214
|
-
sequence:
|
|
5275
|
+
sequence: chunkVVFCCNU2_cjs.getSequence(utxoExitLeaf)
|
|
5215
5276
|
});
|
|
5216
5277
|
}
|
|
5217
5278
|
tx.addOutputAddress(boardingAddress, outputAmount, this.getNetwork());
|
|
@@ -5437,8 +5498,8 @@ var VtxoManager = class _VtxoManager {
|
|
|
5437
5498
|
const cls = classifyAgainstSignerSet(serverPubKey, signerSet, nowSeconds);
|
|
5438
5499
|
if (cls.status === "CURRENT") continue;
|
|
5439
5500
|
const live = vtxos.filter((v) => !v.isUnrolled);
|
|
5440
|
-
const recoverable = live.filter((v) => v.isSwept && !
|
|
5441
|
-
const spendable = live.filter((v) => !
|
|
5501
|
+
const recoverable = live.filter((v) => v.isSwept && !chunkVVFCCNU2_cjs.isVtxoSpent(v));
|
|
5502
|
+
const spendable = live.filter((v) => !chunkVVFCCNU2_cjs.isVtxoSpent(v) && !v.isSwept);
|
|
5442
5503
|
const value = spendable.reduce((sum, v) => sum + v.value, 0);
|
|
5443
5504
|
let recoverableCount = 0;
|
|
5444
5505
|
let recoverableValue = 0;
|
|
@@ -5678,7 +5739,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
5678
5739
|
}
|
|
5679
5740
|
getBoardingTimelock() {
|
|
5680
5741
|
const wallet = this.getSweepWallet();
|
|
5681
|
-
const exitScript =
|
|
5742
|
+
const exitScript = chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(
|
|
5682
5743
|
base.hex.decode(wallet.boardingTapscript.exitScript)
|
|
5683
5744
|
);
|
|
5684
5745
|
return exitScript.params.timelock;
|
|
@@ -5728,7 +5789,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
5728
5789
|
if (e.message.includes("is below dust threshold")) {
|
|
5729
5790
|
return;
|
|
5730
5791
|
}
|
|
5731
|
-
if (e.message.includes("VTXO_ALREADY_REGISTERED") || e.message.includes("duplicated input")) {
|
|
5792
|
+
if (e.name === "VtxoReservedError" || e.message.includes("VTXO_ALREADY_REGISTERED") || e.message.includes("duplicated input")) {
|
|
5732
5793
|
return;
|
|
5733
5794
|
}
|
|
5734
5795
|
if (e.message.includes("VTXO_ALREADY_SPENT")) {
|
|
@@ -5786,8 +5847,8 @@ var VtxoManager = class _VtxoManager {
|
|
|
5786
5847
|
}
|
|
5787
5848
|
/** The outpoint a `VTXO_ALREADY_SPENT` error carries in `metadata.vtxo_outpoint`, if any. */
|
|
5788
5849
|
extractSpentOutpoint(error) {
|
|
5789
|
-
const ark =
|
|
5790
|
-
if (!
|
|
5850
|
+
const ark = chunkVVFCCNU2_cjs.maybeArkError(error);
|
|
5851
|
+
if (!chunkVVFCCNU2_cjs.isArkError(ark, chunkVVFCCNU2_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
|
|
5791
5852
|
const raw = ark.metadata?.vtxo_outpoint;
|
|
5792
5853
|
if (typeof raw !== "string") return void 0;
|
|
5793
5854
|
const [txid, voutStr] = raw.split(":");
|
|
@@ -5856,7 +5917,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
5856
5917
|
let hadError = false;
|
|
5857
5918
|
try {
|
|
5858
5919
|
await runWithCrossInstanceLock(BOARDING_POLL_LOCK_NAME, async () => {
|
|
5859
|
-
const boardingUtxos = await this.wallet
|
|
5920
|
+
const boardingUtxos = await getSelectableBoardingUtxos(this.wallet);
|
|
5860
5921
|
try {
|
|
5861
5922
|
await this.runPeriodicSettle(boardingUtxos);
|
|
5862
5923
|
} catch (e) {
|
|
@@ -5961,7 +6022,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
5961
6022
|
if (filteredVtxos.length >= MAX_VTXOS_PER_SETTLEMENT) {
|
|
5962
6023
|
break;
|
|
5963
6024
|
}
|
|
5964
|
-
const inputFee = estimator.evalOffchainInput(
|
|
6025
|
+
const inputFee = estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(v));
|
|
5965
6026
|
if (inputFee.satoshis >= v.value) {
|
|
5966
6027
|
continue;
|
|
5967
6028
|
}
|
|
@@ -5981,7 +6042,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
5981
6042
|
const arkAddress = await this.wallet.getAddress();
|
|
5982
6043
|
const outputFee = estimator.evalOffchainOutput({
|
|
5983
6044
|
amount: totalAmount,
|
|
5984
|
-
script: base.hex.encode(
|
|
6045
|
+
script: base.hex.encode(chunkVVFCCNU2_cjs.ArkAddress.decode(arkAddress).pkScript)
|
|
5985
6046
|
});
|
|
5986
6047
|
totalAmount -= BigInt(outputFee.satoshis);
|
|
5987
6048
|
if (totalAmount < dustAmount) return;
|
|
@@ -5990,20 +6051,24 @@ var VtxoManager = class _VtxoManager {
|
|
|
5990
6051
|
this.renewalInProgress = true;
|
|
5991
6052
|
}
|
|
5992
6053
|
let success = false;
|
|
5993
|
-
let
|
|
6054
|
+
let skipWithoutBackoff = false;
|
|
5994
6055
|
try {
|
|
5995
6056
|
try {
|
|
5996
|
-
await this.wallet.settle(
|
|
5997
|
-
|
|
5998
|
-
|
|
5999
|
-
|
|
6057
|
+
await this.wallet.settle(
|
|
6058
|
+
markSdkPicked({
|
|
6059
|
+
inputs: [...filteredBoarding, ...filteredVtxos],
|
|
6060
|
+
outputs: [{ address: arkAddress, amount: totalAmount }]
|
|
6061
|
+
})
|
|
6062
|
+
);
|
|
6000
6063
|
for (const u of filteredBoarding) {
|
|
6001
6064
|
this.knownBoardingUtxos.add(`${u.txid}:${u.vout}`);
|
|
6002
6065
|
}
|
|
6003
6066
|
success = true;
|
|
6004
6067
|
} catch (e) {
|
|
6005
|
-
if (e instanceof Error && e.
|
|
6006
|
-
|
|
6068
|
+
if (e instanceof Error && e.name === "VtxoReservedError") {
|
|
6069
|
+
skipWithoutBackoff = true;
|
|
6070
|
+
} else if (e instanceof Error && e.message.includes("VTXO_ALREADY_SPENT")) {
|
|
6071
|
+
skipWithoutBackoff = true;
|
|
6007
6072
|
void this.maybeRefreshAfterVtxoSpent(this.extractSpentOutpoint(e));
|
|
6008
6073
|
} else {
|
|
6009
6074
|
throw e;
|
|
@@ -6017,7 +6082,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
6017
6082
|
}
|
|
6018
6083
|
if (success) {
|
|
6019
6084
|
this.consecutivePeriodicSettleFailures = 0;
|
|
6020
|
-
} else if (!
|
|
6085
|
+
} else if (!skipWithoutBackoff) {
|
|
6021
6086
|
this.consecutivePeriodicSettleFailures++;
|
|
6022
6087
|
}
|
|
6023
6088
|
}
|
|
@@ -6061,7 +6126,7 @@ var ArkNote = class _ArkNote {
|
|
|
6061
6126
|
this.value = value;
|
|
6062
6127
|
this.HRP = HRP;
|
|
6063
6128
|
const preimageHash = utils_js.sha256(this.preimage);
|
|
6064
|
-
this.vtxoScript = new
|
|
6129
|
+
this.vtxoScript = new chunkVVFCCNU2_cjs.VtxoScript([noteTapscript(preimageHash)]);
|
|
6065
6130
|
const leaf = this.vtxoScript.leaves[0];
|
|
6066
6131
|
this.txid = base.hex.encode(new Uint8Array(preimageHash).reverse());
|
|
6067
6132
|
this.tapTree = this.vtxoScript.encode();
|
|
@@ -6234,7 +6299,7 @@ var ArkadeCash = class _ArkadeCash {
|
|
|
6234
6299
|
const privateKey = data.slice(1, 33);
|
|
6235
6300
|
const serverPubKey = data.slice(33, 65);
|
|
6236
6301
|
const sequence = new DataView(data.buffer, data.byteOffset + 65, 4).getUint32(0, false);
|
|
6237
|
-
const csvTimelock2 =
|
|
6302
|
+
const csvTimelock2 = chunkVVFCCNU2_cjs.sequenceToTimelock(sequence);
|
|
6238
6303
|
return new _ArkadeCash(privateKey, serverPubKey, csvTimelock2, decoded.prefix);
|
|
6239
6304
|
}
|
|
6240
6305
|
toString() {
|
|
@@ -6242,7 +6307,7 @@ var ArkadeCash = class _ArkadeCash {
|
|
|
6242
6307
|
data[0] = _ArkadeCash.Version;
|
|
6243
6308
|
data.set(this._privateKey, 1);
|
|
6244
6309
|
data.set(this._serverPubKey, 33);
|
|
6245
|
-
const sequence =
|
|
6310
|
+
const sequence = chunkVVFCCNU2_cjs.timelockToSequence(this.csvTimelock);
|
|
6246
6311
|
new DataView(data.buffer, data.byteOffset + 65, 4).setUint32(0, sequence, false);
|
|
6247
6312
|
const words = base.bech32m.toWords(data);
|
|
6248
6313
|
return base.bech32m.encode(this.hrp, words, 1023);
|
|
@@ -6251,7 +6316,7 @@ var ArkadeCash = class _ArkadeCash {
|
|
|
6251
6316
|
return SingleKey.fromPrivateKey(this._privateKey);
|
|
6252
6317
|
}
|
|
6253
6318
|
get vtxoScript() {
|
|
6254
|
-
return new
|
|
6319
|
+
return new chunkCFOIHLON_cjs.DefaultVtxo.Script({
|
|
6255
6320
|
pubKey: this._publicKey,
|
|
6256
6321
|
serverPubKey: this._serverPubKey,
|
|
6257
6322
|
csvTimelock: this.csvTimelock
|
|
@@ -6267,7 +6332,7 @@ var NON_TERMINAL_INTENT_STATES = ALL_INTENT_STATES.filter(
|
|
|
6267
6332
|
(s) => !isTerminalIntentState(s)
|
|
6268
6333
|
);
|
|
6269
6334
|
function isConsumed(vtxo) {
|
|
6270
|
-
return vtxo !== void 0 &&
|
|
6335
|
+
return vtxo !== void 0 && chunkVVFCCNU2_cjs.isVtxoSpent(vtxo);
|
|
6271
6336
|
}
|
|
6272
6337
|
async function classifyIntent(intent, vtxosByOutpoint, now) {
|
|
6273
6338
|
if (isTerminalIntentState(intent.state)) return void 0;
|
|
@@ -6310,7 +6375,7 @@ async function reconcileIntents(deps) {
|
|
|
6310
6375
|
let vtxosByOutpoint = /* @__PURE__ */ new Map();
|
|
6311
6376
|
if (outpoints.length > 0) {
|
|
6312
6377
|
try {
|
|
6313
|
-
const { vtxos } = await
|
|
6378
|
+
const { vtxos } = await chunkVVFCCNU2_cjs.getNormalizedVtxos(deps.indexerProvider, { outpoints });
|
|
6314
6379
|
vtxosByOutpoint = new Map(vtxos.map((v) => [outpointKey(v), v]));
|
|
6315
6380
|
} catch (e) {
|
|
6316
6381
|
console.error("reconcileIntents: failed to fetch input VTXO state", e);
|
|
@@ -6370,7 +6435,7 @@ async function releaseFromServer(intent, deps, now) {
|
|
|
6370
6435
|
});
|
|
6371
6436
|
}
|
|
6372
6437
|
function isNoMatchingIntentsError(e) {
|
|
6373
|
-
return
|
|
6438
|
+
return chunkVVFCCNU2_cjs.isArkError(e, chunkVVFCCNU2_cjs.ArkErrorName.INVALID_INTENT_PROOF) && e.message.includes("no matching intents found");
|
|
6374
6439
|
}
|
|
6375
6440
|
function terminal(intent, state, now, patch) {
|
|
6376
6441
|
return { ...intent, ...patch, state, updatedAt: now };
|
|
@@ -6589,7 +6654,7 @@ async function captureExitBranch(params) {
|
|
|
6589
6654
|
const nonCommitment = ordered.filter((c) => chainTxTypeToChainedExit(c.type) !== 1 /* Commitment */).map((c) => c.txid);
|
|
6590
6655
|
if (nonCommitment.length > 0) {
|
|
6591
6656
|
for (const psbt of await resolver.getVirtualTxs(nonCommitment)) {
|
|
6592
|
-
psbtByTxid.set(
|
|
6657
|
+
psbtByTxid.set(chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
6593
6658
|
}
|
|
6594
6659
|
}
|
|
6595
6660
|
}
|
|
@@ -6632,10 +6697,10 @@ var IndexerExitDataSource = class {
|
|
|
6632
6697
|
while (hasMore) {
|
|
6633
6698
|
const { chain: page, page: meta } = await this.indexer.getVtxoChain(
|
|
6634
6699
|
{ txid: vtxo.txid, vout: vtxo.vout },
|
|
6635
|
-
{ pageIndex, pageSize:
|
|
6700
|
+
{ pageIndex, pageSize: chunkVVFCCNU2_cjs.DEFAULT_PAGE_SIZE }
|
|
6636
6701
|
);
|
|
6637
6702
|
chain.push(...page);
|
|
6638
|
-
hasMore = meta ? page.length ===
|
|
6703
|
+
hasMore = meta ? page.length === chunkVVFCCNU2_cjs.DEFAULT_PAGE_SIZE : false;
|
|
6639
6704
|
pageIndex++;
|
|
6640
6705
|
}
|
|
6641
6706
|
return chain;
|
|
@@ -6647,12 +6712,12 @@ var IndexerExitDataSource = class {
|
|
|
6647
6712
|
while (hasMore) {
|
|
6648
6713
|
const { txs, page } = await this.indexer.getVirtualTxs(txids, {
|
|
6649
6714
|
pageIndex,
|
|
6650
|
-
pageSize:
|
|
6715
|
+
pageSize: chunkVVFCCNU2_cjs.DEFAULT_PAGE_SIZE
|
|
6651
6716
|
});
|
|
6652
6717
|
for (const psbt of txs) {
|
|
6653
|
-
out.set(
|
|
6718
|
+
out.set(chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
6654
6719
|
}
|
|
6655
|
-
hasMore = page ? txs.length ===
|
|
6720
|
+
hasMore = page ? txs.length === chunkVVFCCNU2_cjs.DEFAULT_PAGE_SIZE : false;
|
|
6656
6721
|
pageIndex++;
|
|
6657
6722
|
}
|
|
6658
6723
|
return out;
|
|
@@ -6673,7 +6738,7 @@ function chainedTxTypeToChainTxType(t) {
|
|
|
6673
6738
|
}
|
|
6674
6739
|
}
|
|
6675
6740
|
function psbtInputTxids(psbtBase64) {
|
|
6676
|
-
return txInputTxids(
|
|
6741
|
+
return txInputTxids(chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64)));
|
|
6677
6742
|
}
|
|
6678
6743
|
function txInputTxids(tx) {
|
|
6679
6744
|
const ids = [];
|
|
@@ -6977,10 +7042,10 @@ async function resolveArkInfo(arkProvider, walletRepository, opts) {
|
|
|
6977
7042
|
try {
|
|
6978
7043
|
info = await arkProvider.getInfo();
|
|
6979
7044
|
} catch (err) {
|
|
6980
|
-
if (opts?.requireLive || !
|
|
7045
|
+
if (opts?.requireLive || !chunkVVFCCNU2_cjs.isRetryableProviderError(err)) throw err;
|
|
6981
7046
|
const snapshot = await loadArkInfoSnapshot(walletRepository);
|
|
6982
7047
|
if (!snapshot) {
|
|
6983
|
-
throw new
|
|
7048
|
+
throw new chunkVVFCCNU2_cjs.ProviderUnavailableError(
|
|
6984
7049
|
"Arkade server info is unavailable and no cached snapshot exists",
|
|
6985
7050
|
{ cause: err }
|
|
6986
7051
|
);
|
|
@@ -7172,7 +7237,7 @@ function buildGraph(rootTxid, chunksByTxid) {
|
|
|
7172
7237
|
return new TxTree(rootTx, children);
|
|
7173
7238
|
}
|
|
7174
7239
|
function decodeNode(chunk) {
|
|
7175
|
-
const tx =
|
|
7240
|
+
const tx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(chunk.tx));
|
|
7176
7241
|
return { tx, children: chunk.children };
|
|
7177
7242
|
}
|
|
7178
7243
|
exports.Batch = void 0;
|
|
@@ -7375,7 +7440,7 @@ function collectArkTxidsNeedingCreatedAt(vtxos, localCreatedAt) {
|
|
|
7375
7440
|
return [...txids];
|
|
7376
7441
|
}
|
|
7377
7442
|
async function buildTransactionHistory(vtxos, allBoardingTxs, commitmentsToIgnore, resolveTxCreatedAt, gatedScripts = /* @__PURE__ */ new Map()) {
|
|
7378
|
-
const normalized = vtxos.map(
|
|
7443
|
+
const normalized = vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
7379
7444
|
const localCreatedAt = localCreatedAtByTxid(normalized);
|
|
7380
7445
|
const gatedVtxos = normalized.filter((vtxo) => isGatedVtxo(vtxo, gatedScripts));
|
|
7381
7446
|
const ownVtxos = normalized.filter((vtxo) => !isGatedVtxo(vtxo, gatedScripts));
|
|
@@ -7542,6 +7607,9 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7542
7607
|
* ```
|
|
7543
7608
|
*/
|
|
7544
7609
|
async issue(params) {
|
|
7610
|
+
return this.wallet.withSpendLock((submit) => this.issueWith(params, submit));
|
|
7611
|
+
}
|
|
7612
|
+
async issueWith(params, submit) {
|
|
7545
7613
|
if (params.amount <= 0n) {
|
|
7546
7614
|
throw new Error(`Issue amount must be greater than 0, got ${params.amount}`);
|
|
7547
7615
|
}
|
|
@@ -7550,7 +7618,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7550
7618
|
withRecoverable: false,
|
|
7551
7619
|
genericallySpendableOnly: true
|
|
7552
7620
|
});
|
|
7553
|
-
const controlAssetRef = params.controlAssetId ?
|
|
7621
|
+
const controlAssetRef = params.controlAssetId ? chunkFEBAG2K2_cjs.AssetRef.fromId(chunkFEBAG2K2_cjs.AssetId.fromString(params.controlAssetId)) : null;
|
|
7554
7622
|
const coinSelection = selectVirtualCoins(virtualCoins, Number(this.wallet.dustAmount));
|
|
7555
7623
|
let totalBtcSelected = 0n;
|
|
7556
7624
|
const assetChanges = /* @__PURE__ */ new Map();
|
|
@@ -7563,8 +7631,8 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7563
7631
|
}
|
|
7564
7632
|
}
|
|
7565
7633
|
const groups = [];
|
|
7566
|
-
const issuedAssetOutput =
|
|
7567
|
-
const issuedAssetGroup =
|
|
7634
|
+
const issuedAssetOutput = chunkFEBAG2K2_cjs.AssetOutput.create(0, params.amount);
|
|
7635
|
+
const issuedAssetGroup = chunkFEBAG2K2_cjs.AssetGroup.create(
|
|
7568
7636
|
null,
|
|
7569
7637
|
controlAssetRef,
|
|
7570
7638
|
[],
|
|
@@ -7577,17 +7645,18 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7577
7645
|
for (const [assetId, amount] of assetChanges) {
|
|
7578
7646
|
const changeInputs = inputsForAsset(assetInputs, assetId);
|
|
7579
7647
|
groups.push(
|
|
7580
|
-
|
|
7581
|
-
|
|
7648
|
+
chunkFEBAG2K2_cjs.AssetGroup.create(
|
|
7649
|
+
chunkFEBAG2K2_cjs.AssetId.fromString(assetId),
|
|
7582
7650
|
null,
|
|
7583
7651
|
changeInputs,
|
|
7584
|
-
[
|
|
7652
|
+
[chunkFEBAG2K2_cjs.AssetOutput.create(0, amount)],
|
|
7585
7653
|
[]
|
|
7586
7654
|
)
|
|
7587
7655
|
);
|
|
7588
7656
|
}
|
|
7589
7657
|
}
|
|
7590
7658
|
const arkTxid = await submitToSelf(
|
|
7659
|
+
submit,
|
|
7591
7660
|
this.wallet,
|
|
7592
7661
|
coinSelection.inputs,
|
|
7593
7662
|
totalBtcSelected,
|
|
@@ -7595,7 +7664,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7595
7664
|
);
|
|
7596
7665
|
return {
|
|
7597
7666
|
arkTxId: arkTxid,
|
|
7598
|
-
assetId:
|
|
7667
|
+
assetId: chunkFEBAG2K2_cjs.AssetId.create(arkTxid, 0).toString()
|
|
7599
7668
|
};
|
|
7600
7669
|
}
|
|
7601
7670
|
/**
|
|
@@ -7616,6 +7685,9 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7616
7685
|
* ```
|
|
7617
7686
|
*/
|
|
7618
7687
|
async reissue(params) {
|
|
7688
|
+
return this.wallet.withSpendLock((submit) => this.reissueWith(params, submit));
|
|
7689
|
+
}
|
|
7690
|
+
async reissueWith(params, submit) {
|
|
7619
7691
|
if (params.amount <= 0n) {
|
|
7620
7692
|
throw new Error(`Reissuance amount must be greater than 0, got ${params.amount}`);
|
|
7621
7693
|
}
|
|
@@ -7666,28 +7738,28 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7666
7738
|
const assetInputs = selectedCoinsToAssetInputs(selectedCoins);
|
|
7667
7739
|
const reissueInputs = inputsForAsset(assetInputs, params.assetId);
|
|
7668
7740
|
const totalAssetAmount = assetToReissueAmount + params.amount;
|
|
7669
|
-
const reissueAssetIdObj =
|
|
7670
|
-
const reissueAssetGroup =
|
|
7741
|
+
const reissueAssetIdObj = chunkFEBAG2K2_cjs.AssetId.fromString(params.assetId);
|
|
7742
|
+
const reissueAssetGroup = chunkFEBAG2K2_cjs.AssetGroup.create(
|
|
7671
7743
|
reissueAssetIdObj,
|
|
7672
7744
|
null,
|
|
7673
7745
|
reissueInputs,
|
|
7674
|
-
[
|
|
7746
|
+
[chunkFEBAG2K2_cjs.AssetOutput.create(0, totalAssetAmount)],
|
|
7675
7747
|
[]
|
|
7676
7748
|
);
|
|
7677
7749
|
const groups = [reissueAssetGroup];
|
|
7678
7750
|
for (const [assetId, amount] of assetChanges) {
|
|
7679
7751
|
const changeInputs = inputsForAsset(assetInputs, assetId);
|
|
7680
7752
|
groups.push(
|
|
7681
|
-
|
|
7682
|
-
|
|
7753
|
+
chunkFEBAG2K2_cjs.AssetGroup.create(
|
|
7754
|
+
chunkFEBAG2K2_cjs.AssetId.fromString(assetId),
|
|
7683
7755
|
null,
|
|
7684
7756
|
changeInputs,
|
|
7685
|
-
[
|
|
7757
|
+
[chunkFEBAG2K2_cjs.AssetOutput.create(0, amount)],
|
|
7686
7758
|
[]
|
|
7687
7759
|
)
|
|
7688
7760
|
);
|
|
7689
7761
|
}
|
|
7690
|
-
return submitToSelf(this.wallet, selectedCoins, totalBtcSelected, groups);
|
|
7762
|
+
return submitToSelf(submit, this.wallet, selectedCoins, totalBtcSelected, groups);
|
|
7691
7763
|
}
|
|
7692
7764
|
/**
|
|
7693
7765
|
* Burn assets.
|
|
@@ -7705,6 +7777,9 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7705
7777
|
* ```
|
|
7706
7778
|
*/
|
|
7707
7779
|
async burn(params) {
|
|
7780
|
+
return this.wallet.withSpendLock((submit) => this.burnWith(params, submit));
|
|
7781
|
+
}
|
|
7782
|
+
async burnWith(params, submit) {
|
|
7708
7783
|
if (params.amount <= 0n) {
|
|
7709
7784
|
throw new Error(`Burn amount must be greater than 0, got ${params.amount}`);
|
|
7710
7785
|
}
|
|
@@ -7750,16 +7825,16 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7750
7825
|
for (const [assetId, amount] of assetChanges) {
|
|
7751
7826
|
const changeInputs = inputsForAsset(assetInputs, assetId);
|
|
7752
7827
|
groups.push(
|
|
7753
|
-
|
|
7754
|
-
|
|
7828
|
+
chunkFEBAG2K2_cjs.AssetGroup.create(
|
|
7829
|
+
chunkFEBAG2K2_cjs.AssetId.fromString(assetId),
|
|
7755
7830
|
null,
|
|
7756
7831
|
changeInputs,
|
|
7757
|
-
amount > 0n ? [
|
|
7832
|
+
amount > 0n ? [chunkFEBAG2K2_cjs.AssetOutput.create(0, amount)] : [],
|
|
7758
7833
|
[]
|
|
7759
7834
|
)
|
|
7760
7835
|
);
|
|
7761
7836
|
}
|
|
7762
|
-
return submitToSelf(this.wallet, selectedCoins, totalBtcSelected, groups);
|
|
7837
|
+
return submitToSelf(submit, this.wallet, selectedCoins, totalBtcSelected, groups);
|
|
7763
7838
|
}
|
|
7764
7839
|
};
|
|
7765
7840
|
function inputsForAsset(assetInputs, assetId) {
|
|
@@ -7767,18 +7842,18 @@ function inputsForAsset(assetInputs, assetId) {
|
|
|
7767
7842
|
for (const [inputIndex, assets] of assetInputs) {
|
|
7768
7843
|
for (const asset of assets) {
|
|
7769
7844
|
if (asset.assetId !== assetId) continue;
|
|
7770
|
-
inputs.push(
|
|
7845
|
+
inputs.push(chunkFEBAG2K2_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
7771
7846
|
}
|
|
7772
7847
|
}
|
|
7773
7848
|
return inputs;
|
|
7774
7849
|
}
|
|
7775
|
-
async function submitToSelf(wallet, inputs, amount, groups) {
|
|
7776
|
-
const outputAddress =
|
|
7850
|
+
async function submitToSelf(submit, wallet, inputs, amount, groups) {
|
|
7851
|
+
const outputAddress = chunkVVFCCNU2_cjs.ArkAddress.decode(await wallet.getAddress());
|
|
7777
7852
|
const outputs = [
|
|
7778
7853
|
{ script: outputAddress.pkScript, amount: BigInt(amount) },
|
|
7779
|
-
Extension.create([
|
|
7854
|
+
Extension.create([chunkFEBAG2K2_cjs.Packet.create(groups)]).txOut()
|
|
7780
7855
|
];
|
|
7781
|
-
const { arkTxid } = await
|
|
7856
|
+
const { arkTxid } = await submit(inputs, outputs);
|
|
7782
7857
|
return arkTxid;
|
|
7783
7858
|
}
|
|
7784
7859
|
function castMetadata(metadata) {
|
|
@@ -7800,7 +7875,7 @@ function castMetadata(metadata) {
|
|
|
7800
7875
|
} else {
|
|
7801
7876
|
throw new Error("Invalid metadata value type");
|
|
7802
7877
|
}
|
|
7803
|
-
md.push(
|
|
7878
|
+
md.push(chunkFEBAG2K2_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
|
|
7804
7879
|
}
|
|
7805
7880
|
return md;
|
|
7806
7881
|
}
|
|
@@ -7821,10 +7896,10 @@ var DelegateManagerImpl = class {
|
|
|
7821
7896
|
if (vtxos.length === 0) {
|
|
7822
7897
|
return { delegated: [], failed: [] };
|
|
7823
7898
|
}
|
|
7824
|
-
const destinationScript =
|
|
7899
|
+
const destinationScript = chunkVVFCCNU2_cjs.ArkAddress.decode(destination).pkScript;
|
|
7825
7900
|
const arkInfo = await this.arkInfoProvider.getInfo();
|
|
7826
7901
|
const delegateInfo = await this.delegateProvider.getDelegateInfo();
|
|
7827
|
-
const eligible = vtxos.map(
|
|
7902
|
+
const eligible = vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo).filter(
|
|
7828
7903
|
(v) => isAnnotated(v) && findDelegateTapLeaf(v, delegateInfo.pubkey) !== void 0
|
|
7829
7904
|
);
|
|
7830
7905
|
if (eligible.length === 0) {
|
|
@@ -7856,7 +7931,7 @@ var DelegateManagerImpl = class {
|
|
|
7856
7931
|
const groupByExpiry = /* @__PURE__ */ new Map();
|
|
7857
7932
|
let recoverableVtxos = [];
|
|
7858
7933
|
for (const vtxo of eligible) {
|
|
7859
|
-
if (
|
|
7934
|
+
if (chunkVVFCCNU2_cjs.canRecoverOnchain(vtxo, now)) {
|
|
7860
7935
|
recoverableVtxos.push(vtxo);
|
|
7861
7936
|
continue;
|
|
7862
7937
|
}
|
|
@@ -7908,7 +7983,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
7908
7983
|
}
|
|
7909
7984
|
if (!delegateAt) {
|
|
7910
7985
|
const now = { timestamp: /* @__PURE__ */ new Date() };
|
|
7911
|
-
const expiryTimestamp = vtxos.filter((coin) => !
|
|
7986
|
+
const expiryTimestamp = vtxos.filter((coin) => !chunkVVFCCNU2_cjs.canRecoverOnchain(coin, now) && coin.expiresAt).reduce(
|
|
7912
7987
|
(min, coin) => Math.min(min, coin.expiresAt.getTime()),
|
|
7913
7988
|
Number.MAX_SAFE_INTEGER
|
|
7914
7989
|
);
|
|
@@ -7935,7 +8010,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
7935
8010
|
let amount = 0n;
|
|
7936
8011
|
for (const coin of vtxos) {
|
|
7937
8012
|
const inputFee = estimator.evalOffchainInput({
|
|
7938
|
-
...
|
|
8013
|
+
...chunkVVFCCNU2_cjs.toOffchainInputFeeParams(coin),
|
|
7939
8014
|
type: "vtxo"
|
|
7940
8015
|
});
|
|
7941
8016
|
if (inputFee.satoshis >= coin.value) {
|
|
@@ -7949,7 +8024,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
7949
8024
|
const delegateFee = BigInt(Number(fee));
|
|
7950
8025
|
if (delegateFee > 0n) {
|
|
7951
8026
|
outputs.push({
|
|
7952
|
-
script:
|
|
8027
|
+
script: chunkVVFCCNU2_cjs.ArkAddress.decode(delegateAddress).pkScript,
|
|
7953
8028
|
amount: delegateFee
|
|
7954
8029
|
});
|
|
7955
8030
|
}
|
|
@@ -7982,10 +8057,10 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
7982
8057
|
destinationScript
|
|
7983
8058
|
);
|
|
7984
8059
|
const forfeitOutputScript = btcSigner.OutScript.encode(
|
|
7985
|
-
btcSigner.Address(
|
|
8060
|
+
btcSigner.Address(chunkVVFCCNU2_cjs.getNetwork(network)).decode(forfeitAddress)
|
|
7986
8061
|
);
|
|
7987
8062
|
const forfeits = await Promise.all(
|
|
7988
|
-
vtxos.filter((v) =>
|
|
8063
|
+
vtxos.filter((v) => chunkVVFCCNU2_cjs.requiresForfeit(v)).map(async (coin) => {
|
|
7989
8064
|
const forfeit = await makeDelegateForfeitTx(
|
|
7990
8065
|
coin,
|
|
7991
8066
|
dust,
|
|
@@ -8010,7 +8085,7 @@ async function makeDelegateForfeitTx(input, connectorAmount, delegatePubkey, for
|
|
|
8010
8085
|
index: input.vout,
|
|
8011
8086
|
witnessUtxo: {
|
|
8012
8087
|
amount: BigInt(input.value),
|
|
8013
|
-
script:
|
|
8088
|
+
script: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
8014
8089
|
},
|
|
8015
8090
|
sighashType: btcSigner.SigHash.ALL_ANYONECANPAY,
|
|
8016
8091
|
tapLeafScript: [delegateTapLeaf]
|
|
@@ -8068,7 +8143,7 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
8068
8143
|
expire_at: 0,
|
|
8069
8144
|
cosigners_public_keys: cosignerPubKeys
|
|
8070
8145
|
};
|
|
8071
|
-
const proof =
|
|
8146
|
+
const proof = chunkVVFCCNU2_cjs.Intent.create(message, coins, outputs);
|
|
8072
8147
|
const signedProof = await identity.sign(proof);
|
|
8073
8148
|
return {
|
|
8074
8149
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -8094,10 +8169,10 @@ function getDayTimestamp(timestamp) {
|
|
|
8094
8169
|
function findDelegateTapLeaf(vtxo, delegatePubkey) {
|
|
8095
8170
|
if (!vtxo.tapTree) return void 0;
|
|
8096
8171
|
const pk = delegatePubkey.length === 66 ? delegatePubkey.slice(2) : delegatePubkey;
|
|
8097
|
-
const vtxoScript =
|
|
8172
|
+
const vtxoScript = chunkVVFCCNU2_cjs.VtxoScript.decode(vtxo.tapTree);
|
|
8098
8173
|
return vtxoScript.leaves.find((tapLeaf) => {
|
|
8099
|
-
const arkTapscript =
|
|
8100
|
-
if (!
|
|
8174
|
+
const arkTapscript = chunkVVFCCNU2_cjs.decodeTapscript(chunkVVFCCNU2_cjs.scriptFromTapLeafScript(tapLeaf));
|
|
8175
|
+
if (!chunkVVFCCNU2_cjs.MultisigTapscript.is(arkTapscript)) return false;
|
|
8101
8176
|
return arkTapscript.params.pubkeys.map(base.hex.encode).includes(pk);
|
|
8102
8177
|
});
|
|
8103
8178
|
}
|
|
@@ -8653,8 +8728,8 @@ function checkSaveVtxosForScript(backend, key, vtxos) {
|
|
|
8653
8728
|
}
|
|
8654
8729
|
async function getVtxosForContract(repo, contract, options) {
|
|
8655
8730
|
const vtxos = repo.getVtxosForScriptPage ? await collectScriptVtxos(repo, contract.script, options) : filterVtxosForScript(await collectVtxos(repo, contract.address), contract.script);
|
|
8656
|
-
const normalized = vtxos.map(
|
|
8657
|
-
return options?.unspentOnly ? normalized.filter((vtxo) => !
|
|
8731
|
+
const normalized = vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
|
|
8732
|
+
return options?.unspentOnly ? normalized.filter((vtxo) => !chunkVVFCCNU2_cjs.isVtxoSpent(vtxo)) : normalized;
|
|
8658
8733
|
}
|
|
8659
8734
|
async function hasVtxosForContract(repo, contract) {
|
|
8660
8735
|
if (repo.getVtxosForScriptPage) {
|
|
@@ -8885,7 +8960,7 @@ function decodeArkContract(encoded) {
|
|
|
8885
8960
|
}
|
|
8886
8961
|
function contractFromArkContract(encoded, options = {}) {
|
|
8887
8962
|
const parsed = decodeArkContract(encoded);
|
|
8888
|
-
const handler =
|
|
8963
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.get(parsed.type);
|
|
8889
8964
|
if (!handler) {
|
|
8890
8965
|
throw new Error(`No handler registered for contract type '${parsed.type}'`);
|
|
8891
8966
|
}
|
|
@@ -8899,9 +8974,9 @@ function contractFromArkContract(encoded, options = {}) {
|
|
|
8899
8974
|
metadata: options.metadata
|
|
8900
8975
|
};
|
|
8901
8976
|
}
|
|
8902
|
-
function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix =
|
|
8977
|
+
function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunkVVFCCNU2_cjs.DEFAULT_NETWORK.hrp, options = {}) {
|
|
8903
8978
|
const parsed = decodeArkContract(encoded);
|
|
8904
|
-
const handler =
|
|
8979
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.getOrThrow(parsed.type);
|
|
8905
8980
|
const params = parsed.data;
|
|
8906
8981
|
const vtxoScript = handler.createScript(params);
|
|
8907
8982
|
return {
|
|
@@ -8927,8 +9002,9 @@ var DEFAULT_CONTRACT_WATCHER_CONFIG = {
|
|
|
8927
9002
|
failsafePollIntervalMs: 2e4,
|
|
8928
9003
|
reconnectDelayMs: 1e3,
|
|
8929
9004
|
maxReconnectDelayMs: 5e3,
|
|
8930
|
-
maxReconnectAttempts: 0
|
|
9005
|
+
maxReconnectAttempts: 0,
|
|
8931
9006
|
// unlimited
|
|
9007
|
+
subscriptionRequestTimeoutMs: 3e4
|
|
8932
9008
|
};
|
|
8933
9009
|
var ContractWatcher = class {
|
|
8934
9010
|
config;
|
|
@@ -8946,13 +9022,24 @@ var ContractWatcher = class {
|
|
|
8946
9022
|
/** See {@link withCoalescedSubscription}. */
|
|
8947
9023
|
subscriptionBatchDepth = 0;
|
|
8948
9024
|
subscriptionUpdateDeferred = false;
|
|
9025
|
+
/** Subscription POSTs can fail while the event stream remains healthy. */
|
|
9026
|
+
subscriptionRetryTimeoutId;
|
|
9027
|
+
subscriptionRetryAttempts = 0;
|
|
9028
|
+
/** A failed update needs catch-up even when reconnect owns the next attempt. */
|
|
9029
|
+
subscriptionNeedsCatchUp = false;
|
|
9030
|
+
/** Serialize subscription creation and updates against the latest desired scripts. */
|
|
9031
|
+
subscriptionUpdate = Promise.resolve();
|
|
8949
9032
|
/** See {@link reportEventSourceUnavailable} — said once, not per attempt. */
|
|
8950
9033
|
eventSourceReported = false;
|
|
8951
9034
|
/** @see ContractWatcherConfig */
|
|
8952
9035
|
constructor(config) {
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
9036
|
+
chunkVVFCCNU2_cjs.assertTimerMs("failsafePollIntervalMs", config.failsafePollIntervalMs);
|
|
9037
|
+
chunkVVFCCNU2_cjs.assertTimerMs("reconnectDelayMs", config.reconnectDelayMs);
|
|
9038
|
+
chunkVVFCCNU2_cjs.assertTimerMs("maxReconnectDelayMs", config.maxReconnectDelayMs);
|
|
9039
|
+
chunkVVFCCNU2_cjs.assertTimerMs("subscriptionRequestTimeoutMs", config.subscriptionRequestTimeoutMs);
|
|
9040
|
+
if (config.subscriptionRequestTimeoutMs === 0) {
|
|
9041
|
+
throw new Error("subscriptionRequestTimeoutMs must be greater than 0");
|
|
9042
|
+
}
|
|
8956
9043
|
this.config = {
|
|
8957
9044
|
...DEFAULT_CONTRACT_WATCHER_CONFIG,
|
|
8958
9045
|
...config
|
|
@@ -9112,9 +9199,12 @@ var ContractWatcher = class {
|
|
|
9112
9199
|
}
|
|
9113
9200
|
this.eventCallback = callback;
|
|
9114
9201
|
this.isWatching = true;
|
|
9115
|
-
|
|
9202
|
+
const session = new AbortController();
|
|
9203
|
+
this.abortController = session;
|
|
9116
9204
|
this.reconnectAttempts = 0;
|
|
9205
|
+
this.subscriptionUpdate = Promise.resolve();
|
|
9117
9206
|
await this.connect();
|
|
9207
|
+
if (session.signal.aborted) return () => this.stopWatching();
|
|
9118
9208
|
this.startFailsafePolling();
|
|
9119
9209
|
return () => this.stopWatching();
|
|
9120
9210
|
}
|
|
@@ -9122,6 +9212,9 @@ var ContractWatcher = class {
|
|
|
9122
9212
|
this.isWatching = false;
|
|
9123
9213
|
this.connectionState = "disconnected";
|
|
9124
9214
|
this.abortController?.abort();
|
|
9215
|
+
this.cancelSubscriptionRetry();
|
|
9216
|
+
this.subscriptionRetryAttempts = 0;
|
|
9217
|
+
this.subscriptionNeedsCatchUp = false;
|
|
9125
9218
|
if (this.reconnectTimeoutId) {
|
|
9126
9219
|
clearTimeout(this.reconnectTimeoutId);
|
|
9127
9220
|
this.reconnectTimeoutId = void 0;
|
|
@@ -9153,18 +9246,22 @@ var ContractWatcher = class {
|
|
|
9153
9246
|
/** @param skipUpdate - The caller already established `subscriptionId`. */
|
|
9154
9247
|
async connect(skipUpdate = false) {
|
|
9155
9248
|
if (!this.isWatching) return;
|
|
9249
|
+
const signal = this.abortController?.signal;
|
|
9156
9250
|
this.connectionState = "connecting";
|
|
9157
9251
|
try {
|
|
9158
9252
|
if (!skipUpdate) {
|
|
9159
9253
|
await this.updateSubscription();
|
|
9160
9254
|
}
|
|
9255
|
+
if (!this.isWatching || signal?.aborted) return;
|
|
9161
9256
|
await this.pollAllContracts();
|
|
9257
|
+
if (!this.isWatching || signal?.aborted) return;
|
|
9162
9258
|
this.connectionState = "connected";
|
|
9163
9259
|
this.reconnectAttempts = 0;
|
|
9164
9260
|
this.listenLoop().catch((e) => {
|
|
9165
|
-
if (
|
|
9261
|
+
if (!this.isWatching || signal?.aborted) return;
|
|
9262
|
+
if (chunkVVFCCNU2_cjs.isEventSourceError(e)) {
|
|
9166
9263
|
console.debug("ContractWatcher subscription disconnected; reconnecting");
|
|
9167
|
-
} else if (!
|
|
9264
|
+
} else if (!chunkVVFCCNU2_cjs.isEventSourceUnavailableError(e)) {
|
|
9168
9265
|
console.error(e);
|
|
9169
9266
|
}
|
|
9170
9267
|
this.connectionState = "disconnected";
|
|
@@ -9173,7 +9270,8 @@ var ContractWatcher = class {
|
|
|
9173
9270
|
this.scheduleReconnect();
|
|
9174
9271
|
});
|
|
9175
9272
|
} catch (error) {
|
|
9176
|
-
if (!
|
|
9273
|
+
if (!this.isWatching || signal?.aborted) return;
|
|
9274
|
+
if (!chunkVVFCCNU2_cjs.isEventSourceUnavailableError(error)) {
|
|
9177
9275
|
console.error("ContractWatcher connection failed:", error);
|
|
9178
9276
|
}
|
|
9179
9277
|
this.connectionState = "disconnected";
|
|
@@ -9189,7 +9287,7 @@ var ContractWatcher = class {
|
|
|
9189
9287
|
* few seconds.
|
|
9190
9288
|
*/
|
|
9191
9289
|
reportEventSourceUnavailable(error) {
|
|
9192
|
-
if (!
|
|
9290
|
+
if (!chunkVVFCCNU2_cjs.isEventSourceUnavailableError(error)) return false;
|
|
9193
9291
|
if (!this.eventSourceReported) {
|
|
9194
9292
|
this.eventSourceReported = true;
|
|
9195
9293
|
console.warn(
|
|
@@ -9200,6 +9298,7 @@ var ContractWatcher = class {
|
|
|
9200
9298
|
}
|
|
9201
9299
|
scheduleReconnect() {
|
|
9202
9300
|
if (!this.isWatching) return;
|
|
9301
|
+
this.cancelSubscriptionRetry();
|
|
9203
9302
|
if (this.config.maxReconnectAttempts > 0 && this.reconnectAttempts >= this.config.maxReconnectAttempts) {
|
|
9204
9303
|
console.error(
|
|
9205
9304
|
`ContractWatcher: Max reconnection attempts (${this.config.maxReconnectAttempts}) reached`
|
|
@@ -9253,7 +9352,7 @@ var ContractWatcher = class {
|
|
|
9253
9352
|
const now = Date.now();
|
|
9254
9353
|
let current;
|
|
9255
9354
|
try {
|
|
9256
|
-
current = await
|
|
9355
|
+
current = await chunkVVFCCNU2_cjs.getAllNormalizedVtxos(this.config.indexerProvider, scripts, {
|
|
9257
9356
|
spendableOnly: true
|
|
9258
9357
|
});
|
|
9259
9358
|
} catch (error) {
|
|
@@ -9371,12 +9470,18 @@ var ContractWatcher = class {
|
|
|
9371
9470
|
this.subscriptionUpdateDeferred = true;
|
|
9372
9471
|
return;
|
|
9373
9472
|
}
|
|
9473
|
+
const signal = this.abortController?.signal;
|
|
9374
9474
|
const hadSubscription = this.subscriptionId !== void 0;
|
|
9375
9475
|
try {
|
|
9376
9476
|
await this.updateSubscription();
|
|
9377
9477
|
} catch (error) {
|
|
9478
|
+
if (!signal?.aborted) {
|
|
9479
|
+
this.subscriptionNeedsCatchUp = true;
|
|
9480
|
+
this.scheduleSubscriptionRetry();
|
|
9481
|
+
}
|
|
9378
9482
|
return;
|
|
9379
9483
|
}
|
|
9484
|
+
if (!this.isWatching || signal?.aborted) return;
|
|
9380
9485
|
const justGotSubscription = !hadSubscription && this.subscriptionId !== void 0;
|
|
9381
9486
|
const listenerParked = this.connectionState === "disconnected" || this.connectionState === "reconnecting";
|
|
9382
9487
|
if (this.isWatching && justGotSubscription && listenerParked) {
|
|
@@ -9390,8 +9495,47 @@ var ContractWatcher = class {
|
|
|
9390
9495
|
});
|
|
9391
9496
|
}
|
|
9392
9497
|
}
|
|
9498
|
+
cancelSubscriptionRetry() {
|
|
9499
|
+
if (this.subscriptionRetryTimeoutId !== void 0) {
|
|
9500
|
+
clearTimeout(this.subscriptionRetryTimeoutId);
|
|
9501
|
+
this.subscriptionRetryTimeoutId = void 0;
|
|
9502
|
+
}
|
|
9503
|
+
}
|
|
9504
|
+
scheduleSubscriptionRetry() {
|
|
9505
|
+
if (!this.isWatching || this.reconnectTimeoutId !== void 0 || this.subscriptionRetryTimeoutId !== void 0)
|
|
9506
|
+
return;
|
|
9507
|
+
if (this.config.maxReconnectAttempts > 0 && this.subscriptionRetryAttempts >= this.config.maxReconnectAttempts)
|
|
9508
|
+
return;
|
|
9509
|
+
const delay = computeReconnectDelay(
|
|
9510
|
+
++this.subscriptionRetryAttempts,
|
|
9511
|
+
this.config.reconnectDelayMs,
|
|
9512
|
+
this.config.maxReconnectDelayMs
|
|
9513
|
+
);
|
|
9514
|
+
this.subscriptionRetryTimeoutId = setTimeout(() => {
|
|
9515
|
+
this.subscriptionRetryTimeoutId = void 0;
|
|
9516
|
+
void this.tryUpdateSubscription();
|
|
9517
|
+
}, delay);
|
|
9518
|
+
}
|
|
9393
9519
|
/** @see getSubscribedScripts */
|
|
9394
|
-
|
|
9520
|
+
updateSubscription() {
|
|
9521
|
+
const signal = this.abortController?.signal;
|
|
9522
|
+
const update = this.subscriptionUpdate.then(async () => {
|
|
9523
|
+
if (!this.isWatching || !signal || signal.aborted) return;
|
|
9524
|
+
await this.sendSubscriptionUpdate(signal);
|
|
9525
|
+
if (signal.aborted) return;
|
|
9526
|
+
const recovered = this.subscriptionNeedsCatchUp;
|
|
9527
|
+
this.cancelSubscriptionRetry();
|
|
9528
|
+
this.subscriptionRetryAttempts = 0;
|
|
9529
|
+
this.subscriptionNeedsCatchUp = false;
|
|
9530
|
+
if (recovered) {
|
|
9531
|
+
this.emitConnectionReset();
|
|
9532
|
+
}
|
|
9533
|
+
});
|
|
9534
|
+
this.subscriptionUpdate = update.catch(() => {
|
|
9535
|
+
});
|
|
9536
|
+
return update;
|
|
9537
|
+
}
|
|
9538
|
+
async sendSubscriptionUpdate(signal) {
|
|
9395
9539
|
const scriptsToWatch = this.getSubscribedScripts();
|
|
9396
9540
|
if (scriptsToWatch.length === 0) {
|
|
9397
9541
|
if (this.subscriptionId) {
|
|
@@ -9399,24 +9543,66 @@ var ContractWatcher = class {
|
|
|
9399
9543
|
await this.config.indexerProvider.unsubscribeForScripts(this.subscriptionId);
|
|
9400
9544
|
} catch {
|
|
9401
9545
|
}
|
|
9546
|
+
if (signal.aborted) return;
|
|
9402
9547
|
this.subscriptionId = void 0;
|
|
9403
9548
|
}
|
|
9404
9549
|
return;
|
|
9405
9550
|
}
|
|
9551
|
+
let subscriptionId;
|
|
9406
9552
|
try {
|
|
9407
|
-
|
|
9553
|
+
subscriptionId = await this.subscribeWithTimeout(
|
|
9408
9554
|
scriptsToWatch,
|
|
9409
|
-
this.subscriptionId
|
|
9555
|
+
this.subscriptionId,
|
|
9556
|
+
signal
|
|
9410
9557
|
);
|
|
9411
9558
|
} catch (error) {
|
|
9559
|
+
if (signal.aborted) return;
|
|
9412
9560
|
const isStale = error instanceof Error && /subscription\b.*\bnot\s+found/i.test(error.message);
|
|
9413
9561
|
if (this.subscriptionId && isStale) {
|
|
9414
9562
|
this.subscriptionId = void 0;
|
|
9415
|
-
|
|
9563
|
+
subscriptionId = await this.subscribeWithTimeout(scriptsToWatch, void 0, signal);
|
|
9416
9564
|
} else {
|
|
9417
9565
|
throw error;
|
|
9418
9566
|
}
|
|
9419
9567
|
}
|
|
9568
|
+
if (signal.aborted) {
|
|
9569
|
+
if (subscriptionId !== this.subscriptionId) {
|
|
9570
|
+
void this.config.indexerProvider.unsubscribeForScripts(subscriptionId).catch(() => {
|
|
9571
|
+
});
|
|
9572
|
+
}
|
|
9573
|
+
return;
|
|
9574
|
+
}
|
|
9575
|
+
this.subscriptionId = subscriptionId;
|
|
9576
|
+
}
|
|
9577
|
+
async subscribeWithTimeout(scripts, subscriptionId, sessionSignal) {
|
|
9578
|
+
if (sessionSignal.aborted) throw sessionSignal.reason;
|
|
9579
|
+
const request = new AbortController();
|
|
9580
|
+
let cancel;
|
|
9581
|
+
const cancelled = new Promise((_resolve, reject) => {
|
|
9582
|
+
cancel = (reason) => {
|
|
9583
|
+
reject(reason);
|
|
9584
|
+
request.abort(reason);
|
|
9585
|
+
};
|
|
9586
|
+
});
|
|
9587
|
+
const onStop = () => cancel(sessionSignal.reason);
|
|
9588
|
+
sessionSignal.addEventListener("abort", onStop, { once: true });
|
|
9589
|
+
const timer = setTimeout(
|
|
9590
|
+
() => cancel(new Error("Subscription request timed out")),
|
|
9591
|
+
this.config.subscriptionRequestTimeoutMs
|
|
9592
|
+
);
|
|
9593
|
+
try {
|
|
9594
|
+
const pending = this.config.indexerProvider.subscribeForScripts(scripts, subscriptionId, request.signal).then((id) => {
|
|
9595
|
+
if (request.signal.aborted && id !== subscriptionId && id !== this.subscriptionId) {
|
|
9596
|
+
void this.config.indexerProvider.unsubscribeForScripts(id).catch(() => {
|
|
9597
|
+
});
|
|
9598
|
+
}
|
|
9599
|
+
return id;
|
|
9600
|
+
});
|
|
9601
|
+
return await Promise.race([pending, cancelled]);
|
|
9602
|
+
} finally {
|
|
9603
|
+
clearTimeout(timer);
|
|
9604
|
+
sessionSignal.removeEventListener("abort", onStop);
|
|
9605
|
+
}
|
|
9420
9606
|
}
|
|
9421
9607
|
async listenLoop() {
|
|
9422
9608
|
if (!this.subscriptionId || !this.abortController || !this.isWatching) {
|
|
@@ -9448,14 +9634,14 @@ var ContractWatcher = class {
|
|
|
9448
9634
|
const timestamp = Date.now();
|
|
9449
9635
|
if (update.newVtxos?.length) {
|
|
9450
9636
|
this.processSubscriptionVtxos(
|
|
9451
|
-
update.newVtxos.map(
|
|
9637
|
+
update.newVtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo),
|
|
9452
9638
|
"vtxo_received",
|
|
9453
9639
|
timestamp
|
|
9454
9640
|
);
|
|
9455
9641
|
}
|
|
9456
9642
|
if (update.spentVtxos?.length) {
|
|
9457
9643
|
this.processSubscriptionVtxos(
|
|
9458
|
-
update.spentVtxos.map(
|
|
9644
|
+
update.spentVtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo),
|
|
9459
9645
|
"vtxo_spent",
|
|
9460
9646
|
timestamp
|
|
9461
9647
|
);
|
|
@@ -9480,8 +9666,8 @@ var ContractWatcher = class {
|
|
|
9480
9666
|
continue;
|
|
9481
9667
|
}
|
|
9482
9668
|
if (target === byWatchedScript && eventType === "vtxo_received") {
|
|
9483
|
-
const n =
|
|
9484
|
-
if (
|
|
9669
|
+
const n = chunkVVFCCNU2_cjs.normalizeVtxo(vtxo);
|
|
9670
|
+
if (chunkVVFCCNU2_cjs.isVtxoSpent(n) || n.isSwept || chunkVVFCCNU2_cjs.isPastExpiry(n, now)) continue;
|
|
9485
9671
|
}
|
|
9486
9672
|
let bucket = target.get(vtxo.script);
|
|
9487
9673
|
if (!bucket) {
|
|
@@ -9618,7 +9804,7 @@ function annotatableIn(scriptToContract, vtxos, memo) {
|
|
|
9618
9804
|
if (!contract) continue;
|
|
9619
9805
|
try {
|
|
9620
9806
|
const key = `${contract.type}\0${script}\0${JSON.stringify(contract.params)}`;
|
|
9621
|
-
const handler =
|
|
9807
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
|
|
9622
9808
|
const hit = memo?.get(script);
|
|
9623
9809
|
let tapscripts;
|
|
9624
9810
|
if (hit && hit.key === key && hit.handler === handler) {
|
|
@@ -9646,6 +9832,11 @@ function annotatableIn(scriptToContract, vtxos, memo) {
|
|
|
9646
9832
|
}
|
|
9647
9833
|
return { scripts, cache, failures };
|
|
9648
9834
|
}
|
|
9835
|
+
function annotateAgainst(vtxos, byScript, tapscripts = /* @__PURE__ */ new Map()) {
|
|
9836
|
+
return vtxos.map(
|
|
9837
|
+
(vtxo) => extendVirtualCoinForContract(chunkVVFCCNU2_cjs.normalizeVtxo(vtxo), byScript, tapscripts)
|
|
9838
|
+
);
|
|
9839
|
+
}
|
|
9649
9840
|
var SCAN_MAX_INDEX = 1e4;
|
|
9650
9841
|
var DEFAULT_SCAN_BATCH = 10;
|
|
9651
9842
|
var CHAIN_TIP_TTL_MS = 3e4;
|
|
@@ -9687,8 +9878,8 @@ var ContractManager = class _ContractManager {
|
|
|
9687
9878
|
* `dispose()`, so it re-checks this at every await rather than run on a torn-down watcher. */
|
|
9688
9879
|
disposed = false;
|
|
9689
9880
|
constructor(config) {
|
|
9690
|
-
|
|
9691
|
-
|
|
9881
|
+
chunkVVFCCNU2_cjs.assertNonNegativeMs("vtxoSyncMaxAgeMs", config.vtxoSyncMaxAgeMs);
|
|
9882
|
+
chunkVVFCCNU2_cjs.assertNonNegativeMs("vtxoSyncOverlapMs", config.vtxoSyncOverlapMs);
|
|
9692
9883
|
this.config = { ...config };
|
|
9693
9884
|
this.watcher = new ContractWatcher({
|
|
9694
9885
|
indexerProvider: config.indexerProvider,
|
|
@@ -9724,12 +9915,12 @@ var ContractManager = class _ContractManager {
|
|
|
9724
9915
|
}
|
|
9725
9916
|
/** @see ContractManagerConfig.vtxoSyncMaxAgeMs — for factory-built managers. */
|
|
9726
9917
|
setVtxoSyncMaxAge(maxAgeMs) {
|
|
9727
|
-
|
|
9918
|
+
chunkVVFCCNU2_cjs.assertNonNegativeMs("vtxoSyncMaxAgeMs", maxAgeMs);
|
|
9728
9919
|
this.config.vtxoSyncMaxAgeMs = maxAgeMs;
|
|
9729
9920
|
}
|
|
9730
9921
|
/** @see ContractManagerConfig.vtxoSyncOverlapMs — for factory-built managers. */
|
|
9731
9922
|
setVtxoSyncOverlap(overlapMs) {
|
|
9732
|
-
|
|
9923
|
+
chunkVVFCCNU2_cjs.assertNonNegativeMs("vtxoSyncOverlapMs", overlapMs);
|
|
9733
9924
|
this.config.vtxoSyncOverlapMs = overlapMs;
|
|
9734
9925
|
}
|
|
9735
9926
|
markSyncOnline() {
|
|
@@ -9777,7 +9968,7 @@ var ContractManager = class _ContractManager {
|
|
|
9777
9968
|
this.markSyncOnline();
|
|
9778
9969
|
return void 0;
|
|
9779
9970
|
} catch (err) {
|
|
9780
|
-
if (!
|
|
9971
|
+
if (!chunkVVFCCNU2_cjs.isRetryableProviderError(err)) throw err;
|
|
9781
9972
|
this.markSyncDegraded(err);
|
|
9782
9973
|
return err;
|
|
9783
9974
|
}
|
|
@@ -9800,7 +9991,7 @@ var ContractManager = class _ContractManager {
|
|
|
9800
9991
|
try {
|
|
9801
9992
|
await this.scheduleLookAheadDrain();
|
|
9802
9993
|
} catch (err) {
|
|
9803
|
-
if (!
|
|
9994
|
+
if (!chunkVVFCCNU2_cjs.isRetryableProviderError(err)) throw err;
|
|
9804
9995
|
this.lookAheadRefillOwed = true;
|
|
9805
9996
|
this.markSyncDegraded(err);
|
|
9806
9997
|
}
|
|
@@ -9863,7 +10054,7 @@ var ContractManager = class _ContractManager {
|
|
|
9863
10054
|
/** No throw: construction returned long ago, so the state is the channel. */
|
|
9864
10055
|
reportBackgroundFailure(stage, err) {
|
|
9865
10056
|
this.markSyncDegraded(err);
|
|
9866
|
-
if (!
|
|
10057
|
+
if (!chunkVVFCCNU2_cjs.isRetryableProviderError(err)) {
|
|
9867
10058
|
console.error(`[contracts] background ${stage} failed`, err);
|
|
9868
10059
|
}
|
|
9869
10060
|
}
|
|
@@ -9965,7 +10156,7 @@ var ContractManager = class _ContractManager {
|
|
|
9965
10156
|
const from = Math.max(0, watermark - lookAhead.size);
|
|
9966
10157
|
const to = watermark + lookAhead.size;
|
|
9967
10158
|
const deps = lookAhead.candidateDeps();
|
|
9968
|
-
const handlers =
|
|
10159
|
+
const handlers = chunkCFOIHLON_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkCFOIHLON_cjs.contractHandlers.get(t)).filter(hasCandidates);
|
|
9969
10160
|
const band = /* @__PURE__ */ new Map();
|
|
9970
10161
|
for (let index = from; index <= to; index++) {
|
|
9971
10162
|
const descriptor = lookAhead.materialize(index);
|
|
@@ -9976,7 +10167,7 @@ var ContractManager = class _ContractManager {
|
|
|
9976
10167
|
index,
|
|
9977
10168
|
params: {
|
|
9978
10169
|
...candidate,
|
|
9979
|
-
...
|
|
10170
|
+
...chunkCFOIHLON_cjs.speculativeReceiveMetadata(descriptor)
|
|
9980
10171
|
}
|
|
9981
10172
|
});
|
|
9982
10173
|
}
|
|
@@ -10035,7 +10226,7 @@ var ContractManager = class _ContractManager {
|
|
|
10035
10226
|
});
|
|
10036
10227
|
for (const entry of pending) entry.catchUpPending = false;
|
|
10037
10228
|
} catch (err) {
|
|
10038
|
-
if (!
|
|
10229
|
+
if (!chunkVVFCCNU2_cjs.isRetryableProviderError(err)) throw err;
|
|
10039
10230
|
this.markSyncDegraded(err);
|
|
10040
10231
|
}
|
|
10041
10232
|
}
|
|
@@ -10126,7 +10317,7 @@ var ContractManager = class _ContractManager {
|
|
|
10126
10317
|
return result;
|
|
10127
10318
|
}
|
|
10128
10319
|
async upsertContractRow(params) {
|
|
10129
|
-
const handler =
|
|
10320
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.get(params.type);
|
|
10130
10321
|
if (!handler) {
|
|
10131
10322
|
throw new Error(`No handler registered for contract type '${params.type}'`);
|
|
10132
10323
|
}
|
|
@@ -10194,7 +10385,7 @@ var ContractManager = class _ContractManager {
|
|
|
10194
10385
|
`scanContracts: batchSize must be a positive integer (got ${String(opts.batchSize)})`
|
|
10195
10386
|
);
|
|
10196
10387
|
}
|
|
10197
|
-
const registered =
|
|
10388
|
+
const registered = chunkCFOIHLON_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkCFOIHLON_cjs.contractHandlers.get(t)).filter(isDiscoverable);
|
|
10198
10389
|
const discoverables = [
|
|
10199
10390
|
...registered.filter((h) => h.type === "boarding"),
|
|
10200
10391
|
...registered.filter((h) => h.type !== "boarding")
|
|
@@ -10320,7 +10511,7 @@ var ContractManager = class _ContractManager {
|
|
|
10320
10511
|
return await collectContracts(this.config.contractRepository, dbFilter);
|
|
10321
10512
|
}
|
|
10322
10513
|
async getContractsWithVtxos(filter, pageSize, options) {
|
|
10323
|
-
|
|
10514
|
+
chunkVVFCCNU2_cjs.assertNonNegativeMs("maxSyncAgeMs", options?.maxSyncAgeMs);
|
|
10324
10515
|
const contracts = await this.getContracts(filter);
|
|
10325
10516
|
if (this.syncedWithin(
|
|
10326
10517
|
contracts,
|
|
@@ -10383,10 +10574,7 @@ var ContractManager = class _ContractManager {
|
|
|
10383
10574
|
for (const contract of contracts) {
|
|
10384
10575
|
byScript.set(contract.script, contract);
|
|
10385
10576
|
}
|
|
10386
|
-
|
|
10387
|
-
return vtxos.map(
|
|
10388
|
-
(vtxo) => extendVirtualCoinForContract(chunk65CTZR2O_cjs.normalizeVtxo(vtxo), byScript, tapscriptCache)
|
|
10389
|
-
);
|
|
10577
|
+
return annotateAgainst(vtxos, byScript, tapscripts);
|
|
10390
10578
|
}
|
|
10391
10579
|
/** @inheritdoc */
|
|
10392
10580
|
async assertAnnotatable(vtxos) {
|
|
@@ -10430,14 +10618,14 @@ var ContractManager = class _ContractManager {
|
|
|
10430
10618
|
const byScript = new Map(contracts.map((contract) => [contract.script, contract]));
|
|
10431
10619
|
const asking = vtxos.filter((vtxo) => {
|
|
10432
10620
|
const contract = byScript.get(vtxo.script);
|
|
10433
|
-
return contract !== void 0 &&
|
|
10621
|
+
return contract !== void 0 && chunkCFOIHLON_cjs.contractHandlers.get(contract.type)?.assertSpendableNow !== void 0;
|
|
10434
10622
|
});
|
|
10435
10623
|
if (asking.length === 0) return refused;
|
|
10436
10624
|
const tip = await this.currentChainTip();
|
|
10437
10625
|
const walletDescriptorValue = await walletDescriptor?.();
|
|
10438
10626
|
for (const vtxo of asking) {
|
|
10439
10627
|
const contract = byScript.get(vtxo.script);
|
|
10440
|
-
const handler =
|
|
10628
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
|
|
10441
10629
|
if (!handler?.assertSpendableNow) continue;
|
|
10442
10630
|
const context = {
|
|
10443
10631
|
collaborative: true,
|
|
@@ -10447,7 +10635,7 @@ var ContractManager = class _ContractManager {
|
|
|
10447
10635
|
walletDescriptor: walletDescriptorValue,
|
|
10448
10636
|
// `isVirtualCoin` only checks `script`, which every input has; `isCsvSpendable`
|
|
10449
10637
|
// reads `vtxo.status.block_time` unguarded, so require `status` too.
|
|
10450
|
-
vtxo:
|
|
10638
|
+
vtxo: chunkVVFCCNU2_cjs.isVirtualCoin(vtxo) && "status" in vtxo ? vtxo : void 0
|
|
10451
10639
|
};
|
|
10452
10640
|
try {
|
|
10453
10641
|
await handler.assertSpendableNow(
|
|
@@ -10560,7 +10748,7 @@ var ContractManager = class _ContractManager {
|
|
|
10560
10748
|
const { contractScript, collaborative = true, walletDescriptor, vtxo } = options;
|
|
10561
10749
|
const [contract] = await this.getContracts({ script: contractScript });
|
|
10562
10750
|
if (!contract) return [];
|
|
10563
|
-
const handler =
|
|
10751
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
|
|
10564
10752
|
if (!handler) return [];
|
|
10565
10753
|
const script = handler.createScript(contract.params);
|
|
10566
10754
|
const tip = await this.currentChainTip();
|
|
@@ -10582,7 +10770,7 @@ var ContractManager = class _ContractManager {
|
|
|
10582
10770
|
const { contractScript, collaborative = true, walletDescriptor } = options;
|
|
10583
10771
|
const [contract] = await this.getContracts({ script: contractScript });
|
|
10584
10772
|
if (!contract) return [];
|
|
10585
|
-
const handler =
|
|
10773
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
|
|
10586
10774
|
if (!handler) return [];
|
|
10587
10775
|
const script = handler.createScript(contract.params);
|
|
10588
10776
|
const context = {
|
|
@@ -10628,7 +10816,7 @@ var ContractManager = class _ContractManager {
|
|
|
10628
10816
|
}
|
|
10629
10817
|
async refreshOutpoints(outpoints) {
|
|
10630
10818
|
if (outpoints.length === 0) return;
|
|
10631
|
-
const { vtxos } = await
|
|
10819
|
+
const { vtxos } = await chunkVVFCCNU2_cjs.getNormalizedVtxos(this.config.indexerProvider, {
|
|
10632
10820
|
outpoints
|
|
10633
10821
|
});
|
|
10634
10822
|
if (vtxos.length === 0) return;
|
|
@@ -10637,9 +10825,15 @@ var ContractManager = class _ContractManager {
|
|
|
10637
10825
|
script: scripts
|
|
10638
10826
|
});
|
|
10639
10827
|
const scriptToContract = new Map(contracts.map((c) => [c.script, c]));
|
|
10640
|
-
const
|
|
10828
|
+
const {
|
|
10829
|
+
scripts: annotatable,
|
|
10830
|
+
cache,
|
|
10831
|
+
failures
|
|
10832
|
+
} = annotatableIn(scriptToContract, vtxos, this.tapscriptMemo);
|
|
10833
|
+
this.recordAnnotationFailures(annotatable, failures);
|
|
10834
|
+
const owned = vtxos.filter((v) => annotatable.has(v.script));
|
|
10641
10835
|
if (owned.length === 0) return;
|
|
10642
|
-
const annotated =
|
|
10836
|
+
const annotated = annotateAgainst(owned, scriptToContract, cache);
|
|
10643
10837
|
const byAddress = /* @__PURE__ */ new Map();
|
|
10644
10838
|
for (const vtxo of annotated) {
|
|
10645
10839
|
const contract = scriptToContract.get(vtxo.script);
|
|
@@ -10723,7 +10917,7 @@ var ContractManager = class _ContractManager {
|
|
|
10723
10917
|
break;
|
|
10724
10918
|
}
|
|
10725
10919
|
} catch (err) {
|
|
10726
|
-
if (!
|
|
10920
|
+
if (!chunkVVFCCNU2_cjs.isRetryableProviderError(err)) throw err;
|
|
10727
10921
|
this.markSyncDegraded(err);
|
|
10728
10922
|
synced = false;
|
|
10729
10923
|
}
|
|
@@ -10811,7 +11005,7 @@ var ContractManager = class _ContractManager {
|
|
|
10811
11005
|
*/
|
|
10812
11006
|
async reconcilePendingFrontier(contracts) {
|
|
10813
11007
|
const scriptToContract = new Map(contracts.map((c) => [c.script, c]));
|
|
10814
|
-
const vtxos = await
|
|
11008
|
+
const vtxos = await chunkVVFCCNU2_cjs.getAllNormalizedVtxos(
|
|
10815
11009
|
this.config.indexerProvider,
|
|
10816
11010
|
contracts.map((c) => c.script),
|
|
10817
11011
|
{ pendingOnly: true }
|
|
@@ -10826,7 +11020,7 @@ var ContractManager = class _ContractManager {
|
|
|
10826
11020
|
} = annotatableIn(scriptToContract, vtxos, this.tapscriptMemo);
|
|
10827
11021
|
this.recordAnnotationFailures(annotatable, failures);
|
|
10828
11022
|
const owned = vtxos.filter((v) => annotatable.has(v.script));
|
|
10829
|
-
const annotated =
|
|
11023
|
+
const annotated = annotateAgainst(owned, scriptToContract, cache);
|
|
10830
11024
|
const byContract = /* @__PURE__ */ new Map();
|
|
10831
11025
|
const contractByAddress = /* @__PURE__ */ new Map();
|
|
10832
11026
|
for (const vtxo of annotated) {
|
|
@@ -10885,7 +11079,7 @@ var ContractManager = class _ContractManager {
|
|
|
10885
11079
|
}
|
|
10886
11080
|
return result;
|
|
10887
11081
|
}
|
|
10888
|
-
async fetchContractVtxosBulk(contracts, pageSize =
|
|
11082
|
+
async fetchContractVtxosBulk(contracts, pageSize = chunkVVFCCNU2_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
|
|
10889
11083
|
if (contracts.length === 0) {
|
|
10890
11084
|
return { vtxosByScript: /* @__PURE__ */ new Map(), promoted: /* @__PURE__ */ new Map() };
|
|
10891
11085
|
}
|
|
@@ -10901,7 +11095,7 @@ var ContractManager = class _ContractManager {
|
|
|
10901
11095
|
before: syncWindow.before
|
|
10902
11096
|
}
|
|
10903
11097
|
} : {};
|
|
10904
|
-
const vtxos = await
|
|
11098
|
+
const vtxos = await chunkVVFCCNU2_cjs.getAllNormalizedVtxos(
|
|
10905
11099
|
this.config.indexerProvider,
|
|
10906
11100
|
contracts.map((c) => c.script),
|
|
10907
11101
|
{ ...windowOpts, pageSize }
|
|
@@ -10917,7 +11111,7 @@ var ContractManager = class _ContractManager {
|
|
|
10917
11111
|
} = annotatableIn(scriptToContract, vtxos, this.tapscriptMemo);
|
|
10918
11112
|
this.recordAnnotationFailures(annotatable, failures);
|
|
10919
11113
|
const owned = vtxos.filter((v) => annotatable.has(v.script));
|
|
10920
|
-
const annotated =
|
|
11114
|
+
const annotated = annotateAgainst(owned, scriptToContract, cache);
|
|
10921
11115
|
for (const vtxo of annotated) {
|
|
10922
11116
|
result.get(vtxo.script).push({
|
|
10923
11117
|
...vtxo,
|
|
@@ -11003,7 +11197,7 @@ function parseLegacyExpiry(batchExpiry) {
|
|
|
11003
11197
|
if (typeof batchExpiry !== "number" || !Number.isFinite(batchExpiry) || batchExpiry <= 0) {
|
|
11004
11198
|
return {};
|
|
11005
11199
|
}
|
|
11006
|
-
if (batchExpiry >=
|
|
11200
|
+
if (batchExpiry >= chunkVVFCCNU2_cjs.EXPIRY_MIN_PLAUSIBLE_MS) return { expiresAt: new Date(batchExpiry) };
|
|
11007
11201
|
return { expiresAtHeight: batchExpiry / 1e3 };
|
|
11008
11202
|
}
|
|
11009
11203
|
function legacyVtxoFacts(status) {
|
|
@@ -11241,7 +11435,7 @@ function backfillContractWatchState(store) {
|
|
|
11241
11435
|
};
|
|
11242
11436
|
readPage();
|
|
11243
11437
|
}
|
|
11244
|
-
var unspentFlag = (vtxo) =>
|
|
11438
|
+
var unspentFlag = (vtxo) => chunkVVFCCNU2_cjs.isVtxoSpent(vtxo) ? {} : { unspent: 1 };
|
|
11245
11439
|
function backfillVtxoIndexFields(transaction) {
|
|
11246
11440
|
const store = transaction.objectStore(STORE_VTXOS);
|
|
11247
11441
|
const pageSize = 1e3;
|
|
@@ -11272,7 +11466,7 @@ var DEFAULT_DB_NAME = "arkade-service-worker";
|
|
|
11272
11466
|
var DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS = 1e4;
|
|
11273
11467
|
function normalizeOptions2(pathOrOptions) {
|
|
11274
11468
|
const o = typeof pathOrOptions === "string" ? { path: pathOrOptions } : pathOrOptions;
|
|
11275
|
-
|
|
11469
|
+
chunkVVFCCNU2_cjs.assertTimerMs("activationTimeoutMs", o.activationTimeoutMs);
|
|
11276
11470
|
return {
|
|
11277
11471
|
path: o.path,
|
|
11278
11472
|
activationTimeoutMs: o.activationTimeoutMs ?? DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS
|
|
@@ -11491,7 +11685,7 @@ var deserializeTapLeaf = (t) => {
|
|
|
11491
11685
|
const s = base.hex.decode(t.s);
|
|
11492
11686
|
return [cb, s];
|
|
11493
11687
|
};
|
|
11494
|
-
var deserializeVtxo = (o) =>
|
|
11688
|
+
var deserializeVtxo = (o) => chunkVVFCCNU2_cjs.normalizeVtxo({
|
|
11495
11689
|
...o,
|
|
11496
11690
|
createdAt: new Date(o.createdAt),
|
|
11497
11691
|
tapTree: base.hex.decode(o.tapTree),
|
|
@@ -11915,7 +12109,7 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
|
|
|
11915
12109
|
*/
|
|
11916
12110
|
materializeDescriptorAt(index) {
|
|
11917
12111
|
const descriptor = this.identity.descriptor;
|
|
11918
|
-
const network =
|
|
12112
|
+
const network = chunkCFOIHLON_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
11919
12113
|
const expansion = descriptorsScure.expand({ descriptor, network, index });
|
|
11920
12114
|
const keyInfo = expansion.expansionMap?.["@0"];
|
|
11921
12115
|
if (!keyInfo?.keyExpression) {
|
|
@@ -11983,7 +12177,7 @@ function signingDescriptorIndex(descriptor) {
|
|
|
11983
12177
|
}
|
|
11984
12178
|
function newestWalletReceiveContract(contracts, serverPubKeyHex) {
|
|
11985
12179
|
return contracts.filter(
|
|
11986
|
-
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source ===
|
|
12180
|
+
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkCFOIHLON_cjs.WALLET_RECEIVE_SOURCE
|
|
11987
12181
|
).sort((a, b) => {
|
|
11988
12182
|
if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
|
|
11989
12183
|
return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
|
|
@@ -12034,7 +12228,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
12034
12228
|
const provider = await resolveDescriptorProvider(config, setup.walletRepository);
|
|
12035
12229
|
if (!provider) return void 0;
|
|
12036
12230
|
const allowSilentFallback = (config.walletMode ?? "auto") === "auto";
|
|
12037
|
-
const expectedContractType = setup.offchainTapscript instanceof
|
|
12231
|
+
const expectedContractType = setup.offchainTapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? "delegate" : "default";
|
|
12038
12232
|
const factoryOpts = {
|
|
12039
12233
|
walletRepository: setup.walletRepository,
|
|
12040
12234
|
contractRepository: setup.contractRepository,
|
|
@@ -12191,7 +12385,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
12191
12385
|
};
|
|
12192
12386
|
function deriveLeafPubkey(descriptor) {
|
|
12193
12387
|
try {
|
|
12194
|
-
return
|
|
12388
|
+
return chunkCFOIHLON_cjs.deriveDescriptorLeafPubKey(descriptor);
|
|
12195
12389
|
} catch (e) {
|
|
12196
12390
|
throw new NonRangeableDescriptorError(
|
|
12197
12391
|
"Cannot derive leaf pubkey: descriptor is not a materialized, parsable tr(...) shape.",
|
|
@@ -12203,7 +12397,7 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
|
|
|
12203
12397
|
const pubKey = deriveLeafPubkey(descriptor);
|
|
12204
12398
|
const tapscript = rebuildTapscript(current, pubKey);
|
|
12205
12399
|
const serverPubKey = tapscript.options.serverPubKey;
|
|
12206
|
-
const csvTimelock2 =
|
|
12400
|
+
const csvTimelock2 = chunkVVFCCNU2_cjs.timelockToSequence(tapscript.options.csvTimelock).toString();
|
|
12207
12401
|
const base$1 = {
|
|
12208
12402
|
script: base.hex.encode(tapscript.pkScript),
|
|
12209
12403
|
address: tapscript.address(hrp, serverPubKey).encode(),
|
|
@@ -12211,11 +12405,11 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
|
|
|
12211
12405
|
// Read at sign time to route rotated-pubkey inputs through `signWithDescriptor`; without
|
|
12212
12406
|
// it spends are rejected with `INVALID_PSBT_INPUT (5): missing tapscript spend sig`.
|
|
12213
12407
|
metadata: {
|
|
12214
|
-
...tagSource && { source:
|
|
12408
|
+
...tagSource && { source: chunkCFOIHLON_cjs.WALLET_RECEIVE_SOURCE },
|
|
12215
12409
|
signingDescriptor: descriptor
|
|
12216
12410
|
}
|
|
12217
12411
|
};
|
|
12218
|
-
const params = tapscript instanceof
|
|
12412
|
+
const params = tapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? {
|
|
12219
12413
|
...base$1,
|
|
12220
12414
|
type: "delegate",
|
|
12221
12415
|
params: {
|
|
@@ -12236,10 +12430,10 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
|
|
|
12236
12430
|
return { tapscript, params };
|
|
12237
12431
|
}
|
|
12238
12432
|
function rebuildTapscript(current, pubKey) {
|
|
12239
|
-
if (current instanceof
|
|
12240
|
-
return new
|
|
12433
|
+
if (current instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script) {
|
|
12434
|
+
return new chunkCFOIHLON_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
|
|
12241
12435
|
}
|
|
12242
|
-
return new
|
|
12436
|
+
return new chunkCFOIHLON_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
|
|
12243
12437
|
}
|
|
12244
12438
|
async function pickActiveReceive(contractRepository, serverPubKey, expectedType) {
|
|
12245
12439
|
const candidates = await collectContracts(contractRepository, {
|
|
@@ -12280,12 +12474,13 @@ async function resolveDescriptorProvider(config, walletRepository) {
|
|
|
12280
12474
|
|
|
12281
12475
|
// src/wallet/balance.ts
|
|
12282
12476
|
function computeOffchainBalance(vtxos, caps) {
|
|
12283
|
-
const { now, isPendingRecovery, isGenericallySpendable, isUnlocked, dustCarrier } = caps;
|
|
12477
|
+
const { now, isPendingRecovery, isGenericallySpendable, isUnlocked, isReserved, dustCarrier } = caps;
|
|
12284
12478
|
let settled = 0;
|
|
12285
12479
|
let preconfirmed = 0;
|
|
12286
12480
|
let available = 0;
|
|
12287
12481
|
let gated = 0;
|
|
12288
12482
|
let intentLocked = 0;
|
|
12483
|
+
let reserved = 0;
|
|
12289
12484
|
let recoverable = 0;
|
|
12290
12485
|
let pendingRecovery = 0;
|
|
12291
12486
|
let unrolled = 0;
|
|
@@ -12297,7 +12492,7 @@ function computeOffchainBalance(vtxos, caps) {
|
|
|
12297
12492
|
}
|
|
12298
12493
|
};
|
|
12299
12494
|
for (const vtxo of vtxos) {
|
|
12300
|
-
if (
|
|
12495
|
+
if (chunkVVFCCNU2_cjs.isVtxoSpent(vtxo)) continue;
|
|
12301
12496
|
addAssets(owned, vtxo);
|
|
12302
12497
|
if (vtxo.isUnrolled) {
|
|
12303
12498
|
unrolled += vtxo.value;
|
|
@@ -12307,11 +12502,11 @@ function computeOffchainBalance(vtxos, caps) {
|
|
|
12307
12502
|
pendingRecovery += vtxo.value;
|
|
12308
12503
|
continue;
|
|
12309
12504
|
}
|
|
12310
|
-
if (
|
|
12505
|
+
if (chunkVVFCCNU2_cjs.canRecoverOnchain(vtxo, now)) {
|
|
12311
12506
|
recoverable += vtxo.value;
|
|
12312
12507
|
continue;
|
|
12313
12508
|
}
|
|
12314
|
-
if (!
|
|
12509
|
+
if (!chunkVVFCCNU2_cjs.canSpendOffchain(vtxo, now)) continue;
|
|
12315
12510
|
if (vtxo.isPreconfirmed) {
|
|
12316
12511
|
preconfirmed += vtxo.value;
|
|
12317
12512
|
} else {
|
|
@@ -12321,6 +12516,8 @@ function computeOffchainBalance(vtxos, caps) {
|
|
|
12321
12516
|
gated += vtxo.value;
|
|
12322
12517
|
} else if (!isUnlocked(vtxo)) {
|
|
12323
12518
|
intentLocked += vtxo.value;
|
|
12519
|
+
} else if (isReserved?.(vtxo)) {
|
|
12520
|
+
reserved += vtxo.value;
|
|
12324
12521
|
} else {
|
|
12325
12522
|
available += vtxo.value;
|
|
12326
12523
|
addAssets(spendable, vtxo);
|
|
@@ -12336,6 +12533,7 @@ function computeOffchainBalance(vtxos, caps) {
|
|
|
12336
12533
|
available,
|
|
12337
12534
|
gated,
|
|
12338
12535
|
intentLocked,
|
|
12536
|
+
reserved,
|
|
12339
12537
|
recoverable,
|
|
12340
12538
|
pendingRecovery,
|
|
12341
12539
|
unrolled,
|
|
@@ -12366,6 +12564,7 @@ function toWalletBalance(boardingUtxos, offchain) {
|
|
|
12366
12564
|
available: offchain.available,
|
|
12367
12565
|
gated: offchain.gated,
|
|
12368
12566
|
intentLocked: offchain.intentLocked,
|
|
12567
|
+
reserved: offchain.reserved,
|
|
12369
12568
|
recoverable: offchain.recoverable,
|
|
12370
12569
|
pendingRecovery: offchain.pendingRecovery,
|
|
12371
12570
|
unrolled: offchain.unrolled,
|
|
@@ -12522,7 +12721,7 @@ function intentProofJobs(coins) {
|
|
|
12522
12721
|
if (coins.length === 0) return [];
|
|
12523
12722
|
const coinJobs = coins.map((coin, i) => ({
|
|
12524
12723
|
index: i + 1,
|
|
12525
|
-
lookupScript:
|
|
12724
|
+
lookupScript: chunkVVFCCNU2_cjs.VtxoScript.decode(coin.tapTree).pkScript
|
|
12526
12725
|
}));
|
|
12527
12726
|
return [{ index: 0, lookupScript: coinJobs[0].lookupScript }, ...coinJobs];
|
|
12528
12727
|
}
|
|
@@ -12548,7 +12747,7 @@ function dedupeTimelocks(timelocks) {
|
|
|
12548
12747
|
const seen = /* @__PURE__ */ new Set();
|
|
12549
12748
|
const deduped = [];
|
|
12550
12749
|
for (const timelock of timelocks) {
|
|
12551
|
-
const sequence =
|
|
12750
|
+
const sequence = chunkVVFCCNU2_cjs.timelockToSequence(timelock).toString();
|
|
12552
12751
|
if (seen.has(sequence)) continue;
|
|
12553
12752
|
seen.add(sequence);
|
|
12554
12753
|
deduped.push(timelock);
|
|
@@ -12564,7 +12763,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
|
|
|
12564
12763
|
if (!newest?.params.pubKey) return baseline;
|
|
12565
12764
|
try {
|
|
12566
12765
|
const pubKey = base.hex.decode(newest.params.pubKey);
|
|
12567
|
-
return new
|
|
12766
|
+
return new chunkCFOIHLON_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
|
|
12568
12767
|
} catch (e) {
|
|
12569
12768
|
console.warn("Skipping malformed boarding contract at boot", newest.script, e);
|
|
12570
12769
|
return baseline;
|
|
@@ -12596,21 +12795,21 @@ function filterFlatVtxos(vtxos, filter, pendingSpendOutpoints) {
|
|
|
12596
12795
|
if (vtxo.isUnrolled) {
|
|
12597
12796
|
return !!f.withUnrolled;
|
|
12598
12797
|
}
|
|
12599
|
-
if (
|
|
12798
|
+
if (chunkVVFCCNU2_cjs.isVtxoSpent(vtxo)) {
|
|
12600
12799
|
return false;
|
|
12601
12800
|
}
|
|
12602
|
-
if (!f.withRecoverable &&
|
|
12801
|
+
if (!f.withRecoverable && chunkVVFCCNU2_cjs.canRecoverOnchain(vtxo, now)) {
|
|
12603
12802
|
return false;
|
|
12604
12803
|
}
|
|
12605
12804
|
return true;
|
|
12606
12805
|
});
|
|
12607
12806
|
}
|
|
12608
12807
|
async function refreshSweptStateOfExpiredInputs(wallet, inputs) {
|
|
12609
|
-
const candidates = inputs.filter(
|
|
12808
|
+
const candidates = inputs.filter(chunkVVFCCNU2_cjs.isVirtualCoin).map(chunkVVFCCNU2_cjs.normalizeVtxo).filter((v) => !v.isSwept);
|
|
12610
12809
|
if (candidates.length === 0) return inputs;
|
|
12611
|
-
const now = candidates.some((v) => v.expiresAtHeight !== void 0) ? await
|
|
12810
|
+
const now = candidates.some((v) => v.expiresAtHeight !== void 0) ? await chunkVVFCCNU2_cjs.resolveTimeHeight(wallet.onchainProvider) : { timestamp: /* @__PURE__ */ new Date() };
|
|
12612
12811
|
const suspects = candidates.filter(
|
|
12613
|
-
(v) =>
|
|
12812
|
+
(v) => chunkVVFCCNU2_cjs.isPastExpiry(v, now) || v.expiresAtHeight !== void 0 && now.height === void 0
|
|
12614
12813
|
);
|
|
12615
12814
|
if (suspects.length === 0) return inputs;
|
|
12616
12815
|
let sweptNow;
|
|
@@ -12624,12 +12823,12 @@ async function refreshSweptStateOfExpiredInputs(wallet, inputs) {
|
|
|
12624
12823
|
);
|
|
12625
12824
|
} catch (e) {
|
|
12626
12825
|
const message = "could not confirm the swept state of expired settlement inputs; retry the settlement";
|
|
12627
|
-
throw
|
|
12826
|
+
throw chunkVVFCCNU2_cjs.isRetryableProviderError(e) ? new chunkVVFCCNU2_cjs.ProviderUnavailableError(message, { cause: e }) : new Error(message, { cause: e });
|
|
12628
12827
|
}
|
|
12629
12828
|
if (sweptNow.size === 0) return inputs;
|
|
12630
12829
|
return inputs.map((input) => {
|
|
12631
|
-
if (!
|
|
12632
|
-
return { ...
|
|
12830
|
+
if (!chunkVVFCCNU2_cjs.isVirtualCoin(input) || !sweptNow.has(`${input.txid}:${input.vout}`)) return input;
|
|
12831
|
+
return { ...chunkVVFCCNU2_cjs.normalizeVtxo(input), isSwept: true };
|
|
12633
12832
|
});
|
|
12634
12833
|
}
|
|
12635
12834
|
var PENDING_RECOVERY_REASON = "is past its operator signer's rotation cutoff \u2014 the operator will not co-sign it until it recovers";
|
|
@@ -12641,6 +12840,9 @@ function omittedOutpoints(before, after) {
|
|
|
12641
12840
|
before.map((vtxo) => `${vtxo.txid}:${vtxo.vout}`).filter((outpoint) => !kept.has(outpoint))
|
|
12642
12841
|
);
|
|
12643
12842
|
}
|
|
12843
|
+
function coinKeys(inputs) {
|
|
12844
|
+
return inputs.filter((input) => typeof input === "object" && input !== null).map((input) => `${input.txid}:${input.vout}`);
|
|
12845
|
+
}
|
|
12644
12846
|
function excludeLockedOutpoints(vtxos, locked) {
|
|
12645
12847
|
if (locked.length === 0) return vtxos;
|
|
12646
12848
|
const lockedKeys = new Set(locked.map((o) => `${o.txid}:${o.vout}`));
|
|
@@ -12675,6 +12877,18 @@ var ArkadeCashCreateError = class extends Error {
|
|
|
12675
12877
|
cash;
|
|
12676
12878
|
cause;
|
|
12677
12879
|
};
|
|
12880
|
+
var ArkadeCashOperatorMismatchError = class extends Error {
|
|
12881
|
+
constructor(cashSignerPubKey, activeSignerPubKey) {
|
|
12882
|
+
super(
|
|
12883
|
+
`ArkadeCash comes from another operator: its signer ${cashSignerPubKey} is not the active signer ${activeSignerPubKey} of the connected operator, and not one of its deprecated signers. Connect to the operator that issued it to claim it.`
|
|
12884
|
+
);
|
|
12885
|
+
this.cashSignerPubKey = cashSignerPubKey;
|
|
12886
|
+
this.activeSignerPubKey = activeSignerPubKey;
|
|
12887
|
+
this.name = "ArkadeCashOperatorMismatchError";
|
|
12888
|
+
}
|
|
12889
|
+
cashSignerPubKey;
|
|
12890
|
+
activeSignerPubKey;
|
|
12891
|
+
};
|
|
12678
12892
|
var ReadonlyWallet = class _ReadonlyWallet {
|
|
12679
12893
|
constructor(identity, network, onchainProvider, arkProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, dustAmount, walletRepository, contractRepository, delegateProvider, watcherConfig, walletContractTimelocks) {
|
|
12680
12894
|
this.identity = identity;
|
|
@@ -12735,6 +12949,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12735
12949
|
// Outpoints committed to an in-flight settle/send, filtered from getVtxos() so concurrent
|
|
12736
12950
|
// callers can't reselect them. In-memory only: a stale entry only hides a VTXO.
|
|
12737
12951
|
_pendingSpendOutpoints = /* @__PURE__ */ new Set();
|
|
12952
|
+
_heldOutpoints = /* @__PURE__ */ new Set();
|
|
12738
12953
|
/** Activity resolvers consumed by {@link getActivityHistory}. */
|
|
12739
12954
|
activity = createDefaultActivityRegistry();
|
|
12740
12955
|
get assetManager() {
|
|
@@ -12902,7 +13117,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12902
13117
|
async getArkadeReader() {
|
|
12903
13118
|
const indexer = this.indexerProvider;
|
|
12904
13119
|
return {
|
|
12905
|
-
getVtxos: (opts) =>
|
|
13120
|
+
getVtxos: (opts) => chunkVVFCCNU2_cjs.getNormalizedVtxos(indexer, opts),
|
|
12906
13121
|
getVirtualTxs: (txids, opts) => indexer.getVirtualTxs(txids, opts)
|
|
12907
13122
|
};
|
|
12908
13123
|
}
|
|
@@ -12937,7 +13152,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12937
13152
|
}
|
|
12938
13153
|
/** Shared setup for ReadonlyWallet.create() and Wallet.create(). */
|
|
12939
13154
|
static async setupWalletConfig(config, pubKey) {
|
|
12940
|
-
const arkProvider = config.arkProvider || new
|
|
13155
|
+
const arkProvider = config.arkProvider || new chunkVVFCCNU2_cjs.RestArkProvider();
|
|
12941
13156
|
let indexerProvider = config.indexerProvider;
|
|
12942
13157
|
if (!indexerProvider) {
|
|
12943
13158
|
const derived = extractArkProviderUrl(arkProvider);
|
|
@@ -12946,7 +13161,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12946
13161
|
"indexerProvider is required when arkProvider is provided without a discoverable serverUrl"
|
|
12947
13162
|
);
|
|
12948
13163
|
}
|
|
12949
|
-
indexerProvider = new
|
|
13164
|
+
indexerProvider = new chunkFEBAG2K2_cjs.RestIndexerProvider(derived ?? chunkVVFCCNU2_cjs.DEFAULT_ARKADE_SERVER_URL);
|
|
12950
13165
|
}
|
|
12951
13166
|
const walletRepository = config.storage?.walletRepository ?? new IndexedDBWalletRepository();
|
|
12952
13167
|
const contractRepository = config.storage?.contractRepository ?? new IndexedDBContractRepository();
|
|
@@ -12955,7 +13170,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12955
13170
|
source: serverInfoSource,
|
|
12956
13171
|
lastOnlineAt: serverInfoLastOnlineAt
|
|
12957
13172
|
} = await resolveArkInfo(arkProvider, walletRepository);
|
|
12958
|
-
const network =
|
|
13173
|
+
const network = chunkVVFCCNU2_cjs.networkFromArkadeInfo(info);
|
|
12959
13174
|
if ("descriptor" in config.identity) {
|
|
12960
13175
|
const descriptor = config.identity.descriptor;
|
|
12961
13176
|
const identityIsMainnet = !descriptor.includes("tpub");
|
|
@@ -12991,18 +13206,18 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12991
13206
|
}
|
|
12992
13207
|
}
|
|
12993
13208
|
const boardingTimelock = config.boardingTimelock ?? toTimelock(info.boardingExitDelay);
|
|
12994
|
-
const serverPubKey =
|
|
12995
|
-
const delegatePubKey = config.delegateProvider ? await config.delegateProvider.getDelegateInfo().then((info2) =>
|
|
13209
|
+
const serverPubKey = chunkCFOIHLON_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
|
|
13210
|
+
const delegatePubKey = config.delegateProvider ? await config.delegateProvider.getDelegateInfo().then((info2) => chunkCFOIHLON_cjs.toXOnly(base.hex.decode(info2.pubkey), "delegate key")).catch(() => void 0) : void 0;
|
|
12996
13211
|
const offchainOptions = {
|
|
12997
13212
|
pubKey,
|
|
12998
13213
|
serverPubKey,
|
|
12999
13214
|
csvTimelock: exitTimelock
|
|
13000
13215
|
};
|
|
13001
|
-
const offchainTapscript = !delegatePubKey ? new
|
|
13002
|
-
const boardingTapscript =
|
|
13216
|
+
const offchainTapscript = !delegatePubKey ? new chunkCFOIHLON_cjs.DefaultVtxo.Script(offchainOptions) : new chunkCFOIHLON_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
|
|
13217
|
+
const boardingTapscript = chunkCFOIHLON_cjs.BoardingContractHandler.createScript({
|
|
13003
13218
|
pubKey: base.hex.encode(pubKey),
|
|
13004
13219
|
serverPubKey: base.hex.encode(serverPubKey),
|
|
13005
|
-
csvTimelock:
|
|
13220
|
+
csvTimelock: chunkVVFCCNU2_cjs.timelockToSequence(boardingTimelock).toString()
|
|
13006
13221
|
});
|
|
13007
13222
|
return {
|
|
13008
13223
|
arkProvider,
|
|
@@ -13135,6 +13350,16 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13135
13350
|
this._pendingSpendOutpoints
|
|
13136
13351
|
);
|
|
13137
13352
|
}
|
|
13353
|
+
/**
|
|
13354
|
+
* @internal The stored VTXOs {@link reserveVtxos} holds, minus any being spent: for renewal,
|
|
13355
|
+
* which skips them, to report the ones it would have renewed. No sync.
|
|
13356
|
+
*/
|
|
13357
|
+
async getHeldVtxos() {
|
|
13358
|
+
if (this._heldOutpoints.size === 0) return [];
|
|
13359
|
+
return (await this.getStoredVtxos()).filter(
|
|
13360
|
+
(vtxo) => this._heldOutpoints.has(`${vtxo.txid}:${vtxo.vout}`)
|
|
13361
|
+
);
|
|
13362
|
+
}
|
|
13138
13363
|
/** @inheritdoc */
|
|
13139
13364
|
async getSpendableVtxos(filter) {
|
|
13140
13365
|
const snapshot = await this.contractSnapshot(filter, {
|
|
@@ -13143,12 +13368,13 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13143
13368
|
const vtxos = filterSnapshotVtxos(snapshot, filter, this._pendingSpendOutpoints);
|
|
13144
13369
|
const { gated, pendingRecovery } = this.spendabilityView(snapshot);
|
|
13145
13370
|
const selectable = vtxos.filter(
|
|
13146
|
-
(vtxo) => !isGatedVtxo(vtxo, gated) && !pendingRecovery.has(`${vtxo.txid}:${vtxo.vout}`)
|
|
13371
|
+
(vtxo) => !isGatedVtxo(vtxo, gated) && !pendingRecovery.has(`${vtxo.txid}:${vtxo.vout}`) && !this._heldOutpoints.has(`${vtxo.txid}:${vtxo.vout}`)
|
|
13147
13372
|
);
|
|
13148
13373
|
const unlocked = await spendableVtxosExcludingLocked(selectable, this.intentRepository);
|
|
13149
13374
|
logExcludedVtxos("getSpendableVtxos", vtxos, [
|
|
13150
13375
|
gateExclusion(gated),
|
|
13151
13376
|
outpointExclusion(pendingRecovery, PENDING_RECOVERY_REASON),
|
|
13377
|
+
outpointExclusion(this._heldOutpoints, "is held by reserveVtxos"),
|
|
13152
13378
|
outpointExclusion(
|
|
13153
13379
|
omittedOutpoints(selectable, unlocked),
|
|
13154
13380
|
"is locked by an in-flight settlement intent"
|
|
@@ -13157,7 +13383,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13157
13383
|
if (!filter?.withUnrolled) {
|
|
13158
13384
|
logExcludedVtxos(
|
|
13159
13385
|
"getSpendableVtxos",
|
|
13160
|
-
snapshot.flatMap((contract) => contract.vtxos).filter((vtxo) => vtxo.isUnrolled && !
|
|
13386
|
+
snapshot.flatMap((contract) => contract.vtxos).filter((vtxo) => vtxo.isUnrolled && !chunkVVFCCNU2_cjs.isVtxoSpent(vtxo)),
|
|
13161
13387
|
[() => UNROLLED_REASON]
|
|
13162
13388
|
);
|
|
13163
13389
|
}
|
|
@@ -13241,7 +13467,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13241
13467
|
}
|
|
13242
13468
|
async contractSnapshotStored() {
|
|
13243
13469
|
const contractManager = await this.getContractManager();
|
|
13244
|
-
return contractManager.getStoredContractsWithVtxos
|
|
13470
|
+
return contractManager.getStoredContractsWithVtxos();
|
|
13245
13471
|
}
|
|
13246
13472
|
/**
|
|
13247
13473
|
* The two exclusion sets the gate is made of, derived from one snapshot so
|
|
@@ -13266,6 +13492,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13266
13492
|
isPendingRecovery: (vtxo) => pendingRecovery.has(`${vtxo.txid}:${vtxo.vout}`),
|
|
13267
13493
|
isGenericallySpendable: (vtxo) => !isGatedVtxo(vtxo, gated),
|
|
13268
13494
|
isUnlocked: (vtxo) => unlocked.has(`${vtxo.txid}:${vtxo.vout}`),
|
|
13495
|
+
isReserved: (vtxo) => this._heldOutpoints.has(`${vtxo.txid}:${vtxo.vout}`),
|
|
13269
13496
|
dustCarrier: getDustAmount(this)
|
|
13270
13497
|
};
|
|
13271
13498
|
}
|
|
@@ -13299,7 +13526,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13299
13526
|
this.getBoardingTxs()
|
|
13300
13527
|
]);
|
|
13301
13528
|
const allVtxos = snapshot.flatMap((_) => _.vtxos);
|
|
13302
|
-
const resolveTxCreatedAt = (txids) =>
|
|
13529
|
+
const resolveTxCreatedAt = (txids) => chunkVVFCCNU2_cjs.fetchVtxoCreatedAtByTxid(this.indexerProvider, txids);
|
|
13303
13530
|
return buildTransactionHistory(
|
|
13304
13531
|
allVtxos,
|
|
13305
13532
|
boardingTxs,
|
|
@@ -13453,9 +13680,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13453
13680
|
async getBoardingTapscripts(allowedSigners) {
|
|
13454
13681
|
const byScript = /* @__PURE__ */ new Map();
|
|
13455
13682
|
const add = (s) => byScript.set(base.hex.encode(s.pkScript), s);
|
|
13456
|
-
const boardingCsv = this.boardingTapscript.options.csvTimelock ??
|
|
13683
|
+
const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunkCFOIHLON_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
13457
13684
|
add(
|
|
13458
|
-
new
|
|
13685
|
+
new chunkCFOIHLON_cjs.DefaultVtxo.Script({
|
|
13459
13686
|
pubKey: await this.identity.xOnlyPublicKey(),
|
|
13460
13687
|
serverPubKey: this.boardingTapscript.options.serverPubKey,
|
|
13461
13688
|
csvTimelock: boardingCsv
|
|
@@ -13470,7 +13697,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13470
13697
|
for (const c of boardingContracts) {
|
|
13471
13698
|
if (!allowed.has(toXOnlySignerHex(c.params.serverPubKey))) continue;
|
|
13472
13699
|
try {
|
|
13473
|
-
add(
|
|
13700
|
+
add(chunkCFOIHLON_cjs.BoardingContractHandler.createScript(c.params));
|
|
13474
13701
|
} catch (e) {
|
|
13475
13702
|
console.warn("Skipping malformed boarding contract", c.script, e);
|
|
13476
13703
|
}
|
|
@@ -13499,7 +13726,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13499
13726
|
// Per-row CSV delay decoded from THIS tapscript's exit leaf —
|
|
13500
13727
|
// not the wallet's current boarding timelock, which a signer
|
|
13501
13728
|
// rotation may have changed.
|
|
13502
|
-
csvTimelock:
|
|
13729
|
+
csvTimelock: chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
|
|
13503
13730
|
coins: utxos
|
|
13504
13731
|
};
|
|
13505
13732
|
})
|
|
@@ -13531,6 +13758,16 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13531
13758
|
this.boardingLoaded = true;
|
|
13532
13759
|
return groups.flatMap((g) => g.coins);
|
|
13533
13760
|
}
|
|
13761
|
+
/**
|
|
13762
|
+
* @internal {@link getBoardingUtxos} minus those an in-flight settle is spending, for SDK
|
|
13763
|
+
* picks. The getter itself lists them: callers that mirror it (the worker's cache and
|
|
13764
|
+
* broadcasts, balances) must not see a settle's inputs vanish, and then stay gone if it fails.
|
|
13765
|
+
*/
|
|
13766
|
+
async getSelectableBoardingUtxos() {
|
|
13767
|
+
return (await this.getBoardingUtxos()).filter(
|
|
13768
|
+
(coin) => !this._pendingSpendOutpoints.has(`${coin.txid}:${coin.vout}`)
|
|
13769
|
+
);
|
|
13770
|
+
}
|
|
13534
13771
|
async getStoredBoardingUtxos() {
|
|
13535
13772
|
const currentOnly = /* @__PURE__ */ new Set([
|
|
13536
13773
|
toXOnlySignerHex(base.hex.encode(this.boardingTapscript.options.serverPubKey))
|
|
@@ -13645,7 +13882,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13645
13882
|
/** Fetch Arkade transaction ids that are still pending final settlement. */
|
|
13646
13883
|
async fetchPendingTxs() {
|
|
13647
13884
|
const scripts = await this.getWalletScripts();
|
|
13648
|
-
const vtxos = await
|
|
13885
|
+
const vtxos = await chunkVVFCCNU2_cjs.getAllNormalizedVtxos(this.indexerProvider, scripts);
|
|
13649
13886
|
return vtxos.filter(
|
|
13650
13887
|
(vtxo) => (vtxo.isSpent || vtxo.isPreconfirmed && !vtxo.isSwept) && vtxo.arkTxId !== void 0
|
|
13651
13888
|
).map((_) => _.arkTxId);
|
|
@@ -13676,7 +13913,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13676
13913
|
});
|
|
13677
13914
|
for (const contract of contracts) {
|
|
13678
13915
|
if (map.has(contract.script)) continue;
|
|
13679
|
-
const handler =
|
|
13916
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
|
|
13680
13917
|
if (handler) {
|
|
13681
13918
|
const script = handler.createScript(contract.params);
|
|
13682
13919
|
map.set(contract.script, script);
|
|
@@ -13788,7 +14025,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13788
14025
|
}
|
|
13789
14026
|
});
|
|
13790
14027
|
const baselinePubkey = await this.identity.xOnlyPublicKey();
|
|
13791
|
-
const delegatePubKey = this.offchainTapscript instanceof
|
|
14028
|
+
const delegatePubKey = this.offchainTapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
|
|
13792
14029
|
const baselineSigners = [
|
|
13793
14030
|
this.offchainTapscript.options.serverPubKey,
|
|
13794
14031
|
...[...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h))
|
|
@@ -13796,8 +14033,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13796
14033
|
const seenBaselineScripts = /* @__PURE__ */ new Set();
|
|
13797
14034
|
for (const serverPubKey of baselineSigners) {
|
|
13798
14035
|
for (const csvTimelock2 of this.walletContractTimelocks) {
|
|
13799
|
-
const csvTimelockStr =
|
|
13800
|
-
const defaultScript = new
|
|
14036
|
+
const csvTimelockStr = chunkVVFCCNU2_cjs.timelockToSequence(csvTimelock2).toString();
|
|
14037
|
+
const defaultScript = new chunkCFOIHLON_cjs.DefaultVtxo.Script({
|
|
13801
14038
|
pubKey: baselinePubkey,
|
|
13802
14039
|
serverPubKey,
|
|
13803
14040
|
csvTimelock: csvTimelock2
|
|
@@ -13818,7 +14055,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13818
14055
|
});
|
|
13819
14056
|
}
|
|
13820
14057
|
if (delegatePubKey) {
|
|
13821
|
-
const delegateScript = new
|
|
14058
|
+
const delegateScript = new chunkCFOIHLON_cjs.DelegateVtxo.Script({
|
|
13822
14059
|
pubKey: baselinePubkey,
|
|
13823
14060
|
serverPubKey,
|
|
13824
14061
|
delegatePubKey,
|
|
@@ -13842,9 +14079,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13842
14079
|
}
|
|
13843
14080
|
}
|
|
13844
14081
|
}
|
|
13845
|
-
const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ??
|
|
14082
|
+
const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunkCFOIHLON_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
13846
14083
|
for (const serverPubKey of baselineSigners) {
|
|
13847
|
-
const baselineBoarding = new
|
|
14084
|
+
const baselineBoarding = new chunkCFOIHLON_cjs.DefaultVtxo.Script({
|
|
13848
14085
|
pubKey: baselinePubkey,
|
|
13849
14086
|
serverPubKey,
|
|
13850
14087
|
csvTimelock: boardingCsvTimelock
|
|
@@ -13857,7 +14094,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13857
14094
|
params: {
|
|
13858
14095
|
pubKey: base.hex.encode(baselineBoarding.options.pubKey),
|
|
13859
14096
|
serverPubKey: base.hex.encode(serverPubKey),
|
|
13860
|
-
csvTimelock:
|
|
14097
|
+
csvTimelock: chunkVVFCCNU2_cjs.timelockToSequence(boardingCsvTimelock).toString()
|
|
13861
14098
|
},
|
|
13862
14099
|
script: boardingScriptHex,
|
|
13863
14100
|
address: baselineBoarding.address(this.network.hrp, serverPubKey).encode(),
|
|
@@ -14044,7 +14281,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14044
14281
|
serverPubKey: this.offchainTapscript.options.serverPubKey,
|
|
14045
14282
|
deprecatedSignerPubKeys: [...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h)),
|
|
14046
14283
|
csvTimelocks: this.walletContractTimelocks,
|
|
14047
|
-
delegatePubKey: this.offchainTapscript instanceof
|
|
14284
|
+
delegatePubKey: this.offchainTapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0
|
|
14048
14285
|
};
|
|
14049
14286
|
}
|
|
14050
14287
|
_signerRouter;
|
|
@@ -14204,7 +14441,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14204
14441
|
const [row] = await manager.getContracts({ script: base.hex.encode(display.pkScript) });
|
|
14205
14442
|
const persisted = row?.metadata?.signingDescriptor;
|
|
14206
14443
|
if (typeof persisted === "string") return persisted;
|
|
14207
|
-
return
|
|
14444
|
+
return chunkCFOIHLON_cjs.identityDescriptor(this.identity);
|
|
14208
14445
|
}
|
|
14209
14446
|
/**
|
|
14210
14447
|
* Build, persist and shape one address of `type` owned by `descriptor`. The descriptor is the
|
|
@@ -14214,7 +14451,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14214
14451
|
async mintAddress(manager, type, descriptor, tagSource, allocated) {
|
|
14215
14452
|
if (type === "boarding") {
|
|
14216
14453
|
const built2 = this.buildBoardingContract(
|
|
14217
|
-
|
|
14454
|
+
chunkCFOIHLON_cjs.deriveDescriptorLeafPubKey(descriptor),
|
|
14218
14455
|
descriptor,
|
|
14219
14456
|
tagSource
|
|
14220
14457
|
);
|
|
@@ -14251,11 +14488,11 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14251
14488
|
* (offchain analogue: {@link buildReceiveContract}).
|
|
14252
14489
|
*/
|
|
14253
14490
|
buildBoardingContract(pubKey, descriptor, tagSource) {
|
|
14254
|
-
const tapscript = new
|
|
14491
|
+
const tapscript = new chunkCFOIHLON_cjs.DefaultVtxo.Script({
|
|
14255
14492
|
...this._boardingTapscript.options,
|
|
14256
14493
|
pubKey
|
|
14257
14494
|
});
|
|
14258
|
-
const csvTimelock2 = tapscript.options.csvTimelock ??
|
|
14495
|
+
const csvTimelock2 = tapscript.options.csvTimelock ?? chunkCFOIHLON_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
14259
14496
|
return {
|
|
14260
14497
|
tapscript,
|
|
14261
14498
|
params: {
|
|
@@ -14263,13 +14500,13 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14263
14500
|
params: {
|
|
14264
14501
|
pubKey: base.hex.encode(pubKey),
|
|
14265
14502
|
serverPubKey: base.hex.encode(tapscript.options.serverPubKey),
|
|
14266
|
-
csvTimelock:
|
|
14503
|
+
csvTimelock: chunkVVFCCNU2_cjs.timelockToSequence(csvTimelock2).toString()
|
|
14267
14504
|
},
|
|
14268
14505
|
script: base.hex.encode(tapscript.pkScript),
|
|
14269
14506
|
address: tapscript.address(this.network.hrp, this.arkServerPublicKey).encode(),
|
|
14270
14507
|
state: "active",
|
|
14271
14508
|
metadata: {
|
|
14272
|
-
...tagSource && { source:
|
|
14509
|
+
...tagSource && { source: chunkCFOIHLON_cjs.WALLET_RECEIVE_SOURCE },
|
|
14273
14510
|
signingDescriptor: descriptor
|
|
14274
14511
|
}
|
|
14275
14512
|
}
|
|
@@ -14291,7 +14528,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14291
14528
|
if (this._hdProvider) {
|
|
14292
14529
|
return (await this.getContractManager()).getNextSigningDescriptor();
|
|
14293
14530
|
}
|
|
14294
|
-
return
|
|
14531
|
+
return chunkCFOIHLON_cjs.identityDescriptor(this.identity);
|
|
14295
14532
|
}
|
|
14296
14533
|
/**
|
|
14297
14534
|
* @see HDAllocationCapable.advanceSigningDescriptorWatermark
|
|
@@ -14367,7 +14604,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14367
14604
|
* the stable public API.
|
|
14368
14605
|
*/
|
|
14369
14606
|
async rotateServerSigner(newServerPubKey, checkpointTapscript) {
|
|
14370
|
-
const xonly =
|
|
14607
|
+
const xonly = chunkCFOIHLON_cjs.toXOnly(newServerPubKey, "ark signer key");
|
|
14371
14608
|
const newServerUnrollScript = assertValidServerUnrollScript(
|
|
14372
14609
|
checkpointTapscript,
|
|
14373
14610
|
resolveCheckpointExitDelayPolicy(this.network, this.checkpointExitDelayPolicy)
|
|
@@ -14396,21 +14633,21 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14396
14633
|
const [currentBoardingRow] = await manager.getContracts({
|
|
14397
14634
|
script: currentBoardingScript
|
|
14398
14635
|
});
|
|
14399
|
-
const newOffchain = this.offchainTapscript instanceof
|
|
14636
|
+
const newOffchain = this.offchainTapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? new chunkCFOIHLON_cjs.DelegateVtxo.Script({
|
|
14400
14637
|
...this.offchainTapscript.options,
|
|
14401
14638
|
serverPubKey: xonly
|
|
14402
|
-
}) : new
|
|
14639
|
+
}) : new chunkCFOIHLON_cjs.DefaultVtxo.Script({
|
|
14403
14640
|
...this.offchainTapscript.options,
|
|
14404
14641
|
serverPubKey: xonly
|
|
14405
14642
|
});
|
|
14406
|
-
const newBoarding = new
|
|
14643
|
+
const newBoarding = new chunkCFOIHLON_cjs.DefaultVtxo.Script({
|
|
14407
14644
|
...this._boardingTapscript.options,
|
|
14408
14645
|
serverPubKey: xonly
|
|
14409
14646
|
});
|
|
14410
|
-
const offchainCsv =
|
|
14647
|
+
const offchainCsv = chunkVVFCCNU2_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
|
|
14411
14648
|
const newOffchainScript = base.hex.encode(newOffchain.pkScript);
|
|
14412
14649
|
const newOffchainAddress = newOffchain.address(this.network.hrp, xonly).encode();
|
|
14413
|
-
if (newOffchain instanceof
|
|
14650
|
+
if (newOffchain instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script) {
|
|
14414
14651
|
await manager.createContract({
|
|
14415
14652
|
type: "delegate",
|
|
14416
14653
|
params: {
|
|
@@ -14438,13 +14675,13 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14438
14675
|
metadata: currentOffchainRow?.metadata
|
|
14439
14676
|
});
|
|
14440
14677
|
}
|
|
14441
|
-
const boardingCsv = newBoarding.options.csvTimelock ??
|
|
14678
|
+
const boardingCsv = newBoarding.options.csvTimelock ?? chunkCFOIHLON_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
14442
14679
|
await manager.createContract({
|
|
14443
14680
|
type: "boarding",
|
|
14444
14681
|
params: {
|
|
14445
14682
|
pubKey: base.hex.encode(newBoarding.options.pubKey),
|
|
14446
14683
|
serverPubKey: base.hex.encode(xonly),
|
|
14447
|
-
csvTimelock:
|
|
14684
|
+
csvTimelock: chunkVVFCCNU2_cjs.timelockToSequence(boardingCsv).toString()
|
|
14448
14685
|
},
|
|
14449
14686
|
script: base.hex.encode(newBoarding.pkScript),
|
|
14450
14687
|
address: newBoarding.address(this.network.hrp, xonly).encode(),
|
|
@@ -14463,7 +14700,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14463
14700
|
}
|
|
14464
14701
|
/**
|
|
14465
14702
|
* Serializes `settle`/`send` so VtxoManager's background renewal can't race user
|
|
14466
|
-
* transactions for the same inputs.
|
|
14703
|
+
* transactions for the same inputs; with `concurrentSpending`, only until inputs are reserved.
|
|
14467
14704
|
*/
|
|
14468
14705
|
_txLock = Promise.resolve();
|
|
14469
14706
|
// Every input (boarding included) of an intent a live settle owns; reconciliation skips them.
|
|
@@ -14472,18 +14709,59 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14472
14709
|
_restoreInFlight;
|
|
14473
14710
|
_addPendingSpends(inputs) {
|
|
14474
14711
|
for (const input of inputs) {
|
|
14475
|
-
if (
|
|
14712
|
+
if (chunkVVFCCNU2_cjs.isVirtualCoin(input)) {
|
|
14476
14713
|
this._pendingSpendOutpoints.add(`${input.txid}:${input.vout}`);
|
|
14477
14714
|
}
|
|
14478
14715
|
}
|
|
14479
14716
|
}
|
|
14480
14717
|
_removePendingSpends(inputs) {
|
|
14481
14718
|
for (const input of inputs) {
|
|
14482
|
-
if (
|
|
14719
|
+
if (chunkVVFCCNU2_cjs.isVirtualCoin(input)) {
|
|
14483
14720
|
this._pendingSpendOutpoints.delete(`${input.txid}:${input.vout}`);
|
|
14484
14721
|
}
|
|
14485
14722
|
}
|
|
14486
14723
|
}
|
|
14724
|
+
/**
|
|
14725
|
+
* Hold VTXOs so no SDK-chosen spend picks them; the holder still spends them by naming them.
|
|
14726
|
+
* All-or-nothing: throws {@link VtxoReservedError} if any is held or already being spent.
|
|
14727
|
+
* In-memory, for this `Wallet` instance only.
|
|
14728
|
+
*/
|
|
14729
|
+
reserveVtxos(outpoints) {
|
|
14730
|
+
const keys = outpoints.map((o) => `${o.txid}:${o.vout}`);
|
|
14731
|
+
const inFlight = keys.filter((k) => this._pendingSpendOutpoints.has(k));
|
|
14732
|
+
if (inFlight.length > 0) throw new VtxoReservedError(inFlight, "in-flight");
|
|
14733
|
+
const held = keys.filter((k) => this._heldOutpoints.has(k));
|
|
14734
|
+
if (held.length > 0) throw new VtxoReservedError(held, "held");
|
|
14735
|
+
for (const k of keys) this._heldOutpoints.add(k);
|
|
14736
|
+
let released = false;
|
|
14737
|
+
return {
|
|
14738
|
+
outpoints: [...outpoints],
|
|
14739
|
+
release: () => {
|
|
14740
|
+
if (released) return;
|
|
14741
|
+
released = true;
|
|
14742
|
+
for (const k of keys) this._heldOutpoints.delete(k);
|
|
14743
|
+
}
|
|
14744
|
+
};
|
|
14745
|
+
}
|
|
14746
|
+
/**
|
|
14747
|
+
* @internal For `AssetManager`: reserves what `fn` submits, hiding it from other picks until
|
|
14748
|
+
* the submit ends. With `concurrentSpending`, `fn` runs under the wallet lock, released once
|
|
14749
|
+
* the inputs are reserved; otherwise `fn` runs unlocked and only the submit takes the lock.
|
|
14750
|
+
*/
|
|
14751
|
+
withSpendLock(fn) {
|
|
14752
|
+
const run = (release) => fn(async (inputs, outputs) => {
|
|
14753
|
+
this._assertNotHeld(inputs);
|
|
14754
|
+
if (release) this._assertNotInFlight(inputs);
|
|
14755
|
+
this._addPendingSpends(inputs);
|
|
14756
|
+
release?.();
|
|
14757
|
+
try {
|
|
14758
|
+
return await (release ? this._buildAndSubmitOffchainTx(inputs, outputs, this.serverUnrollScript) : this.buildAndSubmitOffchainTx(inputs, outputs));
|
|
14759
|
+
} finally {
|
|
14760
|
+
this._removePendingSpends(inputs);
|
|
14761
|
+
}
|
|
14762
|
+
});
|
|
14763
|
+
return this._concurrentSpending ? this._withTxLock(run) : run();
|
|
14764
|
+
}
|
|
14487
14765
|
_withTxLock(fn) {
|
|
14488
14766
|
let release;
|
|
14489
14767
|
const lock = new Promise((r) => release = r);
|
|
@@ -14491,12 +14769,22 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14491
14769
|
this._txLock = lock;
|
|
14492
14770
|
return prev.then(async () => {
|
|
14493
14771
|
try {
|
|
14494
|
-
return await fn();
|
|
14772
|
+
return await fn(release);
|
|
14495
14773
|
} finally {
|
|
14496
14774
|
release();
|
|
14497
14775
|
}
|
|
14498
14776
|
});
|
|
14499
14777
|
}
|
|
14778
|
+
_assertNotInFlight(inputs) {
|
|
14779
|
+
const clashing = coinKeys(inputs).filter((key) => this._pendingSpendOutpoints.has(key));
|
|
14780
|
+
if (clashing.length > 0) throw new VtxoReservedError(clashing, "in-flight");
|
|
14781
|
+
}
|
|
14782
|
+
_assertNotHeld(inputs) {
|
|
14783
|
+
const held = coinKeys(inputs.filter(chunkVVFCCNU2_cjs.isVirtualCoin)).filter(
|
|
14784
|
+
(key) => this._heldOutpoints.has(key)
|
|
14785
|
+
);
|
|
14786
|
+
if (held.length > 0) throw new VtxoReservedError(held, "held");
|
|
14787
|
+
}
|
|
14500
14788
|
/**
|
|
14501
14789
|
* Explicitly recover this wallet's contracts and balance on a fresh repo: a gap-limit scan
|
|
14502
14790
|
* for HD wallets, the single default pubkey otherwise. Throws on operational failure (a
|
|
@@ -14530,13 +14818,13 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14530
14818
|
const manager = await this.getContractManager();
|
|
14531
14819
|
const provider = this._hdProvider;
|
|
14532
14820
|
const hd = provider !== void 0;
|
|
14533
|
-
const staticDescriptor = hd ? void 0 : await
|
|
14821
|
+
const staticDescriptor = hd ? void 0 : await chunkCFOIHLON_cjs.identityDescriptor(this.identity);
|
|
14534
14822
|
const materialize = (index) => hd ? provider.materializeDescriptorAt(index) : staticDescriptor;
|
|
14535
|
-
const delegatePubKey = this.offchainTapscript instanceof
|
|
14823
|
+
const delegatePubKey = this.offchainTapscript instanceof chunkCFOIHLON_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
|
|
14536
14824
|
const arkInfo = await this.arkProvider.getInfo();
|
|
14537
|
-
const currentSignerPubKey =
|
|
14825
|
+
const currentSignerPubKey = chunkCFOIHLON_cjs.toXOnly(base.hex.decode(arkInfo.signerPubkey), "ark signer key");
|
|
14538
14826
|
const deprecatedSignerPubKeys = arkInfo.deprecatedSigners.map(
|
|
14539
|
-
(s) =>
|
|
14827
|
+
(s) => chunkCFOIHLON_cjs.toXOnly(base.hex.decode(s.pubkey), "deprecated signer key")
|
|
14540
14828
|
);
|
|
14541
14829
|
const deps = {
|
|
14542
14830
|
indexerProvider: this.indexerProvider,
|
|
@@ -14548,7 +14836,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14548
14836
|
deprecatedSignerPubKeys,
|
|
14549
14837
|
csvTimelocks: this.walletContractTimelocks,
|
|
14550
14838
|
// Boarding-exit CSV, distinct from the unilateral-exit matrix.
|
|
14551
|
-
boardingTimelock: this.boardingTapscript.options.csvTimelock ??
|
|
14839
|
+
boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunkCFOIHLON_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
|
|
14552
14840
|
delegatePubKey
|
|
14553
14841
|
};
|
|
14554
14842
|
const result = await manager.scanContracts({
|
|
@@ -14579,6 +14867,12 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14579
14867
|
}
|
|
14580
14868
|
}
|
|
14581
14869
|
settlementConfig;
|
|
14870
|
+
_concurrentSpending = false;
|
|
14871
|
+
_submitsAwaitingFinalize = 0;
|
|
14872
|
+
/** @see WalletConfig.concurrentSpending */
|
|
14873
|
+
get concurrentSpending() {
|
|
14874
|
+
return this._concurrentSpending;
|
|
14875
|
+
}
|
|
14582
14876
|
/**
|
|
14583
14877
|
* Broadcast access bound to this wallet's server, so a plugin needs only the wallet. Not on
|
|
14584
14878
|
* {@link ReadonlyWallet}: a readonly wallet or `toReadonly()` view must not be able to submit.
|
|
@@ -14658,7 +14952,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14658
14952
|
throw new Error("Invalid configured public key");
|
|
14659
14953
|
}
|
|
14660
14954
|
const setup = await ReadonlyWallet.setupWalletConfig(config, pubkey);
|
|
14661
|
-
const forfeitPubkey =
|
|
14955
|
+
const forfeitPubkey = chunkCFOIHLON_cjs.toXOnly(base.hex.decode(setup.info.forfeitPubkey), "forfeit key");
|
|
14662
14956
|
const forfeitAddress = btcSigner.Address(setup.network).decode(setup.info.forfeitAddress);
|
|
14663
14957
|
const forfeitOutputScript = btcSigner.OutScript.encode(forfeitAddress);
|
|
14664
14958
|
const checkpointExitDelayOverrides = {
|
|
@@ -14744,6 +15038,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14744
15038
|
wallet.intentRepository = config.storage?.intentRepository;
|
|
14745
15039
|
wallet.virtualTxRepository = config.storage?.virtualTxRepository;
|
|
14746
15040
|
wallet.exitDataCapture = config.storage?.exitDataCapture;
|
|
15041
|
+
wallet._concurrentSpending = config.concurrentSpending === true;
|
|
14747
15042
|
await wallet.getVtxoManager();
|
|
14748
15043
|
return wallet;
|
|
14749
15044
|
}
|
|
@@ -14803,13 +15098,19 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14803
15098
|
* @returns The finalized Arkade transaction id
|
|
14804
15099
|
*/
|
|
14805
15100
|
async settle(params, eventCallback, hooks) {
|
|
14806
|
-
return this._withTxLock(() => {
|
|
15101
|
+
return this._withTxLock((release) => {
|
|
14807
15102
|
hooks?.onPhase?.("preparing");
|
|
14808
15103
|
const onRegistrationAttempt = hooks?.onPhase ? () => hooks.onPhase?.("registration_attempt") : void 0;
|
|
14809
|
-
return this._settleImpl(
|
|
15104
|
+
return this._settleImpl(
|
|
15105
|
+
params,
|
|
15106
|
+
eventCallback,
|
|
15107
|
+
this._concurrentSpending ? release : void 0,
|
|
15108
|
+
onRegistrationAttempt
|
|
15109
|
+
);
|
|
14810
15110
|
});
|
|
14811
15111
|
}
|
|
14812
|
-
async _settleImpl(params, eventCallback, onRegistrationAttempt) {
|
|
15112
|
+
async _settleImpl(params, eventCallback, onReserved, onRegistrationAttempt) {
|
|
15113
|
+
const picked = params === void 0 || isSdkPicked(params);
|
|
14813
15114
|
if (params?.inputs) {
|
|
14814
15115
|
for (const input of params.inputs) {
|
|
14815
15116
|
if (typeof input === "string") {
|
|
@@ -14823,13 +15124,13 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14823
15124
|
void this.logUngatedInputs("settle({ inputs })", params.inputs);
|
|
14824
15125
|
}
|
|
14825
15126
|
const offchainAddress = await this.getAddress();
|
|
14826
|
-
const offchainPkScript =
|
|
15127
|
+
const offchainPkScript = chunkVVFCCNU2_cjs.ArkAddress.decode(offchainAddress).pkScript;
|
|
14827
15128
|
const offchainOutputScript = base.hex.encode(offchainPkScript);
|
|
14828
15129
|
if (!params) {
|
|
14829
15130
|
const { fees, vtxoMaxAmount } = await this.arkProvider.getInfo();
|
|
14830
15131
|
const estimator = new Estimator(fees.intentFee);
|
|
14831
15132
|
let amount = 0;
|
|
14832
|
-
const exitScript =
|
|
15133
|
+
const exitScript = chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(
|
|
14833
15134
|
base.hex.decode(this.boardingTapscript.exitScript)
|
|
14834
15135
|
);
|
|
14835
15136
|
const boardingTimelock = exitScript.params.timelock;
|
|
@@ -14838,7 +15139,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14838
15139
|
const tip = await this.onchainProvider.getChainTip();
|
|
14839
15140
|
chainTipHeight = tip.height;
|
|
14840
15141
|
}
|
|
14841
|
-
const boardingUtxos = (await this.
|
|
15142
|
+
const boardingUtxos = (await this.getSelectableBoardingUtxos()).filter(
|
|
14842
15143
|
(utxo) => utxo.status.confirmed && !hasBoardingTxExpired(utxo, boardingTimelock, chainTipHeight)
|
|
14843
15144
|
);
|
|
14844
15145
|
const filteredBoardingUtxos = [];
|
|
@@ -14861,7 +15162,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14861
15162
|
if (filteredVtxos.length >= MAX_VTXOS_PER_SETTLEMENT) {
|
|
14862
15163
|
break;
|
|
14863
15164
|
}
|
|
14864
|
-
const inputFee = estimator.evalOffchainInput(
|
|
15165
|
+
const inputFee = estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(vtxo));
|
|
14865
15166
|
if (inputFee.satoshis >= vtxo.value) {
|
|
14866
15167
|
continue;
|
|
14867
15168
|
}
|
|
@@ -14904,6 +15205,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14904
15205
|
...params,
|
|
14905
15206
|
inputs: await refreshSweptStateOfExpiredInputs(this, params.inputs)
|
|
14906
15207
|
};
|
|
15208
|
+
if (onReserved) this._assertNotInFlight(params.inputs);
|
|
14907
15209
|
const onchainOutputIndexes = [];
|
|
14908
15210
|
const outputs = [];
|
|
14909
15211
|
let hasOffchainOutputs = false;
|
|
@@ -14912,7 +15214,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14912
15214
|
let script;
|
|
14913
15215
|
let arkAddress;
|
|
14914
15216
|
try {
|
|
14915
|
-
arkAddress =
|
|
15217
|
+
arkAddress = chunkVVFCCNU2_cjs.ArkAddress.decode(output.address);
|
|
14916
15218
|
} catch {
|
|
14917
15219
|
arkAddress = void 0;
|
|
14918
15220
|
}
|
|
@@ -14984,20 +15286,24 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
14984
15286
|
]);
|
|
14985
15287
|
let intentTxId;
|
|
14986
15288
|
try {
|
|
14987
|
-
intentTxId =
|
|
15289
|
+
intentTxId = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(intent.proof)).id;
|
|
14988
15290
|
} catch {
|
|
14989
15291
|
intentTxId = params.inputs.map((i) => `${i.txid}:${i.vout}`).sort().join("|");
|
|
14990
15292
|
}
|
|
14991
|
-
const settleInputVtxos = params.inputs.filter(
|
|
15293
|
+
const settleInputVtxos = params.inputs.filter(chunkVVFCCNU2_cjs.isVirtualCoin);
|
|
14992
15294
|
const contractManager = await this.getContractManager();
|
|
14993
15295
|
await contractManager.assertAnnotatable(settleInputVtxos);
|
|
14994
15296
|
await contractManager.assertSpendableNow?.(
|
|
14995
15297
|
settleInputVtxos,
|
|
14996
15298
|
async () => base.hex.encode(await this.identity.xOnlyPublicKey())
|
|
14997
15299
|
);
|
|
15300
|
+
if (picked) this._assertNotHeld(params.inputs);
|
|
14998
15301
|
this._addPendingSpends(params.inputs);
|
|
15302
|
+
const boardingKeys = onReserved ? coinKeys(params.inputs.filter((i) => !chunkVVFCCNU2_cjs.isVirtualCoin(i))) : [];
|
|
15303
|
+
for (const key of boardingKeys) this._pendingSpendOutpoints.add(key);
|
|
14999
15304
|
const settlingKeys = params.inputs.map((i) => `${i.txid}:${i.vout}`);
|
|
15000
15305
|
for (const key of settlingKeys) this._settlingOutpoints.add(key);
|
|
15306
|
+
onReserved?.();
|
|
15001
15307
|
await this.persistIntentSnapshot(
|
|
15002
15308
|
intentTxId,
|
|
15003
15309
|
"waiting_to_submit",
|
|
@@ -15011,6 +15317,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15011
15317
|
];
|
|
15012
15318
|
const abortController = new AbortController();
|
|
15013
15319
|
let stream;
|
|
15320
|
+
let registering = false;
|
|
15014
15321
|
let committedTxid;
|
|
15015
15322
|
try {
|
|
15016
15323
|
stream = this.arkProvider.getEventStream(abortController.signal, topics);
|
|
@@ -15024,6 +15331,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15024
15331
|
}
|
|
15025
15332
|
yield* stream;
|
|
15026
15333
|
})();
|
|
15334
|
+
registering = true;
|
|
15027
15335
|
onRegistrationAttempt?.();
|
|
15028
15336
|
const intentId = await this.safeRegisterIntent(intent, params.inputs);
|
|
15029
15337
|
await this.persistIntentSnapshot(
|
|
@@ -15064,12 +15372,15 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15064
15372
|
throw error;
|
|
15065
15373
|
}
|
|
15066
15374
|
const inputIds = params.inputs.map((i) => `${i.txid}:${i.vout}`).join(",");
|
|
15067
|
-
|
|
15068
|
-
|
|
15069
|
-
|
|
15070
|
-
|
|
15071
|
-
|
|
15072
|
-
|
|
15375
|
+
if (registering) {
|
|
15376
|
+
await this.arkProvider.deleteIntent(deleteIntent).catch((e) => {
|
|
15377
|
+
if (isNoMatchingIntentsError(e)) return;
|
|
15378
|
+
console.warn(
|
|
15379
|
+
`Failed to delete intent after settle failure for inputs [${inputIds}]; intent may linger on server and cause 'duplicated input' on next settle`,
|
|
15380
|
+
e
|
|
15381
|
+
);
|
|
15382
|
+
});
|
|
15383
|
+
}
|
|
15073
15384
|
await this.persistIntentSnapshot(
|
|
15074
15385
|
intentTxId,
|
|
15075
15386
|
"cancelled",
|
|
@@ -15083,6 +15394,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15083
15394
|
throw error;
|
|
15084
15395
|
} finally {
|
|
15085
15396
|
this._removePendingSpends(params.inputs);
|
|
15397
|
+
for (const key of boardingKeys) this._pendingSpendOutpoints.delete(key);
|
|
15086
15398
|
for (const key of settlingKeys) this._settlingOutpoints.delete(key);
|
|
15087
15399
|
abortController.abort();
|
|
15088
15400
|
await stream?.return?.().catch(() => {
|
|
@@ -15098,7 +15410,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15098
15410
|
async maybeRotateBoardingAfterBoard(inputs) {
|
|
15099
15411
|
if (!this._descriptorProvider) return;
|
|
15100
15412
|
const consumedBoarding = inputs.some(
|
|
15101
|
-
(input) => typeof input !== "string" && !
|
|
15413
|
+
(input) => typeof input !== "string" && !chunkVVFCCNU2_cjs.isVirtualCoin(input)
|
|
15102
15414
|
);
|
|
15103
15415
|
if (!consumedBoarding) return;
|
|
15104
15416
|
try {
|
|
@@ -15109,7 +15421,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15109
15421
|
}
|
|
15110
15422
|
async handleSettlementFinalizationEvent(event, inputs, forfeitOutputScript, expectedRecipients, connectorsGraph, validatedCommitmentTxid) {
|
|
15111
15423
|
const signedForfeits = [];
|
|
15112
|
-
let settlementPsbt =
|
|
15424
|
+
let settlementPsbt = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
|
|
15113
15425
|
assertFinalCommitmentMatchesValidated(
|
|
15114
15426
|
settlementPsbt,
|
|
15115
15427
|
validatedCommitmentTxid,
|
|
@@ -15122,7 +15434,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15122
15434
|
let connectorIndex = 0;
|
|
15123
15435
|
const connectorsLeaves = connectorsGraph?.leaves() || [];
|
|
15124
15436
|
for (const input of inputs) {
|
|
15125
|
-
if (!
|
|
15437
|
+
if (!chunkVVFCCNU2_cjs.isVirtualCoin(input)) {
|
|
15126
15438
|
let matched = false;
|
|
15127
15439
|
for (let i = 0; i < settlementPsbt.inputsLength; i++) {
|
|
15128
15440
|
const settlementInput = settlementPsbt.getInput(i);
|
|
@@ -15160,7 +15472,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15160
15472
|
}
|
|
15161
15473
|
continue;
|
|
15162
15474
|
}
|
|
15163
|
-
if (!
|
|
15475
|
+
if (!chunkVVFCCNU2_cjs.requiresForfeit(input) || isSubdust({ value: input.value }, this.dustAmount)) {
|
|
15164
15476
|
continue;
|
|
15165
15477
|
}
|
|
15166
15478
|
if (connectorsLeaves.length === 0) {
|
|
@@ -15188,7 +15500,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15188
15500
|
index: input.vout,
|
|
15189
15501
|
witnessUtxo: {
|
|
15190
15502
|
amount: BigInt(input.value),
|
|
15191
|
-
script:
|
|
15503
|
+
script: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
15192
15504
|
},
|
|
15193
15505
|
sighashType: btcSigner.SigHash.DEFAULT,
|
|
15194
15506
|
tapLeafScript: [input.forfeitTapLeafScript]
|
|
@@ -15207,7 +15519,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15207
15519
|
forfeitTx = await this._signerRouter.sign(forfeitTx, [
|
|
15208
15520
|
{
|
|
15209
15521
|
index: 0,
|
|
15210
|
-
lookupScript:
|
|
15522
|
+
lookupScript: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
15211
15523
|
}
|
|
15212
15524
|
]);
|
|
15213
15525
|
signedForfeits.push(base.base64.encode(forfeitTx.toPSBT()));
|
|
@@ -15265,7 +15577,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15265
15577
|
resolveBatchExpiryPolicy(this.network, this.batchExpiryPolicy)
|
|
15266
15578
|
);
|
|
15267
15579
|
await this.arkProvider.confirmRegistration(intentId);
|
|
15268
|
-
const sweepTapscript =
|
|
15580
|
+
const sweepTapscript = chunkVVFCCNU2_cjs.CSVMultisigTapscript.encode({
|
|
15269
15581
|
timelock,
|
|
15270
15582
|
pubkeys: [this.forfeitPubkey]
|
|
15271
15583
|
}).script;
|
|
@@ -15280,14 +15592,14 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15280
15592
|
throw new Error("Sweep tap tree root not set");
|
|
15281
15593
|
}
|
|
15282
15594
|
const xOnlyPublicKeys = event.cosignersPublicKeys.map(
|
|
15283
|
-
(k) => base.hex.encode(
|
|
15595
|
+
(k) => base.hex.encode(chunkCFOIHLON_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
|
|
15284
15596
|
);
|
|
15285
15597
|
const signerPublicKey = await session.getPublicKey();
|
|
15286
|
-
const xonlySignerPublicKey =
|
|
15598
|
+
const xonlySignerPublicKey = chunkCFOIHLON_cjs.toXOnly(signerPublicKey, "signer key");
|
|
15287
15599
|
if (!xOnlyPublicKeys.includes(base.hex.encode(xonlySignerPublicKey))) {
|
|
15288
15600
|
return { skip: true };
|
|
15289
15601
|
}
|
|
15290
|
-
const commitmentTx =
|
|
15602
|
+
const commitmentTx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(
|
|
15291
15603
|
base.base64.decode(event.unsignedCommitmentTx)
|
|
15292
15604
|
);
|
|
15293
15605
|
validateVtxoTxGraph(vtxoTree, commitmentTx, sweepTapTreeRoot);
|
|
@@ -15369,9 +15681,9 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15369
15681
|
...existing ?? {},
|
|
15370
15682
|
intentTxId,
|
|
15371
15683
|
registerProof: intent.proof,
|
|
15372
|
-
registerProofMessage:
|
|
15684
|
+
registerProofMessage: chunkVVFCCNU2_cjs.Intent.encodeMessage(intent.message),
|
|
15373
15685
|
deleteProof: deleteIntent.proof,
|
|
15374
|
-
deleteProofMessage:
|
|
15686
|
+
deleteProofMessage: chunkVVFCCNU2_cjs.Intent.encodeMessage(deleteIntent.message),
|
|
15375
15687
|
intentVtxos: inputs.map((i) => ({
|
|
15376
15688
|
txid: i.txid,
|
|
15377
15689
|
vout: i.vout
|
|
@@ -15404,7 +15716,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15404
15716
|
try {
|
|
15405
15717
|
return await this.arkProvider.registerIntent(intent);
|
|
15406
15718
|
} catch (error) {
|
|
15407
|
-
if (error instanceof
|
|
15719
|
+
if (error instanceof chunkVVFCCNU2_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
|
|
15408
15720
|
const deleteIntent = await this.makeDeleteIntentSignature(inputs);
|
|
15409
15721
|
await this.arkProvider.deleteIntent(deleteIntent);
|
|
15410
15722
|
return this.arkProvider.registerIntent(intent);
|
|
@@ -15420,7 +15732,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15420
15732
|
expire_at: 0,
|
|
15421
15733
|
cosigners_public_keys: cosignerPubKeys
|
|
15422
15734
|
};
|
|
15423
|
-
const proof =
|
|
15735
|
+
const proof = chunkVVFCCNU2_cjs.Intent.create(message, coins, outputs);
|
|
15424
15736
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
15425
15737
|
return {
|
|
15426
15738
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -15432,7 +15744,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15432
15744
|
type: "delete",
|
|
15433
15745
|
expire_at: 0
|
|
15434
15746
|
};
|
|
15435
|
-
const proof =
|
|
15747
|
+
const proof = chunkVVFCCNU2_cjs.Intent.create(message, coins, []);
|
|
15436
15748
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
15437
15749
|
return {
|
|
15438
15750
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -15444,7 +15756,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15444
15756
|
type: "get-pending-tx",
|
|
15445
15757
|
expire_at: 0
|
|
15446
15758
|
};
|
|
15447
|
-
const proof =
|
|
15759
|
+
const proof = chunkVVFCCNU2_cjs.Intent.create(message, coins, []);
|
|
15448
15760
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
15449
15761
|
return {
|
|
15450
15762
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -15465,7 +15777,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15465
15777
|
if (!vtxos || vtxos.length === 0) {
|
|
15466
15778
|
const scriptMap = await this.getScriptMap();
|
|
15467
15779
|
const allExtended = [];
|
|
15468
|
-
const fetchedVtxos = await
|
|
15780
|
+
const fetchedVtxos = await chunkVVFCCNU2_cjs.getAllNormalizedVtxos(this.indexerProvider, [
|
|
15469
15781
|
...scriptMap.keys()
|
|
15470
15782
|
]);
|
|
15471
15783
|
for (const vtxo of fetchedVtxos) {
|
|
@@ -15508,8 +15820,8 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15508
15820
|
batchPending.push(pendingTx.arkTxid);
|
|
15509
15821
|
try {
|
|
15510
15822
|
const checkpointTxs = pendingTx.signedCheckpointTxs.map((c) => {
|
|
15511
|
-
const tx =
|
|
15512
|
-
|
|
15823
|
+
const tx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(c));
|
|
15824
|
+
chunkVVFCCNU2_cjs.assertAllowedSighashTypes(tx);
|
|
15513
15825
|
return tx;
|
|
15514
15826
|
});
|
|
15515
15827
|
assertCheckpointsMatchInputs(
|
|
@@ -15578,11 +15890,11 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15578
15890
|
* and one per deprecated signer — else a pre-rotation tx would stay pending forever.
|
|
15579
15891
|
*/
|
|
15580
15892
|
checkpointUnrollCandidates(info) {
|
|
15581
|
-
const current =
|
|
15893
|
+
const current = chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
|
|
15582
15894
|
const candidates = [this._serverUnrollScript, current];
|
|
15583
15895
|
for (const deprecated of signerSetFromInfo(info).deprecated.keys()) {
|
|
15584
15896
|
candidates.push(
|
|
15585
|
-
|
|
15897
|
+
chunkVVFCCNU2_cjs.CSVMultisigTapscript.encode({
|
|
15586
15898
|
...current.params,
|
|
15587
15899
|
pubkeys: [base.hex.decode(deprecated)]
|
|
15588
15900
|
})
|
|
@@ -15664,6 +15976,12 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15664
15976
|
*/
|
|
15665
15977
|
async claimCash(cashStr) {
|
|
15666
15978
|
const cash = ArkadeCash.fromString(cashStr);
|
|
15979
|
+
const info = await this.arkProvider.getInfo();
|
|
15980
|
+
const signerSet = signerSetFromInfo(info);
|
|
15981
|
+
const signer = classifyAgainstSignerSet(base.hex.encode(cash.serverPubKey), signerSet);
|
|
15982
|
+
if (signer.status === "UNKNOWN_SIGNER") {
|
|
15983
|
+
throw new ArkadeCashOperatorMismatchError(signer.signerPubKey, signerSet.active);
|
|
15984
|
+
}
|
|
15667
15985
|
const cashScript = cash.vtxoScript;
|
|
15668
15986
|
const cashPkScript = base.hex.encode(cashScript.pkScript);
|
|
15669
15987
|
const scripts = [cashPkScript];
|
|
@@ -15671,7 +15989,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15671
15989
|
if (vtxos.length === 0) {
|
|
15672
15990
|
throw new Error("No VTXOs found for this arkadeCash");
|
|
15673
15991
|
}
|
|
15674
|
-
const myPkScript =
|
|
15992
|
+
const myPkScript = chunkVVFCCNU2_cjs.ArkAddress.decode(await this.getAddress()).pkScript;
|
|
15675
15993
|
let { spendable, recoverable, unclaimed } = this.classifyCashVtxos(vtxos);
|
|
15676
15994
|
let swept = 0;
|
|
15677
15995
|
const drainable = vtxos.filter(
|
|
@@ -15699,7 +16017,6 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15699
16017
|
}
|
|
15700
16018
|
}
|
|
15701
16019
|
if (spendable.length > 0) {
|
|
15702
|
-
const info = await this.arkProvider.getInfo();
|
|
15703
16020
|
const serverUnrollScript = assertValidServerUnrollScript(
|
|
15704
16021
|
info.checkpointTapscript,
|
|
15705
16022
|
resolveCheckpointExitDelayPolicy(this.network, this.checkpointExitDelayPolicy)
|
|
@@ -15798,7 +16115,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15798
16115
|
params: {
|
|
15799
16116
|
pubKey: base.hex.encode(cash.publicKey),
|
|
15800
16117
|
serverPubKey: base.hex.encode(cash.serverPubKey),
|
|
15801
|
-
csvTimelock:
|
|
16118
|
+
csvTimelock: chunkVVFCCNU2_cjs.timelockToSequence(cash.csvTimelock).toString()
|
|
15802
16119
|
},
|
|
15803
16120
|
script: base.hex.encode(cashScript.pkScript),
|
|
15804
16121
|
address: cashAddress.encode(),
|
|
@@ -15879,7 +16196,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15879
16196
|
const recoverable = [];
|
|
15880
16197
|
const unclaimed = [];
|
|
15881
16198
|
for (const vtxo of vtxos) {
|
|
15882
|
-
if (
|
|
16199
|
+
if (chunkVVFCCNU2_cjs.isVtxoSpent(vtxo)) {
|
|
15883
16200
|
unclaimed.push(cashReport(vtxo, "already-spent"));
|
|
15884
16201
|
} else if (vtxo.isUnrolled) {
|
|
15885
16202
|
unclaimed.push(cashReport(vtxo, "exited"));
|
|
@@ -15901,7 +16218,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15901
16218
|
const all = [];
|
|
15902
16219
|
const seen = /* @__PURE__ */ new Set();
|
|
15903
16220
|
for (let pageIndex = 0; ; pageIndex++) {
|
|
15904
|
-
const { vtxos, page } = await
|
|
16221
|
+
const { vtxos, page } = await chunkVVFCCNU2_cjs.getNormalizedVtxos(this.indexerProvider, {
|
|
15905
16222
|
scripts,
|
|
15906
16223
|
pageIndex,
|
|
15907
16224
|
pageSize
|
|
@@ -15939,7 +16256,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15939
16256
|
for (let i = 0; i < inputs.length; i += MAX_INPUTS_PER_INTENT) {
|
|
15940
16257
|
const batch = inputs.slice(i, i + MAX_INPUTS_PER_INTENT);
|
|
15941
16258
|
const message = { type: "get-pending-tx", expire_at: 0 };
|
|
15942
|
-
const proof =
|
|
16259
|
+
const proof = chunkVVFCCNU2_cjs.Intent.create(message, batch, []);
|
|
15943
16260
|
const signedProof = await identity.sign(
|
|
15944
16261
|
proof,
|
|
15945
16262
|
Array.from({ length: batch.length + 1 }, (_, j) => j)
|
|
@@ -15960,8 +16277,8 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
15960
16277
|
for (const pendingTx of pendingTxs) {
|
|
15961
16278
|
try {
|
|
15962
16279
|
const checkpointTxs = pendingTx.signedCheckpointTxs.map((checkpoint) => {
|
|
15963
|
-
const tx =
|
|
15964
|
-
|
|
16280
|
+
const tx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(checkpoint));
|
|
16281
|
+
chunkVVFCCNU2_cjs.assertAllowedSighashTypes(tx);
|
|
15965
16282
|
return tx;
|
|
15966
16283
|
});
|
|
15967
16284
|
assertCheckpointsMatchInputs(
|
|
@@ -16001,7 +16318,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16001
16318
|
}
|
|
16002
16319
|
/** Sum the outputs of an ark tx PSBT that pay the given scriptPubKey. */
|
|
16003
16320
|
arkTxAmountPaidTo(arkTxPsbt, pkScriptHex) {
|
|
16004
|
-
const arkTx =
|
|
16321
|
+
const arkTx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(arkTxPsbt));
|
|
16005
16322
|
let total = 0;
|
|
16006
16323
|
for (let i = 0; i < arkTx.outputsLength; i++) {
|
|
16007
16324
|
const output = arkTx.getOutput(i);
|
|
@@ -16039,9 +16356,16 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16039
16356
|
const validUntil = captureSendDeadline(params.validUntil);
|
|
16040
16357
|
const inputExpiryFloor = captureInputExpiryFloor(params.inputExpiryFloor);
|
|
16041
16358
|
assertSendDeadline(validUntil);
|
|
16042
|
-
return this._withTxLock(
|
|
16359
|
+
return this._withTxLock(
|
|
16360
|
+
(release) => this._sendImpl(
|
|
16361
|
+
params,
|
|
16362
|
+
validUntil,
|
|
16363
|
+
inputExpiryFloor,
|
|
16364
|
+
this._concurrentSpending ? release : void 0
|
|
16365
|
+
)
|
|
16366
|
+
);
|
|
16043
16367
|
}
|
|
16044
|
-
async _sendImpl({ recipients: args, selectedVtxos, maxChangeFee }, validUntil, inputExpiryFloor) {
|
|
16368
|
+
async _sendImpl({ recipients: args, selectedVtxos, maxChangeFee }, validUntil, inputExpiryFloor, onReserved) {
|
|
16045
16369
|
assertSendDeadline(validUntil);
|
|
16046
16370
|
if (args.length === 0) {
|
|
16047
16371
|
throw new Error("At least one receiver is required");
|
|
@@ -16053,7 +16377,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16053
16377
|
throw new Error("send({ maxChangeFee }): expected a non-negative safe integer");
|
|
16054
16378
|
}
|
|
16055
16379
|
if (selectedVtxos) {
|
|
16056
|
-
if (inputExpiryFloor) selectedVtxos = selectedVtxos.map(
|
|
16380
|
+
if (inputExpiryFloor) selectedVtxos = selectedVtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
|
|
16057
16381
|
if (inputExpiryFloor && selectedVtxos.some((coin) => !meetsInputExpiryFloor(coin, inputExpiryFloor))) {
|
|
16058
16382
|
throw new Error("send({ selectedVtxos }): input expiry floor not met");
|
|
16059
16383
|
}
|
|
@@ -16188,7 +16512,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16188
16512
|
script: recipient.script,
|
|
16189
16513
|
amount: BigInt(recipient.amount),
|
|
16190
16514
|
// Already checked against the recipient address in `validateRecipients`.
|
|
16191
|
-
...recipient.tapTree ? { tapTree:
|
|
16515
|
+
...recipient.tapTree ? { tapTree: chunkVVFCCNU2_cjs.toBIP371TapTree(recipient.tapTree) } : {}
|
|
16192
16516
|
}));
|
|
16193
16517
|
const totalBtcOutput = outputs.reduce((sum, o) => sum + Number(o.amount), 0);
|
|
16194
16518
|
let changeAmount = totalBtcSelected - totalBtcOutput;
|
|
@@ -16326,6 +16650,8 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16326
16650
|
serverUnrollScript,
|
|
16327
16651
|
changeAssets: changeReceiver?.assets
|
|
16328
16652
|
},
|
|
16653
|
+
onReserved,
|
|
16654
|
+
!selectedVtxos,
|
|
16329
16655
|
{ validUntil }
|
|
16330
16656
|
);
|
|
16331
16657
|
}
|
|
@@ -16333,8 +16659,11 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16333
16659
|
* Shared submit/persist tail of `send` and {@link sendSelectedVtxosToSelf}; callers own coin
|
|
16334
16660
|
* selection, outputs and the synchronous epoch snapshot.
|
|
16335
16661
|
*/
|
|
16336
|
-
async _submitOffchainSpend(inputs, outputs, persist, options) {
|
|
16662
|
+
async _submitOffchainSpend(inputs, outputs, persist, onReserved, picked = false, options) {
|
|
16663
|
+
if (picked) this._assertNotHeld(inputs);
|
|
16664
|
+
if (onReserved) this._assertNotInFlight(inputs);
|
|
16337
16665
|
this._addPendingSpends(inputs);
|
|
16666
|
+
onReserved?.();
|
|
16338
16667
|
try {
|
|
16339
16668
|
const { arkTxid, signedCheckpointTxs } = await this._buildAndSubmitOffchainTx(
|
|
16340
16669
|
inputs,
|
|
@@ -16370,15 +16699,15 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16370
16699
|
if (inputs.length === 0) {
|
|
16371
16700
|
throw new Error("sendSelectedVtxosToSelf: no inputs");
|
|
16372
16701
|
}
|
|
16373
|
-
return this._withTxLock(async () => {
|
|
16702
|
+
return this._withTxLock(async (release) => {
|
|
16374
16703
|
const offchainTapscript = this.offchainTapscript;
|
|
16375
16704
|
const serverPubKey = this.arkServerPublicKey;
|
|
16376
16705
|
const serverUnrollScript = this.serverUnrollScript;
|
|
16377
16706
|
const arkAddress = offchainTapscript.address(this.network.hrp, serverPubKey);
|
|
16378
|
-
const normalizedInputs = inputs.map(
|
|
16379
|
-
const at = now ?? await
|
|
16707
|
+
const normalizedInputs = inputs.map(chunkVVFCCNU2_cjs.normalizeVtxo);
|
|
16708
|
+
const at = now ?? await chunkVVFCCNU2_cjs.resolveTimeHeight(this.onchainProvider);
|
|
16380
16709
|
for (const input of normalizedInputs) {
|
|
16381
|
-
if (!
|
|
16710
|
+
if (!chunkVVFCCNU2_cjs.canSpendOffchain(input, at)) {
|
|
16382
16711
|
throw new Error(
|
|
16383
16712
|
`sendSelectedVtxosToSelf: input ${input.txid}:${input.vout} is not cooperatively spendable`
|
|
16384
16713
|
);
|
|
@@ -16413,16 +16742,21 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16413
16742
|
const packet = createAssetPacket(assetInputs, [], selfReceiver);
|
|
16414
16743
|
outputs.push(Extension.create([packet]).txOut());
|
|
16415
16744
|
}
|
|
16416
|
-
return this._submitOffchainSpend(
|
|
16417
|
-
|
|
16418
|
-
|
|
16419
|
-
|
|
16420
|
-
|
|
16421
|
-
|
|
16422
|
-
|
|
16423
|
-
|
|
16424
|
-
|
|
16425
|
-
|
|
16745
|
+
return this._submitOffchainSpend(
|
|
16746
|
+
normalizedInputs,
|
|
16747
|
+
outputs,
|
|
16748
|
+
{
|
|
16749
|
+
sentAmount: 0,
|
|
16750
|
+
changeAmount: total,
|
|
16751
|
+
changeVout: 0,
|
|
16752
|
+
offchainTapscript,
|
|
16753
|
+
serverPubKey,
|
|
16754
|
+
changeAssets: selfAssets,
|
|
16755
|
+
recordSentHistory: false,
|
|
16756
|
+
serverUnrollScript
|
|
16757
|
+
},
|
|
16758
|
+
this._concurrentSpending ? release : void 0
|
|
16759
|
+
);
|
|
16426
16760
|
});
|
|
16427
16761
|
}
|
|
16428
16762
|
/**
|
|
@@ -16457,7 +16791,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16457
16791
|
);
|
|
16458
16792
|
const arkTxJobs = inputs.map((input, index) => ({
|
|
16459
16793
|
index,
|
|
16460
|
-
lookupScript:
|
|
16794
|
+
lookupScript: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
16461
16795
|
}));
|
|
16462
16796
|
const identity = this.identity;
|
|
16463
16797
|
const signer = {
|
|
@@ -16493,51 +16827,63 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16493
16827
|
this.inputSigningJobsFromWitnessUtxos(checkpoint)
|
|
16494
16828
|
)
|
|
16495
16829
|
};
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
16499
|
-
|
|
16500
|
-
|
|
16501
|
-
|
|
16502
|
-
|
|
16503
|
-
|
|
16504
|
-
|
|
16505
|
-
|
|
16506
|
-
|
|
16507
|
-
|
|
16508
|
-
|
|
16509
|
-
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16514
|
-
|
|
16515
|
-
|
|
16516
|
-
|
|
16830
|
+
let awaitingFinalize = false;
|
|
16831
|
+
try {
|
|
16832
|
+
return await submitOffchainTx(
|
|
16833
|
+
this.arkProvider,
|
|
16834
|
+
offchainTx,
|
|
16835
|
+
signer,
|
|
16836
|
+
{
|
|
16837
|
+
// Mark pending before submitting — if we crash between submit and
|
|
16838
|
+
// finalize, the next init recovers via finalizePendingTxs.
|
|
16839
|
+
beforeSubmit: async () => {
|
|
16840
|
+
const ownsPendingFlag = validUntil !== void 0 && !await this.hasPendingTxFlag();
|
|
16841
|
+
this._submitsAwaitingFinalize++;
|
|
16842
|
+
awaitingFinalize = true;
|
|
16843
|
+
await this.setPendingTxFlag(true);
|
|
16844
|
+
try {
|
|
16845
|
+
assertSendDeadline(validUntil);
|
|
16846
|
+
} catch (error) {
|
|
16847
|
+
this._submitsAwaitingFinalize--;
|
|
16848
|
+
awaitingFinalize = false;
|
|
16849
|
+
if (ownsPendingFlag && this._submitsAwaitingFinalize === 0) {
|
|
16850
|
+
try {
|
|
16851
|
+
await this.setPendingTxFlag(false);
|
|
16852
|
+
} catch (clearError) {
|
|
16853
|
+
console.error(
|
|
16854
|
+
"Failed to clear pending tx flag after deadline expiry:",
|
|
16855
|
+
clearError
|
|
16856
|
+
);
|
|
16857
|
+
}
|
|
16517
16858
|
}
|
|
16859
|
+
throw error;
|
|
16860
|
+
}
|
|
16861
|
+
},
|
|
16862
|
+
afterFinalize: async () => {
|
|
16863
|
+
this._submitsAwaitingFinalize--;
|
|
16864
|
+
awaitingFinalize = false;
|
|
16865
|
+
if (this._submitsAwaitingFinalize > 0) return;
|
|
16866
|
+
try {
|
|
16867
|
+
await this.setPendingTxFlag(false);
|
|
16868
|
+
} catch (error) {
|
|
16869
|
+
console.error("Failed to clear pending tx flag:", error);
|
|
16518
16870
|
}
|
|
16519
|
-
throw error;
|
|
16520
16871
|
}
|
|
16521
16872
|
},
|
|
16522
|
-
|
|
16523
|
-
|
|
16524
|
-
|
|
16525
|
-
|
|
16526
|
-
|
|
16873
|
+
{
|
|
16874
|
+
// Deprecated keys too: a vtxo built before a rotation is still
|
|
16875
|
+
// spent under the signer its leaf names.
|
|
16876
|
+
verifyServerSignatures: {
|
|
16877
|
+
serverPubkey: this._arkServerPublicKey,
|
|
16878
|
+
deprecatedServerPubkeys: [...this._deprecatedSigners.keys()].map(
|
|
16879
|
+
(h) => base.hex.decode(h)
|
|
16880
|
+
)
|
|
16527
16881
|
}
|
|
16528
16882
|
}
|
|
16529
|
-
|
|
16530
|
-
|
|
16531
|
-
|
|
16532
|
-
|
|
16533
|
-
verifyServerSignatures: {
|
|
16534
|
-
serverPubkey: this._arkServerPublicKey,
|
|
16535
|
-
deprecatedServerPubkeys: [...this._deprecatedSigners.keys()].map(
|
|
16536
|
-
(h) => base.hex.decode(h)
|
|
16537
|
-
)
|
|
16538
|
-
}
|
|
16539
|
-
}
|
|
16540
|
-
);
|
|
16883
|
+
);
|
|
16884
|
+
} finally {
|
|
16885
|
+
if (awaitingFinalize) this._submitsAwaitingFinalize--;
|
|
16886
|
+
}
|
|
16541
16887
|
}
|
|
16542
16888
|
// Mark inputs spent and save change. `offchainTapscript`/`serverPubKey` are the caller's epoch
|
|
16543
16889
|
// snapshot, so the record matches what the server saw even if a rotation lands mid-flight.
|
|
@@ -16554,7 +16900,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16554
16900
|
}
|
|
16555
16901
|
const checkpointIdByOutpoint = /* @__PURE__ */ new Map();
|
|
16556
16902
|
for (const encoded of signedCheckpointTxs) {
|
|
16557
|
-
const checkpoint =
|
|
16903
|
+
const checkpoint = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
|
|
16558
16904
|
for (let i = 0; i < checkpoint.inputsLength; i++) {
|
|
16559
16905
|
const input = checkpoint.getInput(i);
|
|
16560
16906
|
if (!input.txid) continue;
|
|
@@ -16670,12 +17016,12 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16670
17016
|
const spentVtxos = [];
|
|
16671
17017
|
const inputArkTxIds = /* @__PURE__ */ new Set();
|
|
16672
17018
|
const boardingRemovalsByAddress = /* @__PURE__ */ new Map();
|
|
16673
|
-
const vtxoInputs = inputs.filter(
|
|
17019
|
+
const vtxoInputs = inputs.filter(chunkVVFCCNU2_cjs.isVirtualCoin);
|
|
16674
17020
|
const cm = await this.getContractManager();
|
|
16675
17021
|
const annotatedVtxos = await cm.annotateVtxos(vtxoInputs);
|
|
16676
17022
|
const annotatedByKey = new Map(annotatedVtxos.map((v) => [`${v.txid}:${v.vout}`, v]));
|
|
16677
17023
|
for (const input of inputs) {
|
|
16678
|
-
if (
|
|
17024
|
+
if (chunkVVFCCNU2_cjs.isVirtualCoin(input)) {
|
|
16679
17025
|
const outpoint = `${input.txid}:${input.vout}`;
|
|
16680
17026
|
const vtxo = annotatedByKey.get(outpoint);
|
|
16681
17027
|
if (!vtxo) {
|
|
@@ -16692,7 +17038,7 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16692
17038
|
} else {
|
|
16693
17039
|
let sourceAddress;
|
|
16694
17040
|
try {
|
|
16695
|
-
sourceAddress =
|
|
17041
|
+
sourceAddress = chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
|
|
16696
17042
|
this.network
|
|
16697
17043
|
);
|
|
16698
17044
|
} catch {
|
|
@@ -16735,13 +17081,19 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16735
17081
|
);
|
|
16736
17082
|
}
|
|
16737
17083
|
}
|
|
16738
|
-
|
|
16739
|
-
|
|
16740
|
-
|
|
16741
|
-
|
|
16742
|
-
|
|
16743
|
-
|
|
16744
|
-
|
|
17084
|
+
if (boardingRemovalsByAddress.size > 0) {
|
|
17085
|
+
await inVtxoWriteOrder(this.walletRepository, async () => {
|
|
17086
|
+
for (const [address, toRemove] of boardingRemovalsByAddress) {
|
|
17087
|
+
const currentUtxos = await collectUtxos(this.walletRepository, address);
|
|
17088
|
+
const filtered = currentUtxos.filter(
|
|
17089
|
+
(u) => !toRemove.has(`${u.txid}:${u.vout}`)
|
|
17090
|
+
);
|
|
17091
|
+
await this.walletRepository.deleteUtxos(address);
|
|
17092
|
+
if (filtered.length > 0) {
|
|
17093
|
+
await this.walletRepository.saveUtxos(address, filtered);
|
|
17094
|
+
}
|
|
17095
|
+
}
|
|
17096
|
+
});
|
|
16745
17097
|
}
|
|
16746
17098
|
} catch (e) {
|
|
16747
17099
|
console.warn("error updating repository after settle", e);
|
|
@@ -16749,15 +17101,16 @@ var Wallet2 = class extends ReadonlyWallet {
|
|
|
16749
17101
|
}
|
|
16750
17102
|
}
|
|
16751
17103
|
};
|
|
17104
|
+
function bySelectionOrder(a, b) {
|
|
17105
|
+
const expiryA = a.expiresAt?.getTime() || Number.MAX_SAFE_INTEGER;
|
|
17106
|
+
const expiryB = b.expiresAt?.getTime() || Number.MAX_SAFE_INTEGER;
|
|
17107
|
+
if (expiryA !== expiryB) {
|
|
17108
|
+
return expiryA - expiryB;
|
|
17109
|
+
}
|
|
17110
|
+
return b.value - a.value;
|
|
17111
|
+
}
|
|
16752
17112
|
function selectVirtualCoins(coins, targetAmount) {
|
|
16753
|
-
const sortedCoins = coins.map(
|
|
16754
|
-
const expiryA = a.expiresAt?.getTime() || Number.MAX_SAFE_INTEGER;
|
|
16755
|
-
const expiryB = b.expiresAt?.getTime() || Number.MAX_SAFE_INTEGER;
|
|
16756
|
-
if (expiryA !== expiryB) {
|
|
16757
|
-
return expiryA - expiryB;
|
|
16758
|
-
}
|
|
16759
|
-
return b.value - a.value;
|
|
16760
|
-
});
|
|
17113
|
+
const sortedCoins = coins.map(chunkVVFCCNU2_cjs.normalizeVtxo).sort(bySelectionOrder);
|
|
16761
17114
|
const selectedCoins = [];
|
|
16762
17115
|
let selectedAmount = 0;
|
|
16763
17116
|
for (const coin of sortedCoins) {
|
|
@@ -16785,6 +17138,18 @@ var AbortError = class extends Error {
|
|
|
16785
17138
|
this.name = "AbortError";
|
|
16786
17139
|
}
|
|
16787
17140
|
};
|
|
17141
|
+
var VtxoReservedError = class extends Error {
|
|
17142
|
+
constructor(outpoints, holder) {
|
|
17143
|
+
super(
|
|
17144
|
+
`${outpoints.join(", ")} ${holder === "held" ? "held by reserveVtxos" : "already being spent by another operation"}`
|
|
17145
|
+
);
|
|
17146
|
+
this.outpoints = outpoints;
|
|
17147
|
+
this.holder = holder;
|
|
17148
|
+
}
|
|
17149
|
+
outpoints;
|
|
17150
|
+
holder;
|
|
17151
|
+
name = "VtxoReservedError";
|
|
17152
|
+
};
|
|
16788
17153
|
function abortReason(signal) {
|
|
16789
17154
|
const { reason } = signal;
|
|
16790
17155
|
if (reason instanceof Error) return reason;
|
|
@@ -16862,7 +17227,7 @@ function assertTimeoutMap(name, timeouts) {
|
|
|
16862
17227
|
if (value === void 0) {
|
|
16863
17228
|
throw new Error(`${name}.${key} must be a non-negative safe integer`);
|
|
16864
17229
|
}
|
|
16865
|
-
|
|
17230
|
+
chunkVVFCCNU2_cjs.assertTimerMs(`${name}.${key}`, value);
|
|
16866
17231
|
}
|
|
16867
17232
|
}
|
|
16868
17233
|
var MessageBus = class {
|
|
@@ -16878,8 +17243,8 @@ var MessageBus = class {
|
|
|
16878
17243
|
}) {
|
|
16879
17244
|
this.walletRepository = walletRepository;
|
|
16880
17245
|
this.contractRepository = contractRepository;
|
|
16881
|
-
|
|
16882
|
-
|
|
17246
|
+
chunkVVFCCNU2_cjs.assertTimerMs("tickIntervalMs", tickIntervalMs);
|
|
17247
|
+
chunkVVFCCNU2_cjs.assertTimerMs("messageTimeoutMs", messageTimeoutMs);
|
|
16883
17248
|
assertTimeoutMap("messageTimeoutOverrides", messageTimeoutOverrides);
|
|
16884
17249
|
this.intentRepository = intentRepository;
|
|
16885
17250
|
this.handlers = new Map(messageHandlers.map((u) => [u.messageTag, u]));
|
|
@@ -17133,14 +17498,14 @@ var MessageBus = class {
|
|
|
17133
17498
|
this.initialized = true;
|
|
17134
17499
|
}
|
|
17135
17500
|
async buildServices(config) {
|
|
17136
|
-
const arkProvider = new
|
|
17501
|
+
const arkProvider = new chunkVVFCCNU2_cjs.RestArkProvider(config.arkServer.url);
|
|
17137
17502
|
const storage = {
|
|
17138
17503
|
walletRepository: this.walletRepository,
|
|
17139
17504
|
contractRepository: this.contractRepository,
|
|
17140
17505
|
...this.intentRepository && { intentRepository: this.intentRepository }
|
|
17141
17506
|
};
|
|
17142
17507
|
const delegateProvider = config.delegateUrl ? new RestDelegateProvider(config.delegateUrl) : void 0;
|
|
17143
|
-
const indexerProvider = new
|
|
17508
|
+
const indexerProvider = new chunkFEBAG2K2_cjs.RestIndexerProvider(config.arkServer.url);
|
|
17144
17509
|
const serialized = normalizeSerializedIdentity(config.wallet);
|
|
17145
17510
|
if (isSigningSerialized(serialized)) {
|
|
17146
17511
|
const identity2 = hydrateIdentity(serialized);
|
|
@@ -17152,6 +17517,7 @@ var MessageBus = class {
|
|
|
17152
17517
|
storage,
|
|
17153
17518
|
delegateProvider,
|
|
17154
17519
|
settlementConfig: config.settlementConfig,
|
|
17520
|
+
concurrentSpending: config.concurrentSpending,
|
|
17155
17521
|
walletMode: config.walletMode,
|
|
17156
17522
|
lazyInitialization: config.lazyInitialization,
|
|
17157
17523
|
watcherConfig: config.watcherConfig,
|
|
@@ -17480,7 +17846,7 @@ var offboardNetworkNames = [
|
|
|
17480
17846
|
function offboardDestinationScript(destinationAddress) {
|
|
17481
17847
|
for (const networkName of offboardNetworkNames) {
|
|
17482
17848
|
try {
|
|
17483
|
-
const network =
|
|
17849
|
+
const network = chunkVVFCCNU2_cjs.networks[networkName];
|
|
17484
17850
|
const addr = btcSigner.Address(network).decode(destinationAddress);
|
|
17485
17851
|
return btcSigner.OutScript.encode(addr);
|
|
17486
17852
|
} catch {
|
|
@@ -17511,12 +17877,16 @@ function reportUngatedInputs(wallet, inputs) {
|
|
|
17511
17877
|
const logger = wallet;
|
|
17512
17878
|
void logger.logUngatedInputs("Ramps.offboard({ vtxos })", inputs);
|
|
17513
17879
|
}
|
|
17880
|
+
var MAX_EXIT_PICKS = 3;
|
|
17881
|
+
function picksCovering(wallet) {
|
|
17882
|
+
return wallet.concurrentSpending === true;
|
|
17883
|
+
}
|
|
17514
17884
|
function filterOffboardInputs(vtxos, feeInfo, named) {
|
|
17515
17885
|
const estimator = new Estimator(feeInfo?.intentFee ?? {});
|
|
17516
17886
|
const inputs = [];
|
|
17517
17887
|
let subtotal = 0n;
|
|
17518
17888
|
for (const vtxo of vtxos) {
|
|
17519
|
-
const inputFee = estimator.evalOffchainInput(
|
|
17889
|
+
const inputFee = estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(vtxo));
|
|
17520
17890
|
if (inputFee.satoshis >= vtxo.value) {
|
|
17521
17891
|
if (named) {
|
|
17522
17892
|
throw new Error(
|
|
@@ -17574,7 +17944,7 @@ var Ramps = class {
|
|
|
17574
17944
|
* ```
|
|
17575
17945
|
*/
|
|
17576
17946
|
async onboard(feeInfo, boardingUtxos, amount, eventCallback) {
|
|
17577
|
-
boardingUtxos = boardingUtxos ?? await this.wallet
|
|
17947
|
+
boardingUtxos = boardingUtxos ?? await getSelectableBoardingUtxos(this.wallet);
|
|
17578
17948
|
const estimator = new Estimator(feeInfo?.intentFee ?? {});
|
|
17579
17949
|
const filteredBoardingUtxos = [];
|
|
17580
17950
|
let totalAmount = 0n;
|
|
@@ -17613,7 +17983,7 @@ var Ramps = class {
|
|
|
17613
17983
|
}
|
|
17614
17984
|
amount = amount ?? totalAmount;
|
|
17615
17985
|
const offchainAddress = await this.wallet.getAddress();
|
|
17616
|
-
const offchainAddr =
|
|
17986
|
+
const offchainAddr = chunkVVFCCNU2_cjs.ArkAddress.decode(offchainAddress);
|
|
17617
17987
|
const offchainScript = base.hex.encode(offchainAddr.pkScript);
|
|
17618
17988
|
const outputFee = estimator.evalOffchainOutput({
|
|
17619
17989
|
amount,
|
|
@@ -17668,29 +18038,39 @@ var Ramps = class {
|
|
|
17668
18038
|
* ```
|
|
17669
18039
|
*/
|
|
17670
18040
|
async offboard(destinationAddress, feeInfo, amount, eventCallback, vtxos) {
|
|
17671
|
-
|
|
17672
|
-
|
|
17673
|
-
|
|
17674
|
-
|
|
17675
|
-
|
|
17676
|
-
|
|
17677
|
-
amount
|
|
17678
|
-
|
|
17679
|
-
|
|
17680
|
-
|
|
17681
|
-
|
|
17682
|
-
|
|
17683
|
-
|
|
17684
|
-
|
|
17685
|
-
|
|
17686
|
-
|
|
18041
|
+
return this.withRepick(vtxos !== void 0, async () => {
|
|
18042
|
+
const {
|
|
18043
|
+
estimator,
|
|
18044
|
+
inputs: candidates,
|
|
18045
|
+
subtotal
|
|
18046
|
+
} = await this.offboardInputs(feeInfo, vtxos);
|
|
18047
|
+
if (amount && amount > subtotal) {
|
|
18048
|
+
throw new Error("Amount is greater than total amount of vtxos after fees");
|
|
18049
|
+
}
|
|
18050
|
+
const handed = amount || subtotal;
|
|
18051
|
+
const { inputs, change, changeAddress } = await this.fundExit(
|
|
18052
|
+
candidates,
|
|
18053
|
+
subtotal,
|
|
18054
|
+
handed,
|
|
18055
|
+
estimator,
|
|
18056
|
+
Boolean(amount) && vtxos === void 0
|
|
17687
18057
|
);
|
|
17688
|
-
|
|
17689
|
-
|
|
17690
|
-
|
|
17691
|
-
|
|
17692
|
-
|
|
17693
|
-
|
|
18058
|
+
const outputFee = estimator.evalOnchainOutput({
|
|
18059
|
+
amount: handed,
|
|
18060
|
+
script: base.hex.encode(offboardDestinationScript(destinationAddress))
|
|
18061
|
+
});
|
|
18062
|
+
if (BigInt(outputFee.satoshis) > handed) {
|
|
18063
|
+
throw new Error(
|
|
18064
|
+
`can't deduct fees from offboard amount (${outputFee.satoshis} > ${handed})`
|
|
18065
|
+
);
|
|
18066
|
+
}
|
|
18067
|
+
const outputs = [
|
|
18068
|
+
{ address: destinationAddress, amount: handed - BigInt(outputFee.satoshis) }
|
|
18069
|
+
];
|
|
18070
|
+
if (change > 0n) outputs.push({ address: changeAddress, amount: change });
|
|
18071
|
+
const params = { inputs, outputs };
|
|
18072
|
+
return this.wallet.settle(vtxos ? params : markSdkPicked(params), eventCallback);
|
|
18073
|
+
});
|
|
17694
18074
|
}
|
|
17695
18075
|
/**
|
|
17696
18076
|
* Collaboratively exit with the DESTINATION paid exactly `amount`, pricing the
|
|
@@ -17703,23 +18083,36 @@ var Ramps = class {
|
|
|
17703
18083
|
if (amount <= 0n) {
|
|
17704
18084
|
throw new Error(`offboard amount must be positive, got ${amount}`);
|
|
17705
18085
|
}
|
|
17706
|
-
|
|
17707
|
-
|
|
17708
|
-
|
|
17709
|
-
|
|
17710
|
-
|
|
17711
|
-
})
|
|
17712
|
-
|
|
17713
|
-
|
|
17714
|
-
|
|
17715
|
-
|
|
17716
|
-
|
|
18086
|
+
return this.withRepick(vtxos !== void 0, async () => {
|
|
18087
|
+
const {
|
|
18088
|
+
estimator,
|
|
18089
|
+
inputs: candidates,
|
|
18090
|
+
subtotal
|
|
18091
|
+
} = await this.offboardInputs(feeInfo, vtxos);
|
|
18092
|
+
const outputFee = BigInt(
|
|
18093
|
+
estimator.evalOnchainOutput({
|
|
18094
|
+
amount,
|
|
18095
|
+
script: base.hex.encode(offboardDestinationScript(destinationAddress))
|
|
18096
|
+
}).satoshis
|
|
17717
18097
|
);
|
|
17718
|
-
|
|
17719
|
-
|
|
17720
|
-
|
|
17721
|
-
|
|
17722
|
-
|
|
18098
|
+
const needed = amount + outputFee;
|
|
18099
|
+
if (needed > subtotal) {
|
|
18100
|
+
throw new Error(
|
|
18101
|
+
`selected vtxos net ${subtotal} sats, ${needed} needed to deliver ${amount} exactly (${amount} + a ${outputFee} sat exit fee)`
|
|
18102
|
+
);
|
|
18103
|
+
}
|
|
18104
|
+
const { inputs, change, changeAddress } = await this.fundExit(
|
|
18105
|
+
candidates,
|
|
18106
|
+
subtotal,
|
|
18107
|
+
needed,
|
|
18108
|
+
estimator,
|
|
18109
|
+
vtxos === void 0
|
|
18110
|
+
);
|
|
18111
|
+
const outputs = [{ address: destinationAddress, amount }];
|
|
18112
|
+
if (change > 0n) outputs.push({ address: changeAddress, amount: change });
|
|
18113
|
+
const params2 = { inputs, outputs };
|
|
18114
|
+
return this.wallet.settle(vtxos ? params2 : markSdkPicked(params2), eventCallback);
|
|
18115
|
+
});
|
|
17723
18116
|
}
|
|
17724
18117
|
async offboardInputs(feeInfo, vtxos) {
|
|
17725
18118
|
const named = vtxos !== void 0;
|
|
@@ -17732,12 +18125,49 @@ var Ramps = class {
|
|
|
17732
18125
|
const estimator = new Estimator(feeInfo?.intentFee ?? {});
|
|
17733
18126
|
return { estimator, ...filterOffboardInputs(spendable, feeInfo, named) };
|
|
17734
18127
|
}
|
|
18128
|
+
/** Every candidate, or with `concurrentSpending` the shortest covering prefix in send order. */
|
|
18129
|
+
async fundExit(candidates, subtotal, needed, estimator, cover) {
|
|
18130
|
+
if (!cover || !picksCovering(this.wallet)) {
|
|
18131
|
+
return { inputs: candidates, ...await this.fundChange(subtotal - needed, estimator) };
|
|
18132
|
+
}
|
|
18133
|
+
const ordered = [...candidates].sort(bySelectionOrder);
|
|
18134
|
+
let covered = 0n;
|
|
18135
|
+
for (let i = 0; i < ordered.length && i < MAX_VTXOS_PER_SETTLEMENT; i++) {
|
|
18136
|
+
const fee = estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(ordered[i])).satoshis;
|
|
18137
|
+
covered += BigInt(ordered[i].value) - BigInt(fee);
|
|
18138
|
+
if (covered < needed) continue;
|
|
18139
|
+
try {
|
|
18140
|
+
return {
|
|
18141
|
+
inputs: ordered.slice(0, i + 1),
|
|
18142
|
+
...await this.fundChange(covered - needed, estimator)
|
|
18143
|
+
};
|
|
18144
|
+
} catch (error) {
|
|
18145
|
+
if (!(error instanceof DustChangeError) || i + 1 === ordered.length) throw error;
|
|
18146
|
+
}
|
|
18147
|
+
}
|
|
18148
|
+
throw new Error(
|
|
18149
|
+
`this exit needs more than ${MAX_VTXOS_PER_SETTLEMENT} inputs; exit less, or consolidate first`
|
|
18150
|
+
);
|
|
18151
|
+
}
|
|
18152
|
+
/** Re-runs an SDK-picked exit that lost a coin to a concurrent spend. */
|
|
18153
|
+
async withRepick(named, exit) {
|
|
18154
|
+
for (let attempt = 1; ; attempt++) {
|
|
18155
|
+
try {
|
|
18156
|
+
return await exit();
|
|
18157
|
+
} catch (error) {
|
|
18158
|
+
const lostRace = error?.name === "VtxoReservedError";
|
|
18159
|
+
if (named || !lostRace || !picksCovering(this.wallet) || attempt >= MAX_EXIT_PICKS) {
|
|
18160
|
+
throw error;
|
|
18161
|
+
}
|
|
18162
|
+
}
|
|
18163
|
+
}
|
|
18164
|
+
}
|
|
17735
18165
|
/** Fund the change output: pay its own fee, then judge it against both
|
|
17736
18166
|
* server-side bounds. `0n` in is `0n` out — no change output at all. */
|
|
17737
18167
|
async fundChange(left, estimator) {
|
|
17738
18168
|
if (left <= 0n) return { change: 0n };
|
|
17739
18169
|
const changeAddress = await this.wallet.getAddress();
|
|
17740
|
-
const changeScript = base.hex.encode(
|
|
18170
|
+
const changeScript = base.hex.encode(chunkVVFCCNU2_cjs.ArkAddress.decode(changeAddress).pkScript);
|
|
17741
18171
|
const { change } = changeAfterOutputFee(
|
|
17742
18172
|
left,
|
|
17743
18173
|
(amount) => BigInt(estimator.evalOffchainOutput({ amount, script: changeScript }).satoshis)
|
|
@@ -18228,6 +18658,17 @@ var WalletMessageHandler = class {
|
|
|
18228
18658
|
payload: { contracts, filterApplied: true }
|
|
18229
18659
|
});
|
|
18230
18660
|
}
|
|
18661
|
+
case "GET_STORED_CONTRACTS_WITH_VTXOS": {
|
|
18662
|
+
const manager = await this.readonlyWallet.getContractManager();
|
|
18663
|
+
const contracts = await manager.getStoredContractsWithVtxos(
|
|
18664
|
+
message.payload.filter
|
|
18665
|
+
);
|
|
18666
|
+
return this.tagged({
|
|
18667
|
+
id,
|
|
18668
|
+
type: "STORED_CONTRACTS_WITH_VTXOS",
|
|
18669
|
+
payload: { contracts }
|
|
18670
|
+
});
|
|
18671
|
+
}
|
|
18231
18672
|
case "WATCH_SCRIPT": {
|
|
18232
18673
|
const manager = await this.readonlyWallet.getContractManager();
|
|
18233
18674
|
if (!manager.watchScript) throw unsupportedByManager("watchScript");
|
|
@@ -18651,7 +19092,7 @@ var WalletMessageHandler = class {
|
|
|
18651
19092
|
this.lazyBoardingInit = payload.lazyBoarding ?? false;
|
|
18652
19093
|
this.boardingEpoch++;
|
|
18653
19094
|
this.boardingLoaded = false;
|
|
18654
|
-
this.indexerProvider = new
|
|
19095
|
+
this.indexerProvider = new chunkFEBAG2K2_cjs.RestIndexerProvider(arkServerUrl);
|
|
18655
19096
|
await this.onWalletInitialized();
|
|
18656
19097
|
}
|
|
18657
19098
|
/** @see RequestInitWallet.payload.lazyBoarding */
|
|
@@ -19073,7 +19514,7 @@ var WalletMessageHandler = class {
|
|
|
19073
19514
|
this.readonlyWallet.getBoardingTxs()
|
|
19074
19515
|
]);
|
|
19075
19516
|
const indexerProvider = this.indexerProvider;
|
|
19076
|
-
const resolveTxCreatedAt = indexerProvider ? (txids) =>
|
|
19517
|
+
const resolveTxCreatedAt = indexerProvider ? (txids) => chunkVVFCCNU2_cjs.fetchVtxoCreatedAtByTxid(indexerProvider, txids) : void 0;
|
|
19077
19518
|
return buildTransactionHistory(
|
|
19078
19519
|
vtxos,
|
|
19079
19520
|
boardingTxs,
|
|
@@ -19142,7 +19583,7 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
|
|
|
19142
19583
|
// budget so the worker's snapshot fallback stays reachable before this
|
|
19143
19584
|
// page deadline fires — lowering it below the budget would time the page
|
|
19144
19585
|
// out while the worker is still seconds from answering from cache.
|
|
19145
|
-
GET_ARKADE_INFO:
|
|
19586
|
+
GET_ARKADE_INFO: chunkVVFCCNU2_cjs.INFO_FETCH_TIMEOUT_MS + 8e3,
|
|
19146
19587
|
INDEXER_GET_VTXOS: 2e4,
|
|
19147
19588
|
INDEXER_GET_VIRTUAL_TXS: 2e4,
|
|
19148
19589
|
GET_VTXOS: 2e4,
|
|
@@ -19151,6 +19592,7 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
|
|
|
19151
19592
|
GET_TRANSACTION_HISTORY: 2e4,
|
|
19152
19593
|
GET_CONTRACTS: 2e4,
|
|
19153
19594
|
GET_CONTRACTS_WITH_VTXOS: 2e4,
|
|
19595
|
+
GET_STORED_CONTRACTS_WITH_VTXOS: 2e4,
|
|
19154
19596
|
GET_WATCHED_SCRIPTS: 1e4,
|
|
19155
19597
|
ANNOTATE_VTXOS: 2e4,
|
|
19156
19598
|
GET_SPENDABLE_PATHS: 2e4,
|
|
@@ -19220,6 +19662,7 @@ var DEDUPABLE_REQUEST_TYPES = /* @__PURE__ */ new Set([
|
|
|
19220
19662
|
"GET_SPENDABLE_VTXOS",
|
|
19221
19663
|
"GET_CONTRACTS",
|
|
19222
19664
|
"GET_CONTRACTS_WITH_VTXOS",
|
|
19665
|
+
"GET_STORED_CONTRACTS_WITH_VTXOS",
|
|
19223
19666
|
"GET_WATCHED_SCRIPTS",
|
|
19224
19667
|
"ANNOTATE_VTXOS",
|
|
19225
19668
|
"GET_SPENDABLE_PATHS",
|
|
@@ -19283,7 +19726,7 @@ var ServiceWorkerAssetManager = class extends ServiceWorkerReadonlyAssetManager
|
|
|
19283
19726
|
}
|
|
19284
19727
|
};
|
|
19285
19728
|
var initializeMessageBus = (serviceWorker, config, timeoutMs = 2e3) => {
|
|
19286
|
-
|
|
19729
|
+
chunkVVFCCNU2_cjs.assertTimerMs("messageBusTimeoutMs", timeoutMs);
|
|
19287
19730
|
const initCmd = {
|
|
19288
19731
|
tag: "INITIALIZE_MESSAGE_BUS",
|
|
19289
19732
|
id: getRandomId(),
|
|
@@ -19371,7 +19814,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
19371
19814
|
}
|
|
19372
19815
|
/** Shared tail of both `create()` factories: boot the bus, INIT_WALLET, cache for reinit. */
|
|
19373
19816
|
static async bootstrap(wallet, options, serializedWallet, busConfig) {
|
|
19374
|
-
const arkServer = options.arkServer ?? { url:
|
|
19817
|
+
const arkServer = options.arkServer ?? { url: chunkVVFCCNU2_cjs.DEFAULT_ARKADE_SERVER_URL };
|
|
19375
19818
|
const initWalletPayload = {
|
|
19376
19819
|
lazyBoarding: options.lazyBoarding,
|
|
19377
19820
|
arkServerUrl: arkServer.url,
|
|
@@ -19381,7 +19824,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
19381
19824
|
Object.entries(options.messageTimeouts ?? {}).filter(([, ms]) => ms !== void 0)
|
|
19382
19825
|
);
|
|
19383
19826
|
for (const [key, value] of Object.entries(overrides)) {
|
|
19384
|
-
|
|
19827
|
+
chunkVVFCCNU2_cjs.assertTimerMs(`messageTimeouts.${key}`, value);
|
|
19385
19828
|
}
|
|
19386
19829
|
const messageTimeouts = {
|
|
19387
19830
|
...DEFAULT_MESSAGE_TIMEOUTS,
|
|
@@ -19721,7 +20164,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
19721
20164
|
try {
|
|
19722
20165
|
const response = await this.sendMessage(message);
|
|
19723
20166
|
const { vtxos, page } = response.payload;
|
|
19724
|
-
return { vtxos: vtxos.map(
|
|
20167
|
+
return { vtxos: vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo), page: page && { ...page } };
|
|
19725
20168
|
} catch (cause) {
|
|
19726
20169
|
throw new Error(`Failed to get vtxos: ${cause}`, { cause });
|
|
19727
20170
|
}
|
|
@@ -19825,7 +20268,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
19825
20268
|
};
|
|
19826
20269
|
try {
|
|
19827
20270
|
const response = await this.sendMessage(message);
|
|
19828
|
-
return response.payload.vtxos.map(
|
|
20271
|
+
return response.payload.vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
|
|
19829
20272
|
} catch (error) {
|
|
19830
20273
|
throw new Error(`Failed to get vtxos: ${error}`);
|
|
19831
20274
|
}
|
|
@@ -19856,7 +20299,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
19856
20299
|
"Service worker does not support the requested contract scope or freshness check"
|
|
19857
20300
|
);
|
|
19858
20301
|
}
|
|
19859
|
-
return payload.vtxos.map(
|
|
20302
|
+
return payload.vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
|
|
19860
20303
|
} catch (error) {
|
|
19861
20304
|
throw new Error(`Failed to get spendable vtxos: ${error}`);
|
|
19862
20305
|
}
|
|
@@ -19963,6 +20406,23 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
19963
20406
|
});
|
|
19964
20407
|
}
|
|
19965
20408
|
},
|
|
20409
|
+
async getStoredContractsWithVtxos(filter) {
|
|
20410
|
+
const message = {
|
|
20411
|
+
type: "GET_STORED_CONTRACTS_WITH_VTXOS",
|
|
20412
|
+
id: getRandomId(),
|
|
20413
|
+
tag: messageTag,
|
|
20414
|
+
payload: { filter }
|
|
20415
|
+
};
|
|
20416
|
+
try {
|
|
20417
|
+
const response = await sendContractMessage(message);
|
|
20418
|
+
await refreshSyncState();
|
|
20419
|
+
return response.payload.contracts;
|
|
20420
|
+
} catch (cause) {
|
|
20421
|
+
throw new Error(`Failed to get stored contracts with vtxos: ${cause}`, {
|
|
20422
|
+
cause
|
|
20423
|
+
});
|
|
20424
|
+
}
|
|
20425
|
+
},
|
|
19966
20426
|
async watchScript(script, options) {
|
|
19967
20427
|
const message = {
|
|
19968
20428
|
type: "WATCH_SCRIPT",
|
|
@@ -20034,7 +20494,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
20034
20494
|
};
|
|
20035
20495
|
try {
|
|
20036
20496
|
const response = await sendContractMessage(message);
|
|
20037
|
-
return response.payload.vtxos.map(
|
|
20497
|
+
return response.payload.vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
|
|
20038
20498
|
} catch (cause) {
|
|
20039
20499
|
throw new Error(`Failed to annotate vtxos: ${cause}`, { cause });
|
|
20040
20500
|
}
|
|
@@ -20237,6 +20697,11 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
|
|
|
20237
20697
|
_assetManager;
|
|
20238
20698
|
hasDelegate;
|
|
20239
20699
|
_restoreInFlight;
|
|
20700
|
+
_concurrentSpending = false;
|
|
20701
|
+
/** @see WalletConfig.concurrentSpending */
|
|
20702
|
+
get concurrentSpending() {
|
|
20703
|
+
return this._concurrentSpending;
|
|
20704
|
+
}
|
|
20240
20705
|
get assetManager() {
|
|
20241
20706
|
return this._assetManager;
|
|
20242
20707
|
}
|
|
@@ -20264,9 +20729,11 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
|
|
|
20264
20729
|
messageTag,
|
|
20265
20730
|
!!options.delegateUrl
|
|
20266
20731
|
);
|
|
20732
|
+
wallet._concurrentSpending = options.concurrentSpending === true;
|
|
20267
20733
|
return _ServiceWorkerWallet.bootstrap(wallet, options, serializedWallet, {
|
|
20268
20734
|
delegateUrl: options.delegateUrl,
|
|
20269
20735
|
settlementConfig: options.settlementConfig,
|
|
20736
|
+
concurrentSpending: options.concurrentSpending,
|
|
20270
20737
|
walletMode: options.walletMode,
|
|
20271
20738
|
lazyInitialization: options.lazyInitialization,
|
|
20272
20739
|
watcherConfig: options.watcherConfig,
|
|
@@ -20460,6 +20927,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
|
|
|
20460
20927
|
});
|
|
20461
20928
|
return response.payload.txid;
|
|
20462
20929
|
} catch (error) {
|
|
20930
|
+
if (error instanceof Error && error.name === "VtxoReservedError") throw error;
|
|
20463
20931
|
throw new Error(`Settlement failed: ${error}`);
|
|
20464
20932
|
}
|
|
20465
20933
|
}
|
|
@@ -20550,6 +21018,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
|
|
|
20550
21018
|
const response = await this.sendMessage(message);
|
|
20551
21019
|
return response.payload.txid;
|
|
20552
21020
|
} catch (error) {
|
|
21021
|
+
if (error instanceof Error && error.name === "VtxoReservedError") throw error;
|
|
20553
21022
|
if (error instanceof SendDeadlineExceededError) throw error;
|
|
20554
21023
|
throw new Error(`Send failed: ${error}`);
|
|
20555
21024
|
}
|
|
@@ -20653,7 +21122,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
|
|
|
20653
21122
|
};
|
|
20654
21123
|
try {
|
|
20655
21124
|
const response = await wallet.sendMessage(message);
|
|
20656
|
-
return response.payload.vtxos.map(
|
|
21125
|
+
return response.payload.vtxos.map(chunkVVFCCNU2_cjs.normalizeVtxo);
|
|
20657
21126
|
} catch (e) {
|
|
20658
21127
|
throw new Error(`Failed to get expiring vtxos: ${e}`);
|
|
20659
21128
|
}
|
|
@@ -20770,12 +21239,12 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
20770
21239
|
* @returns Configured onchain wallet
|
|
20771
21240
|
* @throws Error if the configured identity cannot produce a valid x-only public key
|
|
20772
21241
|
*/
|
|
20773
|
-
static async create(identity, networkName =
|
|
21242
|
+
static async create(identity, networkName = chunkVVFCCNU2_cjs.DEFAULT_NETWORK_NAME, provider) {
|
|
20774
21243
|
const pubkey = await identity.xOnlyPublicKey();
|
|
20775
21244
|
if (!pubkey) {
|
|
20776
21245
|
throw new Error("Invalid configured public key");
|
|
20777
21246
|
}
|
|
20778
|
-
const network =
|
|
21247
|
+
const network = chunkVVFCCNU2_cjs.getNetwork(networkName);
|
|
20779
21248
|
const onchainProvider = provider || new EsploraProvider(ESPLORA_URL[networkName]);
|
|
20780
21249
|
const onchainP2TR = btcSigner.p2tr(pubkey, void 0, network);
|
|
20781
21250
|
return new _OnchainWallet(identity, network, onchainP2TR, onchainProvider);
|
|
@@ -20875,7 +21344,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
20875
21344
|
feeRate,
|
|
20876
21345
|
params.address
|
|
20877
21346
|
);
|
|
20878
|
-
let tx = new
|
|
21347
|
+
let tx = new chunkVVFCCNU2_cjs.Transaction();
|
|
20879
21348
|
for (const input of inputs) {
|
|
20880
21349
|
tx.addInput({
|
|
20881
21350
|
txid: input.txid,
|
|
@@ -20933,7 +21402,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
20933
21402
|
* @throws If the parent has no anchor, or funding cannot be selected/signed
|
|
20934
21403
|
*/
|
|
20935
21404
|
async bumpAnchor(parentHex, feeRate) {
|
|
20936
|
-
const parent =
|
|
21405
|
+
const parent = chunkVVFCCNU2_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
|
|
20937
21406
|
const coins = (await this.getCoins()).filter((c) => c.status.confirmed);
|
|
20938
21407
|
const child = await this.buildBumpPackage(parent, feeRate, coins);
|
|
20939
21408
|
return [parent.hex, child.hex];
|
|
@@ -21749,7 +22218,7 @@ var CachingArkProvider = class {
|
|
|
21749
22218
|
constructor(inner, ttlMs = DEFAULT_TTL_MS) {
|
|
21750
22219
|
this.inner = inner;
|
|
21751
22220
|
this.ttlMs = ttlMs;
|
|
21752
|
-
|
|
22221
|
+
chunkVVFCCNU2_cjs.assertNonNegativeMs("ttlMs", ttlMs);
|
|
21753
22222
|
this.unsubscribe = inner.onServerInfoChanged?.((info) => {
|
|
21754
22223
|
this.cached = info;
|
|
21755
22224
|
this.expiresAt = Date.now() + this.ttlMs;
|
|
@@ -21841,7 +22310,7 @@ async function resolvePrevTxs(txids, source, onchain) {
|
|
|
21841
22310
|
try {
|
|
21842
22311
|
const { txs } = await source.getVirtualTxs(wanted);
|
|
21843
22312
|
for (const psbt of txs) {
|
|
21844
|
-
const tx =
|
|
22313
|
+
const tx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbt));
|
|
21845
22314
|
resolved.set(tx.id, tx.toBytes());
|
|
21846
22315
|
}
|
|
21847
22316
|
} catch (err) {
|
|
@@ -21874,7 +22343,7 @@ async function resolvePrevTxs(txids, source, onchain) {
|
|
|
21874
22343
|
async function attachPrevArkTxs(tx, txids, source, onchain) {
|
|
21875
22344
|
const pending = [];
|
|
21876
22345
|
for (let i = 0; i < tx.inputsLength; i++) {
|
|
21877
|
-
if (
|
|
22346
|
+
if (chunkVVFCCNU2_cjs.getArkPsbtFields(tx, i, chunkVVFCCNU2_cjs.PrevArkTxField).length === 0) pending.push(i);
|
|
21878
22347
|
}
|
|
21879
22348
|
if (pending.length === 0) return;
|
|
21880
22349
|
const resolved = await resolvePrevTxs(
|
|
@@ -21883,13 +22352,13 @@ async function attachPrevArkTxs(tx, txids, source, onchain) {
|
|
|
21883
22352
|
onchain
|
|
21884
22353
|
);
|
|
21885
22354
|
for (const i of pending) {
|
|
21886
|
-
|
|
22355
|
+
chunkVVFCCNU2_cjs.setArkPsbtField(tx, i, chunkVVFCCNU2_cjs.PrevArkTxField, resolved.get(txidAt(txids, i)));
|
|
21887
22356
|
}
|
|
21888
22357
|
}
|
|
21889
22358
|
async function attachPrevoutTxs(tx, source) {
|
|
21890
22359
|
const pending = [];
|
|
21891
22360
|
for (let i = 0; i < tx.inputsLength; i++) {
|
|
21892
|
-
if (
|
|
22361
|
+
if (chunkVVFCCNU2_cjs.getArkPsbtFields(tx, i, chunkVVFCCNU2_cjs.PrevoutTxField).length > 0) continue;
|
|
21893
22362
|
const input = tx.getInput(i);
|
|
21894
22363
|
if (!input?.txid) throw new PrevTxUnavailableError(`input ${i} has no outpoint`);
|
|
21895
22364
|
pending.push({ index: i, txid: base.hex.encode(input.txid) });
|
|
@@ -21900,7 +22369,7 @@ async function attachPrevoutTxs(tx, source) {
|
|
|
21900
22369
|
resolved.set(txid, await source.getRawTransaction(txid));
|
|
21901
22370
|
}
|
|
21902
22371
|
for (const { index, txid } of pending) {
|
|
21903
|
-
|
|
22372
|
+
chunkVVFCCNU2_cjs.setArkPsbtField(tx, index, chunkVVFCCNU2_cjs.PrevoutTxField, resolved.get(txid));
|
|
21904
22373
|
}
|
|
21905
22374
|
}
|
|
21906
22375
|
async function withPrevTxs(coins, source, onchain) {
|
|
@@ -21926,7 +22395,7 @@ exports.BIP322 = void 0;
|
|
|
21926
22395
|
async function sign2(message, identity, network) {
|
|
21927
22396
|
const xOnlyPubKey = await identity.xOnlyPublicKey();
|
|
21928
22397
|
const payment = btcSigner.p2tr(xOnlyPubKey, void 0, network);
|
|
21929
|
-
const toSpend =
|
|
22398
|
+
const toSpend = chunkVVFCCNU2_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
|
|
21930
22399
|
const toSign = craftBIP322ToSignP2TR(toSpend, payment.script, xOnlyPubKey);
|
|
21931
22400
|
const signed = await identity.sign(toSign, [0]);
|
|
21932
22401
|
signed.finalizeIdx(0);
|
|
@@ -21984,7 +22453,7 @@ function verifyP2TR(message, witnessItems, pkScript, pubkey) {
|
|
|
21984
22453
|
if (sighashType !== btcSigner.SigHash.DEFAULT && sighashType !== btcSigner.SigHash.ALL) {
|
|
21985
22454
|
return false;
|
|
21986
22455
|
}
|
|
21987
|
-
const toSpend =
|
|
22456
|
+
const toSpend = chunkVVFCCNU2_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
|
|
21988
22457
|
const toSign = craftBIP322ToSignP2TR(toSpend, pkScript);
|
|
21989
22458
|
const sighash = toSign.preimageWitnessV1(0, [pkScript], sighashType, [0n]);
|
|
21990
22459
|
const rawSig = sig.length === 65 ? sig.subarray(0, 64) : sig;
|
|
@@ -22005,7 +22474,7 @@ function verifyP2WPKH(message, witnessItems, pkScript, addressHash) {
|
|
|
22005
22474
|
}
|
|
22006
22475
|
const sighashType = sigWithHash[sigWithHash.length - 1];
|
|
22007
22476
|
const derSig = sigWithHash.subarray(0, sigWithHash.length - 1);
|
|
22008
|
-
const toSpend =
|
|
22477
|
+
const toSpend = chunkVVFCCNU2_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
|
|
22009
22478
|
const toSign = craftBIP322ToSignSimple(toSpend, pkScript);
|
|
22010
22479
|
const scriptCode = btcSigner.OutScript.encode({ type: "pkh", hash: addressHash });
|
|
22011
22480
|
const sighash = toSign.preimageWitnessV0(0, scriptCode, sighashType, 0n);
|
|
@@ -22058,7 +22527,7 @@ function encodeCompactSize(n) {
|
|
|
22058
22527
|
return buf;
|
|
22059
22528
|
}
|
|
22060
22529
|
function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
|
|
22061
|
-
const tx = new
|
|
22530
|
+
const tx = new chunkVVFCCNU2_cjs.Transaction({ version: 0 });
|
|
22062
22531
|
tx.addInput({
|
|
22063
22532
|
txid: toSpend.id,
|
|
22064
22533
|
index: 0,
|
|
@@ -22072,12 +22541,12 @@ function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
|
|
|
22072
22541
|
});
|
|
22073
22542
|
tx.addOutput({
|
|
22074
22543
|
amount: 0n,
|
|
22075
|
-
script:
|
|
22544
|
+
script: chunkVVFCCNU2_cjs.OP_RETURN_EMPTY_PKSCRIPT
|
|
22076
22545
|
});
|
|
22077
22546
|
return tx;
|
|
22078
22547
|
}
|
|
22079
22548
|
function craftBIP322ToSignSimple(toSpend, pkScript) {
|
|
22080
|
-
const tx = new
|
|
22549
|
+
const tx = new chunkVVFCCNU2_cjs.Transaction({ version: 0 });
|
|
22081
22550
|
tx.addInput({
|
|
22082
22551
|
txid: toSpend.id,
|
|
22083
22552
|
index: 0,
|
|
@@ -22089,7 +22558,7 @@ function craftBIP322ToSignSimple(toSpend, pkScript) {
|
|
|
22089
22558
|
});
|
|
22090
22559
|
tx.addOutput({
|
|
22091
22560
|
amount: 0n,
|
|
22092
|
-
script:
|
|
22561
|
+
script: chunkVVFCCNU2_cjs.OP_RETURN_EMPTY_PKSCRIPT
|
|
22093
22562
|
});
|
|
22094
22563
|
return tx;
|
|
22095
22564
|
}
|
|
@@ -22102,7 +22571,7 @@ var RestEmulatorProvider = class {
|
|
|
22102
22571
|
serverUrl;
|
|
22103
22572
|
async getInfo() {
|
|
22104
22573
|
const url = `${this.serverUrl}/v1/info`;
|
|
22105
|
-
const response = await
|
|
22574
|
+
const response = await chunkVVFCCNU2_cjs.baseFetch(url);
|
|
22106
22575
|
if (!response.ok) {
|
|
22107
22576
|
const errorText2 = await response.text();
|
|
22108
22577
|
throw new Error(`Failed to get emulator info: ${errorText2}`);
|
|
@@ -22220,7 +22689,7 @@ var RestEmulatorProvider = class {
|
|
|
22220
22689
|
}
|
|
22221
22690
|
};
|
|
22222
22691
|
function finalizeVirtualTx(type, psbtBase64) {
|
|
22223
|
-
const tx =
|
|
22692
|
+
const tx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
|
|
22224
22693
|
if (type === "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */) {
|
|
22225
22694
|
const input = tx.getInput(0);
|
|
22226
22695
|
if (!input) {
|
|
@@ -22247,14 +22716,14 @@ var ExitPathError = class extends Error {
|
|
|
22247
22716
|
reason;
|
|
22248
22717
|
};
|
|
22249
22718
|
function delayWeight(sequence) {
|
|
22250
|
-
const t =
|
|
22719
|
+
const t = chunkVVFCCNU2_cjs.sequenceToTimelock(sequence);
|
|
22251
22720
|
return t.type === "blocks" ? Number(t.value) : Number(t.value) / 600;
|
|
22252
22721
|
}
|
|
22253
22722
|
async function resolveUnilateralPath(params) {
|
|
22254
22723
|
const { vtxo, scriptHex, contractRepository } = params;
|
|
22255
22724
|
const contract = contractRepository ? (await collectContracts(contractRepository, { script: scriptHex }))[0] : void 0;
|
|
22256
22725
|
if (contract) {
|
|
22257
|
-
const handler =
|
|
22726
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
|
|
22258
22727
|
if (!handler) {
|
|
22259
22728
|
throw new ExitPathError(
|
|
22260
22729
|
"no-handler",
|
|
@@ -22276,12 +22745,12 @@ async function resolveUnilateralPath(params) {
|
|
|
22276
22745
|
paths.sort((a, b) => delayWeight(a.sequence) - delayWeight(b.sequence));
|
|
22277
22746
|
return { selection: paths[0], label: `${contract.type}:unilateral` };
|
|
22278
22747
|
}
|
|
22279
|
-
const decoded =
|
|
22748
|
+
const decoded = chunkVVFCCNU2_cjs.VtxoScript.decode(vtxo.tapTree);
|
|
22280
22749
|
let best;
|
|
22281
22750
|
for (const exit of decoded.exitPaths()) {
|
|
22282
22751
|
const leaf = decoded.findLeaf(base.hex.encode(exit.script));
|
|
22283
22752
|
if (!leaf) continue;
|
|
22284
|
-
const sequence =
|
|
22753
|
+
const sequence = chunkVVFCCNU2_cjs.timelockToSequence(exit.params.timelock);
|
|
22285
22754
|
const weight = delayWeight(sequence);
|
|
22286
22755
|
if (!best || weight < best.weight) {
|
|
22287
22756
|
best = { selection: { leaf, sequence }, weight };
|
|
@@ -22488,7 +22957,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
22488
22957
|
const txWeightEstimator = TxWeightEstimator.create();
|
|
22489
22958
|
const walletDescriptor = base.hex.encode(await wallet.identity.xOnlyPublicKey());
|
|
22490
22959
|
for (const vtxo of vtxos) {
|
|
22491
|
-
if (!
|
|
22960
|
+
if (!chunkVVFCCNU2_cjs.canSweepOnchain(vtxo)) {
|
|
22492
22961
|
throw new Error(
|
|
22493
22962
|
`Vtxo ${vtxo.txid}:${vtxo.vout} cannot be swept onchain: it is not fully unrolled (use unroll first), or its exit output was already spent`
|
|
22494
22963
|
);
|
|
@@ -22499,14 +22968,14 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
22499
22968
|
}
|
|
22500
22969
|
const resolved = await resolveUnilateralPath({
|
|
22501
22970
|
vtxo,
|
|
22502
|
-
scriptHex: base.hex.encode(
|
|
22971
|
+
scriptHex: base.hex.encode(chunkVVFCCNU2_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
|
|
22503
22972
|
contractRepository: wallet.contractRepository,
|
|
22504
22973
|
walletDescriptor,
|
|
22505
22974
|
currentTime: Date.now()
|
|
22506
22975
|
});
|
|
22507
22976
|
const spendingLeaf = resolved.selection.leaf;
|
|
22508
22977
|
const sequence = resolved.selection.sequence;
|
|
22509
|
-
const timelock =
|
|
22978
|
+
const timelock = chunkVVFCCNU2_cjs.sequenceToTimelock(sequence);
|
|
22510
22979
|
const elapsed = timelock.type === "blocks" ? chainTip.height >= txStatus.blockHeight + Number(timelock.value) : chainTip.time >= txStatus.blockTime + Number(timelock.value);
|
|
22511
22980
|
if (!elapsed) {
|
|
22512
22981
|
throw new Error(`no available exit path found for vtxo ${vtxo.txid}:${vtxo.vout}`);
|
|
@@ -22519,7 +22988,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
22519
22988
|
sequence,
|
|
22520
22989
|
witnessUtxo: {
|
|
22521
22990
|
amount: BigInt(vtxo.value),
|
|
22522
|
-
script:
|
|
22991
|
+
script: chunkVVFCCNU2_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
|
|
22523
22992
|
},
|
|
22524
22993
|
sighashType: btcSigner.SigHash.DEFAULT
|
|
22525
22994
|
});
|
|
@@ -22529,7 +22998,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
22529
22998
|
btcSigner.TaprootControlBlock.encode(spendingLeaf[0]).length
|
|
22530
22999
|
);
|
|
22531
23000
|
}
|
|
22532
|
-
const tx = new
|
|
23001
|
+
const tx = new chunkVVFCCNU2_cjs.Transaction({ version: 2 });
|
|
22533
23002
|
for (const input of inputs) {
|
|
22534
23003
|
tx.addInput(input);
|
|
22535
23004
|
}
|
|
@@ -22612,7 +23081,7 @@ async function buildSignedSweep(params) {
|
|
|
22612
23081
|
`uneconomic vtxo ${vtxo.txid}:${vtxo.vout}: value ${vtxo.value} - fee ${fee} < dust`
|
|
22613
23082
|
);
|
|
22614
23083
|
}
|
|
22615
|
-
const tx = new
|
|
23084
|
+
const tx = new chunkVVFCCNU2_cjs.Transaction({ version: 2 });
|
|
22616
23085
|
tx.addInput({
|
|
22617
23086
|
txid: vtxo.txid,
|
|
22618
23087
|
index: vtxo.vout,
|
|
@@ -22637,7 +23106,7 @@ async function buildSignedSweep(params) {
|
|
|
22637
23106
|
finalScriptWitness: [
|
|
22638
23107
|
tapScriptSig[0][1],
|
|
22639
23108
|
...path.extraWitness,
|
|
22640
|
-
|
|
23109
|
+
chunkVVFCCNU2_cjs.scriptFromTapLeafScript(path.leaf),
|
|
22641
23110
|
btcSigner.TaprootControlBlock.encode(controlBlock)
|
|
22642
23111
|
]
|
|
22643
23112
|
});
|
|
@@ -22667,7 +23136,7 @@ async function resolveFeeRate(opts) {
|
|
|
22667
23136
|
}
|
|
22668
23137
|
async function selectExitVtxos(opts) {
|
|
22669
23138
|
if (!opts.vtxos) return opts.wallet.getVtxos();
|
|
22670
|
-
const res = await
|
|
23139
|
+
const res = await chunkVVFCCNU2_cjs.getNormalizedVtxos(opts.wallet.indexerProvider, { outpoints: opts.vtxos });
|
|
22671
23140
|
const tapTrees = /* @__PURE__ */ new Map();
|
|
22672
23141
|
const out = [];
|
|
22673
23142
|
for (const vtxo of res.vtxos) {
|
|
@@ -22682,7 +23151,7 @@ async function selectExitVtxos(opts) {
|
|
|
22682
23151
|
`no contract registered for vtxo script ${vtxo.script} \u2014 register the contract before exiting`
|
|
22683
23152
|
);
|
|
22684
23153
|
}
|
|
22685
|
-
const handler =
|
|
23154
|
+
const handler = chunkCFOIHLON_cjs.contractHandlers.get(contract.type);
|
|
22686
23155
|
if (!handler) {
|
|
22687
23156
|
throw new Error(`no contract handler registered for type '${contract.type}'`);
|
|
22688
23157
|
}
|
|
@@ -22712,7 +23181,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
22712
23181
|
if (pendingNodes.length > 0) {
|
|
22713
23182
|
const txs = await resolver.getVirtualTxs(pendingNodes.map((n) => n.txid));
|
|
22714
23183
|
for (const psbt of txs) {
|
|
22715
|
-
psbts.set(
|
|
23184
|
+
psbts.set(chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
22716
23185
|
}
|
|
22717
23186
|
}
|
|
22718
23187
|
const childVsize = Number(
|
|
@@ -22740,7 +23209,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
22740
23209
|
try {
|
|
22741
23210
|
const resolved = await resolveUnilateralPath({
|
|
22742
23211
|
vtxo,
|
|
22743
|
-
scriptHex: base.hex.encode(
|
|
23212
|
+
scriptHex: base.hex.encode(chunkVVFCCNU2_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
|
|
22744
23213
|
contractRepository: wallet.contractRepository,
|
|
22745
23214
|
walletDescriptor,
|
|
22746
23215
|
currentTime: Date.now()
|
|
@@ -22759,7 +23228,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
22759
23228
|
});
|
|
22760
23229
|
continue;
|
|
22761
23230
|
}
|
|
22762
|
-
const t =
|
|
23231
|
+
const t = chunkVVFCCNU2_cjs.sequenceToTimelock(resolved.selection.sequence);
|
|
22763
23232
|
const delay = { type: t.type, value: Number(t.value) };
|
|
22764
23233
|
infos.push({ outpoint, value: vtxo.value, sweepFee, path: resolved.label, delay });
|
|
22765
23234
|
sweeps.push({ vtxo, resolved, sweepFee, delay });
|
|
@@ -22866,7 +23335,7 @@ var Executor = class {
|
|
|
22866
23335
|
constructor(pkg, provider, opts) {
|
|
22867
23336
|
this.pkg = pkg;
|
|
22868
23337
|
this.provider = provider;
|
|
22869
|
-
|
|
23338
|
+
chunkVVFCCNU2_cjs.assertTimerMs("pollIntervalMs", opts?.pollIntervalMs);
|
|
22870
23339
|
this.pollIntervalMs = opts?.pollIntervalMs ?? 5e3;
|
|
22871
23340
|
this.feeWallet = opts?.feeWallet;
|
|
22872
23341
|
this.signal = opts?.signal;
|
|
@@ -23161,7 +23630,7 @@ async function prepare(opts) {
|
|
|
23161
23630
|
txid: sweep.vtxo.txid,
|
|
23162
23631
|
vout: sweep.vtxo.vout,
|
|
23163
23632
|
value: sweep.vtxo.value,
|
|
23164
|
-
pkScript:
|
|
23633
|
+
pkScript: chunkVVFCCNU2_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
|
|
23165
23634
|
},
|
|
23166
23635
|
path: sweep.resolved.selection,
|
|
23167
23636
|
outputAddress: opts.sweepAddress,
|
|
@@ -23250,7 +23719,7 @@ async function prepare(opts) {
|
|
|
23250
23719
|
if (newFee <= splitterFee) break;
|
|
23251
23720
|
splitterFee = newFee;
|
|
23252
23721
|
}
|
|
23253
|
-
const splitter = new
|
|
23722
|
+
const splitter = new chunkVVFCCNU2_cjs.Transaction({ version: 2 });
|
|
23254
23723
|
for (const coin of selected.inputs) {
|
|
23255
23724
|
splitter.addInput({
|
|
23256
23725
|
txid: coin.txid,
|
|
@@ -23389,44 +23858,44 @@ var UnilateralExit = {
|
|
|
23389
23858
|
|
|
23390
23859
|
// src/arkade/index.ts
|
|
23391
23860
|
var arkade_exports = {};
|
|
23392
|
-
|
|
23393
|
-
ARKADE_OP: () =>
|
|
23394
|
-
ARKADE_OPCODES: () =>
|
|
23395
|
-
ARKADE_OPCODE_NAMES: () =>
|
|
23396
|
-
ARKADE_OPCODE_VALUES: () =>
|
|
23397
|
-
ARKADE_OPS: () =>
|
|
23861
|
+
chunkVVFCCNU2_cjs.__export(arkade_exports, {
|
|
23862
|
+
ARKADE_OP: () => chunkCFOIHLON_cjs.ARKADE_OP,
|
|
23863
|
+
ARKADE_OPCODES: () => chunkCFOIHLON_cjs.ARKADE_OPCODES,
|
|
23864
|
+
ARKADE_OPCODE_NAMES: () => chunkCFOIHLON_cjs.ARKADE_OPCODE_NAMES,
|
|
23865
|
+
ARKADE_OPCODE_VALUES: () => chunkCFOIHLON_cjs.ARKADE_OPCODE_VALUES,
|
|
23866
|
+
ARKADE_OPS: () => chunkCFOIHLON_cjs.ARKADE_OPS,
|
|
23398
23867
|
Arkade: () => Arkade,
|
|
23399
23868
|
ArkadeContract: () => ArkadeContract,
|
|
23400
|
-
ArkadeProgramScript: () =>
|
|
23401
|
-
ArkadeScript: () =>
|
|
23869
|
+
ArkadeProgramScript: () => chunkCFOIHLON_cjs.ArkadeProgramScript,
|
|
23870
|
+
ArkadeScript: () => chunkCFOIHLON_cjs.ArkadeScript,
|
|
23402
23871
|
ArkadeTransactionBuilder: () => ArkadeTransactionBuilder,
|
|
23403
|
-
BigNum: () =>
|
|
23872
|
+
BigNum: () => chunkCFOIHLON_cjs.bignum_exports,
|
|
23404
23873
|
OP: () => btcSigner.OP,
|
|
23405
|
-
OPCODE_NAMES: () =>
|
|
23406
|
-
OPCODE_VALUES: () =>
|
|
23407
|
-
SUPPORTED_PROGRAM_VERSION: () =>
|
|
23874
|
+
OPCODE_NAMES: () => chunkCFOIHLON_cjs.OPCODE_NAMES,
|
|
23875
|
+
OPCODE_VALUES: () => chunkCFOIHLON_cjs.OPCODE_VALUES,
|
|
23876
|
+
SUPPORTED_PROGRAM_VERSION: () => chunkCFOIHLON_cjs.SUPPORTED_PROGRAM_VERSION,
|
|
23408
23877
|
Script: () => btcSigner.Script,
|
|
23409
|
-
arkadeScriptHash: () =>
|
|
23410
|
-
arkadeWitnessHash: () =>
|
|
23411
|
-
asmToBytes: () =>
|
|
23412
|
-
bytesToASM: () =>
|
|
23413
|
-
computeArkadeScriptPublicKey: () =>
|
|
23878
|
+
arkadeScriptHash: () => chunkCFOIHLON_cjs.arkadeScriptHash,
|
|
23879
|
+
arkadeWitnessHash: () => chunkCFOIHLON_cjs.arkadeWitnessHash,
|
|
23880
|
+
asmToBytes: () => chunkCFOIHLON_cjs.asmToBytes,
|
|
23881
|
+
bytesToASM: () => chunkCFOIHLON_cjs.bytesToASM,
|
|
23882
|
+
computeArkadeScriptPublicKey: () => chunkCFOIHLON_cjs.computeArkadeScriptPublicKey,
|
|
23414
23883
|
createArkadeBatchHandler: () => createArkadeBatchHandler,
|
|
23415
|
-
deserializeArkadeContractParams: () =>
|
|
23416
|
-
fromASM: () =>
|
|
23417
|
-
getOpcodeName: () =>
|
|
23418
|
-
getOpcodeValue: () =>
|
|
23884
|
+
deserializeArkadeContractParams: () => chunkCFOIHLON_cjs.deserializeArkadeContractParams,
|
|
23885
|
+
fromASM: () => chunkCFOIHLON_cjs.fromASM,
|
|
23886
|
+
getOpcodeName: () => chunkCFOIHLON_cjs.getOpcodeName,
|
|
23887
|
+
getOpcodeValue: () => chunkCFOIHLON_cjs.getOpcodeValue,
|
|
23419
23888
|
isContractArtifact: () => isContractArtifact,
|
|
23420
|
-
parseArtifact: () =>
|
|
23889
|
+
parseArtifact: () => chunkCFOIHLON_cjs.parseArtifact,
|
|
23421
23890
|
programFromArtifact: () => programFromArtifact,
|
|
23422
|
-
resolveAsm: () =>
|
|
23423
|
-
serializeArkadeContractParams: () =>
|
|
23424
|
-
stringifyArtifact: () =>
|
|
23425
|
-
toASM: () =>
|
|
23426
|
-
validateProgram: () =>
|
|
23427
|
-
witnessRefToBytes: () =>
|
|
23891
|
+
resolveAsm: () => chunkCFOIHLON_cjs.resolveAsm,
|
|
23892
|
+
serializeArkadeContractParams: () => chunkCFOIHLON_cjs.serializeArkadeContractParams,
|
|
23893
|
+
stringifyArtifact: () => chunkCFOIHLON_cjs.stringifyArtifact,
|
|
23894
|
+
toASM: () => chunkCFOIHLON_cjs.toASM,
|
|
23895
|
+
validateProgram: () => chunkCFOIHLON_cjs.validateProgram,
|
|
23896
|
+
witnessRefToBytes: () => chunkCFOIHLON_cjs.witnessRefToBytes
|
|
23428
23897
|
});
|
|
23429
|
-
var isVtxoCoin = (input) =>
|
|
23898
|
+
var isVtxoCoin = (input) => chunkVVFCCNU2_cjs.isVirtualCoin(input);
|
|
23430
23899
|
function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message, session, arkProvider, emulator, network, recipients, batchExpiryPolicy) {
|
|
23431
23900
|
let batchId;
|
|
23432
23901
|
let sweepTapTreeRoot;
|
|
@@ -23447,23 +23916,23 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
|
|
|
23447
23916
|
);
|
|
23448
23917
|
await arkProvider.confirmRegistration(intentId);
|
|
23449
23918
|
batchId = event.id;
|
|
23450
|
-
const sweepTapscript =
|
|
23919
|
+
const sweepTapscript = chunkVVFCCNU2_cjs.CSVMultisigTapscript.encode({
|
|
23451
23920
|
timelock,
|
|
23452
|
-
pubkeys: [
|
|
23921
|
+
pubkeys: [chunkCFOIHLON_cjs.toXOnly(base.hex.decode(info.forfeitPubkey), "forfeit key")]
|
|
23453
23922
|
}).script;
|
|
23454
23923
|
sweepTapTreeRoot = payment_js.tapLeafHash(sweepTapscript);
|
|
23455
23924
|
return { skip: false };
|
|
23456
23925
|
},
|
|
23457
23926
|
onTreeSigningStarted: async (event, vtxoTree) => {
|
|
23458
23927
|
const signerPubKey = await session.getPublicKey();
|
|
23459
|
-
const xonlySignerPubKey =
|
|
23928
|
+
const xonlySignerPubKey = chunkCFOIHLON_cjs.toXOnly(signerPubKey, "signer key");
|
|
23460
23929
|
const xOnlyPubkeys = event.cosignersPublicKeys.map(
|
|
23461
|
-
(k) => base.hex.encode(
|
|
23930
|
+
(k) => base.hex.encode(chunkCFOIHLON_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
|
|
23462
23931
|
);
|
|
23463
23932
|
if (!xOnlyPubkeys.includes(base.hex.encode(xonlySignerPubKey))) {
|
|
23464
23933
|
return { skip: true };
|
|
23465
23934
|
}
|
|
23466
|
-
const commitmentTx =
|
|
23935
|
+
const commitmentTx = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(event.unsignedCommitmentTx));
|
|
23467
23936
|
validateVtxoTxGraph(vtxoTree, commitmentTx, sweepTapTreeRoot);
|
|
23468
23937
|
if (recipients && recipients.length > 0) {
|
|
23469
23938
|
validateBatchRecipients(commitmentTx, vtxoTree.leaves(), recipients, network);
|
|
@@ -23501,7 +23970,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
|
|
|
23501
23970
|
if (connectorTree) {
|
|
23502
23971
|
validateConnectorsTxGraph(event.commitmentTx, connectorTree);
|
|
23503
23972
|
}
|
|
23504
|
-
let commitmentPsbt =
|
|
23973
|
+
let commitmentPsbt = chunkVVFCCNU2_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
|
|
23505
23974
|
assertFinalCommitmentMatchesValidated(
|
|
23506
23975
|
commitmentPsbt,
|
|
23507
23976
|
validatedCommitmentTxid,
|
|
@@ -23543,7 +24012,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
|
|
|
23543
24012
|
boardingIndices.push(boardingIdx);
|
|
23544
24013
|
continue;
|
|
23545
24014
|
}
|
|
23546
|
-
if (!
|
|
24015
|
+
if (!chunkVVFCCNU2_cjs.requiresForfeit(input) || isSubdust(input, info.dust)) {
|
|
23547
24016
|
continue;
|
|
23548
24017
|
}
|
|
23549
24018
|
if (connectorIndex >= connectorLeaves.length) {
|
|
@@ -23564,7 +24033,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
|
|
|
23564
24033
|
index: input.vout,
|
|
23565
24034
|
witnessUtxo: {
|
|
23566
24035
|
amount: BigInt(input.value),
|
|
23567
|
-
script:
|
|
24036
|
+
script: chunkVVFCCNU2_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
23568
24037
|
},
|
|
23569
24038
|
sighashType: btcSigner.SigHash.DEFAULT,
|
|
23570
24039
|
tapLeafScript: [input.forfeitTapLeafScript]
|
|
@@ -23709,7 +24178,7 @@ function flatten(param, structs, stack = []) {
|
|
|
23709
24178
|
function opcodeToken(token) {
|
|
23710
24179
|
const base = token.slice(3);
|
|
23711
24180
|
const name = base === "0" || /^([1-9]|1[0-6])$/.test(base) ? token : base;
|
|
23712
|
-
if (!Object.hasOwn(
|
|
24181
|
+
if (!Object.hasOwn(chunkCFOIHLON_cjs.ARKADE_OPS, name)) {
|
|
23713
24182
|
fail(`opcode '${token}' is not in this SDK's table`);
|
|
23714
24183
|
}
|
|
23715
24184
|
return name;
|
|
@@ -23756,7 +24225,7 @@ function providedWitness(witness) {
|
|
|
23756
24225
|
}
|
|
23757
24226
|
function csvTimelock(leafName, operand) {
|
|
23758
24227
|
if (typeof operand === "string") return { type: "sequence", value: operand };
|
|
23759
|
-
const timelock =
|
|
24228
|
+
const timelock = chunkVVFCCNU2_cjs.sequenceToCanonicalTimelock(operand);
|
|
23760
24229
|
if (!timelock) {
|
|
23761
24230
|
fail(`leaf '${leafName}': CSV literal ${operand} is not a canonical BIP68 sequence`);
|
|
23762
24231
|
}
|
|
@@ -23875,7 +24344,7 @@ function programFromArtifact(artifact) {
|
|
|
23875
24344
|
const paramNames = /* @__PURE__ */ new Set();
|
|
23876
24345
|
for (const param of params) claim(paramNames, param.name, "program parameter");
|
|
23877
24346
|
return {
|
|
23878
|
-
version:
|
|
24347
|
+
version: chunkCFOIHLON_cjs.SUPPORTED_PROGRAM_VERSION,
|
|
23879
24348
|
name: artifact.contractName,
|
|
23880
24349
|
params,
|
|
23881
24350
|
functions
|
|
@@ -23916,16 +24385,16 @@ var Arkade = class _Arkade {
|
|
|
23916
24385
|
/** Connect and resolve the server key, checkpoint closure and (if present) the co-signer key. */
|
|
23917
24386
|
static async connect(opts) {
|
|
23918
24387
|
const info = await opts.arkade.getInfo();
|
|
23919
|
-
const serverKey =
|
|
23920
|
-
const checkpoint =
|
|
23921
|
-
const network = opts.network ?? (Object.hasOwn(
|
|
24388
|
+
const serverKey = chunkCFOIHLON_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
|
|
24389
|
+
const checkpoint = chunkVVFCCNU2_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
|
|
24390
|
+
const network = opts.network ?? (Object.hasOwn(chunkVVFCCNU2_cjs.networks, info.network) ? chunkVVFCCNU2_cjs.getNetwork(info.network) : chunkVVFCCNU2_cjs.DEFAULT_NETWORK);
|
|
23922
24391
|
let emulatorKey;
|
|
23923
24392
|
if (opts.emulator) {
|
|
23924
|
-
emulatorKey = base.hex.decode(
|
|
24393
|
+
emulatorKey = base.hex.decode(chunkVVFCCNU2_cjs.resolveEmulatorPubkey(network, opts.emulatorPubkey));
|
|
23925
24394
|
}
|
|
23926
24395
|
let userKey;
|
|
23927
24396
|
if (opts.identity) {
|
|
23928
|
-
userKey =
|
|
24397
|
+
userKey = chunkCFOIHLON_cjs.toXOnly(await opts.identity.xOnlyPublicKey(), "identity key");
|
|
23929
24398
|
}
|
|
23930
24399
|
return new _Arkade({
|
|
23931
24400
|
arkProvider: opts.arkade,
|
|
@@ -23948,7 +24417,7 @@ var Arkade = class _Arkade {
|
|
|
23948
24417
|
* explicit args win.
|
|
23949
24418
|
*/
|
|
23950
24419
|
contract(program, args = {}) {
|
|
23951
|
-
const declared = (program.params ?? []).map(
|
|
24420
|
+
const declared = (program.params ?? []).map(chunkCFOIHLON_cjs.inputName);
|
|
23952
24421
|
if (declared.includes("server") && args.server === void 0) {
|
|
23953
24422
|
args = { ...args, server: this.serverKey };
|
|
23954
24423
|
}
|
|
@@ -23968,7 +24437,7 @@ var ArkadeContract = class _ArkadeContract {
|
|
|
23968
24437
|
userKey: client.userKey,
|
|
23969
24438
|
emulatorKey: client.emulatorKey
|
|
23970
24439
|
};
|
|
23971
|
-
this.vtxoScript = new
|
|
24440
|
+
this.vtxoScript = new chunkCFOIHLON_cjs.ArkadeProgramScript(program, args, this.keys);
|
|
23972
24441
|
this.tapTree = this.vtxoScript.encode();
|
|
23973
24442
|
this.compiled = this.vtxoScript.compiled;
|
|
23974
24443
|
}
|
|
@@ -23993,7 +24462,7 @@ var ArkadeContract = class _ArkadeContract {
|
|
|
23993
24462
|
`ArkadeContract.fromContract: expected contract type 'arkade', got '${contract.type}'`
|
|
23994
24463
|
);
|
|
23995
24464
|
}
|
|
23996
|
-
const typed =
|
|
24465
|
+
const typed = chunkCFOIHLON_cjs.deserializeArkadeContractParams(contract.params);
|
|
23997
24466
|
return new _ArkadeContract(client, typed.program, typed.args, {
|
|
23998
24467
|
serverKey: typed.serverKey,
|
|
23999
24468
|
userKey: typed.userKey,
|
|
@@ -24029,7 +24498,7 @@ var ArkadeContract = class _ArkadeContract {
|
|
|
24029
24498
|
toContractParams() {
|
|
24030
24499
|
return {
|
|
24031
24500
|
type: "arkade",
|
|
24032
|
-
params:
|
|
24501
|
+
params: chunkCFOIHLON_cjs.serializeArkadeContractParams({
|
|
24033
24502
|
program: this.program,
|
|
24034
24503
|
args: this.args,
|
|
24035
24504
|
serverKey: this.keys.serverKey,
|
|
@@ -24069,17 +24538,17 @@ var ArkadeContract = class _ArkadeContract {
|
|
|
24069
24538
|
const [registered] = await manager.getContracts({ script: scriptHex });
|
|
24070
24539
|
if (registered) {
|
|
24071
24540
|
const [withVtxos] = await manager.getContractsWithVtxos({ script: scriptHex });
|
|
24072
|
-
return (withVtxos?.vtxos ?? []).filter((v) => !
|
|
24541
|
+
return (withVtxos?.vtxos ?? []).filter((v) => !chunkVVFCCNU2_cjs.isVtxoSpent(v) && !v.isUnrolled);
|
|
24073
24542
|
}
|
|
24074
24543
|
}
|
|
24075
24544
|
if (!this.client.indexer) {
|
|
24076
24545
|
throw new Error("ArkadeContract.getUtxos: an indexer is required");
|
|
24077
24546
|
}
|
|
24078
|
-
const { vtxos } = await
|
|
24547
|
+
const { vtxos } = await chunkVVFCCNU2_cjs.getNormalizedVtxos(this.client.indexer, {
|
|
24079
24548
|
scripts: [scriptHex],
|
|
24080
24549
|
spendableOnly: true
|
|
24081
24550
|
});
|
|
24082
|
-
return vtxos.filter((v) => !
|
|
24551
|
+
return vtxos.filter((v) => !chunkVVFCCNU2_cjs.isVtxoSpent(v) && !v.isUnrolled);
|
|
24083
24552
|
}
|
|
24084
24553
|
/** Total spendable balance (requires an indexer). */
|
|
24085
24554
|
async getBalance() {
|
|
@@ -24183,7 +24652,7 @@ var ArkadeTransactionBuilder = class {
|
|
|
24183
24652
|
this.contract.client.checkpoint
|
|
24184
24653
|
);
|
|
24185
24654
|
if (coin.sourceTx) {
|
|
24186
|
-
|
|
24655
|
+
chunkVVFCCNU2_cjs.setArkPsbtField(arkTx, 0, chunkVVFCCNU2_cjs.PrevArkTxField, coin.sourceTx);
|
|
24187
24656
|
}
|
|
24188
24657
|
if (this.fn.arkadeScript) {
|
|
24189
24658
|
const indexer = this.contract.client.indexer;
|
|
@@ -24200,8 +24669,8 @@ var ArkadeTransactionBuilder = class {
|
|
|
24200
24669
|
}
|
|
24201
24670
|
const condition = (def.tapscript.witness ?? []).map((w) => this.witnessBytes(w));
|
|
24202
24671
|
if (condition.length > 0) {
|
|
24203
|
-
|
|
24204
|
-
|
|
24672
|
+
chunkVVFCCNU2_cjs.setArkPsbtField(arkTx, 0, chunkVVFCCNU2_cjs.ConditionWitness, condition);
|
|
24673
|
+
chunkVVFCCNU2_cjs.setArkPsbtField(checkpoints[0], 0, chunkVVFCCNU2_cjs.ConditionWitness, condition);
|
|
24205
24674
|
}
|
|
24206
24675
|
const packets = [];
|
|
24207
24676
|
if (this.assetSpecs.length > 0) {
|
|
@@ -24231,22 +24700,9 @@ var ArkadeTransactionBuilder = class {
|
|
|
24231
24700
|
if (!client.emulator) {
|
|
24232
24701
|
throw new Error("covenant spends require an `emulator` on the Arkade client");
|
|
24233
24702
|
}
|
|
24234
|
-
|
|
24235
|
-
|
|
24236
|
-
|
|
24237
|
-
(c, i) => userInputs.includes(i) ? client.identity.sign(c, [0]) : c
|
|
24238
|
-
)
|
|
24239
|
-
) : checkpoints;
|
|
24240
|
-
const res2 = await client.emulator.submitTx(
|
|
24241
|
-
base.base64.encode(signedArk2.toPSBT()),
|
|
24242
|
-
signedCps.map((c) => base.base64.encode(c.toPSBT()))
|
|
24243
|
-
);
|
|
24244
|
-
const txid = chunk65CTZR2O_cjs.Transaction.fromPSBT(base.base64.decode(res2.signedArkTx)).id;
|
|
24245
|
-
return {
|
|
24246
|
-
txid,
|
|
24247
|
-
signedArkTx: res2.signedArkTx,
|
|
24248
|
-
signedCheckpointTxs: res2.signedCheckpointTxs
|
|
24249
|
-
};
|
|
24703
|
+
return submitViaEmulator(client.emulator, { arkTx, checkpoints }, client.identity, {
|
|
24704
|
+
inputIndexes: userInputs
|
|
24705
|
+
});
|
|
24250
24706
|
}
|
|
24251
24707
|
if (!client.identity) {
|
|
24252
24708
|
throw new Error("a signing identity is required for non-covenant spends");
|
|
@@ -24306,23 +24762,23 @@ var ArkadeTransactionBuilder = class {
|
|
|
24306
24762
|
}
|
|
24307
24763
|
buildAssetPacket() {
|
|
24308
24764
|
const groups = this.assetSpecs.map((s) => {
|
|
24309
|
-
const id = typeof s.assetId === "string" ?
|
|
24310
|
-
return
|
|
24765
|
+
const id = typeof s.assetId === "string" ? chunkFEBAG2K2_cjs.AssetId.fromString(s.assetId) : chunkFEBAG2K2_cjs.AssetId.fromBytes(s.assetId);
|
|
24766
|
+
return chunkFEBAG2K2_cjs.AssetGroup.create(
|
|
24311
24767
|
id,
|
|
24312
24768
|
null,
|
|
24313
|
-
s.inputs.map((i) =>
|
|
24314
|
-
s.outputs.map((o) =>
|
|
24315
|
-
(s.metadata ?? []).map((m) =>
|
|
24769
|
+
s.inputs.map((i) => chunkFEBAG2K2_cjs.AssetInput.create(i.vin, i.amount)),
|
|
24770
|
+
s.outputs.map((o) => chunkFEBAG2K2_cjs.AssetOutput.create(o.vout, o.amount)),
|
|
24771
|
+
(s.metadata ?? []).map((m) => chunkFEBAG2K2_cjs.Metadata.create(m.key, m.value))
|
|
24316
24772
|
);
|
|
24317
24773
|
});
|
|
24318
|
-
return
|
|
24774
|
+
return chunkFEBAG2K2_cjs.Packet.create(groups);
|
|
24319
24775
|
}
|
|
24320
24776
|
witnessBytes(ref) {
|
|
24321
|
-
return
|
|
24777
|
+
return chunkCFOIHLON_cjs.witnessRefToBytes(ref, this.args, this.contract.args);
|
|
24322
24778
|
}
|
|
24323
24779
|
};
|
|
24324
24780
|
function bindInputs(fn, callArgs) {
|
|
24325
|
-
const names = (fn.def.inputs ?? []).map(
|
|
24781
|
+
const names = (fn.def.inputs ?? []).map(chunkCFOIHLON_cjs.inputName);
|
|
24326
24782
|
if (callArgs.length !== names.length) {
|
|
24327
24783
|
throw new Error(`${fn.name}: expected ${names.length} argument(s), got ${callArgs.length}`);
|
|
24328
24784
|
}
|
|
@@ -24736,17 +25192,17 @@ var walletFeeSource = (wallet) => async () => (await wallet.arkProvider.getInfo(
|
|
|
24736
25192
|
function offchainInputFees(vtxos, fees) {
|
|
24737
25193
|
const estimator = new Estimator(fees?.intentFee ?? {});
|
|
24738
25194
|
return vtxos.reduce(
|
|
24739
|
-
(total, vtxo) => total + estimator.evalOffchainInput(
|
|
25195
|
+
(total, vtxo) => total + estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(vtxo)).satoshis,
|
|
24740
25196
|
0
|
|
24741
25197
|
);
|
|
24742
25198
|
}
|
|
24743
25199
|
async function changeOutputFee(wallet, inputs, needed, fees) {
|
|
24744
25200
|
const estimator = new Estimator(fees?.intentFee ?? {});
|
|
24745
25201
|
const net = inputs.reduce(
|
|
24746
|
-
(total, vtxo) => total + BigInt(vtxo.value) - BigInt(estimator.evalOffchainInput(
|
|
25202
|
+
(total, vtxo) => total + BigInt(vtxo.value) - BigInt(estimator.evalOffchainInput(chunkVVFCCNU2_cjs.toOffchainInputFeeParams(vtxo)).satoshis),
|
|
24747
25203
|
0n
|
|
24748
25204
|
);
|
|
24749
|
-
const script = base.hex.encode(
|
|
25205
|
+
const script = base.hex.encode(chunkVVFCCNU2_cjs.ArkAddress.decode(await wallet.getAddress()).pkScript);
|
|
24750
25206
|
return changeAfterOutputFee(
|
|
24751
25207
|
net - needed,
|
|
24752
25208
|
(amount) => BigInt(estimator.evalOffchainOutput({ amount, script }).satoshis)
|
|
@@ -24822,6 +25278,7 @@ exports.AmbiguousRouteError = AmbiguousRouteError;
|
|
|
24822
25278
|
exports.ArkNote = ArkNote;
|
|
24823
25279
|
exports.ArkadeCash = ArkadeCash;
|
|
24824
25280
|
exports.ArkadeCashCreateError = ArkadeCashCreateError;
|
|
25281
|
+
exports.ArkadeCashOperatorMismatchError = ArkadeCashOperatorMismatchError;
|
|
24825
25282
|
exports.AssetManager = AssetManager;
|
|
24826
25283
|
exports.BIP21 = BIP21;
|
|
24827
25284
|
exports.BIP21Error = BIP21Error;
|
|
@@ -24901,6 +25358,7 @@ exports.UnannotatableInputError = UnannotatableInputError;
|
|
|
24901
25358
|
exports.UnilateralExit = UnilateralExit;
|
|
24902
25359
|
exports.UnknownPacket = UnknownPacket;
|
|
24903
25360
|
exports.VtxoManager = VtxoManager;
|
|
25361
|
+
exports.VtxoReservedError = VtxoReservedError;
|
|
24904
25362
|
exports.Wallet = Wallet2;
|
|
24905
25363
|
exports.WalletCannotAllocateAddressError = WalletCannotAllocateAddressError;
|
|
24906
25364
|
exports.WalletCannotSignError = WalletCannotSignError;
|
|
@@ -25040,6 +25498,7 @@ exports.signAndSubmitOffchainTx = signAndSubmitOffchainTx;
|
|
|
25040
25498
|
exports.signerSetFromInfo = signerSetFromInfo;
|
|
25041
25499
|
exports.signingDescriptorIndex = signingDescriptorIndex;
|
|
25042
25500
|
exports.strictSigningDescriptorIndex = strictSigningDescriptorIndex;
|
|
25501
|
+
exports.submitViaEmulator = submitViaEmulator;
|
|
25043
25502
|
exports.toXOnlySignerHex = toXOnlySignerHex;
|
|
25044
25503
|
exports.tryResolveSendAmount = tryResolveSendAmount;
|
|
25045
25504
|
exports.utxoEntries = utxoEntries;
|
|
@@ -25051,5 +25510,5 @@ exports.waitForIncomingFunds = waitForIncomingFunds;
|
|
|
25051
25510
|
exports.walletFeeSource = walletFeeSource;
|
|
25052
25511
|
exports.warnAndFilterVtxosForScript = warnAndFilterVtxosForScript;
|
|
25053
25512
|
exports.withPrevTxs = withPrevTxs;
|
|
25054
|
-
//# sourceMappingURL=chunk-
|
|
25055
|
-
//# sourceMappingURL=chunk-
|
|
25513
|
+
//# sourceMappingURL=chunk-B2YMUJD5.cjs.map
|
|
25514
|
+
//# sourceMappingURL=chunk-B2YMUJD5.cjs.map
|