@arkade-os/sdk 0.4.65 → 0.4.67
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 +66 -15
- package/dist/adapters/expo.cjs +5 -5
- package/dist/adapters/expo.d.cts +3 -6
- package/dist/adapters/expo.d.ts +3 -6
- package/dist/adapters/expo.js +3 -3
- package/dist/adapters/indexedDB.cjs +5 -5
- package/dist/adapters/indexedDB.js +4 -4
- package/dist/{asyncStorageTaskQueue-Chwe60Ce.d.cts → asyncStorageTaskQueue-LTpeXYaD.d.cts} +2 -2
- package/dist/{asyncStorageTaskQueue-Dq_UcvDx.d.ts → asyncStorageTaskQueue-Za-e_zMk.d.ts} +2 -2
- package/dist/{chunk-G552MISJ.cjs → chunk-2JV4VQ7C.cjs} +56 -28
- package/dist/chunk-2JV4VQ7C.cjs.map +1 -0
- package/dist/{chunk-TFSVXMTM.js → chunk-3WIWNE4P.js} +56 -29
- package/dist/chunk-3WIWNE4P.js.map +1 -0
- package/dist/{chunk-XMOIRDLF.js → chunk-6TAQF6EV.js} +118 -16
- package/dist/chunk-6TAQF6EV.js.map +1 -0
- package/dist/{chunk-5YTSQSLE.js → chunk-AEWJU6NZ.js} +1033 -193
- package/dist/chunk-AEWJU6NZ.js.map +1 -0
- package/dist/{chunk-XN55B6EP.cjs → chunk-CO3KKSWM.cjs} +46 -19
- package/dist/chunk-CO3KKSWM.cjs.map +1 -0
- package/dist/{chunk-RESN6QHP.js → chunk-EALWOVHK.js} +4 -4
- package/dist/{chunk-RESN6QHP.js.map → chunk-EALWOVHK.js.map} +1 -1
- package/dist/{chunk-GFZNEMGL.cjs → chunk-MJUTO3PY.cjs} +1425 -574
- package/dist/chunk-MJUTO3PY.cjs.map +1 -0
- package/dist/{chunk-TYTPVPKD.js → chunk-MZFUZUTQ.js} +4 -4
- package/dist/{chunk-TYTPVPKD.js.map → chunk-MZFUZUTQ.js.map} +1 -1
- package/dist/{chunk-BABJ77NG.cjs → chunk-OIZ2V2VD.cjs} +163 -60
- package/dist/chunk-OIZ2V2VD.cjs.map +1 -0
- package/dist/{chunk-SJQM5AVB.cjs → chunk-R2YAMONM.cjs} +17 -17
- package/dist/{chunk-SJQM5AVB.cjs.map → chunk-R2YAMONM.cjs.map} +1 -1
- package/dist/{chunk-3G5V564P.js → chunk-X3VEMUVV.js} +32 -6
- package/dist/chunk-X3VEMUVV.js.map +1 -0
- package/dist/{chunk-7X744EFF.cjs → chunk-YDRZDZPP.cjs} +10 -10
- package/dist/{chunk-7X744EFF.cjs.map → chunk-YDRZDZPP.cjs.map} +1 -1
- 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-BBQW61ym.d.cts → delegate-Bz2e2zXY.d.cts} +1 -1
- package/dist/{delegate-Dv_9OVHv.d.ts → delegate-cdmzb2f9.d.ts} +1 -1
- package/dist/{wallet-DJUnN939.d.ts → hdWalletCapable-BSjuUYOO.d.cts} +319 -128
- package/dist/{wallet-C2NvHjWB.d.cts → hdWalletCapable-Hi12xjCJ.d.ts} +319 -128
- package/dist/{index-fDDiA1-L.d.ts → index-BiACuWaf.d.ts} +109 -13
- package/dist/{index-BtTtQFUX.d.cts → index-D2GjZxBr.d.cts} +109 -13
- package/dist/{index-CFOMyVMt.d.cts → index-DU5o_hz7.d.cts} +275 -51
- package/dist/{index-CFOMyVMt.d.ts → index-DU5o_hz7.d.ts} +275 -51
- package/dist/index.cjs +328 -276
- package/dist/index.d.cts +312 -41
- package/dist/index.d.ts +312 -41
- package/dist/index.js +4 -4
- package/dist/repositories/realm/index.cjs +19 -19
- 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 +18 -18
- 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-CIKOS2OO.d.cts → taskRunner-BZJMLQ6g.d.cts} +2 -2
- package/dist/{taskRunner-BDzWbpct.d.ts → taskRunner-DATaRQus.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 +18 -14
- package/dist/wallet/expo/index.cjs.map +1 -1
- package/dist/wallet/expo/index.d.cts +7 -5
- package/dist/wallet/expo/index.d.ts +7 -5
- package/dist/wallet/expo/index.js +10 -6
- package/dist/wallet/expo/index.js.map +1 -1
- 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 +3 -3
- package/dist/chunk-3G5V564P.js.map +0 -1
- package/dist/chunk-5YTSQSLE.js.map +0 -1
- package/dist/chunk-BABJ77NG.cjs.map +0 -1
- package/dist/chunk-G552MISJ.cjs.map +0 -1
- package/dist/chunk-GFZNEMGL.cjs.map +0 -1
- package/dist/chunk-TFSVXMTM.js.map +0 -1
- package/dist/chunk-XMOIRDLF.js.map +0 -1
- package/dist/chunk-XN55B6EP.cjs.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunkCO3KKSWM_cjs = require('./chunk-CO3KKSWM.cjs');
|
|
4
|
+
var chunkOIZ2V2VD_cjs = require('./chunk-OIZ2V2VD.cjs');
|
|
5
|
+
var chunk2JV4VQ7C_cjs = require('./chunk-2JV4VQ7C.cjs');
|
|
6
6
|
var chunk5BLDMQED_cjs = require('./chunk-5BLDMQED.cjs');
|
|
7
7
|
var utils_js = require('@scure/btc-signer/utils.js');
|
|
8
8
|
var btcSigner = require('@scure/btc-signer');
|
|
@@ -188,7 +188,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
188
188
|
noncesByPubkey.set(base.hex.encode(myPublicKey.subarray(1)), myNonce);
|
|
189
189
|
const tx = this.graph.find(txid);
|
|
190
190
|
if (!tx) throw new Error(`missing tx for txid ${txid}`);
|
|
191
|
-
const cosigners =
|
|
191
|
+
const cosigners = chunk2JV4VQ7C_cjs.getArkPsbtFields(tx.root, 0, chunk2JV4VQ7C_cjs.CosignerPublicKey).map(
|
|
192
192
|
(c) => base.hex.encode(c.key.subarray(1))
|
|
193
193
|
// xonly pubkey
|
|
194
194
|
);
|
|
@@ -240,7 +240,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
240
240
|
if (!aggNonce) throw new Error("missing aggregate nonce");
|
|
241
241
|
const prevoutAmounts = [];
|
|
242
242
|
const prevoutScripts = [];
|
|
243
|
-
const cosigners =
|
|
243
|
+
const cosigners = chunk2JV4VQ7C_cjs.getArkPsbtFields(g.root, 0, chunk2JV4VQ7C_cjs.CosignerPublicKey).map((c) => c.key);
|
|
244
244
|
const { finalKey } = aggregateKeys(cosigners, true, {
|
|
245
245
|
taprootTweak: this.scriptRoot
|
|
246
246
|
});
|
|
@@ -431,7 +431,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
431
431
|
let network;
|
|
432
432
|
if ("descriptor" in opts && typeof opts.descriptor === "string") {
|
|
433
433
|
descriptor = opts.descriptor;
|
|
434
|
-
network =
|
|
434
|
+
network = chunkOIZ2V2VD_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
435
435
|
} else {
|
|
436
436
|
network = opts.isMainnet ?? true ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
437
437
|
descriptor = descriptorsScure.scriptExpressions.trBIP32({
|
|
@@ -529,7 +529,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
529
529
|
* `StaticDescriptorProvider` for legacy single-key wallets.
|
|
530
530
|
*/
|
|
531
531
|
isOurs(descriptor) {
|
|
532
|
-
return
|
|
532
|
+
return chunkOIZ2V2VD_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
|
|
533
533
|
}
|
|
534
534
|
/**
|
|
535
535
|
* Signs each request with the key derived from its descriptor.
|
|
@@ -578,7 +578,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
578
578
|
}
|
|
579
579
|
// ── internal helpers ─────────────────────────────────────────────
|
|
580
580
|
derivePrivateKeyForDescriptor(descriptor) {
|
|
581
|
-
const network =
|
|
581
|
+
const network = chunkOIZ2V2VD_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
582
582
|
const expansion = descriptorsScure.expand({ descriptor, network });
|
|
583
583
|
if (expansion.isRanged) {
|
|
584
584
|
throw new Error(
|
|
@@ -664,7 +664,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
|
|
|
664
664
|
*/
|
|
665
665
|
descriptor;
|
|
666
666
|
constructor(descriptor) {
|
|
667
|
-
const network =
|
|
667
|
+
const network = chunkOIZ2V2VD_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
668
668
|
let expansion;
|
|
669
669
|
try {
|
|
670
670
|
expansion = descriptorsScure.expand({ descriptor, network, index: 0 });
|
|
@@ -714,7 +714,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
|
|
|
714
714
|
* `StaticDescriptorProvider` for legacy single-key wallets.
|
|
715
715
|
*/
|
|
716
716
|
isOurs(descriptor) {
|
|
717
|
-
return
|
|
717
|
+
return chunkOIZ2V2VD_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
|
|
718
718
|
}
|
|
719
719
|
};
|
|
720
720
|
function serializeSeedOwnedSigningIdentity(identity) {
|
|
@@ -876,10 +876,10 @@ var DescriptorIdentity = class {
|
|
|
876
876
|
this.base = base;
|
|
877
877
|
}
|
|
878
878
|
async xOnlyPublicKey() {
|
|
879
|
-
return
|
|
879
|
+
return chunkOIZ2V2VD_cjs.deriveDescriptorLeafPubKey(this.descriptor);
|
|
880
880
|
}
|
|
881
881
|
async compressedPublicKey() {
|
|
882
|
-
return
|
|
882
|
+
return chunkOIZ2V2VD_cjs.deriveDescriptorLeafCompressedPubKey(this.descriptor);
|
|
883
883
|
}
|
|
884
884
|
async sign(tx, inputIndexes) {
|
|
885
885
|
const [signed] = await this.signer.signWithDescriptor([
|
|
@@ -939,14 +939,20 @@ var ForeignDescriptorError = class extends Error {
|
|
|
939
939
|
descriptor;
|
|
940
940
|
name = "ForeignDescriptorError";
|
|
941
941
|
};
|
|
942
|
+
var WalletCannotAllocateAddressError = class extends Error {
|
|
943
|
+
name = "WalletCannotAllocateAddressError";
|
|
944
|
+
constructor(reason, options) {
|
|
945
|
+
super(`cannot allocate a fresh address: ${reason}`, options);
|
|
946
|
+
}
|
|
947
|
+
};
|
|
942
948
|
async function resolveDescriptorSigner(descriptor, identity, provider) {
|
|
943
949
|
const owner = provider?.isOurs(descriptor) ? provider : isHDCapableIdentity(identity) && identity.isOurs(descriptor) ? identity : void 0;
|
|
944
|
-
if (owner &&
|
|
950
|
+
if (owner && chunkOIZ2V2VD_cjs.parseHDDescriptor(descriptor)) {
|
|
945
951
|
return new DescriptorIdentity({ descriptor, signer: owner, base: identity });
|
|
946
952
|
}
|
|
947
953
|
let key;
|
|
948
954
|
try {
|
|
949
|
-
key =
|
|
955
|
+
key = chunkOIZ2V2VD_cjs.deriveDescriptorLeafPubKey(descriptor);
|
|
950
956
|
} catch {
|
|
951
957
|
throw new ForeignDescriptorError(descriptor);
|
|
952
958
|
}
|
|
@@ -963,6 +969,10 @@ function isHDAllocationCapable(value) {
|
|
|
963
969
|
const v = value;
|
|
964
970
|
return typeof v.getNextSigningDescriptor === "function" && typeof v.advanceSigningDescriptorWatermark === "function";
|
|
965
971
|
}
|
|
972
|
+
function isAddressAllocationCapable(value) {
|
|
973
|
+
if (typeof value !== "object" || value === null) return false;
|
|
974
|
+
return typeof value.getNewAddresses === "function";
|
|
975
|
+
}
|
|
966
976
|
|
|
967
977
|
// ../../node_modules/@noble/hashes/utils.js
|
|
968
978
|
function isBytes(a) {
|
|
@@ -1317,22 +1327,33 @@ function buildSaltedPreimageMessage(xonly, salt) {
|
|
|
1317
1327
|
}
|
|
1318
1328
|
var PREIMAGE_INDEX = 0;
|
|
1319
1329
|
function isPerArtifactDescriptor(descriptor) {
|
|
1320
|
-
return
|
|
1330
|
+
return chunkOIZ2V2VD_cjs.parseHDDescriptor(descriptor) !== null;
|
|
1321
1331
|
}
|
|
1322
1332
|
async function provisionDescriptor(wallet) {
|
|
1323
1333
|
const allocated = isHDAllocationCapable(wallet) ? await wallet.getNextSigningDescriptor() : void 0;
|
|
1324
|
-
return allocated ?? await
|
|
1334
|
+
return allocated ?? await chunkOIZ2V2VD_cjs.identityDescriptor(wallet.identity);
|
|
1325
1335
|
}
|
|
1326
1336
|
async function provisionRefundKey(wallet) {
|
|
1327
|
-
const descriptor = await
|
|
1337
|
+
const descriptor = await chunkOIZ2V2VD_cjs.identityDescriptor(wallet.identity);
|
|
1328
1338
|
const signer = await contractSigner(wallet, descriptor);
|
|
1329
|
-
|
|
1339
|
+
const pubkey = await signer.xOnlyPublicKey();
|
|
1340
|
+
const identityPubkey = await wallet.identity.xOnlyPublicKey();
|
|
1341
|
+
if (!utils_js.equalBytes(pubkey, identityPubkey)) {
|
|
1342
|
+
throw new Error(
|
|
1343
|
+
"provisionRefundKey: descriptor pubkey does not match wallet identity \u2014 the refund key and the refund address would be on different keys"
|
|
1344
|
+
);
|
|
1345
|
+
}
|
|
1346
|
+
const address = await wallet.getAddress();
|
|
1347
|
+
const { pkScript } = chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
|
|
1348
|
+
return { descriptor, pubkey, pkScript, address };
|
|
1330
1349
|
}
|
|
1331
1350
|
async function provisionClaimSecret(wallet, opts = {}) {
|
|
1332
1351
|
if (opts.preimage && opts.preimage.length !== 32) {
|
|
1333
1352
|
throw new Error(`preimage must be 32 bytes, got ${opts.preimage.length}`);
|
|
1334
1353
|
}
|
|
1335
|
-
const
|
|
1354
|
+
const descriptor = await provisionDescriptor(wallet);
|
|
1355
|
+
const signer = await contractSigner(wallet, descriptor);
|
|
1356
|
+
const pubkey = await signer.xOnlyPublicKey();
|
|
1336
1357
|
const claim = async () => {
|
|
1337
1358
|
if (opts.preimage) return { preimage: opts.preimage, mustPersistPreimage: true };
|
|
1338
1359
|
if (isPerArtifactDescriptor(descriptor)) {
|
|
@@ -1369,7 +1390,7 @@ async function contractSigner(wallet, descriptor) {
|
|
|
1369
1390
|
const signer = isHDWalletCapable(wallet) ? await wallet.signerForDescriptor(descriptor) : wallet.identity;
|
|
1370
1391
|
let expected;
|
|
1371
1392
|
try {
|
|
1372
|
-
expected =
|
|
1393
|
+
expected = chunkOIZ2V2VD_cjs.deriveDescriptorLeafPubKey(descriptor);
|
|
1373
1394
|
} catch (cause) {
|
|
1374
1395
|
throw new ForeignDescriptorError(descriptor, { cause });
|
|
1375
1396
|
}
|
|
@@ -1588,14 +1609,14 @@ var RestDelegateProvider = class {
|
|
|
1588
1609
|
*/
|
|
1589
1610
|
async delegate(intent, forfeitTxs, options) {
|
|
1590
1611
|
const url = `${this.url}/v1/delegate`;
|
|
1591
|
-
const response = await
|
|
1612
|
+
const response = await chunk2JV4VQ7C_cjs.baseFetch(url, {
|
|
1592
1613
|
method: "POST",
|
|
1593
1614
|
headers: {
|
|
1594
1615
|
"Content-Type": "application/json"
|
|
1595
1616
|
},
|
|
1596
1617
|
body: JSON.stringify({
|
|
1597
1618
|
intent: {
|
|
1598
|
-
message:
|
|
1619
|
+
message: chunk2JV4VQ7C_cjs.Intent.encodeMessage(intent.message),
|
|
1599
1620
|
proof: intent.proof
|
|
1600
1621
|
},
|
|
1601
1622
|
forfeit_txs: forfeitTxs,
|
|
@@ -1615,7 +1636,7 @@ var RestDelegateProvider = class {
|
|
|
1615
1636
|
*/
|
|
1616
1637
|
async getDelegateInfo() {
|
|
1617
1638
|
const url = `${this.url}/v1/delegator/info`;
|
|
1618
|
-
const response = await
|
|
1639
|
+
const response = await chunk2JV4VQ7C_cjs.rateGate.runHttp(url, () => chunk2JV4VQ7C_cjs.baseFetch(url));
|
|
1619
1640
|
if (!response.ok) {
|
|
1620
1641
|
const errorText2 = await response.text();
|
|
1621
1642
|
throw new Error(`Failed to get delegate info: ${errorText2}`);
|
|
@@ -1632,8 +1653,6 @@ var RestDelegatorProvider = RestDelegateProvider;
|
|
|
1632
1653
|
function isDelegateInfo(data) {
|
|
1633
1654
|
return !!data && typeof data === "object" && "pubkey" in data && "fee" in data && typeof data.pubkey === "string" && typeof data.fee === "string" && data.pubkey !== "" && data.fee !== "" && (typeof data.delegateAddress === "string" && data.delegateAddress !== "" || typeof data.delegatorAddress === "string" && data.delegatorAddress !== "");
|
|
1634
1655
|
}
|
|
1635
|
-
|
|
1636
|
-
// src/providers/onchain.ts
|
|
1637
1656
|
var ESPLORA_URL = {
|
|
1638
1657
|
bitcoin: "https://mempool.arkade.sh/api",
|
|
1639
1658
|
testnet: "https://mempool.space/testnet/api",
|
|
@@ -1642,7 +1661,7 @@ var ESPLORA_URL = {
|
|
|
1642
1661
|
regtest: "http://localhost:3000/api"
|
|
1643
1662
|
};
|
|
1644
1663
|
var EsploraProvider = class {
|
|
1645
|
-
constructor(baseUrl = ESPLORA_URL[
|
|
1664
|
+
constructor(baseUrl = ESPLORA_URL[chunk2JV4VQ7C_cjs.DEFAULT_NETWORK_NAME], opts) {
|
|
1646
1665
|
this.baseUrl = baseUrl;
|
|
1647
1666
|
this.pollingInterval = opts?.pollingInterval ?? 15e3;
|
|
1648
1667
|
this.forcePolling = opts?.forcePolling ?? false;
|
|
@@ -1651,14 +1670,14 @@ var EsploraProvider = class {
|
|
|
1651
1670
|
pollingInterval;
|
|
1652
1671
|
forcePolling;
|
|
1653
1672
|
async getCoins(address) {
|
|
1654
|
-
const response = await
|
|
1673
|
+
const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
|
|
1655
1674
|
if (!response.ok) {
|
|
1656
1675
|
throw new Error(`Failed to fetch UTXOs: ${response.statusText}`);
|
|
1657
1676
|
}
|
|
1658
1677
|
return response.json();
|
|
1659
1678
|
}
|
|
1660
1679
|
async getFeeRate() {
|
|
1661
|
-
const response = await
|
|
1680
|
+
const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/fee-estimates`);
|
|
1662
1681
|
if (response.status === 404) {
|
|
1663
1682
|
return void 0;
|
|
1664
1683
|
}
|
|
@@ -1679,7 +1698,7 @@ var EsploraProvider = class {
|
|
|
1679
1698
|
}
|
|
1680
1699
|
}
|
|
1681
1700
|
async getTxOutspends(txid) {
|
|
1682
|
-
const response = await
|
|
1701
|
+
const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
|
|
1683
1702
|
if (!response.ok) {
|
|
1684
1703
|
const error = await response.text();
|
|
1685
1704
|
throw new Error(`Failed to get transaction outspends: ${error}`);
|
|
@@ -1687,15 +1706,23 @@ var EsploraProvider = class {
|
|
|
1687
1706
|
return response.json();
|
|
1688
1707
|
}
|
|
1689
1708
|
async getTransactions(address) {
|
|
1690
|
-
const response = await
|
|
1709
|
+
const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
|
|
1691
1710
|
if (!response.ok) {
|
|
1692
1711
|
const error = await response.text();
|
|
1693
1712
|
throw new Error(`Failed to get transactions: ${error}`);
|
|
1694
1713
|
}
|
|
1695
1714
|
return response.json();
|
|
1696
1715
|
}
|
|
1716
|
+
async getRawTransaction(txid) {
|
|
1717
|
+
const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/hex`);
|
|
1718
|
+
if (!response.ok) {
|
|
1719
|
+
const error = await response.text();
|
|
1720
|
+
throw new Error(`Failed to get raw transaction ${txid}: ${error}`);
|
|
1721
|
+
}
|
|
1722
|
+
return base.hex.decode((await response.text()).trim());
|
|
1723
|
+
}
|
|
1697
1724
|
async getTxStatus(txid) {
|
|
1698
|
-
const txresponse = await
|
|
1725
|
+
const txresponse = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
|
|
1699
1726
|
if (!txresponse.ok) {
|
|
1700
1727
|
throw new Error(txresponse.statusText);
|
|
1701
1728
|
}
|
|
@@ -1703,7 +1730,7 @@ var EsploraProvider = class {
|
|
|
1703
1730
|
if (!tx.status.confirmed) {
|
|
1704
1731
|
return { confirmed: false };
|
|
1705
1732
|
}
|
|
1706
|
-
const response = await
|
|
1733
|
+
const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
|
|
1707
1734
|
if (!response.ok) {
|
|
1708
1735
|
throw new Error(`Failed to get transaction status: ${response.statusText}`);
|
|
1709
1736
|
}
|
|
@@ -1787,7 +1814,7 @@ var EsploraProvider = class {
|
|
|
1787
1814
|
return stopFunc;
|
|
1788
1815
|
}
|
|
1789
1816
|
async getChainTip() {
|
|
1790
|
-
const tipBlocks = await
|
|
1817
|
+
const tipBlocks = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/blocks`);
|
|
1791
1818
|
if (!tipBlocks.ok) {
|
|
1792
1819
|
throw new Error(`Failed to get chain tip: ${tipBlocks.statusText}`);
|
|
1793
1820
|
}
|
|
@@ -1806,7 +1833,7 @@ var EsploraProvider = class {
|
|
|
1806
1833
|
};
|
|
1807
1834
|
}
|
|
1808
1835
|
async broadcastPackage(parent, child) {
|
|
1809
|
-
const response = await
|
|
1836
|
+
const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
|
|
1810
1837
|
method: "POST",
|
|
1811
1838
|
headers: {
|
|
1812
1839
|
"Content-Type": "application/json"
|
|
@@ -1817,10 +1844,12 @@ var EsploraProvider = class {
|
|
|
1817
1844
|
const error = await response.text();
|
|
1818
1845
|
throw new Error(`Failed to broadcast package: ${error}`);
|
|
1819
1846
|
}
|
|
1820
|
-
|
|
1847
|
+
const result = await response.json();
|
|
1848
|
+
assertPackageAccepted(result);
|
|
1849
|
+
return result;
|
|
1821
1850
|
}
|
|
1822
1851
|
async broadcastTx(tx) {
|
|
1823
|
-
const response = await
|
|
1852
|
+
const response = await chunk2JV4VQ7C_cjs.baseFetch(`${this.baseUrl}/tx`, {
|
|
1824
1853
|
method: "POST",
|
|
1825
1854
|
headers: {
|
|
1826
1855
|
"Content-Type": "text/plain"
|
|
@@ -1834,6 +1863,24 @@ var EsploraProvider = class {
|
|
|
1834
1863
|
return response.text();
|
|
1835
1864
|
}
|
|
1836
1865
|
};
|
|
1866
|
+
function assertPackageAccepted(result) {
|
|
1867
|
+
if (!result || typeof result !== "object") return;
|
|
1868
|
+
const r = result;
|
|
1869
|
+
const msg = typeof r.package_msg === "string" ? r.package_msg : void 0;
|
|
1870
|
+
if (msg === void 0 || msg === "success") return;
|
|
1871
|
+
const reasons = [];
|
|
1872
|
+
const results = r["tx-results"];
|
|
1873
|
+
if (results && typeof results === "object") {
|
|
1874
|
+
for (const entry of Object.values(results)) {
|
|
1875
|
+
if (!entry || typeof entry !== "object" || entry.error === void 0) continue;
|
|
1876
|
+
const txid = typeof entry.txid === "string" ? entry.txid : "unknown tx";
|
|
1877
|
+
reasons.push(`${txid}: ${String(entry.error)}`);
|
|
1878
|
+
}
|
|
1879
|
+
}
|
|
1880
|
+
throw new Error(
|
|
1881
|
+
reasons.length > 0 ? `Package rejected (${msg}) \u2014 ${reasons.join("; ")}` : `Package rejected (${msg})`
|
|
1882
|
+
);
|
|
1883
|
+
}
|
|
1837
1884
|
function isValidBlocksTip(tip) {
|
|
1838
1885
|
return Array.isArray(tip) && tip.every((t) => {
|
|
1839
1886
|
return t && typeof t === "object" && typeof t.id === "string" && t.id.length > 0 && typeof t.height === "number" && t.height >= 0 && typeof t.mediantime === "number" && t.mediantime > 0;
|
|
@@ -1982,7 +2029,7 @@ function findP2AOutput(tx) {
|
|
|
1982
2029
|
var CHILD_DUST_AMOUNT = 546;
|
|
1983
2030
|
function buildAnchorChild(params) {
|
|
1984
2031
|
const { parent, feeRate, fundingCoins, changeAddress, tapInternalKey, network } = params;
|
|
1985
|
-
const child = new
|
|
2032
|
+
const child = new chunk2JV4VQ7C_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
|
|
1986
2033
|
child.addInput(findP2AOutput(parent));
|
|
1987
2034
|
const estimator = TxWeightEstimator.create().addP2AInput();
|
|
1988
2035
|
for (const _ of fundingCoins) {
|
|
@@ -2030,7 +2077,7 @@ function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
|
|
|
2030
2077
|
);
|
|
2031
2078
|
}
|
|
2032
2079
|
function buildForfeitTxWithOutput(inputs, output, txLocktime) {
|
|
2033
|
-
const tx = new
|
|
2080
|
+
const tx = new chunk2JV4VQ7C_cjs.Transaction({
|
|
2034
2081
|
version: 3,
|
|
2035
2082
|
lockTime: txLocktime
|
|
2036
2083
|
});
|
|
@@ -2106,7 +2153,7 @@ function validateVtxoTxGraph(graph, roundTransaction, sweepTapTreeRoot) {
|
|
|
2106
2153
|
if (previousScriptKey.length !== 32) {
|
|
2107
2154
|
throw new Error(`parent output ${childIndex} has invalid script`);
|
|
2108
2155
|
}
|
|
2109
|
-
const cosigners =
|
|
2156
|
+
const cosigners = chunk2JV4VQ7C_cjs.getArkPsbtFields(child.root, 0, chunk2JV4VQ7C_cjs.CosignerPublicKey);
|
|
2110
2157
|
if (cosigners.length === 0) {
|
|
2111
2158
|
throw ErrMissingCosignersPublicKeys;
|
|
2112
2159
|
}
|
|
@@ -2164,7 +2211,7 @@ var EmulatorPacket = class _EmulatorPacket {
|
|
|
2164
2211
|
return new _EmulatorPacket(entries);
|
|
2165
2212
|
}
|
|
2166
2213
|
static fromBytes(data) {
|
|
2167
|
-
const reader = new
|
|
2214
|
+
const reader = new chunkCO3KKSWM_cjs.BufferReader(data);
|
|
2168
2215
|
const entryCount = reader.readCompactSize();
|
|
2169
2216
|
const entries = [];
|
|
2170
2217
|
for (let i = 0; i < entryCount; i++) {
|
|
@@ -2182,7 +2229,7 @@ var EmulatorPacket = class _EmulatorPacket {
|
|
|
2182
2229
|
return _EmulatorPacket.PACKET_TYPE;
|
|
2183
2230
|
}
|
|
2184
2231
|
serialize() {
|
|
2185
|
-
const writer = new
|
|
2232
|
+
const writer = new chunkCO3KKSWM_cjs.BufferWriter();
|
|
2186
2233
|
writer.writeCompactSize(this.entries.length);
|
|
2187
2234
|
for (const entry of this.entries) {
|
|
2188
2235
|
writer.writeUint16LE(entry.vin);
|
|
@@ -2269,7 +2316,7 @@ var Extension = class _Extension {
|
|
|
2269
2316
|
`expected magic prefix ${base.hex.encode(ARKADE_MAGIC)}, got ${base.hex.encode(payload.slice(0, Math.min(payload.length, ARKADE_MAGIC.length)))}`
|
|
2270
2317
|
);
|
|
2271
2318
|
}
|
|
2272
|
-
const reader = new
|
|
2319
|
+
const reader = new chunkCO3KKSWM_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
|
|
2273
2320
|
const packets = [];
|
|
2274
2321
|
while (reader.remaining() > 0) {
|
|
2275
2322
|
const packetType = reader.readByte();
|
|
@@ -2343,7 +2390,7 @@ var Extension = class _Extension {
|
|
|
2343
2390
|
*/
|
|
2344
2391
|
getAssetPacket() {
|
|
2345
2392
|
for (const p of this.packets) {
|
|
2346
|
-
if (p instanceof
|
|
2393
|
+
if (p instanceof chunkCO3KKSWM_cjs.Packet) {
|
|
2347
2394
|
return p;
|
|
2348
2395
|
}
|
|
2349
2396
|
}
|
|
@@ -2381,8 +2428,8 @@ var Extension = class _Extension {
|
|
|
2381
2428
|
};
|
|
2382
2429
|
function parsePacket(packetType, data) {
|
|
2383
2430
|
switch (packetType) {
|
|
2384
|
-
case
|
|
2385
|
-
return
|
|
2431
|
+
case chunkCO3KKSWM_cjs.Packet.PACKET_TYPE:
|
|
2432
|
+
return chunkCO3KKSWM_cjs.Packet.fromBytes(data);
|
|
2386
2433
|
case EmulatorPacket.PACKET_TYPE:
|
|
2387
2434
|
return EmulatorPacket.fromBytes(data);
|
|
2388
2435
|
default:
|
|
@@ -2429,16 +2476,16 @@ function buildOpReturnScript(data) {
|
|
|
2429
2476
|
}
|
|
2430
2477
|
return script;
|
|
2431
2478
|
}
|
|
2432
|
-
var ErrOffchainOutputNotFound = (address) => new
|
|
2433
|
-
var ErrInvalidAssetOutputAmount = (got, want, assetId) => new
|
|
2479
|
+
var ErrOffchainOutputNotFound = (address) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(`offchain send output not found: ${address}`);
|
|
2480
|
+
var ErrInvalidAssetOutputAmount = (got, want, assetId) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
2434
2481
|
`invalid asset output amount for ${assetId}: got ${got}, want ${want}`
|
|
2435
2482
|
);
|
|
2436
|
-
var ErrAssetGroupNotFound = (assetId) => new
|
|
2437
|
-
var ErrAssetOutputNotFound = (assetId, outputIndex) => new
|
|
2483
|
+
var ErrAssetGroupNotFound = (assetId) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(`asset group not found in batch leaf: ${assetId}`);
|
|
2484
|
+
var ErrAssetOutputNotFound = (assetId, outputIndex) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
2438
2485
|
`asset output not found in asset group ${assetId} at index ${outputIndex}`
|
|
2439
2486
|
);
|
|
2440
|
-
var ErrOnchainOutputNotFound = (address) => new
|
|
2441
|
-
var ErrUnvalidatedOffchainOutput = (address) => new
|
|
2487
|
+
var ErrOnchainOutputNotFound = (address) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(`onchain output not found: ${address}`);
|
|
2488
|
+
var ErrUnvalidatedOffchainOutput = (address) => new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
2442
2489
|
`offchain output ${address} cannot be validated: virtual output tree signing did not run`
|
|
2443
2490
|
);
|
|
2444
2491
|
var ErrInvalidOnchainOutputAmount = (address) => new Error(`invalid onchain output amount: ${address}`);
|
|
@@ -2447,7 +2494,7 @@ var ErrInvalidOffchainOutputAmount = (address) => new Error(`invalid offchain ou
|
|
|
2447
2494
|
function assertFinalCommitmentMatchesValidated(finalCommitmentTx, validatedCommitmentTxid, context) {
|
|
2448
2495
|
if (!validatedCommitmentTxid) return;
|
|
2449
2496
|
if (finalCommitmentTx.id === validatedCommitmentTxid) return;
|
|
2450
|
-
throw new
|
|
2497
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
2451
2498
|
`${context}: finalization commitment tx ${finalCommitmentTx.id} differs from the validated commitment tx ${validatedCommitmentTxid}`
|
|
2452
2499
|
);
|
|
2453
2500
|
}
|
|
@@ -2457,7 +2504,7 @@ function validateBatchRecipients(commitmentTx, vtxoTreeLeaves, recipients, netwo
|
|
|
2457
2504
|
for (const recipient of recipients) {
|
|
2458
2505
|
let arkAddress;
|
|
2459
2506
|
try {
|
|
2460
|
-
arkAddress =
|
|
2507
|
+
arkAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(recipient.address);
|
|
2461
2508
|
} catch {
|
|
2462
2509
|
validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
|
|
2463
2510
|
continue;
|
|
@@ -2469,7 +2516,7 @@ function validateBatchRecipientsWithoutTree(commitmentTx, recipients, network) {
|
|
|
2469
2516
|
const usedOnchainOutputs = /* @__PURE__ */ new Set();
|
|
2470
2517
|
for (const recipient of recipients) {
|
|
2471
2518
|
try {
|
|
2472
|
-
|
|
2519
|
+
chunk2JV4VQ7C_cjs.ArkAddress.decode(recipient.address);
|
|
2473
2520
|
} catch {
|
|
2474
2521
|
validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
|
|
2475
2522
|
continue;
|
|
@@ -2702,7 +2749,7 @@ function assetMintResolver() {
|
|
|
2702
2749
|
if (!tx.assets?.length || !tx.key.arkTxid) return void 0;
|
|
2703
2750
|
const minted = tx.assets.filter((a) => {
|
|
2704
2751
|
try {
|
|
2705
|
-
return base.hex.encode(
|
|
2752
|
+
return base.hex.encode(chunkCO3KKSWM_cjs.AssetId.fromString(a.assetId).txid) === tx.key.arkTxid;
|
|
2706
2753
|
} catch {
|
|
2707
2754
|
return false;
|
|
2708
2755
|
}
|
|
@@ -2745,7 +2792,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
2745
2792
|
const existing = inputsByAssetId.get(asset.assetId);
|
|
2746
2793
|
inputsByAssetId.set(asset.assetId, [
|
|
2747
2794
|
...existing ?? [],
|
|
2748
|
-
|
|
2795
|
+
chunkCO3KKSWM_cjs.AssetInput.create(inputIndex, asset.amount)
|
|
2749
2796
|
]);
|
|
2750
2797
|
}
|
|
2751
2798
|
}
|
|
@@ -2757,7 +2804,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
2757
2804
|
const existing = outputsByAssetId.get(asset.assetId);
|
|
2758
2805
|
outputsByAssetId.set(asset.assetId, [
|
|
2759
2806
|
...existing ?? [],
|
|
2760
|
-
|
|
2807
|
+
chunkCO3KKSWM_cjs.AssetOutput.create(outputIndex, asset.amount)
|
|
2761
2808
|
]);
|
|
2762
2809
|
}
|
|
2763
2810
|
}
|
|
@@ -2768,7 +2815,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
2768
2815
|
const existing = outputsByAssetId.get(asset.assetId);
|
|
2769
2816
|
outputsByAssetId.set(asset.assetId, [
|
|
2770
2817
|
...existing ?? [],
|
|
2771
|
-
|
|
2818
|
+
chunkCO3KKSWM_cjs.AssetOutput.create(outputIndex, asset.amount)
|
|
2772
2819
|
]);
|
|
2773
2820
|
}
|
|
2774
2821
|
}
|
|
@@ -2777,11 +2824,11 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
2777
2824
|
for (const assetIdStr of allAssetIds) {
|
|
2778
2825
|
const inputs = inputsByAssetId.get(assetIdStr);
|
|
2779
2826
|
const outputs = outputsByAssetId.get(assetIdStr);
|
|
2780
|
-
const assetId =
|
|
2781
|
-
const group =
|
|
2827
|
+
const assetId = chunkCO3KKSWM_cjs.AssetId.fromString(assetIdStr);
|
|
2828
|
+
const group = chunkCO3KKSWM_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
|
|
2782
2829
|
groups.push(group);
|
|
2783
2830
|
}
|
|
2784
|
-
return
|
|
2831
|
+
return chunkCO3KKSWM_cjs.Packet.create(groups);
|
|
2785
2832
|
}
|
|
2786
2833
|
function selectCoinsWithAsset(coins, assetId, requiredAmount) {
|
|
2787
2834
|
const coinsWithAsset = coins.filter((coin) => coin.assets?.some((a) => a.assetId === assetId));
|
|
@@ -2818,8 +2865,7 @@ function selectedCoinsToAssetInputs(selectedCoins) {
|
|
|
2818
2865
|
}
|
|
2819
2866
|
function toXOnlySignerHex(pubkeyHex) {
|
|
2820
2867
|
const bytes = base.hex.decode(pubkeyHex);
|
|
2821
|
-
if (bytes.length === 33) return base.hex.encode(
|
|
2822
|
-
if (bytes.length === 32) return base.hex.encode(bytes);
|
|
2868
|
+
if (bytes.length === 32 || bytes.length === 33) return base.hex.encode(chunkOIZ2V2VD_cjs.toXOnly(bytes, "signer key"));
|
|
2823
2869
|
throw new Error(`invalid signer pubkey length: expected 32 or 33 bytes, got ${bytes.length}`);
|
|
2824
2870
|
}
|
|
2825
2871
|
function signerSetFromInfo(info) {
|
|
@@ -2866,13 +2912,13 @@ var toTimelock = (value) => ({
|
|
|
2866
2912
|
var toSeconds = (t) => t.type === "seconds" ? t.value : t.value * NOMINAL_BLOCK_SECONDS;
|
|
2867
2913
|
function assertTimelockInPolicy(timelock, policy, label, overrideOption) {
|
|
2868
2914
|
if (policy.requireSeconds && timelock.type === "blocks") {
|
|
2869
|
-
throw new
|
|
2915
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
2870
2916
|
`${label} rejected: block-typed timelocks are not accepted (got ${timelock.value})`
|
|
2871
2917
|
);
|
|
2872
2918
|
}
|
|
2873
2919
|
const seconds = toSeconds(timelock);
|
|
2874
2920
|
if (seconds < policy.minSeconds) {
|
|
2875
|
-
throw new
|
|
2921
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
2876
2922
|
`${label} rejected: ${timelock.value} ${timelock.type} is below the ${policy.minSeconds}s floor; pass ${overrideOption}: ${seconds}n to Wallet.create to lower it`
|
|
2877
2923
|
);
|
|
2878
2924
|
}
|
|
@@ -2893,7 +2939,7 @@ function resolveBatchExpiryPolicy(network, overrides) {
|
|
|
2893
2939
|
}
|
|
2894
2940
|
function assertValidBatchExpiry(batchExpiry, policy) {
|
|
2895
2941
|
if (policy.advertisedVtxoTreeExpiry !== void 0 && batchExpiry !== policy.advertisedVtxoTreeExpiry) {
|
|
2896
|
-
throw new
|
|
2942
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
2897
2943
|
`batch expiry rejected: ${batchExpiry} does not match the advertised vtxoTreeExpiry ${policy.advertisedVtxoTreeExpiry}`
|
|
2898
2944
|
);
|
|
2899
2945
|
}
|
|
@@ -2923,21 +2969,21 @@ function resolveCheckpointExitDelayPolicy(network, overrides) {
|
|
|
2923
2969
|
function assertValidServerUnrollScript(checkpointTapscript, policy) {
|
|
2924
2970
|
let script;
|
|
2925
2971
|
try {
|
|
2926
|
-
script =
|
|
2972
|
+
script = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
|
|
2927
2973
|
} catch (e) {
|
|
2928
|
-
throw new
|
|
2974
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
2929
2975
|
`checkpoint exit delay rejected: invalid checkpointTapscript from server (${e instanceof Error ? e.message : String(e)})`
|
|
2930
2976
|
);
|
|
2931
2977
|
}
|
|
2932
2978
|
if (policy.advertisedForfeitPubkey !== void 0) {
|
|
2933
2979
|
const { pubkeys } = script.params;
|
|
2934
2980
|
if (pubkeys.length !== 1) {
|
|
2935
|
-
throw new
|
|
2981
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
2936
2982
|
`checkpoint exit delay rejected: checkpointTapscript must commit to exactly one pubkey, got ${pubkeys.length} [${pubkeys.map(base.hex.encode).join(", ")}]`
|
|
2937
2983
|
);
|
|
2938
2984
|
}
|
|
2939
2985
|
if (!utils_js.equalBytes(pubkeys[0], policy.advertisedForfeitPubkey)) {
|
|
2940
|
-
throw new
|
|
2986
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
2941
2987
|
`checkpoint exit delay rejected: checkpointTapscript pubkey ${base.hex.encode(pubkeys[0])} does not match the advertised forfeitPubkey ${base.hex.encode(policy.advertisedForfeitPubkey)}`
|
|
2942
2988
|
);
|
|
2943
2989
|
}
|
|
@@ -2981,8 +3027,8 @@ function buildOffchainTx(inputs, outputs, serverUnrollScript) {
|
|
|
2981
3027
|
function buildVirtualTx(inputs, outputs) {
|
|
2982
3028
|
let lockTime = 0n;
|
|
2983
3029
|
for (const input of inputs) {
|
|
2984
|
-
const tapscript =
|
|
2985
|
-
if (
|
|
3030
|
+
const tapscript = chunk2JV4VQ7C_cjs.decodeTapscript(chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(input.tapLeafScript));
|
|
3031
|
+
if (chunk2JV4VQ7C_cjs.CLTVMultisigTapscript.is(tapscript)) {
|
|
2986
3032
|
if (lockTime !== 0n) {
|
|
2987
3033
|
if (isSeconds(lockTime) !== isSeconds(tapscript.params.absoluteTimelock)) {
|
|
2988
3034
|
throw new Error("cannot mix seconds and blocks locktime");
|
|
@@ -2993,7 +3039,7 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
2993
3039
|
}
|
|
2994
3040
|
}
|
|
2995
3041
|
}
|
|
2996
|
-
const tx = new
|
|
3042
|
+
const tx = new chunk2JV4VQ7C_cjs.Transaction({
|
|
2997
3043
|
version: 3,
|
|
2998
3044
|
lockTime: Number(lockTime)
|
|
2999
3045
|
});
|
|
@@ -3003,12 +3049,12 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
3003
3049
|
index: input.vout,
|
|
3004
3050
|
sequence: lockTime ? btcSigner.DEFAULT_SEQUENCE - 1 : void 0,
|
|
3005
3051
|
witnessUtxo: {
|
|
3006
|
-
script:
|
|
3052
|
+
script: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript,
|
|
3007
3053
|
amount: BigInt(input.value)
|
|
3008
3054
|
},
|
|
3009
3055
|
tapLeafScript: [input.tapLeafScript]
|
|
3010
3056
|
});
|
|
3011
|
-
|
|
3057
|
+
chunk2JV4VQ7C_cjs.setArkPsbtField(tx, i, chunk2JV4VQ7C_cjs.VtxoTaprootTree, input.tapTree);
|
|
3012
3058
|
}
|
|
3013
3059
|
for (const output of outputs) {
|
|
3014
3060
|
tx.addOutput(output);
|
|
@@ -3017,8 +3063,8 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
3017
3063
|
return tx;
|
|
3018
3064
|
}
|
|
3019
3065
|
function buildCheckpointTx(vtxo, serverUnrollScript) {
|
|
3020
|
-
const collaborativeClosure =
|
|
3021
|
-
const checkpointVtxoScript = new
|
|
3066
|
+
const collaborativeClosure = chunk2JV4VQ7C_cjs.decodeTapscript(chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
|
|
3067
|
+
const checkpointVtxoScript = new chunk2JV4VQ7C_cjs.VtxoScript([
|
|
3022
3068
|
serverUnrollScript.script,
|
|
3023
3069
|
collaborativeClosure.script
|
|
3024
3070
|
]);
|
|
@@ -3171,7 +3217,7 @@ function combineTapscriptSigs(signedTx, originalTx) {
|
|
|
3171
3217
|
}
|
|
3172
3218
|
function isValidArkAddress(address) {
|
|
3173
3219
|
try {
|
|
3174
|
-
|
|
3220
|
+
chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
|
|
3175
3221
|
return true;
|
|
3176
3222
|
} catch (e) {
|
|
3177
3223
|
return false;
|
|
@@ -3179,16 +3225,16 @@ function isValidArkAddress(address) {
|
|
|
3179
3225
|
}
|
|
3180
3226
|
function matchServerCheckpoints(serverCheckpointTxs, expectedCheckpoints, context) {
|
|
3181
3227
|
if (serverCheckpointTxs.length !== expectedCheckpoints.length) {
|
|
3182
|
-
throw new
|
|
3228
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
3183
3229
|
`${context} returned ${serverCheckpointTxs.length} checkpoints, expected ${expectedCheckpoints.length}`
|
|
3184
3230
|
);
|
|
3185
3231
|
}
|
|
3186
3232
|
const byTxid = new Map(expectedCheckpoints.map((c) => [c.id, c]));
|
|
3187
3233
|
return serverCheckpointTxs.map((encoded, index) => {
|
|
3188
|
-
const server =
|
|
3234
|
+
const server = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(encoded));
|
|
3189
3235
|
const local = byTxid.get(server.id);
|
|
3190
3236
|
if (!local) {
|
|
3191
|
-
throw new
|
|
3237
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
3192
3238
|
`${context} checkpoint ${index} txid ${server.id} does not match any submitted checkpoint`
|
|
3193
3239
|
);
|
|
3194
3240
|
}
|
|
@@ -3198,14 +3244,14 @@ function matchServerCheckpoints(serverCheckpointTxs, expectedCheckpoints, contex
|
|
|
3198
3244
|
}
|
|
3199
3245
|
function assertSubmittedArkTxid(response, signedArkTx, context) {
|
|
3200
3246
|
if (response.arkTxid !== signedArkTx.id) {
|
|
3201
|
-
throw new
|
|
3247
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
3202
3248
|
`${context} returned ark txid ${response.arkTxid}, expected ${signedArkTx.id}`
|
|
3203
3249
|
);
|
|
3204
3250
|
}
|
|
3205
3251
|
if (response.finalArkTx === void 0) return;
|
|
3206
|
-
const finalTxid =
|
|
3252
|
+
const finalTxid = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx)).id;
|
|
3207
3253
|
if (finalTxid !== signedArkTx.id) {
|
|
3208
|
-
throw new
|
|
3254
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
3209
3255
|
`${context} returned final ark tx ${finalTxid}, expected ${signedArkTx.id}`
|
|
3210
3256
|
);
|
|
3211
3257
|
}
|
|
@@ -3224,10 +3270,10 @@ function assertServerSignedLeaf(serverTx, localTx, inputIndex, serverPubkeyHex,
|
|
|
3224
3270
|
[serverPubkeyHex],
|
|
3225
3271
|
void 0,
|
|
3226
3272
|
void 0,
|
|
3227
|
-
payment_js.tapLeafHash(
|
|
3273
|
+
payment_js.tapLeafHash(chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(leaf))
|
|
3228
3274
|
);
|
|
3229
3275
|
} catch (error) {
|
|
3230
|
-
throw new
|
|
3276
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
3231
3277
|
`${context}: input ${inputIndex} is not signed by the server on the leaf being spent (${error instanceof Error ? error.message : String(error)})`
|
|
3232
3278
|
);
|
|
3233
3279
|
}
|
|
@@ -3236,20 +3282,20 @@ function assertCheckpointsMatchInputs(checkpoints, inputs, unrollCandidates, con
|
|
|
3236
3282
|
const byOutpoint = new Map(inputs.map((input) => [`${input.txid}:${input.vout}`, input]));
|
|
3237
3283
|
for (const [index, checkpoint] of checkpoints.entries()) {
|
|
3238
3284
|
if (checkpoint.inputsLength !== 1) {
|
|
3239
|
-
throw new
|
|
3285
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
3240
3286
|
`${context}: checkpoint ${index} spends ${checkpoint.inputsLength} inputs, expected 1`
|
|
3241
3287
|
);
|
|
3242
3288
|
}
|
|
3243
3289
|
const spent = checkpoint.getInput(0);
|
|
3244
3290
|
if (!spent.txid || spent.index === void 0) {
|
|
3245
|
-
throw new
|
|
3291
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
3246
3292
|
`${context}: checkpoint ${index} has no input outpoint`
|
|
3247
3293
|
);
|
|
3248
3294
|
}
|
|
3249
3295
|
const outpoint = `${base.hex.encode(spent.txid)}:${spent.index}`;
|
|
3250
3296
|
const input = byOutpoint.get(outpoint);
|
|
3251
3297
|
if (!input) {
|
|
3252
|
-
throw new
|
|
3298
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
3253
3299
|
`${context}: checkpoint ${index} spends ${outpoint}, which is not one of the requested virtual outputs`
|
|
3254
3300
|
);
|
|
3255
3301
|
}
|
|
@@ -3257,7 +3303,7 @@ function assertCheckpointsMatchInputs(checkpoints, inputs, unrollCandidates, con
|
|
|
3257
3303
|
(unroll) => buildCheckpointTx(input, unroll).tx.id === checkpoint.id
|
|
3258
3304
|
);
|
|
3259
3305
|
if (!rebuilt) {
|
|
3260
|
-
throw new
|
|
3306
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
3261
3307
|
`${context}: checkpoint ${index} txid ${checkpoint.id} differs from the checkpoint built locally for ${outpoint}`
|
|
3262
3308
|
);
|
|
3263
3309
|
}
|
|
@@ -3284,14 +3330,12 @@ async function submitOffchainTx(provider, offchainTx, signer, hooks, options) {
|
|
|
3284
3330
|
const verify = options?.verifyServerSignatures;
|
|
3285
3331
|
if (verify) {
|
|
3286
3332
|
if (response.finalArkTx === void 0) {
|
|
3287
|
-
throw new
|
|
3333
|
+
throw new chunk2JV4VQ7C_cjs.ServerResponseMismatchError(
|
|
3288
3334
|
"submitTx: server returned no final ark tx to verify its signatures against"
|
|
3289
3335
|
);
|
|
3290
3336
|
}
|
|
3291
|
-
const finalArkTx =
|
|
3292
|
-
const serverPubkeyHex = base.hex.encode(
|
|
3293
|
-
verify.serverPubkey.length === 33 ? verify.serverPubkey.subarray(1) : verify.serverPubkey
|
|
3294
|
-
);
|
|
3337
|
+
const finalArkTx = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(response.finalArkTx));
|
|
3338
|
+
const serverPubkeyHex = base.hex.encode(chunkOIZ2V2VD_cjs.toXOnly(verify.serverPubkey, "server key"));
|
|
3295
3339
|
for (let i = 0; i < offchainTx.arkTx.inputsLength; i++) {
|
|
3296
3340
|
assertServerSignedLeaf(
|
|
3297
3341
|
finalArkTx,
|
|
@@ -3347,12 +3391,12 @@ function claimWithPreimageIdentity(identity, preimage) {
|
|
|
3347
3391
|
return {
|
|
3348
3392
|
...identity,
|
|
3349
3393
|
sign: async (tx, inputIndexes) => {
|
|
3350
|
-
const signed =
|
|
3394
|
+
const signed = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(
|
|
3351
3395
|
(await identity.sign(tx.clone(), inputIndexes)).toPSBT()
|
|
3352
3396
|
);
|
|
3353
3397
|
const indexes = inputIndexes ?? Array.from({ length: signed.inputsLength }, (_, i) => i);
|
|
3354
3398
|
for (const index of indexes) {
|
|
3355
|
-
|
|
3399
|
+
chunk2JV4VQ7C_cjs.setArkPsbtField(signed, index, chunk2JV4VQ7C_cjs.ConditionWitness, [preimage]);
|
|
3356
3400
|
}
|
|
3357
3401
|
return signed;
|
|
3358
3402
|
}
|
|
@@ -3544,7 +3588,7 @@ function extendCoinWithTapscript(boardingTapscript, utxo) {
|
|
|
3544
3588
|
};
|
|
3545
3589
|
}
|
|
3546
3590
|
function deriveContractTapscripts(contract) {
|
|
3547
|
-
const handler =
|
|
3591
|
+
const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
|
|
3548
3592
|
if (!handler) {
|
|
3549
3593
|
throw new Error(`No handler for contract type '${contract.type}'`);
|
|
3550
3594
|
}
|
|
@@ -3615,7 +3659,7 @@ function getRandomId() {
|
|
|
3615
3659
|
}
|
|
3616
3660
|
function isValidArkAddress2(address) {
|
|
3617
3661
|
try {
|
|
3618
|
-
|
|
3662
|
+
chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
|
|
3619
3663
|
return true;
|
|
3620
3664
|
} catch (e) {
|
|
3621
3665
|
return false;
|
|
@@ -3643,7 +3687,7 @@ function assertRecipientArkAddress(encoded, address, context) {
|
|
|
3643
3687
|
function assertTapTreeDerivesAddress(encoded, tapTree, address) {
|
|
3644
3688
|
let derived;
|
|
3645
3689
|
try {
|
|
3646
|
-
derived =
|
|
3690
|
+
derived = chunk2JV4VQ7C_cjs.VtxoScript.decode(tapTree).pkScript;
|
|
3647
3691
|
} catch (e) {
|
|
3648
3692
|
throw new Error(
|
|
3649
3693
|
`Invalid tapTree for ${encoded}: ${e instanceof Error ? e.message : String(e)}`
|
|
@@ -3660,7 +3704,7 @@ function validateRecipients(recipients, dustAmount, context) {
|
|
|
3660
3704
|
for (const recipient of recipients) {
|
|
3661
3705
|
let address;
|
|
3662
3706
|
try {
|
|
3663
|
-
address =
|
|
3707
|
+
address = chunk2JV4VQ7C_cjs.ArkAddress.decode(recipient.address);
|
|
3664
3708
|
} catch (e) {
|
|
3665
3709
|
throw new Error(`Invalid Arkade address: ${recipient.address}`);
|
|
3666
3710
|
}
|
|
@@ -3685,7 +3729,7 @@ function validateRecipients(recipients, dustAmount, context) {
|
|
|
3685
3729
|
|
|
3686
3730
|
// src/contracts/spendability.ts
|
|
3687
3731
|
function isContractGenericallySpendable(contract) {
|
|
3688
|
-
return
|
|
3732
|
+
return chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type)?.isGenericallySpendable?.(contract) === true;
|
|
3689
3733
|
}
|
|
3690
3734
|
function gatedContracts(contracts) {
|
|
3691
3735
|
const gated = /* @__PURE__ */ new Map();
|
|
@@ -3698,7 +3742,7 @@ function gateExclusion(gated) {
|
|
|
3698
3742
|
return (vtxo) => {
|
|
3699
3743
|
const type = vtxo.script === void 0 ? void 0 : gated.get(vtxo.script);
|
|
3700
3744
|
if (type === void 0) return void 0;
|
|
3701
|
-
if (!
|
|
3745
|
+
if (!chunkOIZ2V2VD_cjs.contractHandlers.has(type)) {
|
|
3702
3746
|
return `at ${vtxo.script} (contract type '${type}') has no handler registered in this build`;
|
|
3703
3747
|
}
|
|
3704
3748
|
return `at ${vtxo.script} (contract type '${type}') is not generically spendable`;
|
|
@@ -3734,7 +3778,9 @@ function selectPendingRecoveryOutpoints(contractsWithVtxos, signerSet, nowSecond
|
|
|
3734
3778
|
continue;
|
|
3735
3779
|
}
|
|
3736
3780
|
for (const v of vtxos) {
|
|
3737
|
-
if (!
|
|
3781
|
+
if (!chunk2JV4VQ7C_cjs.hasTerminalSpend(v) && !v.isSwept && !v.isUnrolled) {
|
|
3782
|
+
out.add(`${v.txid}:${v.vout}`);
|
|
3783
|
+
}
|
|
3738
3784
|
}
|
|
3739
3785
|
}
|
|
3740
3786
|
return out;
|
|
@@ -3767,10 +3813,10 @@ function byValueDescending(vtxos) {
|
|
|
3767
3813
|
return [...vtxos].sort((a, b) => b.value - a.value);
|
|
3768
3814
|
}
|
|
3769
3815
|
async function fetchTimeHeight(wallet) {
|
|
3770
|
-
return
|
|
3816
|
+
return chunk2JV4VQ7C_cjs.resolveTimeHeight(wallet.onchainProvider);
|
|
3771
3817
|
}
|
|
3772
3818
|
function canMigrateBySend(vtxo, now) {
|
|
3773
|
-
if (!
|
|
3819
|
+
if (!chunk2JV4VQ7C_cjs.canSpendOffchain(vtxo, now)) return false;
|
|
3774
3820
|
return vtxo.expiresAt !== void 0 || vtxo.expiresAtHeight !== void 0;
|
|
3775
3821
|
}
|
|
3776
3822
|
function byExpiryAscending(vtxos, now) {
|
|
@@ -3778,7 +3824,7 @@ function byExpiryAscending(vtxos, now) {
|
|
|
3778
3824
|
if (vtxo.isSwept) return -Infinity;
|
|
3779
3825
|
if (vtxo.expiresAt !== void 0) return vtxo.expiresAt.getTime();
|
|
3780
3826
|
if (vtxo.expiresAtHeight !== void 0) {
|
|
3781
|
-
return
|
|
3827
|
+
return chunk2JV4VQ7C_cjs.isPastExpiry(vtxo, now) ? -Infinity : Infinity;
|
|
3782
3828
|
}
|
|
3783
3829
|
return Infinity;
|
|
3784
3830
|
};
|
|
@@ -3805,7 +3851,7 @@ function priceSettlementInputs(vtxos, estimator) {
|
|
|
3805
3851
|
const payable = [];
|
|
3806
3852
|
const net = /* @__PURE__ */ new Map();
|
|
3807
3853
|
for (const vtxo of vtxos) {
|
|
3808
|
-
const inputFee = estimator.evalOffchainInput(
|
|
3854
|
+
const inputFee = estimator.evalOffchainInput(chunk2JV4VQ7C_cjs.toOffchainInputFeeParams(vtxo));
|
|
3809
3855
|
if (inputFee.satoshis >= vtxo.value) {
|
|
3810
3856
|
continue;
|
|
3811
3857
|
}
|
|
@@ -3831,7 +3877,7 @@ function deductOffchainOutputFee(subtotal, estimator, arkAddress) {
|
|
|
3831
3877
|
}
|
|
3832
3878
|
const outputFee = estimator.evalOffchainOutput({
|
|
3833
3879
|
amount: subtotal,
|
|
3834
|
-
script: base.hex.encode(
|
|
3880
|
+
script: base.hex.encode(chunk2JV4VQ7C_cjs.ArkAddress.decode(arkAddress).pkScript)
|
|
3835
3881
|
});
|
|
3836
3882
|
return subtotal - BigInt(outputFee.satoshis);
|
|
3837
3883
|
}
|
|
@@ -3849,10 +3895,10 @@ var DEFAULT_SETTLEMENT_CONFIG = {
|
|
|
3849
3895
|
};
|
|
3850
3896
|
function getRecoverableVtxos(vtxos, dustAmount, now) {
|
|
3851
3897
|
return vtxos.filter((vtxo) => {
|
|
3852
|
-
if (
|
|
3898
|
+
if (chunk2JV4VQ7C_cjs.canRecoverOnchain(vtxo, now)) {
|
|
3853
3899
|
return true;
|
|
3854
3900
|
}
|
|
3855
|
-
if (
|
|
3901
|
+
if (chunk2JV4VQ7C_cjs.canSpendOffchain(vtxo, now) && vtxo.isPreconfirmed && isSubdust(vtxo, dustAmount)) {
|
|
3856
3902
|
return true;
|
|
3857
3903
|
}
|
|
3858
3904
|
return false;
|
|
@@ -3883,7 +3929,7 @@ function getRecoverableWithSubdust(vtxos, dustAmount, now) {
|
|
|
3883
3929
|
}
|
|
3884
3930
|
function isVtxoExpiringSoon(vtxo, thresholdMs) {
|
|
3885
3931
|
const realThresholdMs = thresholdMs <= 100 ? DEFAULT_THRESHOLD_MS : thresholdMs;
|
|
3886
|
-
const expiresAt =
|
|
3932
|
+
const expiresAt = chunk2JV4VQ7C_cjs.normalizeVtxo(vtxo).expiresAt;
|
|
3887
3933
|
if (expiresAt === void 0) return false;
|
|
3888
3934
|
const now = Date.now();
|
|
3889
3935
|
const batchExpiry = expiresAt.getTime();
|
|
@@ -3892,7 +3938,7 @@ function isVtxoExpiringSoon(vtxo, thresholdMs) {
|
|
|
3892
3938
|
}
|
|
3893
3939
|
function getExpiringAndRecoverableVtxos(vtxos, thresholdMs, dustAmount, now) {
|
|
3894
3940
|
return vtxos.filter(
|
|
3895
|
-
(vtxo) => isVtxoExpiringSoon(vtxo, thresholdMs) ||
|
|
3941
|
+
(vtxo) => isVtxoExpiringSoon(vtxo, thresholdMs) || chunk2JV4VQ7C_cjs.canRecoverOnchain(vtxo, now) || isSubdust(vtxo, dustAmount)
|
|
3896
3942
|
);
|
|
3897
3943
|
}
|
|
3898
3944
|
function isMigrationCapable(wallet) {
|
|
@@ -4491,11 +4537,11 @@ var VtxoManager = class _VtxoManager {
|
|
|
4491
4537
|
`Sweep not economical: output ${outputAmount} sats after ${fee} sats fee is below dust (${dustAmount} sats)`
|
|
4492
4538
|
);
|
|
4493
4539
|
}
|
|
4494
|
-
const tx = new
|
|
4540
|
+
const tx = new chunk2JV4VQ7C_cjs.Transaction();
|
|
4495
4541
|
for (const utxo of expiredUtxos) {
|
|
4496
|
-
const utxoScript =
|
|
4542
|
+
const utxoScript = chunk2JV4VQ7C_cjs.VtxoScript.decode(utxo.tapTree);
|
|
4497
4543
|
const utxoExitLeaf = utxoScript.leaves.find(
|
|
4498
|
-
(leaf) =>
|
|
4544
|
+
(leaf) => chunk2JV4VQ7C_cjs.CSVMultisigTapscript.isScriptValid(chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(leaf)) === true
|
|
4499
4545
|
);
|
|
4500
4546
|
if (!utxoExitLeaf) {
|
|
4501
4547
|
throw new Error(
|
|
@@ -4510,7 +4556,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
4510
4556
|
amount: BigInt(utxo.value)
|
|
4511
4557
|
},
|
|
4512
4558
|
tapLeafScript: [utxoExitLeaf],
|
|
4513
|
-
sequence:
|
|
4559
|
+
sequence: chunk2JV4VQ7C_cjs.getSequence(utxoExitLeaf)
|
|
4514
4560
|
});
|
|
4515
4561
|
}
|
|
4516
4562
|
tx.addOutputAddress(boardingAddress, outputAmount, this.getNetwork());
|
|
@@ -4543,6 +4589,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
4543
4589
|
async getDeprecatedSignerStatus() {
|
|
4544
4590
|
const wallet = this.requireMigrationCapableWallet();
|
|
4545
4591
|
const info = await wallet.arkProvider.getInfo();
|
|
4592
|
+
await wallet.settleServerInfoChanges?.();
|
|
4546
4593
|
const { reports: vtxoReports } = await this.classifyDeprecatedSignerContracts(info);
|
|
4547
4594
|
const { reports: boardingReports } = await this.classifyDeprecatedSignerBoarding(info);
|
|
4548
4595
|
return mergeSignerReports(vtxoReports, boardingReports);
|
|
@@ -4556,26 +4603,33 @@ var VtxoManager = class _VtxoManager {
|
|
|
4556
4603
|
*/
|
|
4557
4604
|
async migrateCore(options) {
|
|
4558
4605
|
const wallet = this.requireMigrationCapableWallet();
|
|
4606
|
+
const signerBeforeRefresh = base.hex.encode(wallet.arkServerPublicKey);
|
|
4559
4607
|
const info = await wallet.arkProvider.getInfo();
|
|
4608
|
+
await wallet.settleServerInfoChanges?.();
|
|
4609
|
+
const rotatedOnRefresh = signerBeforeRefresh !== base.hex.encode(wallet.arkServerPublicKey);
|
|
4560
4610
|
wallet.refreshDeprecatedSigners(info);
|
|
4561
4611
|
const signerSet = signerSetFromInfo(info);
|
|
4562
4612
|
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
4563
4613
|
const walletSignerHex = base.hex.encode(wallet.arkServerPublicKey);
|
|
4564
4614
|
const walletClass = classifyAgainstSignerSet(walletSignerHex, signerSet, nowSeconds);
|
|
4565
4615
|
if (signerSet.deprecated.size === 0 && walletClass.status === "CURRENT") {
|
|
4566
|
-
return { rotated:
|
|
4616
|
+
return { rotated: rotatedOnRefresh, expired: [], signers: [] };
|
|
4567
4617
|
}
|
|
4568
4618
|
if (walletClass.status === "UNKNOWN_SIGNER") {
|
|
4569
4619
|
const { reports: vtxoReports2 } = await this.classifyDeprecatedSignerContracts(info);
|
|
4570
4620
|
const { reports: boardingReports2 } = await this.classifyDeprecatedSignerBoarding(info);
|
|
4571
4621
|
return {
|
|
4572
|
-
|
|
4622
|
+
// Normally false here — a drained rotation targets the active
|
|
4623
|
+
// signer, which classifies CURRENT, not UNKNOWN. It is true only
|
|
4624
|
+
// when a second rotation landed inside the drain, leaving us on a
|
|
4625
|
+
// signer newer than `info`: still a rotation this pass applied.
|
|
4626
|
+
rotated: rotatedOnRefresh,
|
|
4573
4627
|
expired: [],
|
|
4574
4628
|
signers: mergeSignerReports(vtxoReports2, boardingReports2),
|
|
4575
4629
|
skipped: "unknown-wallet-signer"
|
|
4576
4630
|
};
|
|
4577
4631
|
}
|
|
4578
|
-
const rotated = await this.ensureReceiveOnActiveSigner(info);
|
|
4632
|
+
const rotated = await this.ensureReceiveOnActiveSigner(info) || rotatedOnRefresh;
|
|
4579
4633
|
const {
|
|
4580
4634
|
reports: vtxoReports,
|
|
4581
4635
|
migratable: vtxoMigratable,
|
|
@@ -4744,8 +4798,9 @@ var VtxoManager = class _VtxoManager {
|
|
|
4744
4798
|
if (!serverPubKey) continue;
|
|
4745
4799
|
const cls = classifyAgainstSignerSet(serverPubKey, signerSet, nowSeconds);
|
|
4746
4800
|
if (cls.status === "CURRENT") continue;
|
|
4747
|
-
const
|
|
4748
|
-
const
|
|
4801
|
+
const live = vtxos.filter((v) => !v.isUnrolled);
|
|
4802
|
+
const recoverable = live.filter((v) => v.isSwept && !chunk2JV4VQ7C_cjs.hasTerminalSpend(v));
|
|
4803
|
+
const spendable = live.filter((v) => !chunk2JV4VQ7C_cjs.hasTerminalSpend(v) && !v.isSwept);
|
|
4749
4804
|
const value = spendable.reduce((sum, v) => sum + v.value, 0);
|
|
4750
4805
|
let recoverableCount = 0;
|
|
4751
4806
|
let recoverableValue = 0;
|
|
@@ -4758,7 +4813,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
4758
4813
|
awaitingSweepCount = spendable.length;
|
|
4759
4814
|
awaitingSweepValue = value;
|
|
4760
4815
|
for (const v of spendable) {
|
|
4761
|
-
const exp =
|
|
4816
|
+
const exp = chunk2JV4VQ7C_cjs.toBatchExpiry(v);
|
|
4762
4817
|
if (exp !== void 0 && (nextSweepEta === void 0 || exp < nextSweepEta)) {
|
|
4763
4818
|
nextSweepEta = exp;
|
|
4764
4819
|
}
|
|
@@ -5019,7 +5074,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
5019
5074
|
/** Decodes the boarding tapscript exit path to extract the CSV timelock. */
|
|
5020
5075
|
getBoardingTimelock() {
|
|
5021
5076
|
const wallet = this.getSweepWallet();
|
|
5022
|
-
const exitScript =
|
|
5077
|
+
const exitScript = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(
|
|
5023
5078
|
base.hex.decode(wallet.boardingTapscript.exitScript)
|
|
5024
5079
|
);
|
|
5025
5080
|
return exitScript.params.timelock;
|
|
@@ -5150,8 +5205,8 @@ var VtxoManager = class _VtxoManager {
|
|
|
5150
5205
|
* or doesn't carry the metadata.
|
|
5151
5206
|
*/
|
|
5152
5207
|
extractSpentOutpoint(error) {
|
|
5153
|
-
const ark =
|
|
5154
|
-
if (!
|
|
5208
|
+
const ark = chunk2JV4VQ7C_cjs.maybeArkError(error);
|
|
5209
|
+
if (!chunk2JV4VQ7C_cjs.isArkError(ark, chunk2JV4VQ7C_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
|
|
5155
5210
|
const raw = ark.metadata?.vtxo_outpoint;
|
|
5156
5211
|
if (typeof raw !== "string") return void 0;
|
|
5157
5212
|
const [txid, voutStr] = raw.split(":");
|
|
@@ -5341,7 +5396,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
5341
5396
|
if (filteredVtxos.length >= MAX_VTXOS_PER_SETTLEMENT) {
|
|
5342
5397
|
break;
|
|
5343
5398
|
}
|
|
5344
|
-
const inputFee = estimator.evalOffchainInput(
|
|
5399
|
+
const inputFee = estimator.evalOffchainInput(chunk2JV4VQ7C_cjs.toOffchainInputFeeParams(v));
|
|
5345
5400
|
if (inputFee.satoshis >= v.value) {
|
|
5346
5401
|
continue;
|
|
5347
5402
|
}
|
|
@@ -5361,7 +5416,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
5361
5416
|
const arkAddress = await this.wallet.getAddress();
|
|
5362
5417
|
const outputFee = estimator.evalOffchainOutput({
|
|
5363
5418
|
amount: totalAmount,
|
|
5364
|
-
script: base.hex.encode(
|
|
5419
|
+
script: base.hex.encode(chunk2JV4VQ7C_cjs.ArkAddress.decode(arkAddress).pkScript)
|
|
5365
5420
|
});
|
|
5366
5421
|
totalAmount -= BigInt(outputFee.satoshis);
|
|
5367
5422
|
if (totalAmount < dustAmount) return;
|
|
@@ -5441,7 +5496,7 @@ var ArkNote = class _ArkNote {
|
|
|
5441
5496
|
this.value = value;
|
|
5442
5497
|
this.HRP = HRP;
|
|
5443
5498
|
const preimageHash = utils_js.sha256(this.preimage);
|
|
5444
|
-
this.vtxoScript = new
|
|
5499
|
+
this.vtxoScript = new chunk2JV4VQ7C_cjs.VtxoScript([noteTapscript(preimageHash)]);
|
|
5445
5500
|
const leaf = this.vtxoScript.leaves[0];
|
|
5446
5501
|
this.txid = base.hex.encode(new Uint8Array(preimageHash).reverse());
|
|
5447
5502
|
this.tapTree = this.vtxoScript.encode();
|
|
@@ -5608,7 +5663,7 @@ var ArkadeCash = class _ArkadeCash {
|
|
|
5608
5663
|
const privateKey = data.slice(1, 33);
|
|
5609
5664
|
const serverPubKey = data.slice(33, 65);
|
|
5610
5665
|
const sequence = new DataView(data.buffer, data.byteOffset + 65, 4).getUint32(0, false);
|
|
5611
|
-
const csvTimelock =
|
|
5666
|
+
const csvTimelock = chunk2JV4VQ7C_cjs.sequenceToTimelock(sequence);
|
|
5612
5667
|
return new _ArkadeCash(privateKey, serverPubKey, csvTimelock, decoded.prefix);
|
|
5613
5668
|
}
|
|
5614
5669
|
toString() {
|
|
@@ -5616,7 +5671,7 @@ var ArkadeCash = class _ArkadeCash {
|
|
|
5616
5671
|
data[0] = _ArkadeCash.Version;
|
|
5617
5672
|
data.set(this._privateKey, 1);
|
|
5618
5673
|
data.set(this._serverPubKey, 33);
|
|
5619
|
-
const sequence =
|
|
5674
|
+
const sequence = chunk2JV4VQ7C_cjs.timelockToSequence(this.csvTimelock);
|
|
5620
5675
|
new DataView(data.buffer, data.byteOffset + 65, 4).setUint32(0, sequence, false);
|
|
5621
5676
|
const words = base.bech32m.toWords(data);
|
|
5622
5677
|
return base.bech32m.encode(this.hrp, words, 1023);
|
|
@@ -5625,7 +5680,7 @@ var ArkadeCash = class _ArkadeCash {
|
|
|
5625
5680
|
return SingleKey.fromPrivateKey(this._privateKey);
|
|
5626
5681
|
}
|
|
5627
5682
|
get vtxoScript() {
|
|
5628
|
-
return new
|
|
5683
|
+
return new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
|
|
5629
5684
|
pubKey: this._publicKey,
|
|
5630
5685
|
serverPubKey: this._serverPubKey,
|
|
5631
5686
|
csvTimelock: this.csvTimelock
|
|
@@ -5886,7 +5941,7 @@ async function captureExitBranch(params) {
|
|
|
5886
5941
|
const nonCommitment = ordered.filter((c) => chainTxTypeToChainedExit(c.type) !== 1 /* Commitment */).map((c) => c.txid);
|
|
5887
5942
|
if (nonCommitment.length > 0) {
|
|
5888
5943
|
for (const psbt of await resolver.getVirtualTxs(nonCommitment)) {
|
|
5889
|
-
psbtByTxid.set(
|
|
5944
|
+
psbtByTxid.set(chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
5890
5945
|
}
|
|
5891
5946
|
}
|
|
5892
5947
|
}
|
|
@@ -5929,10 +5984,10 @@ var IndexerExitDataSource = class {
|
|
|
5929
5984
|
while (hasMore) {
|
|
5930
5985
|
const { chain: page, page: meta } = await this.indexer.getVtxoChain(
|
|
5931
5986
|
{ txid: vtxo.txid, vout: vtxo.vout },
|
|
5932
|
-
{ pageIndex, pageSize:
|
|
5987
|
+
{ pageIndex, pageSize: chunk2JV4VQ7C_cjs.DEFAULT_PAGE_SIZE }
|
|
5933
5988
|
);
|
|
5934
5989
|
chain.push(...page);
|
|
5935
|
-
hasMore = meta ? page.length ===
|
|
5990
|
+
hasMore = meta ? page.length === chunk2JV4VQ7C_cjs.DEFAULT_PAGE_SIZE : false;
|
|
5936
5991
|
pageIndex++;
|
|
5937
5992
|
}
|
|
5938
5993
|
return chain;
|
|
@@ -5944,12 +5999,12 @@ var IndexerExitDataSource = class {
|
|
|
5944
5999
|
while (hasMore) {
|
|
5945
6000
|
const { txs, page } = await this.indexer.getVirtualTxs(txids, {
|
|
5946
6001
|
pageIndex,
|
|
5947
|
-
pageSize:
|
|
6002
|
+
pageSize: chunk2JV4VQ7C_cjs.DEFAULT_PAGE_SIZE
|
|
5948
6003
|
});
|
|
5949
6004
|
for (const psbt of txs) {
|
|
5950
|
-
out.set(
|
|
6005
|
+
out.set(chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
5951
6006
|
}
|
|
5952
|
-
hasMore = page ? txs.length ===
|
|
6007
|
+
hasMore = page ? txs.length === chunk2JV4VQ7C_cjs.DEFAULT_PAGE_SIZE : false;
|
|
5953
6008
|
pageIndex++;
|
|
5954
6009
|
}
|
|
5955
6010
|
return out;
|
|
@@ -5970,7 +6025,7 @@ function chainedTxTypeToChainTxType(t) {
|
|
|
5970
6025
|
}
|
|
5971
6026
|
}
|
|
5972
6027
|
function psbtInputTxids(psbtBase64) {
|
|
5973
|
-
const tx =
|
|
6028
|
+
const tx = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
|
|
5974
6029
|
const ids = [];
|
|
5975
6030
|
for (let i = 0; i < tx.inputsLength; i++) {
|
|
5976
6031
|
const txid = tx.getInput(i).txid;
|
|
@@ -6151,6 +6206,8 @@ function serializeArkInfoSnapshot(info, savedAt) {
|
|
|
6151
6206
|
unilateralExitDelay: info.unilateralExitDelay.toString(),
|
|
6152
6207
|
boardingExitDelay: info.boardingExitDelay.toString(),
|
|
6153
6208
|
vtxoTreeExpiry: info.vtxoTreeExpiry?.toString(),
|
|
6209
|
+
maxTxWeight: info.maxTxWeight?.toString(),
|
|
6210
|
+
maxOpReturnOutputs: info.maxOpReturnOutputs?.toString(),
|
|
6154
6211
|
sessionDuration: info.sessionDuration.toString(),
|
|
6155
6212
|
dust: info.dust.toString(),
|
|
6156
6213
|
fees: info.fees,
|
|
@@ -6201,6 +6258,8 @@ function hydrateArkInfo(snapshot) {
|
|
|
6201
6258
|
signerPubkey: a.signerPubkey,
|
|
6202
6259
|
unilateralExitDelay: BigInt(a.unilateralExitDelay),
|
|
6203
6260
|
vtxoTreeExpiry: a.vtxoTreeExpiry !== void 0 ? BigInt(a.vtxoTreeExpiry) : void 0,
|
|
6261
|
+
maxTxWeight: a.maxTxWeight !== void 0 ? BigInt(a.maxTxWeight) : void 0,
|
|
6262
|
+
maxOpReturnOutputs: a.maxOpReturnOutputs !== void 0 ? BigInt(a.maxOpReturnOutputs) : void 0,
|
|
6204
6263
|
utxoMaxAmount: BigInt(a.utxoMaxAmount),
|
|
6205
6264
|
utxoMinAmount: BigInt(a.utxoMinAmount),
|
|
6206
6265
|
version: a.version,
|
|
@@ -6273,8 +6332,10 @@ function parseStoredArkInfoSnapshot(raw) {
|
|
|
6273
6332
|
]) {
|
|
6274
6333
|
assertDecimalString(a[field], `arkInfo.${field}`);
|
|
6275
6334
|
}
|
|
6276
|
-
|
|
6277
|
-
|
|
6335
|
+
for (const field of ["vtxoTreeExpiry", "maxTxWeight", "maxOpReturnOutputs"]) {
|
|
6336
|
+
if (a[field] !== void 0) {
|
|
6337
|
+
assertDecimalString(a[field], `arkInfo.${field}`);
|
|
6338
|
+
}
|
|
6278
6339
|
}
|
|
6279
6340
|
assertFeeInfo(a.fees, "arkInfo.fees");
|
|
6280
6341
|
if (!Array.isArray(a.deprecatedSigners)) {
|
|
@@ -6323,10 +6384,10 @@ async function resolveArkInfo(arkProvider, walletRepository) {
|
|
|
6323
6384
|
try {
|
|
6324
6385
|
info = await arkProvider.getInfo();
|
|
6325
6386
|
} catch (err) {
|
|
6326
|
-
if (!
|
|
6387
|
+
if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
|
|
6327
6388
|
const snapshot = await loadArkInfoSnapshot(walletRepository);
|
|
6328
6389
|
if (!snapshot) {
|
|
6329
|
-
throw new
|
|
6390
|
+
throw new chunk2JV4VQ7C_cjs.ProviderUnavailableError(
|
|
6330
6391
|
"Arkade server info is unavailable and no cached snapshot exists",
|
|
6331
6392
|
{ cause: err }
|
|
6332
6393
|
);
|
|
@@ -6709,7 +6770,7 @@ function collectArkTxidsNeedingCreatedAt(vtxos) {
|
|
|
6709
6770
|
return [...txids];
|
|
6710
6771
|
}
|
|
6711
6772
|
async function buildTransactionHistory(vtxos, allBoardingTxs, commitmentsToIgnore, resolveTxCreatedAt) {
|
|
6712
|
-
const fromOldestVtxo = vtxos.map(
|
|
6773
|
+
const fromOldestVtxo = vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo).sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
|
6713
6774
|
const txidsNeedingCreatedAt = resolveTxCreatedAt ? collectArkTxidsNeedingCreatedAt(fromOldestVtxo) : [];
|
|
6714
6775
|
const resolvedCreatedAt = resolveTxCreatedAt && txidsNeedingCreatedAt.length > 0 ? await resolveTxCreatedAt(txidsNeedingCreatedAt) : /* @__PURE__ */ new Map();
|
|
6715
6776
|
const unmatchedSettledBoardingTxs = allBoardingTxs.filter(isSettledBoardingReceive).sort((a, b) => a.createdAt - b.createdAt);
|
|
@@ -6873,7 +6934,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
6873
6934
|
const virtualCoins = await this.wallet.getSpendableVtxos({
|
|
6874
6935
|
withRecoverable: false
|
|
6875
6936
|
});
|
|
6876
|
-
const controlAssetRef = params.controlAssetId ?
|
|
6937
|
+
const controlAssetRef = params.controlAssetId ? chunkCO3KKSWM_cjs.AssetRef.fromId(chunkCO3KKSWM_cjs.AssetId.fromString(params.controlAssetId)) : null;
|
|
6877
6938
|
const coinSelection = selectVirtualCoins(virtualCoins, Number(this.wallet.dustAmount));
|
|
6878
6939
|
let totalBtcSelected = 0n;
|
|
6879
6940
|
const assetChanges = /* @__PURE__ */ new Map();
|
|
@@ -6886,8 +6947,8 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
6886
6947
|
}
|
|
6887
6948
|
}
|
|
6888
6949
|
const groups = [];
|
|
6889
|
-
const issuedAssetOutput =
|
|
6890
|
-
const issuedAssetGroup =
|
|
6950
|
+
const issuedAssetOutput = chunkCO3KKSWM_cjs.AssetOutput.create(0, params.amount);
|
|
6951
|
+
const issuedAssetGroup = chunkCO3KKSWM_cjs.AssetGroup.create(
|
|
6891
6952
|
null,
|
|
6892
6953
|
controlAssetRef,
|
|
6893
6954
|
[],
|
|
@@ -6902,28 +6963,28 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
6902
6963
|
for (const [inputIndex, assets] of assetInputs) {
|
|
6903
6964
|
for (const asset of assets) {
|
|
6904
6965
|
if (asset.assetId !== assetId) continue;
|
|
6905
|
-
changeInputs.push(
|
|
6966
|
+
changeInputs.push(chunkCO3KKSWM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
6906
6967
|
}
|
|
6907
6968
|
}
|
|
6908
6969
|
groups.push(
|
|
6909
|
-
|
|
6910
|
-
|
|
6970
|
+
chunkCO3KKSWM_cjs.AssetGroup.create(
|
|
6971
|
+
chunkCO3KKSWM_cjs.AssetId.fromString(assetId),
|
|
6911
6972
|
null,
|
|
6912
6973
|
changeInputs,
|
|
6913
|
-
[
|
|
6974
|
+
[chunkCO3KKSWM_cjs.AssetOutput.create(0, amount)],
|
|
6914
6975
|
[]
|
|
6915
6976
|
)
|
|
6916
6977
|
);
|
|
6917
6978
|
}
|
|
6918
6979
|
}
|
|
6919
6980
|
const address = await this.wallet.getAddress();
|
|
6920
|
-
const outputAddress =
|
|
6981
|
+
const outputAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
|
|
6921
6982
|
const outputs = [
|
|
6922
6983
|
{
|
|
6923
6984
|
script: outputAddress.pkScript,
|
|
6924
6985
|
amount: BigInt(totalBtcSelected)
|
|
6925
6986
|
},
|
|
6926
|
-
Extension.create([
|
|
6987
|
+
Extension.create([chunkCO3KKSWM_cjs.Packet.create(groups)]).txOut()
|
|
6927
6988
|
];
|
|
6928
6989
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(
|
|
6929
6990
|
coinSelection.inputs,
|
|
@@ -6931,7 +6992,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
6931
6992
|
);
|
|
6932
6993
|
return {
|
|
6933
6994
|
arkTxId: arkTxid,
|
|
6934
|
-
assetId:
|
|
6995
|
+
assetId: chunkCO3KKSWM_cjs.AssetId.create(arkTxid, 0).toString()
|
|
6935
6996
|
};
|
|
6936
6997
|
}
|
|
6937
6998
|
/**
|
|
@@ -7003,16 +7064,16 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7003
7064
|
for (const [inputIndex, assets] of assetInputs) {
|
|
7004
7065
|
for (const asset of assets) {
|
|
7005
7066
|
if (asset.assetId !== params.assetId) continue;
|
|
7006
|
-
reissueInputs.push(
|
|
7067
|
+
reissueInputs.push(chunkCO3KKSWM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
7007
7068
|
}
|
|
7008
7069
|
}
|
|
7009
7070
|
const totalAssetAmount = assetToReissueAmount + params.amount;
|
|
7010
|
-
const reissueAssetIdObj =
|
|
7011
|
-
const reissueAssetGroup =
|
|
7071
|
+
const reissueAssetIdObj = chunkCO3KKSWM_cjs.AssetId.fromString(params.assetId);
|
|
7072
|
+
const reissueAssetGroup = chunkCO3KKSWM_cjs.AssetGroup.create(
|
|
7012
7073
|
reissueAssetIdObj,
|
|
7013
7074
|
null,
|
|
7014
7075
|
reissueInputs,
|
|
7015
|
-
[
|
|
7076
|
+
[chunkCO3KKSWM_cjs.AssetOutput.create(0, totalAssetAmount)],
|
|
7016
7077
|
[]
|
|
7017
7078
|
);
|
|
7018
7079
|
const groups = [reissueAssetGroup];
|
|
@@ -7021,27 +7082,27 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7021
7082
|
for (const [inputIndex, assets] of assetInputs) {
|
|
7022
7083
|
for (const asset of assets) {
|
|
7023
7084
|
if (asset.assetId !== assetId) continue;
|
|
7024
|
-
changeInputs.push(
|
|
7085
|
+
changeInputs.push(chunkCO3KKSWM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
7025
7086
|
}
|
|
7026
7087
|
}
|
|
7027
7088
|
groups.push(
|
|
7028
|
-
|
|
7029
|
-
|
|
7089
|
+
chunkCO3KKSWM_cjs.AssetGroup.create(
|
|
7090
|
+
chunkCO3KKSWM_cjs.AssetId.fromString(assetId),
|
|
7030
7091
|
null,
|
|
7031
7092
|
changeInputs,
|
|
7032
|
-
[
|
|
7093
|
+
[chunkCO3KKSWM_cjs.AssetOutput.create(0, amount)],
|
|
7033
7094
|
[]
|
|
7034
7095
|
)
|
|
7035
7096
|
);
|
|
7036
7097
|
}
|
|
7037
7098
|
const address = await this.wallet.getAddress();
|
|
7038
|
-
const outputAddress =
|
|
7099
|
+
const outputAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
|
|
7039
7100
|
const outputs = [
|
|
7040
7101
|
{
|
|
7041
7102
|
script: outputAddress.pkScript,
|
|
7042
7103
|
amount: BigInt(totalBtcSelected)
|
|
7043
7104
|
},
|
|
7044
|
-
Extension.create([
|
|
7105
|
+
Extension.create([chunkCO3KKSWM_cjs.Packet.create(groups)]).txOut()
|
|
7045
7106
|
];
|
|
7046
7107
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
|
|
7047
7108
|
return arkTxid;
|
|
@@ -7108,27 +7169,27 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
7108
7169
|
for (const [inputIndex, assets] of assetInputs) {
|
|
7109
7170
|
for (const asset of assets) {
|
|
7110
7171
|
if (asset.assetId !== assetId) continue;
|
|
7111
|
-
changeInputs.push(
|
|
7172
|
+
changeInputs.push(chunkCO3KKSWM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
7112
7173
|
}
|
|
7113
7174
|
}
|
|
7114
7175
|
groups.push(
|
|
7115
|
-
|
|
7116
|
-
|
|
7176
|
+
chunkCO3KKSWM_cjs.AssetGroup.create(
|
|
7177
|
+
chunkCO3KKSWM_cjs.AssetId.fromString(assetId),
|
|
7117
7178
|
null,
|
|
7118
7179
|
changeInputs,
|
|
7119
|
-
amount > 0n ? [
|
|
7180
|
+
amount > 0n ? [chunkCO3KKSWM_cjs.AssetOutput.create(0, amount)] : [],
|
|
7120
7181
|
[]
|
|
7121
7182
|
)
|
|
7122
7183
|
);
|
|
7123
7184
|
}
|
|
7124
7185
|
const address = await this.wallet.getAddress();
|
|
7125
|
-
const outputAddress =
|
|
7186
|
+
const outputAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(address);
|
|
7126
7187
|
const outputs = [
|
|
7127
7188
|
{
|
|
7128
7189
|
script: outputAddress.pkScript,
|
|
7129
7190
|
amount: BigInt(totalBtcSelected)
|
|
7130
7191
|
},
|
|
7131
|
-
Extension.create([
|
|
7192
|
+
Extension.create([chunkCO3KKSWM_cjs.Packet.create(groups)]).txOut()
|
|
7132
7193
|
];
|
|
7133
7194
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
|
|
7134
7195
|
return arkTxid;
|
|
@@ -7153,7 +7214,7 @@ function castMetadata(metadata) {
|
|
|
7153
7214
|
} else {
|
|
7154
7215
|
throw new Error("Invalid metadata value type");
|
|
7155
7216
|
}
|
|
7156
|
-
md.push(
|
|
7217
|
+
md.push(chunkCO3KKSWM_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
|
|
7157
7218
|
}
|
|
7158
7219
|
return md;
|
|
7159
7220
|
}
|
|
@@ -7174,10 +7235,10 @@ var DelegateManagerImpl = class {
|
|
|
7174
7235
|
if (vtxos.length === 0) {
|
|
7175
7236
|
return { delegated: [], failed: [] };
|
|
7176
7237
|
}
|
|
7177
|
-
const destinationScript =
|
|
7238
|
+
const destinationScript = chunk2JV4VQ7C_cjs.ArkAddress.decode(destination).pkScript;
|
|
7178
7239
|
const arkInfo = await this.arkInfoProvider.getInfo();
|
|
7179
7240
|
const delegateInfo = await this.delegateProvider.getDelegateInfo();
|
|
7180
|
-
const eligible = vtxos.map(
|
|
7241
|
+
const eligible = vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo).filter(
|
|
7181
7242
|
(v) => isAnnotated(v) && findDelegateTapLeaf(v, delegateInfo.pubkey) !== void 0
|
|
7182
7243
|
);
|
|
7183
7244
|
if (eligible.length === 0) {
|
|
@@ -7206,11 +7267,11 @@ var DelegateManagerImpl = class {
|
|
|
7206
7267
|
const groupByExpiry = /* @__PURE__ */ new Map();
|
|
7207
7268
|
let recoverableVtxos = [];
|
|
7208
7269
|
for (const vtxo of eligible) {
|
|
7209
|
-
if (
|
|
7270
|
+
if (chunk2JV4VQ7C_cjs.canRecoverOnchain(vtxo, now)) {
|
|
7210
7271
|
recoverableVtxos.push(vtxo);
|
|
7211
7272
|
continue;
|
|
7212
7273
|
}
|
|
7213
|
-
const expiry =
|
|
7274
|
+
const expiry = chunk2JV4VQ7C_cjs.toBatchExpiry(vtxo);
|
|
7214
7275
|
if (!expiry) continue;
|
|
7215
7276
|
const dayKey = getDayTimestamp(expiry);
|
|
7216
7277
|
groupByExpiry.set(dayKey, [...groupByExpiry.get(dayKey) ?? [], vtxo]);
|
|
@@ -7275,7 +7336,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
7275
7336
|
}
|
|
7276
7337
|
if (!delegateAt) {
|
|
7277
7338
|
const now = { timestamp: /* @__PURE__ */ new Date() };
|
|
7278
|
-
const expiryTimestamp = vtxos.filter((coin) => !
|
|
7339
|
+
const expiryTimestamp = vtxos.filter((coin) => !chunk2JV4VQ7C_cjs.canRecoverOnchain(coin, now) && chunk2JV4VQ7C_cjs.toBatchExpiry(coin)).reduce((min, coin) => Math.min(min, chunk2JV4VQ7C_cjs.toBatchExpiry(coin)), Number.MAX_SAFE_INTEGER);
|
|
7279
7340
|
if (!expiryTimestamp || expiryTimestamp === Number.MAX_SAFE_INTEGER) {
|
|
7280
7341
|
delegateAt = new Date(Date.now() + 1 * 60 * 1e3);
|
|
7281
7342
|
} else {
|
|
@@ -7304,7 +7365,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
7304
7365
|
let amount = 0n;
|
|
7305
7366
|
for (const coin of vtxos) {
|
|
7306
7367
|
const inputFee = estimator.evalOffchainInput({
|
|
7307
|
-
...
|
|
7368
|
+
...chunk2JV4VQ7C_cjs.toOffchainInputFeeParams(coin),
|
|
7308
7369
|
type: "vtxo"
|
|
7309
7370
|
});
|
|
7310
7371
|
if (inputFee.value >= coin.value) {
|
|
@@ -7318,7 +7379,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
7318
7379
|
const delegateFee = BigInt(Number(fee));
|
|
7319
7380
|
if (delegateFee > 0n) {
|
|
7320
7381
|
outputs.push({
|
|
7321
|
-
script:
|
|
7382
|
+
script: chunk2JV4VQ7C_cjs.ArkAddress.decode(delegateAddress).pkScript,
|
|
7322
7383
|
amount: delegateFee
|
|
7323
7384
|
});
|
|
7324
7385
|
}
|
|
@@ -7351,10 +7412,10 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
7351
7412
|
destinationScript
|
|
7352
7413
|
);
|
|
7353
7414
|
const forfeitOutputScript = btcSigner.OutScript.encode(
|
|
7354
|
-
btcSigner.Address(
|
|
7415
|
+
btcSigner.Address(chunk2JV4VQ7C_cjs.getNetwork(network)).decode(forfeitAddress)
|
|
7355
7416
|
);
|
|
7356
7417
|
const forfeits = await Promise.all(
|
|
7357
|
-
vtxos.filter((v) => !
|
|
7418
|
+
vtxos.filter((v) => !chunk2JV4VQ7C_cjs.canRecoverOnchain(v, { timestamp: /* @__PURE__ */ new Date() })).map(async (coin) => {
|
|
7358
7419
|
const forfeit = await makeDelegateForfeitTx(
|
|
7359
7420
|
coin,
|
|
7360
7421
|
dust,
|
|
@@ -7379,7 +7440,7 @@ async function makeDelegateForfeitTx(input, connectorAmount, delegatePubkey, for
|
|
|
7379
7440
|
index: input.vout,
|
|
7380
7441
|
witnessUtxo: {
|
|
7381
7442
|
amount: BigInt(input.value),
|
|
7382
|
-
script:
|
|
7443
|
+
script: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
7383
7444
|
},
|
|
7384
7445
|
sighashType: btcSigner.SigHash.ALL_ANYONECANPAY,
|
|
7385
7446
|
tapLeafScript: [delegateTapLeaf]
|
|
@@ -7437,7 +7498,7 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
7437
7498
|
expire_at: 0,
|
|
7438
7499
|
cosigners_public_keys: cosignerPubKeys
|
|
7439
7500
|
};
|
|
7440
|
-
const proof =
|
|
7501
|
+
const proof = chunk2JV4VQ7C_cjs.Intent.create(message, coins, outputs);
|
|
7441
7502
|
const signedProof = await identity.sign(proof);
|
|
7442
7503
|
return {
|
|
7443
7504
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -7455,10 +7516,10 @@ function getDayTimestamp(timestamp) {
|
|
|
7455
7516
|
function findDelegateTapLeaf(vtxo, delegatePubkey) {
|
|
7456
7517
|
if (!vtxo.tapTree) return void 0;
|
|
7457
7518
|
const pk = delegatePubkey.length === 66 ? delegatePubkey.slice(2) : delegatePubkey;
|
|
7458
|
-
const vtxoScript =
|
|
7519
|
+
const vtxoScript = chunk2JV4VQ7C_cjs.VtxoScript.decode(vtxo.tapTree);
|
|
7459
7520
|
return vtxoScript.leaves.find((tapLeaf) => {
|
|
7460
|
-
const arkTapscript =
|
|
7461
|
-
if (!
|
|
7521
|
+
const arkTapscript = chunk2JV4VQ7C_cjs.decodeTapscript(chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(tapLeaf));
|
|
7522
|
+
if (!chunk2JV4VQ7C_cjs.MultisigTapscript.is(arkTapscript)) return false;
|
|
7462
7523
|
return arkTapscript.params.pubkeys.map(base.hex.encode).includes(pk);
|
|
7463
7524
|
});
|
|
7464
7525
|
}
|
|
@@ -7739,7 +7800,7 @@ function createManagedConnection(dbName, version, initDatabase2) {
|
|
|
7739
7800
|
};
|
|
7740
7801
|
}
|
|
7741
7802
|
function scriptFromArkAddress(address) {
|
|
7742
|
-
return base.hex.encode(
|
|
7803
|
+
return base.hex.encode(chunk2JV4VQ7C_cjs.ArkAddress.decode(address).pkScript);
|
|
7743
7804
|
}
|
|
7744
7805
|
|
|
7745
7806
|
// src/repositories/indexedDB/schema.ts
|
|
@@ -8234,7 +8295,7 @@ function validateVtxosForScript(vtxos, script, context) {
|
|
|
8234
8295
|
}
|
|
8235
8296
|
async function getVtxosForContract(repo, contract) {
|
|
8236
8297
|
const vtxos = repo.getVtxosForScript ? await repo.getVtxosForScript(contract.script) : filterVtxosForScript(await repo.getVtxos(contract.address), contract.script);
|
|
8237
|
-
return vtxos.map(
|
|
8298
|
+
return vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
|
|
8238
8299
|
}
|
|
8239
8300
|
async function saveVtxosForContract(repo, contract, vtxos) {
|
|
8240
8301
|
if (repo.saveVtxosForScript) {
|
|
@@ -8376,7 +8437,7 @@ function decodeArkContract(encoded) {
|
|
|
8376
8437
|
}
|
|
8377
8438
|
function contractFromArkContract(encoded, options = {}) {
|
|
8378
8439
|
const parsed = decodeArkContract(encoded);
|
|
8379
|
-
const handler =
|
|
8440
|
+
const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(parsed.type);
|
|
8380
8441
|
if (!handler) {
|
|
8381
8442
|
throw new Error(`No handler registered for contract type '${parsed.type}'`);
|
|
8382
8443
|
}
|
|
@@ -8390,9 +8451,9 @@ function contractFromArkContract(encoded, options = {}) {
|
|
|
8390
8451
|
metadata: options.metadata
|
|
8391
8452
|
};
|
|
8392
8453
|
}
|
|
8393
|
-
function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix =
|
|
8454
|
+
function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunk2JV4VQ7C_cjs.DEFAULT_NETWORK.hrp, options = {}) {
|
|
8394
8455
|
const parsed = decodeArkContract(encoded);
|
|
8395
|
-
const handler =
|
|
8456
|
+
const handler = chunkOIZ2V2VD_cjs.contractHandlers.getOrThrow(parsed.type);
|
|
8396
8457
|
const params = parsed.data;
|
|
8397
8458
|
const vtxoScript = handler.createScript(params);
|
|
8398
8459
|
return {
|
|
@@ -8646,9 +8707,9 @@ var ContractWatcher = class {
|
|
|
8646
8707
|
this.connectionState = "connected";
|
|
8647
8708
|
this.reconnectAttempts = 0;
|
|
8648
8709
|
this.listenLoop().catch((e) => {
|
|
8649
|
-
if (
|
|
8710
|
+
if (chunk2JV4VQ7C_cjs.isEventSourceError(e)) {
|
|
8650
8711
|
console.debug("ContractWatcher subscription disconnected; reconnecting");
|
|
8651
|
-
} else if (!
|
|
8712
|
+
} else if (!chunk2JV4VQ7C_cjs.isEventSourceUnavailableError(e)) {
|
|
8652
8713
|
console.error(e);
|
|
8653
8714
|
}
|
|
8654
8715
|
this.connectionState = "disconnected";
|
|
@@ -8660,7 +8721,7 @@ var ContractWatcher = class {
|
|
|
8660
8721
|
this.scheduleReconnect();
|
|
8661
8722
|
});
|
|
8662
8723
|
} catch (error) {
|
|
8663
|
-
if (!
|
|
8724
|
+
if (!chunk2JV4VQ7C_cjs.isEventSourceUnavailableError(error)) {
|
|
8664
8725
|
console.error("ContractWatcher connection failed:", error);
|
|
8665
8726
|
}
|
|
8666
8727
|
this.connectionState = "disconnected";
|
|
@@ -8686,7 +8747,7 @@ var ContractWatcher = class {
|
|
|
8686
8747
|
* slower; what it loses is push latency.
|
|
8687
8748
|
*/
|
|
8688
8749
|
reportEventSourceUnavailable(error) {
|
|
8689
|
-
if (!
|
|
8750
|
+
if (!chunk2JV4VQ7C_cjs.isEventSourceUnavailableError(error)) return false;
|
|
8690
8751
|
if (!this.eventSourceReported) {
|
|
8691
8752
|
this.eventSourceReported = true;
|
|
8692
8753
|
console.warn(
|
|
@@ -8902,14 +8963,14 @@ var ContractWatcher = class {
|
|
|
8902
8963
|
const timestamp = Date.now();
|
|
8903
8964
|
if (update.newVtxos?.length) {
|
|
8904
8965
|
this.processSubscriptionVtxos(
|
|
8905
|
-
update.newVtxos.map(
|
|
8966
|
+
update.newVtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo),
|
|
8906
8967
|
"vtxo_received",
|
|
8907
8968
|
timestamp
|
|
8908
8969
|
);
|
|
8909
8970
|
}
|
|
8910
8971
|
if (update.spentVtxos?.length) {
|
|
8911
8972
|
this.processSubscriptionVtxos(
|
|
8912
|
-
update.spentVtxos.map(
|
|
8973
|
+
update.spentVtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo),
|
|
8913
8974
|
"vtxo_spent",
|
|
8914
8975
|
timestamp
|
|
8915
8976
|
);
|
|
@@ -9004,7 +9065,7 @@ var NON_TERMINAL_INTENT_STATES = ALL_INTENT_STATES.filter(
|
|
|
9004
9065
|
(s) => !isTerminalIntentState(s)
|
|
9005
9066
|
);
|
|
9006
9067
|
function isConsumed(vtxo) {
|
|
9007
|
-
return vtxo !== void 0 && (vtxo
|
|
9068
|
+
return vtxo !== void 0 && chunk2JV4VQ7C_cjs.hasTerminalSpend(vtxo);
|
|
9008
9069
|
}
|
|
9009
9070
|
async function classifyIntent(intent, vtxosByOutpoint, now) {
|
|
9010
9071
|
if (isTerminalIntentState(intent.state)) return void 0;
|
|
@@ -9014,6 +9075,11 @@ async function classifyIntent(intent, vtxosByOutpoint, now) {
|
|
|
9014
9075
|
const commitmentTransactionId = intent.commitmentTransactionId ?? consumed.map((v) => v?.settledBy).find((s) => !!s);
|
|
9015
9076
|
return terminal(intent, "batch_succeeded", now, { commitmentTransactionId });
|
|
9016
9077
|
}
|
|
9078
|
+
if (consumed.some((vtxo) => vtxo?.isUnrolled)) {
|
|
9079
|
+
return terminal(intent, "cancelled", now, {
|
|
9080
|
+
cancellationReason: "reconciliation: an input was unilaterally exited"
|
|
9081
|
+
});
|
|
9082
|
+
}
|
|
9017
9083
|
if (intent.state === "waiting_to_submit") {
|
|
9018
9084
|
return terminal(intent, "cancelled", now, {
|
|
9019
9085
|
cancellationReason: "reconciliation: intent was never submitted before restart"
|
|
@@ -9042,7 +9108,7 @@ async function reconcileIntents(deps) {
|
|
|
9042
9108
|
let vtxosByOutpoint = /* @__PURE__ */ new Map();
|
|
9043
9109
|
if (outpoints.length > 0) {
|
|
9044
9110
|
try {
|
|
9045
|
-
const { vtxos } = await
|
|
9111
|
+
const { vtxos } = await chunk2JV4VQ7C_cjs.getNormalizedVtxos(deps.indexerProvider, { outpoints });
|
|
9046
9112
|
vtxosByOutpoint = new Map(vtxos.map((v) => [outpointKey(v), v]));
|
|
9047
9113
|
} catch (e) {
|
|
9048
9114
|
console.error("reconcileIntents: failed to fetch input VTXO state", e);
|
|
@@ -9216,7 +9282,7 @@ var ContractManager = class _ContractManager {
|
|
|
9216
9282
|
await this.reconcileWatched();
|
|
9217
9283
|
this.markSyncOnline();
|
|
9218
9284
|
} catch (err) {
|
|
9219
|
-
if (!
|
|
9285
|
+
if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
|
|
9220
9286
|
this.markSyncDegraded(err);
|
|
9221
9287
|
}
|
|
9222
9288
|
this.initialized = true;
|
|
@@ -9348,7 +9414,7 @@ var ContractManager = class _ContractManager {
|
|
|
9348
9414
|
const from = Math.max(0, watermark - lookAhead.size);
|
|
9349
9415
|
const to = watermark + lookAhead.size;
|
|
9350
9416
|
const deps = lookAhead.candidateDeps();
|
|
9351
|
-
const handlers =
|
|
9417
|
+
const handlers = chunkOIZ2V2VD_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkOIZ2V2VD_cjs.contractHandlers.get(t)).filter(hasCandidates);
|
|
9352
9418
|
const band = /* @__PURE__ */ new Map();
|
|
9353
9419
|
for (let index = from; index <= to; index++) {
|
|
9354
9420
|
const descriptor = lookAhead.materialize(index);
|
|
@@ -9359,7 +9425,7 @@ var ContractManager = class _ContractManager {
|
|
|
9359
9425
|
index,
|
|
9360
9426
|
params: {
|
|
9361
9427
|
...candidate,
|
|
9362
|
-
...
|
|
9428
|
+
...chunkOIZ2V2VD_cjs.speculativeReceiveMetadata(descriptor)
|
|
9363
9429
|
}
|
|
9364
9430
|
});
|
|
9365
9431
|
}
|
|
@@ -9421,7 +9487,7 @@ var ContractManager = class _ContractManager {
|
|
|
9421
9487
|
});
|
|
9422
9488
|
for (const entry of pending) entry.catchUpPending = false;
|
|
9423
9489
|
} catch (err) {
|
|
9424
|
-
if (!
|
|
9490
|
+
if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
|
|
9425
9491
|
this.markSyncDegraded(err);
|
|
9426
9492
|
}
|
|
9427
9493
|
}
|
|
@@ -9471,7 +9537,7 @@ var ContractManager = class _ContractManager {
|
|
|
9471
9537
|
await this.fetchContractVxosFromIndexer([contract]);
|
|
9472
9538
|
this.markSyncOnline();
|
|
9473
9539
|
} catch (err) {
|
|
9474
|
-
if (!
|
|
9540
|
+
if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
|
|
9475
9541
|
this.markSyncDegraded(err);
|
|
9476
9542
|
}
|
|
9477
9543
|
await this.watcher.addContract(contract);
|
|
@@ -9508,7 +9574,7 @@ var ContractManager = class _ContractManager {
|
|
|
9508
9574
|
return result;
|
|
9509
9575
|
}
|
|
9510
9576
|
async upsertContractRow(params) {
|
|
9511
|
-
const handler =
|
|
9577
|
+
const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(params.type);
|
|
9512
9578
|
if (!handler) {
|
|
9513
9579
|
throw new Error(`No handler registered for contract type '${params.type}'`);
|
|
9514
9580
|
}
|
|
@@ -9608,7 +9674,7 @@ var ContractManager = class _ContractManager {
|
|
|
9608
9674
|
`scanContracts: batchSize must be a positive integer (got ${String(opts.batchSize)})`
|
|
9609
9675
|
);
|
|
9610
9676
|
}
|
|
9611
|
-
const registered =
|
|
9677
|
+
const registered = chunkOIZ2V2VD_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkOIZ2V2VD_cjs.contractHandlers.get(t)).filter(isDiscoverable);
|
|
9612
9678
|
const discoverables = [
|
|
9613
9679
|
...registered.filter((h) => h.type === "boarding"),
|
|
9614
9680
|
...registered.filter((h) => h.type !== "boarding")
|
|
@@ -9743,7 +9809,7 @@ var ContractManager = class _ContractManager {
|
|
|
9743
9809
|
await this.syncContracts({ contracts, pageSize });
|
|
9744
9810
|
this.markSyncOnline();
|
|
9745
9811
|
} catch (err) {
|
|
9746
|
-
if (!
|
|
9812
|
+
if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
|
|
9747
9813
|
this.markSyncDegraded(err);
|
|
9748
9814
|
}
|
|
9749
9815
|
const vtxos = await this.getVtxosForContracts(contracts);
|
|
@@ -9764,7 +9830,7 @@ var ContractManager = class _ContractManager {
|
|
|
9764
9830
|
}
|
|
9765
9831
|
const tapscriptCache = tapscripts ?? /* @__PURE__ */ new Map();
|
|
9766
9832
|
return vtxos.map(
|
|
9767
|
-
(vtxo) => extendVirtualCoinForContract(
|
|
9833
|
+
(vtxo) => extendVirtualCoinForContract(chunk2JV4VQ7C_cjs.normalizeVtxo(vtxo), byScript, tapscriptCache)
|
|
9768
9834
|
);
|
|
9769
9835
|
}
|
|
9770
9836
|
/** @inheritdoc */
|
|
@@ -9808,14 +9874,14 @@ var ContractManager = class _ContractManager {
|
|
|
9808
9874
|
const byScript = new Map(contracts.map((contract) => [contract.script, contract]));
|
|
9809
9875
|
const asking = vtxos.filter((vtxo) => {
|
|
9810
9876
|
const contract = byScript.get(vtxo.script);
|
|
9811
|
-
return contract !== void 0 &&
|
|
9877
|
+
return contract !== void 0 && chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type)?.assertSpendableNow !== void 0;
|
|
9812
9878
|
});
|
|
9813
9879
|
if (asking.length === 0) return refused;
|
|
9814
9880
|
const tip = await this.currentChainTip();
|
|
9815
9881
|
const walletKey = await walletPubKey?.();
|
|
9816
9882
|
for (const vtxo of asking) {
|
|
9817
9883
|
const contract = byScript.get(vtxo.script);
|
|
9818
|
-
const handler =
|
|
9884
|
+
const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
|
|
9819
9885
|
if (!handler?.assertSpendableNow) continue;
|
|
9820
9886
|
const context = {
|
|
9821
9887
|
collaborative: true,
|
|
@@ -9830,7 +9896,7 @@ var ContractManager = class _ContractManager {
|
|
|
9830
9896
|
// the next handler to answer a CSV question would meet a
|
|
9831
9897
|
// TypeError instead of a `false`. Carry the coin only when it
|
|
9832
9898
|
// really is one.
|
|
9833
|
-
vtxo:
|
|
9899
|
+
vtxo: chunk2JV4VQ7C_cjs.isVirtualCoin(vtxo) && "status" in vtxo ? vtxo : void 0
|
|
9834
9900
|
};
|
|
9835
9901
|
try {
|
|
9836
9902
|
await handler.assertSpendableNow(
|
|
@@ -9986,7 +10052,7 @@ var ContractManager = class _ContractManager {
|
|
|
9986
10052
|
const { contractScript, collaborative = true, walletPubKey, vtxo } = options;
|
|
9987
10053
|
const [contract] = await this.getContracts({ script: contractScript });
|
|
9988
10054
|
if (!contract) return [];
|
|
9989
|
-
const handler =
|
|
10055
|
+
const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
|
|
9990
10056
|
if (!handler) return [];
|
|
9991
10057
|
const script = handler.createScript(contract.params);
|
|
9992
10058
|
const tip = await this.currentChainTip();
|
|
@@ -10014,7 +10080,7 @@ var ContractManager = class _ContractManager {
|
|
|
10014
10080
|
const { contractScript, collaborative = true, walletPubKey } = options;
|
|
10015
10081
|
const [contract] = await this.getContracts({ script: contractScript });
|
|
10016
10082
|
if (!contract) return [];
|
|
10017
|
-
const handler =
|
|
10083
|
+
const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
|
|
10018
10084
|
if (!handler) return [];
|
|
10019
10085
|
const script = handler.createScript(contract.params);
|
|
10020
10086
|
const context = {
|
|
@@ -10070,7 +10136,7 @@ var ContractManager = class _ContractManager {
|
|
|
10070
10136
|
}
|
|
10071
10137
|
async refreshOutpoints(outpoints) {
|
|
10072
10138
|
if (outpoints.length === 0) return;
|
|
10073
|
-
const { vtxos } = await
|
|
10139
|
+
const { vtxos } = await chunk2JV4VQ7C_cjs.getNormalizedVtxos(this.config.indexerProvider, {
|
|
10074
10140
|
outpoints
|
|
10075
10141
|
});
|
|
10076
10142
|
if (vtxos.length === 0) return;
|
|
@@ -10149,7 +10215,7 @@ var ContractManager = class _ContractManager {
|
|
|
10149
10215
|
break;
|
|
10150
10216
|
}
|
|
10151
10217
|
} catch (err) {
|
|
10152
|
-
if (!
|
|
10218
|
+
if (!chunk2JV4VQ7C_cjs.isRetryableProviderError(err)) throw err;
|
|
10153
10219
|
this.markSyncDegraded(err);
|
|
10154
10220
|
}
|
|
10155
10221
|
this.emitEvent(event);
|
|
@@ -10228,7 +10294,7 @@ var ContractManager = class _ContractManager {
|
|
|
10228
10294
|
*/
|
|
10229
10295
|
async reconcilePendingFrontier(contracts) {
|
|
10230
10296
|
const scriptToContract = new Map(contracts.map((c) => [c.script, c]));
|
|
10231
|
-
const vtxos = await
|
|
10297
|
+
const vtxos = await chunk2JV4VQ7C_cjs.getAllNormalizedVtxos(
|
|
10232
10298
|
this.config.indexerProvider,
|
|
10233
10299
|
contracts.map((c) => c.script),
|
|
10234
10300
|
{ pendingOnly: true }
|
|
@@ -10311,7 +10377,7 @@ var ContractManager = class _ContractManager {
|
|
|
10311
10377
|
}
|
|
10312
10378
|
return result;
|
|
10313
10379
|
}
|
|
10314
|
-
async fetchContractVtxosBulk(contracts, pageSize =
|
|
10380
|
+
async fetchContractVtxosBulk(contracts, pageSize = chunk2JV4VQ7C_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
|
|
10315
10381
|
if (contracts.length === 0) {
|
|
10316
10382
|
return { vtxosByScript: /* @__PURE__ */ new Map(), promoted: /* @__PURE__ */ new Map() };
|
|
10317
10383
|
}
|
|
@@ -10327,7 +10393,7 @@ var ContractManager = class _ContractManager {
|
|
|
10327
10393
|
before: syncWindow.before
|
|
10328
10394
|
}
|
|
10329
10395
|
} : {};
|
|
10330
|
-
const vtxos = await
|
|
10396
|
+
const vtxos = await chunk2JV4VQ7C_cjs.getAllNormalizedVtxos(
|
|
10331
10397
|
this.config.indexerProvider,
|
|
10332
10398
|
contracts.map((c) => c.script),
|
|
10333
10399
|
{ ...windowOpts, pageSize }
|
|
@@ -10472,7 +10538,7 @@ var deserializeTapLeaf = (t) => {
|
|
|
10472
10538
|
const s = base.hex.decode(t.s);
|
|
10473
10539
|
return [cb, s];
|
|
10474
10540
|
};
|
|
10475
|
-
var deserializeVtxo = (o) =>
|
|
10541
|
+
var deserializeVtxo = (o) => chunk2JV4VQ7C_cjs.normalizeVtxo({
|
|
10476
10542
|
...o,
|
|
10477
10543
|
createdAt: new Date(o.createdAt),
|
|
10478
10544
|
tapTree: base.hex.decode(o.tapTree),
|
|
@@ -11295,7 +11361,7 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
|
|
|
11295
11361
|
*/
|
|
11296
11362
|
materializeDescriptorAt(index) {
|
|
11297
11363
|
const descriptor = this.identity.descriptor;
|
|
11298
|
-
const network =
|
|
11364
|
+
const network = chunkOIZ2V2VD_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
11299
11365
|
const expansion = descriptorsScure.expand({ descriptor, network, index });
|
|
11300
11366
|
const keyInfo = expansion.expansionMap?.["@0"];
|
|
11301
11367
|
if (!keyInfo?.keyExpression) {
|
|
@@ -11443,7 +11509,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
11443
11509
|
const provider = await resolveDescriptorProvider(config, setup.walletRepository);
|
|
11444
11510
|
if (!provider) return void 0;
|
|
11445
11511
|
const allowSilentFallback = (config.walletMode ?? "auto") === "auto";
|
|
11446
|
-
const expectedContractType = setup.offchainTapscript instanceof
|
|
11512
|
+
const expectedContractType = setup.offchainTapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? "delegate" : "default";
|
|
11447
11513
|
const factoryOpts = {
|
|
11448
11514
|
walletRepository: setup.walletRepository,
|
|
11449
11515
|
contractRepository: setup.contractRepository,
|
|
@@ -11623,7 +11689,9 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
11623
11689
|
const { tapscript: newTapscript, params } = buildReceiveContract(
|
|
11624
11690
|
wallet.offchainTapscript,
|
|
11625
11691
|
descriptor,
|
|
11626
|
-
wallet.network.hrp
|
|
11692
|
+
wallet.network.hrp,
|
|
11693
|
+
true
|
|
11694
|
+
);
|
|
11627
11695
|
const newScript = params.script;
|
|
11628
11696
|
const manager = await wallet.getContractManager();
|
|
11629
11697
|
await manager.createContract(params);
|
|
@@ -11642,7 +11710,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
11642
11710
|
};
|
|
11643
11711
|
function deriveLeafPubkey(descriptor) {
|
|
11644
11712
|
try {
|
|
11645
|
-
return
|
|
11713
|
+
return chunkOIZ2V2VD_cjs.deriveDescriptorLeafPubKey(descriptor);
|
|
11646
11714
|
} catch (e) {
|
|
11647
11715
|
throw new NonRangeableDescriptorError(
|
|
11648
11716
|
"Cannot derive leaf pubkey: descriptor is not a materialized, parsable tr(...) shape.",
|
|
@@ -11654,7 +11722,7 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
|
|
|
11654
11722
|
const pubKey = deriveLeafPubkey(descriptor);
|
|
11655
11723
|
const tapscript = rebuildTapscript(current, pubKey);
|
|
11656
11724
|
const serverPubKey = tapscript.options.serverPubKey;
|
|
11657
|
-
const csvTimelock =
|
|
11725
|
+
const csvTimelock = chunk2JV4VQ7C_cjs.timelockToSequence(tapscript.options.csvTimelock).toString();
|
|
11658
11726
|
const base$1 = {
|
|
11659
11727
|
script: base.hex.encode(tapscript.pkScript),
|
|
11660
11728
|
address: tapscript.address(hrp, serverPubKey).encode(),
|
|
@@ -11665,11 +11733,11 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
|
|
|
11665
11733
|
// index-0 key. Without it, spends produce unsigned PSBTs that the
|
|
11666
11734
|
// server rejects with `INVALID_PSBT_INPUT (5): missing tapscript spend sig`.
|
|
11667
11735
|
metadata: {
|
|
11668
|
-
...{ source:
|
|
11736
|
+
...tagSource && { source: chunkOIZ2V2VD_cjs.WALLET_RECEIVE_SOURCE },
|
|
11669
11737
|
signingDescriptor: descriptor
|
|
11670
11738
|
}
|
|
11671
11739
|
};
|
|
11672
|
-
const params = tapscript instanceof
|
|
11740
|
+
const params = tapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? {
|
|
11673
11741
|
...base$1,
|
|
11674
11742
|
type: "delegate",
|
|
11675
11743
|
params: {
|
|
@@ -11690,10 +11758,10 @@ function buildReceiveContract(current, descriptor, hrp, tagSource) {
|
|
|
11690
11758
|
return { tapscript, params };
|
|
11691
11759
|
}
|
|
11692
11760
|
function rebuildTapscript(current, pubKey) {
|
|
11693
|
-
if (current instanceof
|
|
11694
|
-
return new
|
|
11761
|
+
if (current instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script) {
|
|
11762
|
+
return new chunkOIZ2V2VD_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
|
|
11695
11763
|
}
|
|
11696
|
-
return new
|
|
11764
|
+
return new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
|
|
11697
11765
|
}
|
|
11698
11766
|
async function pickActiveReceive(contractRepository, serverPubKey, expectedType) {
|
|
11699
11767
|
const candidates = await contractRepository.getContracts({
|
|
@@ -11702,7 +11770,7 @@ async function pickActiveReceive(contractRepository, serverPubKey, expectedType)
|
|
|
11702
11770
|
});
|
|
11703
11771
|
const serverPubKeyHex = base.hex.encode(serverPubKey);
|
|
11704
11772
|
const matching = candidates.filter(
|
|
11705
|
-
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source ===
|
|
11773
|
+
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkOIZ2V2VD_cjs.WALLET_RECEIVE_SOURCE
|
|
11706
11774
|
).sort((a, b) => {
|
|
11707
11775
|
if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
|
|
11708
11776
|
return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
|
|
@@ -11749,6 +11817,7 @@ function computeOffchainBalance(vtxos, caps) {
|
|
|
11749
11817
|
let intentLocked = 0;
|
|
11750
11818
|
let recoverable = 0;
|
|
11751
11819
|
let pendingRecovery = 0;
|
|
11820
|
+
let unrolled = 0;
|
|
11752
11821
|
const owned = /* @__PURE__ */ new Map();
|
|
11753
11822
|
const spendable = /* @__PURE__ */ new Map();
|
|
11754
11823
|
const addAssets = (into, vtxo) => {
|
|
@@ -11757,17 +11826,21 @@ function computeOffchainBalance(vtxos, caps) {
|
|
|
11757
11826
|
}
|
|
11758
11827
|
};
|
|
11759
11828
|
for (const vtxo of vtxos) {
|
|
11760
|
-
if (
|
|
11829
|
+
if (chunk2JV4VQ7C_cjs.hasTerminalSpend(vtxo)) continue;
|
|
11761
11830
|
addAssets(owned, vtxo);
|
|
11831
|
+
if (vtxo.isUnrolled) {
|
|
11832
|
+
unrolled += vtxo.value;
|
|
11833
|
+
continue;
|
|
11834
|
+
}
|
|
11762
11835
|
if (isPendingRecovery(vtxo)) {
|
|
11763
11836
|
pendingRecovery += vtxo.value;
|
|
11764
11837
|
continue;
|
|
11765
11838
|
}
|
|
11766
|
-
if (
|
|
11839
|
+
if (chunk2JV4VQ7C_cjs.canRecoverOnchain(vtxo, now)) {
|
|
11767
11840
|
recoverable += vtxo.value;
|
|
11768
11841
|
continue;
|
|
11769
11842
|
}
|
|
11770
|
-
if (!
|
|
11843
|
+
if (!chunk2JV4VQ7C_cjs.canSpendOffchain(vtxo, now)) continue;
|
|
11771
11844
|
if (vtxo.isPreconfirmed) {
|
|
11772
11845
|
preconfirmed += vtxo.value;
|
|
11773
11846
|
} else {
|
|
@@ -11791,7 +11864,8 @@ function computeOffchainBalance(vtxos, caps) {
|
|
|
11791
11864
|
intentLocked,
|
|
11792
11865
|
recoverable,
|
|
11793
11866
|
pendingRecovery,
|
|
11794
|
-
|
|
11867
|
+
unrolled,
|
|
11868
|
+
total: settled + preconfirmed + recoverable + pendingRecovery + unrolled,
|
|
11795
11869
|
assets: toAssets(owned),
|
|
11796
11870
|
availableAssets: toAssets(spendable)
|
|
11797
11871
|
};
|
|
@@ -11936,12 +12010,12 @@ var InputSignerRouter = class {
|
|
|
11936
12010
|
};
|
|
11937
12011
|
|
|
11938
12012
|
// src/wallet/wallet.ts
|
|
11939
|
-
var getArkadeServerUrl = ({ arkServerUrl }) => arkServerUrl ||
|
|
12013
|
+
var getArkadeServerUrl = ({ arkServerUrl }) => arkServerUrl || chunk2JV4VQ7C_cjs.DEFAULT_ARKADE_SERVER_URL;
|
|
11940
12014
|
function intentProofJobs(coins) {
|
|
11941
12015
|
if (coins.length === 0) return [];
|
|
11942
12016
|
const coinJobs = coins.map((coin, i) => ({
|
|
11943
12017
|
index: i + 1,
|
|
11944
|
-
lookupScript:
|
|
12018
|
+
lookupScript: chunk2JV4VQ7C_cjs.VtxoScript.decode(coin.tapTree).pkScript
|
|
11945
12019
|
}));
|
|
11946
12020
|
return [{ index: 0, lookupScript: coinJobs[0].lookupScript }, ...coinJobs];
|
|
11947
12021
|
}
|
|
@@ -11963,11 +12037,6 @@ function extractArkProviderUrl(provider) {
|
|
|
11963
12037
|
var DEFAULT_LOOK_AHEAD_WINDOW = 20;
|
|
11964
12038
|
var MAX_USED_SIGNING_DESCRIPTORS_LOOK_AHEAD = 1e3;
|
|
11965
12039
|
var MAINNET_UNILATERAL_EXIT_DELAY = 605184n;
|
|
11966
|
-
function toXOnlyPubKey(pubkey) {
|
|
11967
|
-
if (pubkey.length === 33) return pubkey.slice(1);
|
|
11968
|
-
if (pubkey.length === 32) return pubkey;
|
|
11969
|
-
throw new Error(`invalid signer pubkey length: expected 32 or 33, got ${pubkey.length}`);
|
|
11970
|
-
}
|
|
11971
12040
|
function delayToTimelock(delay) {
|
|
11972
12041
|
return {
|
|
11973
12042
|
value: delay,
|
|
@@ -11978,7 +12047,7 @@ function dedupeTimelocks(timelocks) {
|
|
|
11978
12047
|
const seen = /* @__PURE__ */ new Set();
|
|
11979
12048
|
const deduped = [];
|
|
11980
12049
|
for (const timelock of timelocks) {
|
|
11981
|
-
const sequence =
|
|
12050
|
+
const sequence = chunk2JV4VQ7C_cjs.timelockToSequence(timelock).toString();
|
|
11982
12051
|
if (seen.has(sequence)) continue;
|
|
11983
12052
|
seen.add(sequence);
|
|
11984
12053
|
deduped.push(timelock);
|
|
@@ -11995,7 +12064,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
|
|
|
11995
12064
|
state: "active"
|
|
11996
12065
|
});
|
|
11997
12066
|
const newest = candidates.filter(
|
|
11998
|
-
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source ===
|
|
12067
|
+
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkOIZ2V2VD_cjs.WALLET_RECEIVE_SOURCE
|
|
11999
12068
|
).sort((a, b) => {
|
|
12000
12069
|
if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
|
|
12001
12070
|
return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
|
|
@@ -12003,7 +12072,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
|
|
|
12003
12072
|
if (!newest?.params.pubKey) return baseline;
|
|
12004
12073
|
try {
|
|
12005
12074
|
const pubKey = base.hex.decode(newest.params.pubKey);
|
|
12006
|
-
return new
|
|
12075
|
+
return new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
|
|
12007
12076
|
} catch (e) {
|
|
12008
12077
|
console.warn("Skipping malformed boarding contract at boot", newest.script, e);
|
|
12009
12078
|
return baseline;
|
|
@@ -12019,13 +12088,16 @@ function filterSnapshotVtxos(snapshot, filter, pendingSpendOutpoints) {
|
|
|
12019
12088
|
if (pendingSpendOutpoints.has(`${vtxo.txid}:${vtxo.vout}`)) {
|
|
12020
12089
|
return false;
|
|
12021
12090
|
}
|
|
12022
|
-
if (
|
|
12023
|
-
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
return
|
|
12091
|
+
if (vtxo.isUnrolled) {
|
|
12092
|
+
return !!f.withUnrolled;
|
|
12093
|
+
}
|
|
12094
|
+
if (chunk2JV4VQ7C_cjs.hasTerminalSpend(vtxo)) {
|
|
12095
|
+
return false;
|
|
12096
|
+
}
|
|
12097
|
+
if (!f.withRecoverable && chunk2JV4VQ7C_cjs.canRecoverOnchain(vtxo, now)) {
|
|
12098
|
+
return false;
|
|
12027
12099
|
}
|
|
12028
|
-
return
|
|
12100
|
+
return true;
|
|
12029
12101
|
});
|
|
12030
12102
|
}
|
|
12031
12103
|
var PENDING_RECOVERY_REASON = "is past its operator signer's rotation cutoff \u2014 the operator will not co-sign it until it recovers";
|
|
@@ -12361,7 +12433,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12361
12433
|
*/
|
|
12362
12434
|
static async setupWalletConfig(config, pubKey) {
|
|
12363
12435
|
const arkadeServerUrl = getArkadeServerUrl(config);
|
|
12364
|
-
const arkProvider = config.arkProvider || new
|
|
12436
|
+
const arkProvider = config.arkProvider || new chunk2JV4VQ7C_cjs.RestArkProvider(arkadeServerUrl);
|
|
12365
12437
|
let indexerProvider = config.indexerProvider;
|
|
12366
12438
|
if (!indexerProvider) {
|
|
12367
12439
|
let indexerUrl = config.indexerUrl;
|
|
@@ -12378,7 +12450,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12378
12450
|
indexerUrl = arkadeServerUrl;
|
|
12379
12451
|
}
|
|
12380
12452
|
}
|
|
12381
|
-
indexerProvider = new
|
|
12453
|
+
indexerProvider = new chunkCO3KKSWM_cjs.RestIndexerProvider(indexerUrl);
|
|
12382
12454
|
}
|
|
12383
12455
|
const walletRepository = config.storage?.walletRepository ?? new IndexedDBWalletRepository();
|
|
12384
12456
|
const contractRepository = config.storage?.contractRepository ?? new IndexedDBContractRepository();
|
|
@@ -12387,7 +12459,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12387
12459
|
source: serverInfoSource,
|
|
12388
12460
|
lastOnlineAt: serverInfoLastOnlineAt
|
|
12389
12461
|
} = await resolveArkInfo(arkProvider, walletRepository);
|
|
12390
|
-
const network =
|
|
12462
|
+
const network = chunk2JV4VQ7C_cjs.getNetwork(info.network);
|
|
12391
12463
|
if ("descriptor" in config.identity) {
|
|
12392
12464
|
const descriptor = config.identity.descriptor;
|
|
12393
12465
|
const identityIsMainnet = !descriptor.includes("tpub");
|
|
@@ -12427,18 +12499,18 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12427
12499
|
value: info.boardingExitDelay,
|
|
12428
12500
|
type: info.boardingExitDelay < 512n ? "blocks" : "seconds"
|
|
12429
12501
|
};
|
|
12430
|
-
const serverPubKey = base.hex.decode(info.signerPubkey)
|
|
12431
|
-
const delegatePubKey = config.delegateProvider ? await config.delegateProvider.getDelegateInfo().then((info2) => base.hex.decode(info2.pubkey)
|
|
12502
|
+
const serverPubKey = chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
|
|
12503
|
+
const delegatePubKey = config.delegateProvider ? await config.delegateProvider.getDelegateInfo().then((info2) => chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(info2.pubkey), "delegate key")).catch(() => void 0) : config.delegatorProvider ? await config.delegatorProvider.getDelegateInfo().then((info2) => chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(info2.pubkey), "delegate key")).catch(() => void 0) : void 0;
|
|
12432
12504
|
const offchainOptions = {
|
|
12433
12505
|
pubKey,
|
|
12434
12506
|
serverPubKey,
|
|
12435
12507
|
csvTimelock: exitTimelock
|
|
12436
12508
|
};
|
|
12437
|
-
const offchainTapscript = !delegatePubKey ? new
|
|
12438
|
-
const boardingTapscript =
|
|
12509
|
+
const offchainTapscript = !delegatePubKey ? new chunkOIZ2V2VD_cjs.DefaultVtxo.Script(offchainOptions) : new chunkOIZ2V2VD_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
|
|
12510
|
+
const boardingTapscript = chunkOIZ2V2VD_cjs.BoardingContractHandler.createScript({
|
|
12439
12511
|
pubKey: base.hex.encode(pubKey),
|
|
12440
12512
|
serverPubKey: base.hex.encode(serverPubKey),
|
|
12441
|
-
csvTimelock:
|
|
12513
|
+
csvTimelock: chunk2JV4VQ7C_cjs.timelockToSequence(boardingTimelock).toString()
|
|
12442
12514
|
});
|
|
12443
12515
|
return {
|
|
12444
12516
|
arkProvider,
|
|
@@ -12528,7 +12600,11 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12528
12600
|
this.getBoardingUtxos(),
|
|
12529
12601
|
this.contractSnapshot()
|
|
12530
12602
|
]);
|
|
12531
|
-
const vtxos = filterSnapshotVtxos(
|
|
12603
|
+
const vtxos = filterSnapshotVtxos(
|
|
12604
|
+
snapshot,
|
|
12605
|
+
{ withRecoverable: true, withUnrolled: true },
|
|
12606
|
+
this._pendingSpendOutpoints
|
|
12607
|
+
);
|
|
12532
12608
|
let confirmed = 0;
|
|
12533
12609
|
let unconfirmed = 0;
|
|
12534
12610
|
for (const utxo of boardingUtxos) {
|
|
@@ -12556,6 +12632,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12556
12632
|
intentLocked: offchain.intentLocked,
|
|
12557
12633
|
recoverable: offchain.recoverable,
|
|
12558
12634
|
pendingRecovery: offchain.pendingRecovery,
|
|
12635
|
+
unrolled: offchain.unrolled,
|
|
12559
12636
|
total: totalBoarding + offchain.total,
|
|
12560
12637
|
assets: offchain.assets,
|
|
12561
12638
|
availableAssets: offchain.availableAssets
|
|
@@ -12735,7 +12812,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12735
12812
|
const response = await contractManager.getContractsWithVtxos();
|
|
12736
12813
|
const allVtxos = response.flatMap((_) => _.vtxos);
|
|
12737
12814
|
const { boardingTxs, commitmentsToIgnore } = await this.getBoardingTxs();
|
|
12738
|
-
const resolveTxCreatedAt = (txids) =>
|
|
12815
|
+
const resolveTxCreatedAt = (txids) => chunk2JV4VQ7C_cjs.fetchVtxoCreatedAtByTxid(this.indexerProvider, txids);
|
|
12739
12816
|
return buildTransactionHistory(
|
|
12740
12817
|
allVtxos,
|
|
12741
12818
|
boardingTxs,
|
|
@@ -12829,7 +12906,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12829
12906
|
},
|
|
12830
12907
|
isUnrolled: true,
|
|
12831
12908
|
...boardingFacts,
|
|
12832
|
-
virtualStatus:
|
|
12909
|
+
virtualStatus: chunk2JV4VQ7C_cjs.toVirtualStatus(boardingFacts),
|
|
12833
12910
|
spentBy: "",
|
|
12834
12911
|
createdAt: tx.status.confirmed ? new Date(tx.status.block_time * 1e3) : /* @__PURE__ */ new Date(0),
|
|
12835
12912
|
script: scriptHex
|
|
@@ -12885,9 +12962,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12885
12962
|
async getBoardingTapscripts(allowedSigners) {
|
|
12886
12963
|
const byScript = /* @__PURE__ */ new Map();
|
|
12887
12964
|
const add = (s) => byScript.set(base.hex.encode(s.pkScript), s);
|
|
12888
|
-
const boardingCsv = this.boardingTapscript.options.csvTimelock ??
|
|
12965
|
+
const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunkOIZ2V2VD_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
12889
12966
|
add(
|
|
12890
|
-
new
|
|
12967
|
+
new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
|
|
12891
12968
|
pubKey: await this.identity.xOnlyPublicKey(),
|
|
12892
12969
|
serverPubKey: this.boardingTapscript.options.serverPubKey,
|
|
12893
12970
|
csvTimelock: boardingCsv
|
|
@@ -12902,7 +12979,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12902
12979
|
for (const c of boardingContracts) {
|
|
12903
12980
|
if (!allowed.has(toXOnlySignerHex(c.params.serverPubKey))) continue;
|
|
12904
12981
|
try {
|
|
12905
|
-
add(
|
|
12982
|
+
add(chunkOIZ2V2VD_cjs.BoardingContractHandler.createScript(c.params));
|
|
12906
12983
|
} catch (e) {
|
|
12907
12984
|
console.warn("Skipping malformed boarding contract", c.script, e);
|
|
12908
12985
|
}
|
|
@@ -12940,7 +13017,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
12940
13017
|
// Per-row CSV delay decoded from THIS tapscript's exit leaf —
|
|
12941
13018
|
// not the wallet's current boarding timelock, which a signer
|
|
12942
13019
|
// rotation may have changed.
|
|
12943
|
-
csvTimelock:
|
|
13020
|
+
csvTimelock: chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
|
|
12944
13021
|
coins: utxos
|
|
12945
13022
|
});
|
|
12946
13023
|
}
|
|
@@ -13073,7 +13150,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13073
13150
|
/** Fetch Arkade transaction ids that are still pending final settlement. */
|
|
13074
13151
|
async fetchPendingTxs() {
|
|
13075
13152
|
const scripts = await this.getWalletScripts();
|
|
13076
|
-
const vtxos = await
|
|
13153
|
+
const vtxos = await chunk2JV4VQ7C_cjs.getAllNormalizedVtxos(this.indexerProvider, scripts);
|
|
13077
13154
|
return vtxos.filter(
|
|
13078
13155
|
(vtxo) => (vtxo.isSpent || vtxo.isPreconfirmed && !vtxo.isSwept) && vtxo.arkTxId !== void 0
|
|
13079
13156
|
).map((_) => _.arkTxId);
|
|
@@ -13104,7 +13181,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13104
13181
|
});
|
|
13105
13182
|
for (const contract of contracts) {
|
|
13106
13183
|
if (map.has(contract.script)) continue;
|
|
13107
|
-
const handler =
|
|
13184
|
+
const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
|
|
13108
13185
|
if (handler) {
|
|
13109
13186
|
const script = handler.createScript(contract.params);
|
|
13110
13187
|
map.set(contract.script, script);
|
|
@@ -13216,7 +13293,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13216
13293
|
}
|
|
13217
13294
|
});
|
|
13218
13295
|
const baselinePubkey = await this.identity.xOnlyPublicKey();
|
|
13219
|
-
const delegatePubKey = this.offchainTapscript instanceof
|
|
13296
|
+
const delegatePubKey = this.offchainTapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
|
|
13220
13297
|
const baselineSigners = [
|
|
13221
13298
|
this.offchainTapscript.options.serverPubKey,
|
|
13222
13299
|
...[...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h))
|
|
@@ -13224,8 +13301,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13224
13301
|
const seenBaselineScripts = /* @__PURE__ */ new Set();
|
|
13225
13302
|
for (const serverPubKey of baselineSigners) {
|
|
13226
13303
|
for (const csvTimelock of this.walletContractTimelocks) {
|
|
13227
|
-
const csvTimelockStr =
|
|
13228
|
-
const defaultScript = new
|
|
13304
|
+
const csvTimelockStr = chunk2JV4VQ7C_cjs.timelockToSequence(csvTimelock).toString();
|
|
13305
|
+
const defaultScript = new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
|
|
13229
13306
|
pubKey: baselinePubkey,
|
|
13230
13307
|
serverPubKey,
|
|
13231
13308
|
csvTimelock
|
|
@@ -13246,7 +13323,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13246
13323
|
});
|
|
13247
13324
|
}
|
|
13248
13325
|
if (delegatePubKey) {
|
|
13249
|
-
const delegateScript = new
|
|
13326
|
+
const delegateScript = new chunkOIZ2V2VD_cjs.DelegateVtxo.Script({
|
|
13250
13327
|
pubKey: baselinePubkey,
|
|
13251
13328
|
serverPubKey,
|
|
13252
13329
|
delegatePubKey,
|
|
@@ -13270,9 +13347,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13270
13347
|
}
|
|
13271
13348
|
}
|
|
13272
13349
|
}
|
|
13273
|
-
const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ??
|
|
13350
|
+
const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunkOIZ2V2VD_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
13274
13351
|
for (const serverPubKey of baselineSigners) {
|
|
13275
|
-
const baselineBoarding = new
|
|
13352
|
+
const baselineBoarding = new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
|
|
13276
13353
|
pubKey: baselinePubkey,
|
|
13277
13354
|
serverPubKey,
|
|
13278
13355
|
csvTimelock: boardingCsvTimelock
|
|
@@ -13285,7 +13362,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
13285
13362
|
params: {
|
|
13286
13363
|
pubKey: base.hex.encode(baselineBoarding.options.pubKey),
|
|
13287
13364
|
serverPubKey: base.hex.encode(serverPubKey),
|
|
13288
|
-
csvTimelock:
|
|
13365
|
+
csvTimelock: chunk2JV4VQ7C_cjs.timelockToSequence(boardingCsvTimelock).toString()
|
|
13289
13366
|
},
|
|
13290
13367
|
script: boardingScriptHex,
|
|
13291
13368
|
address: baselineBoarding.address(this.network.hrp, serverPubKey).encode(),
|
|
@@ -13415,6 +13492,27 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13415
13492
|
console.warn("server-signer rotation on info change failed", e);
|
|
13416
13493
|
}
|
|
13417
13494
|
}
|
|
13495
|
+
/**
|
|
13496
|
+
* Await an `onServerInfoChanged` handler still applying a rotation.
|
|
13497
|
+
*
|
|
13498
|
+
* The provider emits synchronously but {@link handleServerInfoChanged} runs
|
|
13499
|
+
* off the emit, so between the two a caller can observe a half-applied
|
|
13500
|
+
* rotation: {@link rotateServerSigner} persists the active signer's contract
|
|
13501
|
+
* rows *before* committing the tapscripts, so `arkServerPublicKey` still
|
|
13502
|
+
* reads the old key while the new key's rows are already in the repository.
|
|
13503
|
+
* A path that refreshes server info and then reads signer-derived state must
|
|
13504
|
+
* drain the chain first, or it both reads that torn state and races the
|
|
13505
|
+
* handler for the rotation itself.
|
|
13506
|
+
*
|
|
13507
|
+
* Resolves once the chain is idle; a handler that threw already logged, and
|
|
13508
|
+
* its rejection is swallowed here.
|
|
13509
|
+
*
|
|
13510
|
+
* @internal Invoked by {@link dispose} and the {@link VtxoManager} migration
|
|
13511
|
+
* pass; not part of the stable public API.
|
|
13512
|
+
*/
|
|
13513
|
+
async settleServerInfoChanges() {
|
|
13514
|
+
await this._serverInfoInFlight?.catch(() => void 0);
|
|
13515
|
+
}
|
|
13418
13516
|
_receiveRotatorInstalled = false;
|
|
13419
13517
|
/**
|
|
13420
13518
|
* Descriptor-aware signer used by {@link _signerRouter} to sign
|
|
@@ -13464,7 +13562,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13464
13562
|
serverPubKey: this.offchainTapscript.options.serverPubKey,
|
|
13465
13563
|
deprecatedSignerPubKeys: [...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h)),
|
|
13466
13564
|
csvTimelocks: this.walletContractTimelocks,
|
|
13467
|
-
delegatePubKey: this.offchainTapscript instanceof
|
|
13565
|
+
delegatePubKey: this.offchainTapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0
|
|
13468
13566
|
};
|
|
13469
13567
|
}
|
|
13470
13568
|
_signerRouter;
|
|
@@ -13549,43 +13647,250 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13549
13647
|
* provider and keeps a single index-0 boarding address for its lifetime,
|
|
13550
13648
|
* so this returns the existing {@link getBoardingAddress} unchanged
|
|
13551
13649
|
* (no rotation, no index burned).
|
|
13650
|
+
*
|
|
13651
|
+
* **Behaviour change.** A wallet configured with a custom
|
|
13652
|
+
* {@link DescriptorProvider} (`walletMode: <provider>`) now rotates here.
|
|
13653
|
+
* It previously did not: allocation went through the contract manager,
|
|
13654
|
+
* which only wires an `allocate` hook for {@link HDDescriptorProvider}, so
|
|
13655
|
+
* such a wallet read as "declined to allocate" and silently kept its
|
|
13656
|
+
* index-0 boarding address forever. Those wallets now burn an index per
|
|
13657
|
+
* call — including via {@link maybeRotateBoardingAfterBoard}, which fires
|
|
13658
|
+
* on every settle that consumes a boarding UTXO. Funds at retired
|
|
13659
|
+
* addresses stay reachable: each rotation persists its `boarding` contract
|
|
13660
|
+
* before swapping, and {@link getBoardingUtxos} fans out over the full
|
|
13661
|
+
* historical set.
|
|
13662
|
+
*
|
|
13663
|
+
* @deprecated Use {@link getNewAddresses} — it mints any combination of
|
|
13664
|
+
* address types at one shared index, and reports the contract row behind
|
|
13665
|
+
* each. Note the difference in display behaviour: this method *swaps* the
|
|
13666
|
+
* advertised boarding address, where `getNewAddresses` mints side
|
|
13667
|
+
* addresses and leaves {@link getBoardingAddress} alone. To keep this
|
|
13668
|
+
* method's behaviour, keep calling this method.
|
|
13552
13669
|
*/
|
|
13553
13670
|
async getNewBoardingAddress() {
|
|
13554
|
-
const
|
|
13555
|
-
if (!
|
|
13556
|
-
|
|
13671
|
+
const [minted] = await this.allocateAddresses(["boarding"], false, true);
|
|
13672
|
+
if (!minted?.allocated) return this.getBoardingAddress();
|
|
13673
|
+
if (minted.type === "boarding") this.setBoardingTapscriptForRotation(minted.tapscript);
|
|
13674
|
+
return minted.address;
|
|
13675
|
+
}
|
|
13676
|
+
/**
|
|
13677
|
+
* Allocate a *fresh* address of each requested type, all derived from one
|
|
13678
|
+
* newly allocated HD index.
|
|
13679
|
+
*
|
|
13680
|
+
* This is the explicit allocator the receive path otherwise lacks:
|
|
13681
|
+
* {@link getAddress} and {@link getBoardingAddress} are stable reads of the
|
|
13682
|
+
* wallet's display addresses, and the display receive address only advances
|
|
13683
|
+
* when a payment arrives ({@link WalletReceiveRotator} rotates on
|
|
13684
|
+
* `vtxo_received`). Issuing a second address before the first is paid — one
|
|
13685
|
+
* invoice for Alice, another for Bob — has to go through here.
|
|
13686
|
+
*
|
|
13687
|
+
* Each call:
|
|
13688
|
+
*
|
|
13689
|
+
* - allocates **one** index from the shared HD stream, however many types
|
|
13690
|
+
* were asked for, so a `default` + `boarding` pair are siblings rather
|
|
13691
|
+
* than two burnt indices;
|
|
13692
|
+
* - builds each requested script at that index, preserving every other
|
|
13693
|
+
* option of the wallet's current script for that flavour (including a
|
|
13694
|
+
* delegate wallet's `delegate` shape);
|
|
13695
|
+
* - persists each as an `active` contract carrying its `signingDescriptor`,
|
|
13696
|
+
* so the ContractWatcher monitors it, the balance counts it, and
|
|
13697
|
+
* {@link signerForDescriptor} can recover the key;
|
|
13698
|
+
* - slides the look-ahead band, since the watermark moved past indices an
|
|
13699
|
+
* external issuer may still be handing out.
|
|
13700
|
+
*
|
|
13701
|
+
* The minted rows are deliberately left **untagged**: the boot lookups
|
|
13702
|
+
* adopt the newest {@link WALLET_RECEIVE_SOURCE}-tagged row as the display
|
|
13703
|
+
* address, and a side address issued to one counterparty must not become
|
|
13704
|
+
* the address the wallet advertises to everyone else. {@link getAddress}
|
|
13705
|
+
* and {@link getBoardingAddress} are unchanged by this call.
|
|
13706
|
+
*
|
|
13707
|
+
* A wallet with no HD stream (`walletMode: 'static'` / `'auto'`) has one
|
|
13708
|
+
* address per flavour for its lifetime. Without `forceNew` it returns those
|
|
13709
|
+
* — the real persisted rows, no index burned; with `forceNew` it throws
|
|
13710
|
+
* {@link WalletCannotAllocateAddressError} rather than hand back an address
|
|
13711
|
+
* that is not in fact fresh.
|
|
13712
|
+
*
|
|
13713
|
+
* @example
|
|
13714
|
+
* ```typescript
|
|
13715
|
+
* const [invoice] = await wallet.getNewAddresses({ forceNew: true });
|
|
13716
|
+
* // hand `invoice.address` to Alice, keep the descriptor with the invoice
|
|
13717
|
+
* const signer = await wallet.signerForDescriptor(invoice.signingDescriptor);
|
|
13718
|
+
* ```
|
|
13719
|
+
*/
|
|
13720
|
+
async getNewAddresses(opts) {
|
|
13721
|
+
const minted = await this.allocateAddresses(
|
|
13722
|
+
opts?.types ?? ["default"],
|
|
13723
|
+
opts?.forceNew ?? false,
|
|
13724
|
+
false
|
|
13725
|
+
);
|
|
13726
|
+
return minted.map(({ address, signingDescriptor, contract }) => ({
|
|
13727
|
+
address,
|
|
13728
|
+
signingDescriptor,
|
|
13729
|
+
contract
|
|
13730
|
+
}));
|
|
13731
|
+
}
|
|
13732
|
+
/**
|
|
13733
|
+
* Shared allocation core behind {@link getNewAddresses} and the deprecated
|
|
13734
|
+
* {@link getNewBoardingAddress}, so the two cannot drift on what an
|
|
13735
|
+
* allocation costs or what gets persisted.
|
|
13736
|
+
*
|
|
13737
|
+
* @param tagSource - Tag the persisted rows {@link WALLET_RECEIVE_SOURCE},
|
|
13738
|
+
* making the next boot adopt them as the display address. Only the
|
|
13739
|
+
* deprecated boarding allocator passes `true`; `getNewAddresses` mints side
|
|
13740
|
+
* addresses and must not hijack what the wallet advertises.
|
|
13741
|
+
*/
|
|
13742
|
+
async allocateAddresses(types, forceNew, tagSource) {
|
|
13743
|
+
if (types.length === 0) {
|
|
13744
|
+
throw new Error("getNewAddresses: `types` must name at least one address type");
|
|
13557
13745
|
}
|
|
13558
13746
|
const manager = await this.getContractManager();
|
|
13559
|
-
const
|
|
13560
|
-
|
|
13561
|
-
|
|
13562
|
-
|
|
13747
|
+
const provider = this._descriptorProvider;
|
|
13748
|
+
const descriptor = !provider ? void 0 : provider instanceof HDDescriptorProvider ? await manager.getNextSigningDescriptor() : await provider.getNextSigningDescriptor();
|
|
13749
|
+
if (!descriptor) {
|
|
13750
|
+
if (forceNew) {
|
|
13751
|
+
throw new WalletCannotAllocateAddressError(
|
|
13752
|
+
provider ? "the descriptor provider declined to allocate an index" : "this wallet has no HD stream (walletMode 'static' / 'auto')"
|
|
13753
|
+
);
|
|
13754
|
+
}
|
|
13755
|
+
return this.currentAddresses(manager, types);
|
|
13756
|
+
}
|
|
13757
|
+
const allocated = [];
|
|
13758
|
+
try {
|
|
13759
|
+
for (const type of types) {
|
|
13760
|
+
allocated.push(await this.mintAddress(manager, type, descriptor, tagSource, true));
|
|
13761
|
+
}
|
|
13762
|
+
} finally {
|
|
13763
|
+
try {
|
|
13764
|
+
await manager.refillLookAhead();
|
|
13765
|
+
} catch (e) {
|
|
13766
|
+
console.warn("look-ahead refill after address allocation failed", e);
|
|
13767
|
+
}
|
|
13768
|
+
}
|
|
13769
|
+
return allocated;
|
|
13770
|
+
}
|
|
13771
|
+
/**
|
|
13772
|
+
* The wallet's existing display addresses, as persisted contract rows —
|
|
13773
|
+
* the honest answer for a wallet with no index to burn.
|
|
13774
|
+
*
|
|
13775
|
+
* Each type is minted from the descriptor that already owns its display
|
|
13776
|
+
* script ({@link displayDescriptor}), not from the identity key, so the
|
|
13777
|
+
* returned `signingDescriptor` is the one that signs for the returned
|
|
13778
|
+
* `address` even on a wallet that has rotated.
|
|
13779
|
+
*/
|
|
13780
|
+
async currentAddresses(manager, types) {
|
|
13781
|
+
const out = [];
|
|
13782
|
+
for (const type of types) {
|
|
13783
|
+
const descriptor = await this.displayDescriptor(manager, type);
|
|
13784
|
+
out.push(await this.mintAddress(manager, type, descriptor, false, false));
|
|
13785
|
+
}
|
|
13786
|
+
return out;
|
|
13787
|
+
}
|
|
13788
|
+
/**
|
|
13789
|
+
* The descriptor that owns the wallet's current display script for `type`,
|
|
13790
|
+
* read off the row the wallet persisted when it adopted that script.
|
|
13791
|
+
*
|
|
13792
|
+
* Deriving it from the identity instead is only correct for a wallet that
|
|
13793
|
+
* never rotates. On one that has — an HD wallet whose provider later
|
|
13794
|
+
* declines to allocate — the display script belongs to an HD child, and
|
|
13795
|
+
* pairing its address with the identity descriptor hands the caller a
|
|
13796
|
+
* {@link NewAddress} whose `signingDescriptor` resolves, via
|
|
13797
|
+
* {@link signerForDescriptor}, to a signer holding the wrong key.
|
|
13798
|
+
*
|
|
13799
|
+
* Falls back to the identity's pathless `tr(pubkey)` when no row carries a
|
|
13800
|
+
* descriptor: the static / `auto` case, where the identity key genuinely
|
|
13801
|
+
* owns the display script and this is what `getNextSigningDescriptor`
|
|
13802
|
+
* answers too. (The index-0 baselines registered at construction carry no
|
|
13803
|
+
* `signingDescriptor` metadata, so those wallets take this path.)
|
|
13804
|
+
*/
|
|
13805
|
+
async displayDescriptor(manager, type) {
|
|
13806
|
+
const display = type === "boarding" ? this._boardingTapscript : this.offchainTapscript;
|
|
13807
|
+
const [row] = await manager.getContracts({ script: base.hex.encode(display.pkScript) });
|
|
13808
|
+
const persisted = row?.metadata?.signingDescriptor;
|
|
13809
|
+
if (typeof persisted === "string") return persisted;
|
|
13810
|
+
return chunkOIZ2V2VD_cjs.identityDescriptor(this.identity);
|
|
13811
|
+
}
|
|
13812
|
+
/**
|
|
13813
|
+
* Build, persist and shape one address of `type` owned by `descriptor` —
|
|
13814
|
+
* the single build-and-register path behind both {@link allocateAddresses}
|
|
13815
|
+
* and {@link currentAddresses}, so a freshly allocated address and a
|
|
13816
|
+
* re-registered display address cannot disagree on what gets written.
|
|
13817
|
+
*
|
|
13818
|
+
* The descriptor is the sole source of the script's owner key in both
|
|
13819
|
+
* branches. Deriving one flavour from the descriptor and the other from a
|
|
13820
|
+
* tapscript field is what lets `address` and `signingDescriptor` drift
|
|
13821
|
+
* apart.
|
|
13822
|
+
*/
|
|
13823
|
+
async mintAddress(manager, type, descriptor, tagSource, allocated) {
|
|
13824
|
+
if (type === "boarding") {
|
|
13825
|
+
const built2 = this.buildBoardingContract(
|
|
13826
|
+
chunkOIZ2V2VD_cjs.deriveDescriptorLeafPubKey(descriptor),
|
|
13827
|
+
descriptor,
|
|
13828
|
+
tagSource
|
|
13829
|
+
);
|
|
13830
|
+
const contract2 = await manager.createContract(built2.params);
|
|
13831
|
+
return {
|
|
13832
|
+
type,
|
|
13833
|
+
// `built.tapscript` is a `DefaultVtxo.Script` here without a
|
|
13834
|
+
// cast — the branch, not a widened local, does the narrowing.
|
|
13835
|
+
tapscript: built2.tapscript,
|
|
13836
|
+
// A boarding row persists the *ark* encoding of its script, so
|
|
13837
|
+
// `contract.address` is unusable for an onchain sender: the
|
|
13838
|
+
// onchain form has to be re-derived.
|
|
13839
|
+
address: built2.tapscript.onchainAddress(this.network),
|
|
13840
|
+
signingDescriptor: descriptor,
|
|
13841
|
+
contract: contract2,
|
|
13842
|
+
allocated
|
|
13843
|
+
};
|
|
13844
|
+
}
|
|
13845
|
+
const built = buildReceiveContract(
|
|
13846
|
+
this.offchainTapscript,
|
|
13847
|
+
descriptor,
|
|
13848
|
+
this.network.hrp,
|
|
13849
|
+
tagSource
|
|
13850
|
+
);
|
|
13851
|
+
const contract = await manager.createContract(built.params);
|
|
13852
|
+
return {
|
|
13853
|
+
type,
|
|
13854
|
+
tapscript: built.tapscript,
|
|
13855
|
+
// Offchain rows already store the address they advertise, and
|
|
13856
|
+
// reading it back keeps a coalesced row (`createContract` is
|
|
13857
|
+
// first-wins on script) honest about what was actually persisted.
|
|
13858
|
+
address: contract.address,
|
|
13859
|
+
signingDescriptor: descriptor,
|
|
13860
|
+
contract,
|
|
13861
|
+
allocated
|
|
13862
|
+
};
|
|
13863
|
+
}
|
|
13864
|
+
/**
|
|
13865
|
+
* Build the boarding contract owned by `pubKey`, keeping every other option
|
|
13866
|
+
* of the wallet's current boarding tapscript (notably the boarding-exit
|
|
13867
|
+
* CSV, which is index-independent). The offchain analogue lives in
|
|
13868
|
+
* {@link buildReceiveContract}.
|
|
13869
|
+
*/
|
|
13870
|
+
buildBoardingContract(pubKey, descriptor, tagSource) {
|
|
13871
|
+
const tapscript = new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
|
|
13563
13872
|
...this._boardingTapscript.options,
|
|
13564
13873
|
pubKey
|
|
13565
13874
|
});
|
|
13566
|
-
const csvTimelock =
|
|
13567
|
-
|
|
13568
|
-
|
|
13875
|
+
const csvTimelock = tapscript.options.csvTimelock ?? chunkOIZ2V2VD_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
13876
|
+
return {
|
|
13877
|
+
tapscript,
|
|
13569
13878
|
params: {
|
|
13570
|
-
|
|
13571
|
-
|
|
13572
|
-
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
|
|
13577
|
-
|
|
13578
|
-
|
|
13579
|
-
|
|
13879
|
+
type: "boarding",
|
|
13880
|
+
params: {
|
|
13881
|
+
pubKey: base.hex.encode(pubKey),
|
|
13882
|
+
serverPubKey: base.hex.encode(tapscript.options.serverPubKey),
|
|
13883
|
+
csvTimelock: chunk2JV4VQ7C_cjs.timelockToSequence(csvTimelock).toString()
|
|
13884
|
+
},
|
|
13885
|
+
script: base.hex.encode(tapscript.pkScript),
|
|
13886
|
+
address: tapscript.address(this.network.hrp, this.arkServerPublicKey).encode(),
|
|
13887
|
+
state: "active",
|
|
13888
|
+
metadata: {
|
|
13889
|
+
...tagSource && { source: chunkOIZ2V2VD_cjs.WALLET_RECEIVE_SOURCE },
|
|
13890
|
+
signingDescriptor: descriptor
|
|
13891
|
+
}
|
|
13580
13892
|
}
|
|
13581
|
-
}
|
|
13582
|
-
this.setBoardingTapscriptForRotation(newBoarding);
|
|
13583
|
-
try {
|
|
13584
|
-
await manager.refillLookAhead();
|
|
13585
|
-
} catch (e) {
|
|
13586
|
-
console.warn("look-ahead refill after boarding allocation failed", e);
|
|
13587
|
-
}
|
|
13588
|
-
return newBoarding.onchainAddress(this.network);
|
|
13893
|
+
};
|
|
13589
13894
|
}
|
|
13590
13895
|
/**
|
|
13591
13896
|
* @see HDWalletCapable.getCurrentSigningDescriptor
|
|
@@ -13610,7 +13915,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13610
13915
|
if (this._descriptorProvider instanceof HDDescriptorProvider) {
|
|
13611
13916
|
return (await this.getContractManager()).getNextSigningDescriptor();
|
|
13612
13917
|
}
|
|
13613
|
-
return
|
|
13918
|
+
return chunkOIZ2V2VD_cjs.identityDescriptor(this.identity);
|
|
13614
13919
|
}
|
|
13615
13920
|
/**
|
|
13616
13921
|
* @see HDAllocationCapable.advanceSigningDescriptorWatermark
|
|
@@ -13706,7 +14011,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13706
14011
|
* the stable public API.
|
|
13707
14012
|
*/
|
|
13708
14013
|
async rotateServerSigner(newServerPubKey, checkpointTapscript) {
|
|
13709
|
-
const xonly =
|
|
14014
|
+
const xonly = chunkOIZ2V2VD_cjs.toXOnly(newServerPubKey, "ark signer key");
|
|
13710
14015
|
const newServerUnrollScript = assertValidServerUnrollScript(
|
|
13711
14016
|
checkpointTapscript,
|
|
13712
14017
|
resolveCheckpointExitDelayPolicy(this.network, this.checkpointExitDelayPolicy)
|
|
@@ -13735,21 +14040,21 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13735
14040
|
const [currentBoardingRow] = await manager.getContracts({
|
|
13736
14041
|
script: currentBoardingScript
|
|
13737
14042
|
});
|
|
13738
|
-
const newOffchain = this.offchainTapscript instanceof
|
|
14043
|
+
const newOffchain = this.offchainTapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? new chunkOIZ2V2VD_cjs.DelegateVtxo.Script({
|
|
13739
14044
|
...this.offchainTapscript.options,
|
|
13740
14045
|
serverPubKey: xonly
|
|
13741
|
-
}) : new
|
|
14046
|
+
}) : new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
|
|
13742
14047
|
...this.offchainTapscript.options,
|
|
13743
14048
|
serverPubKey: xonly
|
|
13744
14049
|
});
|
|
13745
|
-
const newBoarding = new
|
|
14050
|
+
const newBoarding = new chunkOIZ2V2VD_cjs.DefaultVtxo.Script({
|
|
13746
14051
|
...this._boardingTapscript.options,
|
|
13747
14052
|
serverPubKey: xonly
|
|
13748
14053
|
});
|
|
13749
|
-
const offchainCsv =
|
|
14054
|
+
const offchainCsv = chunk2JV4VQ7C_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
|
|
13750
14055
|
const newOffchainScript = base.hex.encode(newOffchain.pkScript);
|
|
13751
14056
|
const newOffchainAddress = newOffchain.address(this.network.hrp, xonly).encode();
|
|
13752
|
-
if (newOffchain instanceof
|
|
14057
|
+
if (newOffchain instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script) {
|
|
13753
14058
|
await manager.createContract({
|
|
13754
14059
|
type: "delegate",
|
|
13755
14060
|
params: {
|
|
@@ -13777,13 +14082,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13777
14082
|
metadata: currentOffchainRow?.metadata
|
|
13778
14083
|
});
|
|
13779
14084
|
}
|
|
13780
|
-
const boardingCsv = newBoarding.options.csvTimelock ??
|
|
14085
|
+
const boardingCsv = newBoarding.options.csvTimelock ?? chunkOIZ2V2VD_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
13781
14086
|
await manager.createContract({
|
|
13782
14087
|
type: "boarding",
|
|
13783
14088
|
params: {
|
|
13784
14089
|
pubKey: base.hex.encode(newBoarding.options.pubKey),
|
|
13785
14090
|
serverPubKey: base.hex.encode(xonly),
|
|
13786
|
-
csvTimelock:
|
|
14091
|
+
csvTimelock: chunk2JV4VQ7C_cjs.timelockToSequence(boardingCsv).toString()
|
|
13787
14092
|
},
|
|
13788
14093
|
script: base.hex.encode(newBoarding.pkScript),
|
|
13789
14094
|
address: newBoarding.address(this.network.hrp, xonly).encode(),
|
|
@@ -13816,14 +14121,14 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13816
14121
|
_restoreInFlight;
|
|
13817
14122
|
_addPendingSpends(inputs) {
|
|
13818
14123
|
for (const input of inputs) {
|
|
13819
|
-
if (
|
|
14124
|
+
if (chunk2JV4VQ7C_cjs.isVirtualCoin(input)) {
|
|
13820
14125
|
this._pendingSpendOutpoints.add(`${input.txid}:${input.vout}`);
|
|
13821
14126
|
}
|
|
13822
14127
|
}
|
|
13823
14128
|
}
|
|
13824
14129
|
_removePendingSpends(inputs) {
|
|
13825
14130
|
for (const input of inputs) {
|
|
13826
|
-
if (
|
|
14131
|
+
if (chunk2JV4VQ7C_cjs.isVirtualCoin(input)) {
|
|
13827
14132
|
this._pendingSpendOutpoints.delete(`${input.txid}:${input.vout}`);
|
|
13828
14133
|
}
|
|
13829
14134
|
}
|
|
@@ -13881,13 +14186,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13881
14186
|
const manager = await this.getContractManager();
|
|
13882
14187
|
const provider = this._descriptorProvider;
|
|
13883
14188
|
const hd = provider instanceof HDDescriptorProvider;
|
|
13884
|
-
const staticDescriptor = hd ? void 0 : await
|
|
14189
|
+
const staticDescriptor = hd ? void 0 : await chunkOIZ2V2VD_cjs.identityDescriptor(this.identity);
|
|
13885
14190
|
const materialize = (index) => hd ? provider.materializeDescriptorAt(index) : staticDescriptor;
|
|
13886
|
-
const delegatePubKey = this.offchainTapscript instanceof
|
|
14191
|
+
const delegatePubKey = this.offchainTapscript instanceof chunkOIZ2V2VD_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
|
|
13887
14192
|
const arkInfo = await this.arkProvider.getInfo();
|
|
13888
|
-
const currentSignerPubKey =
|
|
14193
|
+
const currentSignerPubKey = chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(arkInfo.signerPubkey), "ark signer key");
|
|
13889
14194
|
const deprecatedSignerPubKeys = arkInfo.deprecatedSigners.map(
|
|
13890
|
-
(s) =>
|
|
14195
|
+
(s) => chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(s.pubkey), "deprecated signer key")
|
|
13891
14196
|
);
|
|
13892
14197
|
const deps = {
|
|
13893
14198
|
indexerProvider: this.indexerProvider,
|
|
@@ -13902,7 +14207,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13902
14207
|
csvTimelocks: this.walletContractTimelocks,
|
|
13903
14208
|
// Boarding-exit CSV so the boarding handler can build its
|
|
13904
14209
|
// candidate script (distinct from the unilateral-exit matrix).
|
|
13905
|
-
boardingTimelock: this.boardingTapscript.options.csvTimelock ??
|
|
14210
|
+
boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunkOIZ2V2VD_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
|
|
13906
14211
|
delegatePubKey
|
|
13907
14212
|
};
|
|
13908
14213
|
const result = await manager.scanContracts({
|
|
@@ -13970,7 +14275,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13970
14275
|
await this._restoreInFlight?.catch(() => void 0);
|
|
13971
14276
|
this._serverInfoUnsub?.();
|
|
13972
14277
|
this._serverInfoUnsub = void 0;
|
|
13973
|
-
await this.
|
|
14278
|
+
await this.settleServerInfoChanges();
|
|
13974
14279
|
let rotatorError;
|
|
13975
14280
|
try {
|
|
13976
14281
|
await this._receiveRotator?.dispose();
|
|
@@ -14016,7 +14321,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14016
14321
|
throw new Error("Invalid configured public key");
|
|
14017
14322
|
}
|
|
14018
14323
|
const setup = await ReadonlyWallet.setupWalletConfig(config, pubkey);
|
|
14019
|
-
const forfeitPubkey = base.hex.decode(setup.info.forfeitPubkey)
|
|
14324
|
+
const forfeitPubkey = chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(setup.info.forfeitPubkey), "forfeit key");
|
|
14020
14325
|
const forfeitAddress = btcSigner.Address(setup.network).decode(setup.info.forfeitAddress);
|
|
14021
14326
|
const forfeitOutputScript = btcSigner.OutScript.encode(forfeitAddress);
|
|
14022
14327
|
const checkpointExitDelayOverrides = {
|
|
@@ -14165,7 +14470,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14165
14470
|
inputs: params.selectedVtxos,
|
|
14166
14471
|
changeAmount: BigInt(changeAmount)
|
|
14167
14472
|
};
|
|
14168
|
-
const outputAddress =
|
|
14473
|
+
const outputAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(params.address);
|
|
14169
14474
|
assertRecipientArkAddress(
|
|
14170
14475
|
params.address,
|
|
14171
14476
|
outputAddress,
|
|
@@ -14231,13 +14536,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14231
14536
|
void this.logUngatedInputs("settle({ inputs })", params.inputs);
|
|
14232
14537
|
}
|
|
14233
14538
|
const offchainAddress = await this.getAddress();
|
|
14234
|
-
const offchainPkScript =
|
|
14539
|
+
const offchainPkScript = chunk2JV4VQ7C_cjs.ArkAddress.decode(offchainAddress).pkScript;
|
|
14235
14540
|
const offchainOutputScript = base.hex.encode(offchainPkScript);
|
|
14236
14541
|
if (!params) {
|
|
14237
14542
|
const { fees, vtxoMaxAmount } = await this.arkProvider.getInfo();
|
|
14238
14543
|
const estimator = new Estimator(fees.intentFee);
|
|
14239
14544
|
let amount = 0;
|
|
14240
|
-
const exitScript =
|
|
14545
|
+
const exitScript = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(
|
|
14241
14546
|
base.hex.decode(this.boardingTapscript.exitScript)
|
|
14242
14547
|
);
|
|
14243
14548
|
const boardingTimelock = exitScript.params.timelock;
|
|
@@ -14266,7 +14571,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14266
14571
|
if (filteredVtxos.length >= MAX_VTXOS_PER_SETTLEMENT) {
|
|
14267
14572
|
break;
|
|
14268
14573
|
}
|
|
14269
|
-
const inputFee = estimator.evalOffchainInput(
|
|
14574
|
+
const inputFee = estimator.evalOffchainInput(chunk2JV4VQ7C_cjs.toOffchainInputFeeParams(vtxo));
|
|
14270
14575
|
if (inputFee.satoshis >= vtxo.value) {
|
|
14271
14576
|
continue;
|
|
14272
14577
|
}
|
|
@@ -14313,7 +14618,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14313
14618
|
let script;
|
|
14314
14619
|
let arkAddress;
|
|
14315
14620
|
try {
|
|
14316
|
-
arkAddress =
|
|
14621
|
+
arkAddress = chunk2JV4VQ7C_cjs.ArkAddress.decode(output.address);
|
|
14317
14622
|
} catch {
|
|
14318
14623
|
arkAddress = void 0;
|
|
14319
14624
|
}
|
|
@@ -14403,7 +14708,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14403
14708
|
const abortController = new AbortController();
|
|
14404
14709
|
let stream;
|
|
14405
14710
|
let committedTxid;
|
|
14406
|
-
const settleInputVtxos = params.inputs.filter(
|
|
14711
|
+
const settleInputVtxos = params.inputs.filter(chunk2JV4VQ7C_cjs.isVirtualCoin);
|
|
14407
14712
|
const contractManager = await this.getContractManager();
|
|
14408
14713
|
await contractManager.assertAnnotatable(settleInputVtxos);
|
|
14409
14714
|
await contractManager.assertSpendableNow?.(
|
|
@@ -14502,7 +14807,10 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14502
14807
|
* `typeof` guard skips the arknote strings settle also accepts.
|
|
14503
14808
|
*
|
|
14504
14809
|
* No-ops for static / `auto` wallets (no descriptor provider — boarding
|
|
14505
|
-
* stays on its fixed index-0 address).
|
|
14810
|
+
* stays on its fixed index-0 address). Wallets on a custom
|
|
14811
|
+
* {@link DescriptorProvider} DO rotate here now, where they previously
|
|
14812
|
+
* no-opped — see the behaviour-change note on {@link
|
|
14813
|
+
* getNewBoardingAddress}. Best-effort and non-fatal: the
|
|
14506
14814
|
* settle has already committed and its txid must be returned, so a
|
|
14507
14815
|
* rotation failure is logged and swallowed rather than thrown. Funds at
|
|
14508
14816
|
* the retired boarding address remain discoverable — the old `boarding`
|
|
@@ -14512,7 +14820,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14512
14820
|
async maybeRotateBoardingAfterBoard(inputs) {
|
|
14513
14821
|
if (!this._descriptorProvider) return;
|
|
14514
14822
|
const consumedBoarding = inputs.some(
|
|
14515
|
-
(input) => typeof input !== "string" && !
|
|
14823
|
+
(input) => typeof input !== "string" && !chunk2JV4VQ7C_cjs.isVirtualCoin(input)
|
|
14516
14824
|
);
|
|
14517
14825
|
if (!consumedBoarding) return;
|
|
14518
14826
|
try {
|
|
@@ -14536,7 +14844,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14536
14844
|
let connectorIndex = 0;
|
|
14537
14845
|
const connectorsLeaves = connectorsGraph?.leaves() || [];
|
|
14538
14846
|
for (const input of inputs) {
|
|
14539
|
-
if (!
|
|
14847
|
+
if (!chunk2JV4VQ7C_cjs.isVirtualCoin(input)) {
|
|
14540
14848
|
for (let i = 0; i < settlementPsbt.inputsLength; i++) {
|
|
14541
14849
|
const settlementInput = settlementPsbt.getInput(i);
|
|
14542
14850
|
if (!settlementInput.txid || settlementInput.index === void 0) {
|
|
@@ -14567,7 +14875,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14567
14875
|
}
|
|
14568
14876
|
continue;
|
|
14569
14877
|
}
|
|
14570
|
-
if (
|
|
14878
|
+
if (chunk2JV4VQ7C_cjs.canRecoverOnchain(input, { timestamp: /* @__PURE__ */ new Date() }) || isSubdust({ value: input.value }, this.dustAmount)) {
|
|
14571
14879
|
continue;
|
|
14572
14880
|
}
|
|
14573
14881
|
if (connectorsLeaves.length === 0) {
|
|
@@ -14595,7 +14903,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14595
14903
|
index: input.vout,
|
|
14596
14904
|
witnessUtxo: {
|
|
14597
14905
|
amount: BigInt(input.value),
|
|
14598
|
-
script:
|
|
14906
|
+
script: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
14599
14907
|
},
|
|
14600
14908
|
sighashType: btcSigner.SigHash.DEFAULT,
|
|
14601
14909
|
tapLeafScript: [input.forfeitTapLeafScript]
|
|
@@ -14614,7 +14922,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14614
14922
|
forfeitTx = await this._signerRouter.sign(forfeitTx, [
|
|
14615
14923
|
{
|
|
14616
14924
|
index: 0,
|
|
14617
|
-
lookupScript:
|
|
14925
|
+
lookupScript: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
14618
14926
|
}
|
|
14619
14927
|
]);
|
|
14620
14928
|
signedForfeits.push(base.base64.encode(forfeitTx.toPSBT()));
|
|
@@ -14672,7 +14980,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14672
14980
|
resolveBatchExpiryPolicy(this.network, this.batchExpiryPolicy)
|
|
14673
14981
|
);
|
|
14674
14982
|
await this.arkProvider.confirmRegistration(intentId);
|
|
14675
|
-
const sweepTapscript =
|
|
14983
|
+
const sweepTapscript = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.encode({
|
|
14676
14984
|
timelock,
|
|
14677
14985
|
pubkeys: [this.forfeitPubkey]
|
|
14678
14986
|
}).script;
|
|
@@ -14686,9 +14994,11 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14686
14994
|
if (!sweepTapTreeRoot) {
|
|
14687
14995
|
throw new Error("Sweep tap tree root not set");
|
|
14688
14996
|
}
|
|
14689
|
-
const xOnlyPublicKeys = event.cosignersPublicKeys.map(
|
|
14997
|
+
const xOnlyPublicKeys = event.cosignersPublicKeys.map(
|
|
14998
|
+
(k) => base.hex.encode(chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
|
|
14999
|
+
);
|
|
14690
15000
|
const signerPublicKey = await session.getPublicKey();
|
|
14691
|
-
const xonlySignerPublicKey =
|
|
15001
|
+
const xonlySignerPublicKey = chunkOIZ2V2VD_cjs.toXOnly(signerPublicKey, "signer key");
|
|
14692
15002
|
if (!xOnlyPublicKeys.includes(base.hex.encode(xonlySignerPublicKey))) {
|
|
14693
15003
|
return { skip: true };
|
|
14694
15004
|
}
|
|
@@ -14778,9 +15088,9 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14778
15088
|
...existing ?? {},
|
|
14779
15089
|
intentTxId,
|
|
14780
15090
|
registerProof: intent.proof,
|
|
14781
|
-
registerProofMessage:
|
|
15091
|
+
registerProofMessage: chunk2JV4VQ7C_cjs.Intent.encodeMessage(intent.message),
|
|
14782
15092
|
deleteProof: deleteIntent.proof,
|
|
14783
|
-
deleteProofMessage:
|
|
15093
|
+
deleteProofMessage: chunk2JV4VQ7C_cjs.Intent.encodeMessage(deleteIntent.message),
|
|
14784
15094
|
intentVtxos: inputs.map((i) => ({
|
|
14785
15095
|
txid: i.txid,
|
|
14786
15096
|
vout: i.vout
|
|
@@ -14812,7 +15122,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14812
15122
|
try {
|
|
14813
15123
|
return await this.arkProvider.registerIntent(intent);
|
|
14814
15124
|
} catch (error) {
|
|
14815
|
-
if (error instanceof
|
|
15125
|
+
if (error instanceof chunk2JV4VQ7C_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
|
|
14816
15126
|
const deleteIntent = await this.makeDeleteIntentSignature(inputs);
|
|
14817
15127
|
await this.arkProvider.deleteIntent(deleteIntent);
|
|
14818
15128
|
return this.arkProvider.registerIntent(intent);
|
|
@@ -14828,7 +15138,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14828
15138
|
expire_at: 0,
|
|
14829
15139
|
cosigners_public_keys: cosignerPubKeys
|
|
14830
15140
|
};
|
|
14831
|
-
const proof =
|
|
15141
|
+
const proof = chunk2JV4VQ7C_cjs.Intent.create(message, coins, outputs);
|
|
14832
15142
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
14833
15143
|
return {
|
|
14834
15144
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -14840,7 +15150,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14840
15150
|
type: "delete",
|
|
14841
15151
|
expire_at: 0
|
|
14842
15152
|
};
|
|
14843
|
-
const proof =
|
|
15153
|
+
const proof = chunk2JV4VQ7C_cjs.Intent.create(message, coins, []);
|
|
14844
15154
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
14845
15155
|
return {
|
|
14846
15156
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -14852,7 +15162,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14852
15162
|
type: "get-pending-tx",
|
|
14853
15163
|
expire_at: 0
|
|
14854
15164
|
};
|
|
14855
|
-
const proof =
|
|
15165
|
+
const proof = chunk2JV4VQ7C_cjs.Intent.create(message, coins, []);
|
|
14856
15166
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
14857
15167
|
return {
|
|
14858
15168
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -14873,7 +15183,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14873
15183
|
if (!vtxos || vtxos.length === 0) {
|
|
14874
15184
|
const scriptMap = await this.getScriptMap();
|
|
14875
15185
|
const allExtended = [];
|
|
14876
|
-
const fetchedVtxos = await
|
|
15186
|
+
const fetchedVtxos = await chunk2JV4VQ7C_cjs.getAllNormalizedVtxos(this.indexerProvider, [
|
|
14877
15187
|
...scriptMap.keys()
|
|
14878
15188
|
]);
|
|
14879
15189
|
for (const vtxo of fetchedVtxos) {
|
|
@@ -14987,11 +15297,11 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
14987
15297
|
* against the current key alone would leave it pending forever.
|
|
14988
15298
|
*/
|
|
14989
15299
|
checkpointUnrollCandidates(info) {
|
|
14990
|
-
const current =
|
|
15300
|
+
const current = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
|
|
14991
15301
|
const candidates = [this._serverUnrollScript, current];
|
|
14992
15302
|
for (const deprecated of signerSetFromInfo(info).deprecated.keys()) {
|
|
14993
15303
|
candidates.push(
|
|
14994
|
-
|
|
15304
|
+
chunk2JV4VQ7C_cjs.CSVMultisigTapscript.encode({
|
|
14995
15305
|
...current.params,
|
|
14996
15306
|
pubkeys: [base.hex.decode(deprecated)]
|
|
14997
15307
|
})
|
|
@@ -15082,7 +15392,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15082
15392
|
if (vtxos.length === 0) {
|
|
15083
15393
|
throw new Error("No VTXOs found for this arkadeCash");
|
|
15084
15394
|
}
|
|
15085
|
-
const myPkScript =
|
|
15395
|
+
const myPkScript = chunk2JV4VQ7C_cjs.ArkAddress.decode(await this.getAddress()).pkScript;
|
|
15086
15396
|
let { spendable, unclaimed } = this.classifyCashVtxos(vtxos);
|
|
15087
15397
|
let swept = 0;
|
|
15088
15398
|
const drainable = vtxos.filter((vtxo) => !isSubdust(vtxo, this.dustAmount));
|
|
@@ -15156,8 +15466,10 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15156
15466
|
const spendable = [];
|
|
15157
15467
|
const unclaimed = [];
|
|
15158
15468
|
for (const vtxo of vtxos) {
|
|
15159
|
-
if (
|
|
15469
|
+
if (chunk2JV4VQ7C_cjs.hasTerminalSpend(vtxo)) {
|
|
15160
15470
|
unclaimed.push(cashReport(vtxo, "already-spent"));
|
|
15471
|
+
} else if (vtxo.isUnrolled) {
|
|
15472
|
+
unclaimed.push(cashReport(vtxo, "exited"));
|
|
15161
15473
|
} else if (isSubdust(vtxo, this.dustAmount)) {
|
|
15162
15474
|
unclaimed.push(cashReport(vtxo, "subdust"));
|
|
15163
15475
|
} else if (vtxo.isSwept) {
|
|
@@ -15176,7 +15488,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15176
15488
|
const all = [];
|
|
15177
15489
|
const seen = /* @__PURE__ */ new Set();
|
|
15178
15490
|
for (let pageIndex = 0; ; pageIndex++) {
|
|
15179
|
-
const { vtxos, page } = await
|
|
15491
|
+
const { vtxos, page } = await chunk2JV4VQ7C_cjs.getNormalizedVtxos(this.indexerProvider, {
|
|
15180
15492
|
scripts,
|
|
15181
15493
|
pageIndex,
|
|
15182
15494
|
pageSize
|
|
@@ -15223,7 +15535,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15223
15535
|
for (let i = 0; i < inputs.length; i += MAX_INPUTS_PER_INTENT) {
|
|
15224
15536
|
const batch = inputs.slice(i, i + MAX_INPUTS_PER_INTENT);
|
|
15225
15537
|
const message = { type: "get-pending-tx", expire_at: 0 };
|
|
15226
|
-
const proof =
|
|
15538
|
+
const proof = chunk2JV4VQ7C_cjs.Intent.create(message, batch, []);
|
|
15227
15539
|
const signedProof = await identity.sign(
|
|
15228
15540
|
proof,
|
|
15229
15541
|
Array.from({ length: batch.length + 1 }, (_, j) => j)
|
|
@@ -15442,7 +15754,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15442
15754
|
script: recipient.script,
|
|
15443
15755
|
amount: BigInt(recipient.amount),
|
|
15444
15756
|
// Already checked against the recipient address in `validateRecipients`.
|
|
15445
|
-
...recipient.tapTree ? { tapTree:
|
|
15757
|
+
...recipient.tapTree ? { tapTree: chunk2JV4VQ7C_cjs.TapTreeCoder.decode(recipient.tapTree) } : {}
|
|
15446
15758
|
}));
|
|
15447
15759
|
const totalBtcOutput = outputs.reduce((sum, o) => sum + Number(o.amount), 0);
|
|
15448
15760
|
let changeAmount = totalBtcSelected - totalBtcOutput;
|
|
@@ -15586,10 +15898,10 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15586
15898
|
const serverPubKey = this.arkServerPublicKey;
|
|
15587
15899
|
const serverUnrollScript = this.serverUnrollScript;
|
|
15588
15900
|
const arkAddress = offchainTapscript.address(this.network.hrp, serverPubKey);
|
|
15589
|
-
const normalizedInputs = inputs.map(
|
|
15590
|
-
const at = now ?? await
|
|
15901
|
+
const normalizedInputs = inputs.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
|
|
15902
|
+
const at = now ?? await chunk2JV4VQ7C_cjs.resolveTimeHeight(this.onchainProvider);
|
|
15591
15903
|
for (const input of normalizedInputs) {
|
|
15592
|
-
if (!
|
|
15904
|
+
if (!chunk2JV4VQ7C_cjs.canSpendOffchain(input, at)) {
|
|
15593
15905
|
throw new Error(
|
|
15594
15906
|
`sendSelectedVtxosToSelf: input ${input.txid}:${input.vout} is not cooperatively spendable`
|
|
15595
15907
|
);
|
|
@@ -15659,7 +15971,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15659
15971
|
);
|
|
15660
15972
|
const arkTxJobs = inputs.map((input, index) => ({
|
|
15661
15973
|
index,
|
|
15662
|
-
lookupScript:
|
|
15974
|
+
lookupScript: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
15663
15975
|
}));
|
|
15664
15976
|
const identity = this.identity;
|
|
15665
15977
|
const signer = {
|
|
@@ -15745,14 +16057,14 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15745
16057
|
const spentBy = checkpointIdByOutpoint.get(`${vtxo.txid}:${vtxo.vout}`);
|
|
15746
16058
|
spentVtxos.push({
|
|
15747
16059
|
...spentFacts,
|
|
15748
|
-
virtualStatus:
|
|
16060
|
+
virtualStatus: chunk2JV4VQ7C_cjs.toVirtualStatus(spentFacts),
|
|
15749
16061
|
...spentBy ? { spentBy } : {},
|
|
15750
16062
|
arkTxId: arkTxid
|
|
15751
16063
|
});
|
|
15752
16064
|
for (const id of vtxo.commitmentTxIds) {
|
|
15753
16065
|
commitmentTxIds.add(id);
|
|
15754
16066
|
}
|
|
15755
|
-
const vtxoExpiry =
|
|
16067
|
+
const vtxoExpiry = chunk2JV4VQ7C_cjs.toBatchExpiry(vtxo);
|
|
15756
16068
|
if (vtxoExpiry) {
|
|
15757
16069
|
batchExpiry = Math.min(batchExpiry, vtxoExpiry);
|
|
15758
16070
|
}
|
|
@@ -15765,7 +16077,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15765
16077
|
isSwept: false,
|
|
15766
16078
|
isPreconfirmed: true,
|
|
15767
16079
|
commitmentTxIds: Array.from(commitmentTxIds),
|
|
15768
|
-
...
|
|
16080
|
+
...chunk2JV4VQ7C_cjs.parseLegacyExpiry(batchExpiry)
|
|
15769
16081
|
};
|
|
15770
16082
|
changeVtxo = {
|
|
15771
16083
|
txid: arkTxid,
|
|
@@ -15777,7 +16089,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15777
16089
|
tapTree: offchainTapscript.encode(),
|
|
15778
16090
|
value: Number(changeAmount),
|
|
15779
16091
|
...changeFacts,
|
|
15780
|
-
virtualStatus:
|
|
16092
|
+
virtualStatus: chunk2JV4VQ7C_cjs.toVirtualStatus(changeFacts),
|
|
15781
16093
|
spentBy: "",
|
|
15782
16094
|
status: {
|
|
15783
16095
|
confirmed: false
|
|
@@ -15846,12 +16158,12 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15846
16158
|
const spentVtxos = [];
|
|
15847
16159
|
const inputArkTxIds = /* @__PURE__ */ new Set();
|
|
15848
16160
|
const boardingRemovalsByAddress = /* @__PURE__ */ new Map();
|
|
15849
|
-
const vtxoInputs = inputs.filter(
|
|
16161
|
+
const vtxoInputs = inputs.filter(chunk2JV4VQ7C_cjs.isVirtualCoin);
|
|
15850
16162
|
const cm = await this.getContractManager();
|
|
15851
16163
|
const annotatedVtxos = await cm.annotateVtxos(vtxoInputs);
|
|
15852
16164
|
const annotatedByKey = new Map(annotatedVtxos.map((v) => [`${v.txid}:${v.vout}`, v]));
|
|
15853
16165
|
for (const input of inputs) {
|
|
15854
|
-
if (
|
|
16166
|
+
if (chunk2JV4VQ7C_cjs.isVirtualCoin(input)) {
|
|
15855
16167
|
const outpoint = `${input.txid}:${input.vout}`;
|
|
15856
16168
|
const vtxo = annotatedByKey.get(outpoint);
|
|
15857
16169
|
if (!vtxo) {
|
|
@@ -15863,13 +16175,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15863
16175
|
const settledFacts = { ...vtxo, isSpent: true };
|
|
15864
16176
|
spentVtxos.push({
|
|
15865
16177
|
...settledFacts,
|
|
15866
|
-
virtualStatus:
|
|
16178
|
+
virtualStatus: chunk2JV4VQ7C_cjs.toVirtualStatus(settledFacts),
|
|
15867
16179
|
settledBy: commitmentTxid
|
|
15868
16180
|
});
|
|
15869
16181
|
} else {
|
|
15870
16182
|
let sourceAddress;
|
|
15871
16183
|
try {
|
|
15872
|
-
sourceAddress =
|
|
16184
|
+
sourceAddress = chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
|
|
15873
16185
|
this.network
|
|
15874
16186
|
);
|
|
15875
16187
|
} catch {
|
|
@@ -15927,9 +16239,9 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
15927
16239
|
}
|
|
15928
16240
|
};
|
|
15929
16241
|
function selectVirtualCoins(coins, targetAmount) {
|
|
15930
|
-
const sortedCoins = coins.map(
|
|
15931
|
-
const expiryA =
|
|
15932
|
-
const expiryB =
|
|
16242
|
+
const sortedCoins = coins.map(chunk2JV4VQ7C_cjs.normalizeVtxo).sort((a, b) => {
|
|
16243
|
+
const expiryA = chunk2JV4VQ7C_cjs.toBatchExpiry(a) || Number.MAX_SAFE_INTEGER;
|
|
16244
|
+
const expiryB = chunk2JV4VQ7C_cjs.toBatchExpiry(b) || Number.MAX_SAFE_INTEGER;
|
|
15933
16245
|
if (expiryA !== expiryB) {
|
|
15934
16246
|
return expiryA - expiryB;
|
|
15935
16247
|
}
|
|
@@ -16048,6 +16360,11 @@ var MessageBus = class {
|
|
|
16048
16360
|
buildServicesFn;
|
|
16049
16361
|
boundOnMessage = this.onMessage.bind(this);
|
|
16050
16362
|
intentRepository;
|
|
16363
|
+
/** Pending broadcasts, drained FIFO by a single {@link drain} loop. */
|
|
16364
|
+
broadcastQueue = [];
|
|
16365
|
+
draining = false;
|
|
16366
|
+
/** Bumped wherever the generation owning the queued broadcasts ends. */
|
|
16367
|
+
broadcastEpoch = 0;
|
|
16051
16368
|
/** Start the message bus and attach service-worker event listeners. */
|
|
16052
16369
|
async start() {
|
|
16053
16370
|
if (this.running) return;
|
|
@@ -16070,6 +16387,7 @@ var MessageBus = class {
|
|
|
16070
16387
|
this.running = false;
|
|
16071
16388
|
this.tickInProgress = false;
|
|
16072
16389
|
this.initialized = false;
|
|
16390
|
+
this.invalidateBroadcasts();
|
|
16073
16391
|
if (this.tickTimeout !== null) {
|
|
16074
16392
|
self.clearTimeout(this.tickTimeout);
|
|
16075
16393
|
this.tickTimeout = null;
|
|
@@ -16082,6 +16400,78 @@ var MessageBus = class {
|
|
|
16082
16400
|
self.removeEventListener("message", this.boundOnMessage);
|
|
16083
16401
|
await Promise.all(Array.from(this.handlers.values()).map((updater) => updater.stop()));
|
|
16084
16402
|
}
|
|
16403
|
+
/** Invalidate every broadcast belonging to the outgoing generation. */
|
|
16404
|
+
invalidateBroadcasts() {
|
|
16405
|
+
this.broadcastEpoch++;
|
|
16406
|
+
this.broadcastQueue.length = 0;
|
|
16407
|
+
}
|
|
16408
|
+
broadcastToClients(responses) {
|
|
16409
|
+
this.broadcastQueue.push(...responses);
|
|
16410
|
+
void this.drain();
|
|
16411
|
+
}
|
|
16412
|
+
/**
|
|
16413
|
+
* Single fan-out loop, so pushes and tick responses keep one FIFO order.
|
|
16414
|
+
* A helper posting per response would race: `clients.matchAll()` gives no
|
|
16415
|
+
* cross-call resolution order, and it would de-batch `runTick`.
|
|
16416
|
+
*/
|
|
16417
|
+
async drain() {
|
|
16418
|
+
if (this.draining) return;
|
|
16419
|
+
this.draining = true;
|
|
16420
|
+
try {
|
|
16421
|
+
while (this.broadcastQueue.length) {
|
|
16422
|
+
const epoch = this.broadcastEpoch;
|
|
16423
|
+
const batch = this.broadcastQueue.splice(0);
|
|
16424
|
+
if (!this.running) {
|
|
16425
|
+
this.logDroppedBroadcasts(batch, "bus stopped");
|
|
16426
|
+
return;
|
|
16427
|
+
}
|
|
16428
|
+
let clients;
|
|
16429
|
+
try {
|
|
16430
|
+
clients = await self.clients.matchAll({
|
|
16431
|
+
includeUncontrolled: true,
|
|
16432
|
+
type: "window"
|
|
16433
|
+
});
|
|
16434
|
+
} catch (err) {
|
|
16435
|
+
this.logDroppedBroadcasts(batch, "clients.matchAll failed", err);
|
|
16436
|
+
continue;
|
|
16437
|
+
}
|
|
16438
|
+
if (!this.running) {
|
|
16439
|
+
this.logDroppedBroadcasts(batch, "bus stopped during matchAll");
|
|
16440
|
+
return;
|
|
16441
|
+
}
|
|
16442
|
+
if (this.broadcastEpoch !== epoch) {
|
|
16443
|
+
this.logDroppedBroadcasts(batch, "re-init landed during matchAll");
|
|
16444
|
+
continue;
|
|
16445
|
+
}
|
|
16446
|
+
for (const message of batch) {
|
|
16447
|
+
for (const client of clients) {
|
|
16448
|
+
try {
|
|
16449
|
+
client.postMessage(message);
|
|
16450
|
+
} catch (err) {
|
|
16451
|
+
if (this.debug)
|
|
16452
|
+
console.warn(`[${message.tag}] broadcast to client failed`, err);
|
|
16453
|
+
}
|
|
16454
|
+
}
|
|
16455
|
+
}
|
|
16456
|
+
}
|
|
16457
|
+
} catch {
|
|
16458
|
+
} finally {
|
|
16459
|
+
this.draining = false;
|
|
16460
|
+
if (this.running && this.broadcastQueue.length) void this.drain();
|
|
16461
|
+
}
|
|
16462
|
+
}
|
|
16463
|
+
/**
|
|
16464
|
+
* A dropped batch has no periodic recovery to fall back on now that events
|
|
16465
|
+
* no longer ride the tick, so name the loss under {@link Options.debug}.
|
|
16466
|
+
*/
|
|
16467
|
+
logDroppedBroadcasts(batch, reason, ...error) {
|
|
16468
|
+
if (!this.debug) return;
|
|
16469
|
+
console.warn(
|
|
16470
|
+
`dropping ${batch.length} broadcast(s): ${reason}`,
|
|
16471
|
+
batch.map((response) => response.tag),
|
|
16472
|
+
...error
|
|
16473
|
+
);
|
|
16474
|
+
}
|
|
16085
16475
|
scheduleNextTick() {
|
|
16086
16476
|
if (!this.running) return;
|
|
16087
16477
|
if (this.tickTimeout !== null) return;
|
|
@@ -16110,16 +16500,7 @@ var MessageBus = class {
|
|
|
16110
16500
|
if (this.debug)
|
|
16111
16501
|
console.log(`[${updater.messageTag}] outgoing tick response:`, response);
|
|
16112
16502
|
if (response && response.length > 0) {
|
|
16113
|
-
|
|
16114
|
-
includeUncontrolled: true,
|
|
16115
|
-
type: "window"
|
|
16116
|
-
}).then((clients) => {
|
|
16117
|
-
for (const message of response) {
|
|
16118
|
-
clients.forEach((client) => {
|
|
16119
|
-
client.postMessage(message);
|
|
16120
|
-
});
|
|
16121
|
-
}
|
|
16122
|
-
});
|
|
16503
|
+
this.broadcastToClients(response);
|
|
16123
16504
|
}
|
|
16124
16505
|
} catch (err) {
|
|
16125
16506
|
if (this.debug) console.error(`[${updater.messageTag}] tick failed`, err);
|
|
@@ -16158,6 +16539,14 @@ var MessageBus = class {
|
|
|
16158
16539
|
self.clearTimeout(this.tickTimeout);
|
|
16159
16540
|
this.tickTimeout = null;
|
|
16160
16541
|
}
|
|
16542
|
+
this.invalidateBroadcasts();
|
|
16543
|
+
const epoch = this.broadcastEpoch;
|
|
16544
|
+
const channel = {
|
|
16545
|
+
broadcast: (response) => {
|
|
16546
|
+
if (epoch !== this.broadcastEpoch) return;
|
|
16547
|
+
this.broadcastToClients([response]);
|
|
16548
|
+
}
|
|
16549
|
+
};
|
|
16161
16550
|
if (this.initialized) {
|
|
16162
16551
|
this.initialized = false;
|
|
16163
16552
|
await Promise.all(
|
|
@@ -16174,9 +16563,7 @@ var MessageBus = class {
|
|
|
16174
16563
|
try {
|
|
16175
16564
|
for (const updater of this.handlers.values()) {
|
|
16176
16565
|
if (this.debug) console.log(`Starting updater: ${updater.messageTag}`);
|
|
16177
|
-
await updater.start(services, {
|
|
16178
|
-
walletRepository: this.walletRepository
|
|
16179
|
-
});
|
|
16566
|
+
await updater.start(services, { walletRepository: this.walletRepository }, channel);
|
|
16180
16567
|
started.push(updater);
|
|
16181
16568
|
}
|
|
16182
16569
|
} catch (err) {
|
|
@@ -16189,7 +16576,7 @@ var MessageBus = class {
|
|
|
16189
16576
|
this.initialized = true;
|
|
16190
16577
|
}
|
|
16191
16578
|
async buildServices(config) {
|
|
16192
|
-
const arkProvider = new
|
|
16579
|
+
const arkProvider = new chunk2JV4VQ7C_cjs.RestArkProvider(config.arkServer.url);
|
|
16193
16580
|
const storage = {
|
|
16194
16581
|
walletRepository: this.walletRepository,
|
|
16195
16582
|
contractRepository: this.contractRepository,
|
|
@@ -16531,7 +16918,7 @@ var offboardNetworkNames = [
|
|
|
16531
16918
|
function offboardDestinationScript(destinationAddress) {
|
|
16532
16919
|
for (const networkName of offboardNetworkNames) {
|
|
16533
16920
|
try {
|
|
16534
|
-
const network =
|
|
16921
|
+
const network = chunk2JV4VQ7C_cjs.networks[networkName];
|
|
16535
16922
|
const addr = btcSigner.Address(network).decode(destinationAddress);
|
|
16536
16923
|
return btcSigner.OutScript.encode(addr);
|
|
16537
16924
|
} catch {
|
|
@@ -16595,7 +16982,7 @@ var Ramps = class {
|
|
|
16595
16982
|
}
|
|
16596
16983
|
amount = amount ?? totalAmount;
|
|
16597
16984
|
const offchainAddress = await this.wallet.getAddress();
|
|
16598
|
-
const offchainAddr =
|
|
16985
|
+
const offchainAddr = chunk2JV4VQ7C_cjs.ArkAddress.decode(offchainAddress);
|
|
16599
16986
|
const offchainScript = base.hex.encode(offchainAddr.pkScript);
|
|
16600
16987
|
const outputFee = estimator.evalOffchainOutput({
|
|
16601
16988
|
amount,
|
|
@@ -16655,7 +17042,7 @@ var Ramps = class {
|
|
|
16655
17042
|
const filteredVtxos = [];
|
|
16656
17043
|
let totalAmount = 0n;
|
|
16657
17044
|
for (const vtxo of vtxos) {
|
|
16658
|
-
const inputFee = estimator.evalOffchainInput(
|
|
17045
|
+
const inputFee = estimator.evalOffchainInput(chunk2JV4VQ7C_cjs.toOffchainInputFeeParams(vtxo));
|
|
16659
17046
|
if (inputFee.satoshis >= vtxo.value) {
|
|
16660
17047
|
continue;
|
|
16661
17048
|
}
|
|
@@ -16846,6 +17233,17 @@ var WalletMessageHandler = class {
|
|
|
16846
17233
|
incomingFundsSubscription;
|
|
16847
17234
|
contractEventsSubscription;
|
|
16848
17235
|
onNextTick = [];
|
|
17236
|
+
channel;
|
|
17237
|
+
// One counter per subscription field, bumped exactly where that field is
|
|
17238
|
+
// dropped — never where a neighbour's is. They cannot be merged:
|
|
17239
|
+
// `onWalletInitialized` re-subscribes incoming funds while
|
|
17240
|
+
// `ensureContractEventBroadcasting` deliberately keeps its subscription, so
|
|
17241
|
+
// a shared bump would leave the live contract-event emitter permanently
|
|
17242
|
+
// stale, and folding requests in would truncate an in-flight settle.
|
|
17243
|
+
incomingFundsEpoch = 0;
|
|
17244
|
+
contractEventsEpoch = 0;
|
|
17245
|
+
/** Per-request progress callbacks: ends with the handler, not with a re-init. */
|
|
17246
|
+
requestEpoch = 0;
|
|
16849
17247
|
/**
|
|
16850
17248
|
* Instantiate a new WalletUpdater.
|
|
16851
17249
|
* Can override the default `messageTag` allowing more than one updater to run in parallel.
|
|
@@ -16856,13 +17254,20 @@ var WalletMessageHandler = class {
|
|
|
16856
17254
|
}
|
|
16857
17255
|
// lifecycle methods
|
|
16858
17256
|
async start(...params) {
|
|
16859
|
-
const [services, repositories] = params;
|
|
17257
|
+
const [services, repositories, channel] = params;
|
|
16860
17258
|
this.readonlyWallet = services.readonlyWallet;
|
|
16861
17259
|
this.wallet = services.wallet;
|
|
16862
17260
|
this.arkProvider = services.arkProvider;
|
|
16863
17261
|
this.walletRepository = repositories.walletRepository;
|
|
17262
|
+
this.channel = channel;
|
|
17263
|
+
this.onNextTick = [];
|
|
16864
17264
|
}
|
|
16865
17265
|
async stop() {
|
|
17266
|
+
this.requestEpoch++;
|
|
17267
|
+
this.incomingFundsEpoch++;
|
|
17268
|
+
this.contractEventsEpoch++;
|
|
17269
|
+
this.channel = void 0;
|
|
17270
|
+
this.onNextTick = [];
|
|
16866
17271
|
if (this.incomingFundsSubscription) {
|
|
16867
17272
|
this.incomingFundsSubscription();
|
|
16868
17273
|
this.incomingFundsSubscription = void 0;
|
|
@@ -16885,8 +17290,8 @@ var WalletMessageHandler = class {
|
|
|
16885
17290
|
this.indexerProvider = void 0;
|
|
16886
17291
|
}
|
|
16887
17292
|
async tick(_now) {
|
|
16888
|
-
const
|
|
16889
|
-
|
|
17293
|
+
const pending = this.onNextTick.splice(0);
|
|
17294
|
+
const results = await Promise.allSettled(pending.map((fn) => fn()));
|
|
16890
17295
|
return results.map((result) => {
|
|
16891
17296
|
if (result.status === "fulfilled") {
|
|
16892
17297
|
return result.value;
|
|
@@ -16896,8 +17301,46 @@ var WalletMessageHandler = class {
|
|
|
16896
17301
|
}
|
|
16897
17302
|
}).filter((response) => response !== null);
|
|
16898
17303
|
}
|
|
16899
|
-
|
|
16900
|
-
|
|
17304
|
+
epochOf(scope) {
|
|
17305
|
+
switch (scope) {
|
|
17306
|
+
case "incomingFunds":
|
|
17307
|
+
return this.incomingFundsEpoch;
|
|
17308
|
+
case "contractEvents":
|
|
17309
|
+
return this.contractEventsEpoch;
|
|
17310
|
+
case "request":
|
|
17311
|
+
return this.requestEpoch;
|
|
17312
|
+
default: {
|
|
17313
|
+
const _exhaustive = scope;
|
|
17314
|
+
throw new Error(`Unknown scope: ${_exhaustive}`);
|
|
17315
|
+
}
|
|
17316
|
+
}
|
|
17317
|
+
}
|
|
17318
|
+
newGeneration(scope) {
|
|
17319
|
+
const born = this.epochOf(scope);
|
|
17320
|
+
const stale = () => born !== this.epochOf(scope);
|
|
17321
|
+
return {
|
|
17322
|
+
get stale() {
|
|
17323
|
+
return stale();
|
|
17324
|
+
}
|
|
17325
|
+
};
|
|
17326
|
+
}
|
|
17327
|
+
/**
|
|
17328
|
+
* A handle rather than a `broadcast(response, epoch)` call, because it can
|
|
17329
|
+
* only be written where the closure it guards is created — an epoch passed
|
|
17330
|
+
* at the call site reads identically whether it guards anything or not.
|
|
17331
|
+
*/
|
|
17332
|
+
newEmitter(scope) {
|
|
17333
|
+
const gen = this.newGeneration(scope);
|
|
17334
|
+
return {
|
|
17335
|
+
get stale() {
|
|
17336
|
+
return gen.stale;
|
|
17337
|
+
},
|
|
17338
|
+
emit: (response) => {
|
|
17339
|
+
if (!response || gen.stale) return;
|
|
17340
|
+
if (this.channel) return this.channel.broadcast(response);
|
|
17341
|
+
this.onNextTick.push(() => response);
|
|
17342
|
+
}
|
|
17343
|
+
};
|
|
16901
17344
|
}
|
|
16902
17345
|
requireWallet() {
|
|
16903
17346
|
if (!this.wallet) {
|
|
@@ -16926,6 +17369,7 @@ var WalletMessageHandler = class {
|
|
|
16926
17369
|
}
|
|
16927
17370
|
async handleMessage(message) {
|
|
16928
17371
|
const id = message.id;
|
|
17372
|
+
const emitter = this.newEmitter("request");
|
|
16929
17373
|
if (message.type === "INIT_WALLET") {
|
|
16930
17374
|
await this.handleInitWallet(message);
|
|
16931
17375
|
return this.tagged({
|
|
@@ -17194,6 +17638,18 @@ var WalletMessageHandler = class {
|
|
|
17194
17638
|
payload: { descriptor }
|
|
17195
17639
|
});
|
|
17196
17640
|
}
|
|
17641
|
+
case "GET_NEW_ADDRESSES": {
|
|
17642
|
+
const wallet = this.wallet;
|
|
17643
|
+
if (!wallet) throw new WalletNotInitializedError();
|
|
17644
|
+
const addresses = await wallet.getNewAddresses(
|
|
17645
|
+
message.payload
|
|
17646
|
+
);
|
|
17647
|
+
return this.tagged({
|
|
17648
|
+
id,
|
|
17649
|
+
type: "NEW_ADDRESSES",
|
|
17650
|
+
payload: { addresses }
|
|
17651
|
+
});
|
|
17652
|
+
}
|
|
17197
17653
|
case "GET_USED_SIGNING_DESCRIPTORS": {
|
|
17198
17654
|
const wallet = this.wallet;
|
|
17199
17655
|
const descriptors = isHDWalletCapable(wallet) ? await wallet.getUsedSigningDescriptors(
|
|
@@ -17284,8 +17740,8 @@ var WalletMessageHandler = class {
|
|
|
17284
17740
|
const wallet = this.requireWallet();
|
|
17285
17741
|
const vtxoManager = await wallet.getVtxoManager();
|
|
17286
17742
|
const txid = await vtxoManager.recoverVtxos((e) => {
|
|
17287
|
-
|
|
17288
|
-
|
|
17743
|
+
emitter.emit(
|
|
17744
|
+
this.tagged({
|
|
17289
17745
|
id,
|
|
17290
17746
|
type: "RECOVER_VTXOS_EVENT",
|
|
17291
17747
|
payload: e
|
|
@@ -17329,8 +17785,8 @@ var WalletMessageHandler = class {
|
|
|
17329
17785
|
const wallet = this.requireWallet();
|
|
17330
17786
|
const vtxoManager = await wallet.getVtxoManager();
|
|
17331
17787
|
const txid = await vtxoManager.renewVtxos((e) => {
|
|
17332
|
-
|
|
17333
|
-
|
|
17788
|
+
emitter.emit(
|
|
17789
|
+
this.tagged({
|
|
17334
17790
|
id,
|
|
17335
17791
|
type: "RENEW_VTXOS_EVENT",
|
|
17336
17792
|
payload: e
|
|
@@ -17368,8 +17824,8 @@ var WalletMessageHandler = class {
|
|
|
17368
17824
|
const vtxoManager = await wallet.getVtxoManager();
|
|
17369
17825
|
const report = await vtxoManager.migrateDeprecatedSignerVtxos({
|
|
17370
17826
|
eventCallback: (e) => {
|
|
17371
|
-
|
|
17372
|
-
|
|
17827
|
+
emitter.emit(
|
|
17828
|
+
this.tagged({
|
|
17373
17829
|
id,
|
|
17374
17830
|
type: "MIGRATE_DEPRECATED_SIGNER_VTXOS_EVENT",
|
|
17375
17831
|
payload: e
|
|
@@ -17422,7 +17878,7 @@ var WalletMessageHandler = class {
|
|
|
17422
17878
|
// Wallet methods
|
|
17423
17879
|
async handleInitWallet({ payload }) {
|
|
17424
17880
|
const { arkServerUrl } = payload;
|
|
17425
|
-
this.indexerProvider = new
|
|
17881
|
+
this.indexerProvider = new chunkCO3KKSWM_cjs.RestIndexerProvider(arkServerUrl);
|
|
17426
17882
|
await this.onWalletInitialized();
|
|
17427
17883
|
}
|
|
17428
17884
|
/**
|
|
@@ -17472,6 +17928,7 @@ var WalletMessageHandler = class {
|
|
|
17472
17928
|
intentLocked: offchain.intentLocked,
|
|
17473
17929
|
recoverable: offchain.recoverable,
|
|
17474
17930
|
pendingRecovery: offchain.pendingRecovery,
|
|
17931
|
+
unrolled: offchain.unrolled,
|
|
17475
17932
|
total: totalBoarding + offchain.total,
|
|
17476
17933
|
assets: offchain.assets,
|
|
17477
17934
|
availableAssets: offchain.availableAssets
|
|
@@ -17482,11 +17939,15 @@ var WalletMessageHandler = class {
|
|
|
17482
17939
|
return this.readonlyWallet.getBoardingUtxos();
|
|
17483
17940
|
}
|
|
17484
17941
|
async onWalletInitialized() {
|
|
17485
|
-
|
|
17942
|
+
const wallet = this.readonlyWallet;
|
|
17943
|
+
if (!wallet || !this.arkProvider || !this.indexerProvider || !this.walletRepository) {
|
|
17486
17944
|
return;
|
|
17487
17945
|
}
|
|
17946
|
+
const init = this.newGeneration("incomingFunds");
|
|
17488
17947
|
await this.ensureContractEventBroadcasting();
|
|
17948
|
+
if (init.stale) return;
|
|
17489
17949
|
await this.refreshCachedData();
|
|
17950
|
+
if (init.stale) return;
|
|
17490
17951
|
if (this.wallet) {
|
|
17491
17952
|
try {
|
|
17492
17953
|
const vtxos = await this.getVtxosFromRepo();
|
|
@@ -17499,72 +17960,81 @@ var WalletMessageHandler = class {
|
|
|
17499
17960
|
} catch (error) {
|
|
17500
17961
|
console.error("Error recovering pending transactions:", error);
|
|
17501
17962
|
}
|
|
17963
|
+
if (init.stale) return;
|
|
17502
17964
|
}
|
|
17503
17965
|
if (this.incomingFundsSubscription) this.incomingFundsSubscription();
|
|
17504
|
-
|
|
17505
|
-
this.
|
|
17506
|
-
|
|
17507
|
-
|
|
17508
|
-
|
|
17509
|
-
|
|
17510
|
-
|
|
17511
|
-
|
|
17512
|
-
|
|
17513
|
-
|
|
17514
|
-
|
|
17515
|
-
|
|
17516
|
-
|
|
17517
|
-
|
|
17518
|
-
const arr = byScript.get(v.script) ?? [];
|
|
17519
|
-
arr.push(v);
|
|
17520
|
-
byScript.set(v.script, arr);
|
|
17521
|
-
}
|
|
17522
|
-
let walletScript;
|
|
17523
|
-
try {
|
|
17524
|
-
walletScript = scriptFromArkAddress(address);
|
|
17525
|
-
} catch {
|
|
17526
|
-
walletScript = void 0;
|
|
17527
|
-
}
|
|
17528
|
-
const cm = await this.readonlyWallet.getContractManager();
|
|
17529
|
-
const contracts = await cm.getContracts();
|
|
17530
|
-
const addrByScript = new Map(contracts.map((c) => [c.script, c.address]));
|
|
17531
|
-
for (const [script, vtxos] of byScript) {
|
|
17532
|
-
const filtered = warnAndFilterVtxosForScript(
|
|
17533
|
-
vtxos,
|
|
17534
|
-
script,
|
|
17535
|
-
"WalletMessageHandler.notifyIncomingFunds"
|
|
17966
|
+
this.incomingFundsSubscription = void 0;
|
|
17967
|
+
this.incomingFundsEpoch++;
|
|
17968
|
+
const emitter = this.newEmitter("incomingFunds");
|
|
17969
|
+
const address = await wallet.getAddress();
|
|
17970
|
+
const unsubscribe = await wallet.notifyIncomingFunds(async (funds) => {
|
|
17971
|
+
if (emitter.stale) return;
|
|
17972
|
+
if (funds.type === "vtxo") {
|
|
17973
|
+
const { newVtxos, spentVtxos } = funds;
|
|
17974
|
+
if (newVtxos.length + spentVtxos.length === 0) return;
|
|
17975
|
+
const byScript = /* @__PURE__ */ new Map();
|
|
17976
|
+
for (const v of [...newVtxos, ...spentVtxos]) {
|
|
17977
|
+
if (!v.script) {
|
|
17978
|
+
console.warn(
|
|
17979
|
+
`WalletMessageHandler.notifyIncomingFunds: dropping VTXO without script ${v.txid}:${v.vout}`
|
|
17536
17980
|
);
|
|
17537
|
-
|
|
17538
|
-
const targetAddress = script === walletScript ? address : addrByScript.get(script);
|
|
17539
|
-
if (!targetAddress) continue;
|
|
17540
|
-
if (this.walletRepository) {
|
|
17541
|
-
await saveVtxosForContract(
|
|
17542
|
-
this.walletRepository,
|
|
17543
|
-
{ script, address: targetAddress },
|
|
17544
|
-
filtered
|
|
17545
|
-
);
|
|
17546
|
-
}
|
|
17981
|
+
continue;
|
|
17547
17982
|
}
|
|
17548
|
-
|
|
17549
|
-
|
|
17550
|
-
|
|
17551
|
-
broadcast: true,
|
|
17552
|
-
payload: { newVtxos, spentVtxos }
|
|
17553
|
-
})
|
|
17554
|
-
);
|
|
17983
|
+
const arr = byScript.get(v.script) ?? [];
|
|
17984
|
+
arr.push(v);
|
|
17985
|
+
byScript.set(v.script, arr);
|
|
17555
17986
|
}
|
|
17556
|
-
|
|
17557
|
-
|
|
17558
|
-
|
|
17559
|
-
|
|
17560
|
-
|
|
17561
|
-
|
|
17562
|
-
|
|
17563
|
-
|
|
17987
|
+
let walletScript;
|
|
17988
|
+
try {
|
|
17989
|
+
walletScript = scriptFromArkAddress(address);
|
|
17990
|
+
} catch {
|
|
17991
|
+
walletScript = void 0;
|
|
17992
|
+
}
|
|
17993
|
+
const cm = await wallet.getContractManager();
|
|
17994
|
+
if (emitter.stale) return;
|
|
17995
|
+
const contracts = await cm.getContracts();
|
|
17996
|
+
if (emitter.stale) return;
|
|
17997
|
+
const addrByScript = new Map(contracts.map((c) => [c.script, c.address]));
|
|
17998
|
+
for (const [script, vtxos] of byScript) {
|
|
17999
|
+
const filtered = warnAndFilterVtxosForScript(
|
|
18000
|
+
vtxos,
|
|
18001
|
+
script,
|
|
18002
|
+
"WalletMessageHandler.notifyIncomingFunds"
|
|
17564
18003
|
);
|
|
18004
|
+
if (filtered.length === 0) continue;
|
|
18005
|
+
const targetAddress = script === walletScript ? address : addrByScript.get(script);
|
|
18006
|
+
if (!targetAddress) continue;
|
|
18007
|
+
if (this.walletRepository) {
|
|
18008
|
+
if (emitter.stale) return;
|
|
18009
|
+
await saveVtxosForContract(
|
|
18010
|
+
this.walletRepository,
|
|
18011
|
+
{ script, address: targetAddress },
|
|
18012
|
+
filtered
|
|
18013
|
+
);
|
|
18014
|
+
}
|
|
17565
18015
|
}
|
|
18016
|
+
emitter.emit(
|
|
18017
|
+
this.tagged({
|
|
18018
|
+
type: "VTXO_UPDATE",
|
|
18019
|
+
broadcast: true,
|
|
18020
|
+
payload: { newVtxos, spentVtxos }
|
|
18021
|
+
})
|
|
18022
|
+
);
|
|
17566
18023
|
}
|
|
17567
|
-
|
|
18024
|
+
if (funds.type === "utxo") {
|
|
18025
|
+
if (emitter.stale) return;
|
|
18026
|
+
const utxos = await wallet.getBoardingUtxos();
|
|
18027
|
+
emitter.emit(
|
|
18028
|
+
this.tagged({
|
|
18029
|
+
type: "UTXO_UPDATE",
|
|
18030
|
+
broadcast: true,
|
|
18031
|
+
payload: { coins: utxos }
|
|
18032
|
+
})
|
|
18033
|
+
);
|
|
18034
|
+
}
|
|
18035
|
+
});
|
|
18036
|
+
if (emitter.stale) return unsubscribe();
|
|
18037
|
+
this.incomingFundsSubscription = unsubscribe;
|
|
17568
18038
|
if (this.wallet) {
|
|
17569
18039
|
try {
|
|
17570
18040
|
await this.wallet.getVtxoManager();
|
|
@@ -17609,10 +18079,11 @@ var WalletMessageHandler = class {
|
|
|
17609
18079
|
await this.refreshCachedData();
|
|
17610
18080
|
}
|
|
17611
18081
|
async handleSettle(message) {
|
|
18082
|
+
const emitter = this.newEmitter("request");
|
|
17612
18083
|
const wallet = this.requireWallet();
|
|
17613
18084
|
const txid = await wallet.settle(message.payload.params, (e) => {
|
|
17614
|
-
|
|
17615
|
-
|
|
18085
|
+
emitter.emit(
|
|
18086
|
+
this.tagged({
|
|
17616
18087
|
id: message.id,
|
|
17617
18088
|
type: "SETTLE_EVENT",
|
|
17618
18089
|
payload: e
|
|
@@ -17689,30 +18160,39 @@ var WalletMessageHandler = class {
|
|
|
17689
18160
|
throw new WalletNotInitializedError();
|
|
17690
18161
|
}
|
|
17691
18162
|
const allVtxos = await this.getVtxosFromRepo();
|
|
17692
|
-
const vtxos = allVtxos.filter((v) => !chunkG552MISJ_cjs.hasTerminalSpend(v));
|
|
17693
18163
|
const dustAmount = this.readonlyWallet.dustAmount;
|
|
18164
|
+
const withUnrolled = message.payload.filter?.withUnrolled ?? false;
|
|
17694
18165
|
const includeRecoverable = message.payload.filter?.withRecoverable ?? false;
|
|
17695
|
-
|
|
18166
|
+
return allVtxos.filter((v) => {
|
|
18167
|
+
if (v.isUnrolled) {
|
|
18168
|
+
return withUnrolled;
|
|
18169
|
+
}
|
|
18170
|
+
if (chunk2JV4VQ7C_cjs.hasTerminalSpend(v)) {
|
|
18171
|
+
return false;
|
|
18172
|
+
}
|
|
18173
|
+
if (includeRecoverable) {
|
|
18174
|
+
return true;
|
|
18175
|
+
}
|
|
17696
18176
|
if (dustAmount != null && isSubdust(v, dustAmount)) {
|
|
17697
18177
|
return false;
|
|
17698
18178
|
}
|
|
17699
|
-
if (
|
|
18179
|
+
if (chunk2JV4VQ7C_cjs.isRecoverable(v)) {
|
|
17700
18180
|
return false;
|
|
17701
18181
|
}
|
|
17702
|
-
if (
|
|
18182
|
+
if (chunk2JV4VQ7C_cjs.isExpired(v)) {
|
|
17703
18183
|
return false;
|
|
17704
18184
|
}
|
|
17705
18185
|
return true;
|
|
17706
18186
|
});
|
|
17707
|
-
if (!message.payload.filter?.withUnrolled) {
|
|
17708
|
-
return filteredVtxos;
|
|
17709
|
-
}
|
|
17710
|
-
return filteredVtxos.concat(allVtxos.filter((v) => chunkG552MISJ_cjs.hasTerminalSpend(v) && v.isUnrolled));
|
|
17711
18187
|
}
|
|
17712
18188
|
/** Tear down handler subscriptions, then delegate the full wipe to the wallet. */
|
|
17713
18189
|
async clear() {
|
|
17714
18190
|
const wallet = this.wallet ?? this.readonlyWallet;
|
|
17715
18191
|
if (!wallet) return;
|
|
18192
|
+
this.requestEpoch++;
|
|
18193
|
+
this.incomingFundsEpoch++;
|
|
18194
|
+
this.contractEventsEpoch++;
|
|
18195
|
+
this.onNextTick = [];
|
|
17716
18196
|
if (this.incomingFundsSubscription) {
|
|
17717
18197
|
this.incomingFundsSubscription();
|
|
17718
18198
|
this.incomingFundsSubscription = void 0;
|
|
@@ -17797,17 +18277,21 @@ var WalletMessageHandler = class {
|
|
|
17797
18277
|
if (!this.readonlyWallet) return null;
|
|
17798
18278
|
const { boardingTxs, commitmentsToIgnore } = await this.readonlyWallet.getBoardingTxs();
|
|
17799
18279
|
const indexerProvider = this.indexerProvider;
|
|
17800
|
-
const resolveTxCreatedAt = indexerProvider ? (txids) =>
|
|
18280
|
+
const resolveTxCreatedAt = indexerProvider ? (txids) => chunk2JV4VQ7C_cjs.fetchVtxoCreatedAtByTxid(indexerProvider, txids) : void 0;
|
|
17801
18281
|
return buildTransactionHistory(vtxos, boardingTxs, commitmentsToIgnore, resolveTxCreatedAt);
|
|
17802
18282
|
}
|
|
17803
18283
|
async ensureContractEventBroadcasting() {
|
|
17804
|
-
|
|
18284
|
+
const wallet = this.readonlyWallet;
|
|
18285
|
+
if (!wallet) return;
|
|
17805
18286
|
if (this.contractEventsSubscription) return;
|
|
18287
|
+
const gen = this.newGeneration("contractEvents");
|
|
17806
18288
|
try {
|
|
17807
|
-
const manager = await
|
|
18289
|
+
const manager = await wallet.getContractManager();
|
|
18290
|
+
if (gen.stale || this.contractEventsSubscription) return;
|
|
18291
|
+
const emitter = this.newEmitter("contractEvents");
|
|
17808
18292
|
this.contractEventsSubscription = manager.onContractEvent((event) => {
|
|
17809
|
-
|
|
17810
|
-
|
|
18293
|
+
emitter.emit(
|
|
18294
|
+
this.tagged({
|
|
17811
18295
|
type: "CONTRACT_EVENT",
|
|
17812
18296
|
broadcast: true,
|
|
17813
18297
|
payload: { event }
|
|
@@ -17838,6 +18322,9 @@ var DEFAULT_MESSAGE_TIMEOUTS = {
|
|
|
17838
18322
|
// Allocation is a local repository write plus a fire-and-forget band
|
|
17839
18323
|
// slide — no indexer round trip on the request path.
|
|
17840
18324
|
GET_NEXT_SIGNING_DESCRIPTOR: 1e4,
|
|
18325
|
+
// Same shape as the bare allocation above, plus one contract write per
|
|
18326
|
+
// requested type — still local, still no indexer round trip.
|
|
18327
|
+
GET_NEW_ADDRESSES: 1e4,
|
|
17841
18328
|
GET_USED_SIGNING_DESCRIPTORS: 2e4,
|
|
17842
18329
|
ADVANCE_SIGNING_DESCRIPTOR_WATERMARK: 1e4,
|
|
17843
18330
|
// Medium reads — may involve indexer queries
|
|
@@ -18486,7 +18973,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
18486
18973
|
};
|
|
18487
18974
|
try {
|
|
18488
18975
|
const response = await this.sendMessage(message);
|
|
18489
|
-
return response.payload.vtxos.map(
|
|
18976
|
+
return response.payload.vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
|
|
18490
18977
|
} catch (error) {
|
|
18491
18978
|
throw new Error(`Failed to get vtxos: ${error}`);
|
|
18492
18979
|
}
|
|
@@ -18511,7 +18998,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
18511
18998
|
};
|
|
18512
18999
|
try {
|
|
18513
19000
|
const response = await this.sendMessage(message);
|
|
18514
|
-
return response.payload.vtxos.map(
|
|
19001
|
+
return response.payload.vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
|
|
18515
19002
|
} catch (error) {
|
|
18516
19003
|
throw new Error(`Failed to get spendable vtxos: ${error}`);
|
|
18517
19004
|
}
|
|
@@ -18642,7 +19129,7 @@ var ServiceWorkerReadonlyWallet = class _ServiceWorkerReadonlyWallet {
|
|
|
18642
19129
|
};
|
|
18643
19130
|
try {
|
|
18644
19131
|
const response = await sendContractMessage(message);
|
|
18645
|
-
return response.payload.vtxos.map(
|
|
19132
|
+
return response.payload.vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
|
|
18646
19133
|
} catch (e) {
|
|
18647
19134
|
throw new Error("Failed to annotate vtxos");
|
|
18648
19135
|
}
|
|
@@ -18983,6 +19470,35 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
|
|
|
18983
19470
|
throw new Error(`Failed to allocate next signing descriptor: ${error}`);
|
|
18984
19471
|
}
|
|
18985
19472
|
}
|
|
19473
|
+
/**
|
|
19474
|
+
* @see Wallet.getNewAddresses
|
|
19475
|
+
*
|
|
19476
|
+
* Proxied as a single request rather than rebuilt page-side out of
|
|
19477
|
+
* {@link getNextSigningDescriptor}: the worker owns the HD watermark *and*
|
|
19478
|
+
* the contract repository, so splitting the operation would let a page burn
|
|
19479
|
+
* an index and then fail to register the script, leaving an address nothing
|
|
19480
|
+
* watches.
|
|
19481
|
+
*
|
|
19482
|
+
* Note the error shape — `WalletCannotAllocateAddressError` is thrown
|
|
19483
|
+
* worker-side and cannot cross the message boundary as a class, so a
|
|
19484
|
+
* `forceNew` refusal surfaces here as a plain `Error` carrying its message
|
|
19485
|
+
* (and the worker-side error as `cause`). Callers that must branch on the
|
|
19486
|
+
* refusal match the message rather than `instanceof`.
|
|
19487
|
+
*/
|
|
19488
|
+
async getNewAddresses(opts) {
|
|
19489
|
+
const message = {
|
|
19490
|
+
id: getRandomId(),
|
|
19491
|
+
tag: this.messageTag,
|
|
19492
|
+
type: "GET_NEW_ADDRESSES",
|
|
19493
|
+
...opts ? { payload: opts } : {}
|
|
19494
|
+
};
|
|
19495
|
+
try {
|
|
19496
|
+
const response = await this.sendMessage(message);
|
|
19497
|
+
return response.payload.addresses;
|
|
19498
|
+
} catch (error) {
|
|
19499
|
+
throw new Error(`Failed to allocate new addresses: ${error}`, { cause: error });
|
|
19500
|
+
}
|
|
19501
|
+
}
|
|
18986
19502
|
/** @see HDWalletCapable.getUsedSigningDescriptors */
|
|
18987
19503
|
async getUsedSigningDescriptors(opts) {
|
|
18988
19504
|
const message = {
|
|
@@ -19214,7 +19730,7 @@ var ServiceWorkerWallet = class _ServiceWorkerWallet extends ServiceWorkerReadon
|
|
|
19214
19730
|
};
|
|
19215
19731
|
try {
|
|
19216
19732
|
const response = await wallet.sendMessage(message);
|
|
19217
|
-
return response.payload.vtxos.map(
|
|
19733
|
+
return response.payload.vtxos.map(chunk2JV4VQ7C_cjs.normalizeVtxo);
|
|
19218
19734
|
} catch (e) {
|
|
19219
19735
|
throw new Error(`Failed to get expiring vtxos: ${e}`);
|
|
19220
19736
|
}
|
|
@@ -19326,12 +19842,12 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
19326
19842
|
* @returns Configured onchain wallet
|
|
19327
19843
|
* @throws Error if the configured identity cannot produce a valid x-only public key
|
|
19328
19844
|
*/
|
|
19329
|
-
static async create(identity, networkName =
|
|
19845
|
+
static async create(identity, networkName = chunk2JV4VQ7C_cjs.DEFAULT_NETWORK_NAME, provider) {
|
|
19330
19846
|
const pubkey = await identity.xOnlyPublicKey();
|
|
19331
19847
|
if (!pubkey) {
|
|
19332
19848
|
throw new Error("Invalid configured public key");
|
|
19333
19849
|
}
|
|
19334
|
-
const network =
|
|
19850
|
+
const network = chunk2JV4VQ7C_cjs.getNetwork(networkName);
|
|
19335
19851
|
const onchainProvider = provider || new EsploraProvider(ESPLORA_URL[networkName]);
|
|
19336
19852
|
const onchainP2TR = btcSigner.p2tr(pubkey, void 0, network);
|
|
19337
19853
|
return new _OnchainWallet(identity, network, onchainP2TR, onchainProvider);
|
|
@@ -19437,7 +19953,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
19437
19953
|
if (!inputs) {
|
|
19438
19954
|
throw new Error("Fee estimation failed");
|
|
19439
19955
|
}
|
|
19440
|
-
let tx = new
|
|
19956
|
+
let tx = new chunk2JV4VQ7C_cjs.Transaction();
|
|
19441
19957
|
for (const input of inputs) {
|
|
19442
19958
|
tx.addInput({
|
|
19443
19959
|
txid: input.txid,
|
|
@@ -19495,7 +20011,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
19495
20011
|
* @throws If the parent has no anchor, or funding cannot be selected/signed
|
|
19496
20012
|
*/
|
|
19497
20013
|
async bumpAnchor(parentHex, feeRate) {
|
|
19498
|
-
const parent =
|
|
20014
|
+
const parent = chunk2JV4VQ7C_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
|
|
19499
20015
|
const coins = (await this.getCoins()).filter((c) => c.status.confirmed);
|
|
19500
20016
|
const child = await this.buildBumpPackage(parent, feeRate, coins);
|
|
19501
20017
|
return [parent.hex, child.hex];
|
|
@@ -19949,6 +20465,10 @@ var ElectrumOnchainProvider = class {
|
|
|
19949
20465
|
}
|
|
19950
20466
|
throw new Error("Only 1 or 1P1C package can be broadcast");
|
|
19951
20467
|
}
|
|
20468
|
+
async getRawTransaction(txid) {
|
|
20469
|
+
const [tx] = await this.chain.fetchTransactions([txid]);
|
|
20470
|
+
return base.hex.decode(tx.hex);
|
|
20471
|
+
}
|
|
19952
20472
|
async getTxOutspends(txid) {
|
|
19953
20473
|
const [txResult] = await this.chain.fetchTransactions([txid]);
|
|
19954
20474
|
const tx = btcSigner.Transaction.fromRaw(base.hex.decode(txResult.hex), {
|
|
@@ -20254,13 +20774,190 @@ function childTxidFromHex(txHex) {
|
|
|
20254
20774
|
});
|
|
20255
20775
|
return tx.id;
|
|
20256
20776
|
}
|
|
20777
|
+
|
|
20778
|
+
// src/providers/cachingArk.ts
|
|
20779
|
+
var DEFAULT_TTL_MS = 6e4;
|
|
20780
|
+
var CachingArkProvider = class {
|
|
20781
|
+
constructor(inner, ttlMs = DEFAULT_TTL_MS) {
|
|
20782
|
+
this.inner = inner;
|
|
20783
|
+
this.ttlMs = ttlMs;
|
|
20784
|
+
this.unsubscribe = inner.onServerInfoChanged?.((info) => {
|
|
20785
|
+
this.cached = info;
|
|
20786
|
+
this.expiresAt = Date.now() + this.ttlMs;
|
|
20787
|
+
this.generation++;
|
|
20788
|
+
}) ?? (() => {
|
|
20789
|
+
});
|
|
20790
|
+
}
|
|
20791
|
+
inner;
|
|
20792
|
+
ttlMs;
|
|
20793
|
+
cached;
|
|
20794
|
+
expiresAt = 0;
|
|
20795
|
+
inflight;
|
|
20796
|
+
/** Bumped on every event-driven cache write; see {@link getInfo}. */
|
|
20797
|
+
generation = 0;
|
|
20798
|
+
unsubscribe;
|
|
20799
|
+
/** Releases the inner provider's server-info subscription. */
|
|
20800
|
+
dispose() {
|
|
20801
|
+
this.unsubscribe();
|
|
20802
|
+
}
|
|
20803
|
+
get serverUrl() {
|
|
20804
|
+
const url = this.inner.serverUrl;
|
|
20805
|
+
return typeof url === "string" ? url : void 0;
|
|
20806
|
+
}
|
|
20807
|
+
async getInfo() {
|
|
20808
|
+
if (this.cached && Date.now() < this.expiresAt) return this.cached;
|
|
20809
|
+
if (!this.inflight) {
|
|
20810
|
+
const generation = this.generation;
|
|
20811
|
+
this.inflight = this.inner.getInfo().then((info) => {
|
|
20812
|
+
if (this.generation !== generation) return this.cached ?? info;
|
|
20813
|
+
this.cached = info;
|
|
20814
|
+
this.expiresAt = Date.now() + this.ttlMs;
|
|
20815
|
+
return info;
|
|
20816
|
+
}).finally(() => {
|
|
20817
|
+
this.inflight = void 0;
|
|
20818
|
+
});
|
|
20819
|
+
}
|
|
20820
|
+
return this.inflight;
|
|
20821
|
+
}
|
|
20822
|
+
submitTx(signedArkTx, checkpointTxs) {
|
|
20823
|
+
return this.inner.submitTx(signedArkTx, checkpointTxs);
|
|
20824
|
+
}
|
|
20825
|
+
finalizeTx(arkTxid, finalCheckpointTxs) {
|
|
20826
|
+
return this.inner.finalizeTx(arkTxid, finalCheckpointTxs);
|
|
20827
|
+
}
|
|
20828
|
+
registerIntent(intent) {
|
|
20829
|
+
return this.inner.registerIntent(intent);
|
|
20830
|
+
}
|
|
20831
|
+
deleteIntent(intent) {
|
|
20832
|
+
return this.inner.deleteIntent(intent);
|
|
20833
|
+
}
|
|
20834
|
+
confirmRegistration(intentId) {
|
|
20835
|
+
return this.inner.confirmRegistration(intentId);
|
|
20836
|
+
}
|
|
20837
|
+
submitTreeNonces(batchId, pubkey, nonces) {
|
|
20838
|
+
return this.inner.submitTreeNonces(batchId, pubkey, nonces);
|
|
20839
|
+
}
|
|
20840
|
+
submitTreeSignatures(batchId, pubkey, signatures) {
|
|
20841
|
+
return this.inner.submitTreeSignatures(batchId, pubkey, signatures);
|
|
20842
|
+
}
|
|
20843
|
+
submitSignedForfeitTxs(signedForfeitTxs, signedCommitmentTx) {
|
|
20844
|
+
return this.inner.submitSignedForfeitTxs(signedForfeitTxs, signedCommitmentTx);
|
|
20845
|
+
}
|
|
20846
|
+
getEventStream(signal, topics) {
|
|
20847
|
+
return this.inner.getEventStream(signal, topics);
|
|
20848
|
+
}
|
|
20849
|
+
getTransactionsStream(signal) {
|
|
20850
|
+
return this.inner.getTransactionsStream(signal);
|
|
20851
|
+
}
|
|
20852
|
+
getPendingTxs(intent) {
|
|
20853
|
+
return this.inner.getPendingTxs(intent);
|
|
20854
|
+
}
|
|
20855
|
+
onServerInfoChanged(listener) {
|
|
20856
|
+
return this.inner.onServerInfoChanged?.(listener) ?? (() => {
|
|
20857
|
+
});
|
|
20858
|
+
}
|
|
20859
|
+
};
|
|
20860
|
+
var PrevTxUnavailableError = class extends Error {
|
|
20861
|
+
constructor(message, txids = []) {
|
|
20862
|
+
super(message);
|
|
20863
|
+
this.txids = txids;
|
|
20864
|
+
this.name = "PrevTxUnavailableError";
|
|
20865
|
+
}
|
|
20866
|
+
txids;
|
|
20867
|
+
};
|
|
20868
|
+
async function resolvePrevTxs(txids, source, onchain) {
|
|
20869
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
20870
|
+
const wanted = [...new Set(txids)];
|
|
20871
|
+
if (wanted.length === 0) return resolved;
|
|
20872
|
+
try {
|
|
20873
|
+
const { txs } = await source.getVirtualTxs(wanted);
|
|
20874
|
+
for (const psbt of txs) {
|
|
20875
|
+
const tx = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbt));
|
|
20876
|
+
resolved.set(tx.id, tx.toBytes());
|
|
20877
|
+
}
|
|
20878
|
+
} catch (err) {
|
|
20879
|
+
if (!onchain) throw err;
|
|
20880
|
+
}
|
|
20881
|
+
let missing = wanted.filter((txid) => !resolved.has(txid));
|
|
20882
|
+
if (missing.length > 0 && onchain) {
|
|
20883
|
+
const raw = await Promise.all(
|
|
20884
|
+
missing.map(async (txid) => {
|
|
20885
|
+
try {
|
|
20886
|
+
return await onchain.getRawTransaction(txid);
|
|
20887
|
+
} catch {
|
|
20888
|
+
return void 0;
|
|
20889
|
+
}
|
|
20890
|
+
})
|
|
20891
|
+
);
|
|
20892
|
+
for (const [i, bytes] of raw.entries()) {
|
|
20893
|
+
if (bytes) resolved.set(missing[i], bytes);
|
|
20894
|
+
}
|
|
20895
|
+
missing = missing.filter((txid) => !resolved.has(txid));
|
|
20896
|
+
}
|
|
20897
|
+
if (missing.length > 0) {
|
|
20898
|
+
throw new PrevTxUnavailableError(
|
|
20899
|
+
`cannot resolve the previous transaction of ${missing.join(", ")}` + (onchain ? "" : " (no onchain source configured)"),
|
|
20900
|
+
missing
|
|
20901
|
+
);
|
|
20902
|
+
}
|
|
20903
|
+
return resolved;
|
|
20904
|
+
}
|
|
20905
|
+
async function attachPrevArkTxs(tx, txids, source, onchain) {
|
|
20906
|
+
const pending = [];
|
|
20907
|
+
for (let i = 0; i < tx.inputsLength; i++) {
|
|
20908
|
+
if (chunk2JV4VQ7C_cjs.getArkPsbtFields(tx, i, chunk2JV4VQ7C_cjs.PrevArkTxField).length === 0) pending.push(i);
|
|
20909
|
+
}
|
|
20910
|
+
if (pending.length === 0) return;
|
|
20911
|
+
const resolved = await resolvePrevTxs(
|
|
20912
|
+
pending.map((i) => txidAt(txids, i)),
|
|
20913
|
+
source,
|
|
20914
|
+
onchain
|
|
20915
|
+
);
|
|
20916
|
+
for (const i of pending) {
|
|
20917
|
+
chunk2JV4VQ7C_cjs.setArkPsbtField(tx, i, chunk2JV4VQ7C_cjs.PrevArkTxField, resolved.get(txidAt(txids, i)));
|
|
20918
|
+
}
|
|
20919
|
+
}
|
|
20920
|
+
async function attachPrevoutTxs(tx, source) {
|
|
20921
|
+
const pending = [];
|
|
20922
|
+
for (let i = 0; i < tx.inputsLength; i++) {
|
|
20923
|
+
if (chunk2JV4VQ7C_cjs.getArkPsbtFields(tx, i, chunk2JV4VQ7C_cjs.PrevoutTxField).length > 0) continue;
|
|
20924
|
+
const input = tx.getInput(i);
|
|
20925
|
+
if (!input?.txid) throw new PrevTxUnavailableError(`input ${i} has no outpoint`);
|
|
20926
|
+
pending.push({ index: i, txid: base.hex.encode(input.txid) });
|
|
20927
|
+
}
|
|
20928
|
+
if (pending.length === 0) return;
|
|
20929
|
+
const resolved = /* @__PURE__ */ new Map();
|
|
20930
|
+
for (const txid of new Set(pending.map((p) => p.txid))) {
|
|
20931
|
+
resolved.set(txid, await source.getRawTransaction(txid));
|
|
20932
|
+
}
|
|
20933
|
+
for (const { index, txid } of pending) {
|
|
20934
|
+
chunk2JV4VQ7C_cjs.setArkPsbtField(tx, index, chunk2JV4VQ7C_cjs.PrevoutTxField, resolved.get(txid));
|
|
20935
|
+
}
|
|
20936
|
+
}
|
|
20937
|
+
async function withPrevTxs(coins, source, onchain) {
|
|
20938
|
+
const pending = coins.filter((c) => !c.prevTx);
|
|
20939
|
+
if (pending.length === 0) return coins;
|
|
20940
|
+
const resolved = await resolvePrevTxs(
|
|
20941
|
+
pending.map((c) => c.txid),
|
|
20942
|
+
source,
|
|
20943
|
+
onchain
|
|
20944
|
+
);
|
|
20945
|
+
return coins.map((c) => c.prevTx ? c : { ...c, prevTx: resolved.get(c.txid) });
|
|
20946
|
+
}
|
|
20947
|
+
function txidAt(txids, index) {
|
|
20948
|
+
const txid = txids[index];
|
|
20949
|
+
if (txid === void 0) {
|
|
20950
|
+
throw new PrevTxUnavailableError(`no source txid supplied for input ${index}`);
|
|
20951
|
+
}
|
|
20952
|
+
return txid;
|
|
20953
|
+
}
|
|
20257
20954
|
var TAG_BIP322 = "BIP0322-signed-message";
|
|
20258
20955
|
exports.BIP322 = void 0;
|
|
20259
20956
|
((BIP3222) => {
|
|
20260
20957
|
async function sign2(message, identity, network) {
|
|
20261
20958
|
const xOnlyPubKey = await identity.xOnlyPublicKey();
|
|
20262
20959
|
const payment = btcSigner.p2tr(xOnlyPubKey, void 0, network);
|
|
20263
|
-
const toSpend =
|
|
20960
|
+
const toSpend = chunk2JV4VQ7C_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
|
|
20264
20961
|
const toSign = craftBIP322ToSignP2TR(toSpend, payment.script, xOnlyPubKey);
|
|
20265
20962
|
const signed = await identity.sign(toSign, [0]);
|
|
20266
20963
|
signed.finalizeIdx(0);
|
|
@@ -20318,7 +21015,7 @@ function verifyP2TR(message, witnessItems, pkScript, pubkey) {
|
|
|
20318
21015
|
if (sighashType !== btcSigner.SigHash.DEFAULT && sighashType !== btcSigner.SigHash.ALL) {
|
|
20319
21016
|
return false;
|
|
20320
21017
|
}
|
|
20321
|
-
const toSpend =
|
|
21018
|
+
const toSpend = chunk2JV4VQ7C_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
|
|
20322
21019
|
const toSign = craftBIP322ToSignP2TR(toSpend, pkScript, pubkey);
|
|
20323
21020
|
const sighash = toSign.preimageWitnessV1(0, [pkScript], sighashType, [0n]);
|
|
20324
21021
|
const rawSig = sig.length === 65 ? sig.subarray(0, 64) : sig;
|
|
@@ -20339,7 +21036,7 @@ function verifyP2WPKH(message, witnessItems, pkScript, addressHash) {
|
|
|
20339
21036
|
}
|
|
20340
21037
|
const sighashType = sigWithHash[sigWithHash.length - 1];
|
|
20341
21038
|
const derSig = sigWithHash.subarray(0, sigWithHash.length - 1);
|
|
20342
|
-
const toSpend =
|
|
21039
|
+
const toSpend = chunk2JV4VQ7C_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
|
|
20343
21040
|
const toSign = craftBIP322ToSignSimple(toSpend, pkScript);
|
|
20344
21041
|
const scriptCode = btcSigner.OutScript.encode({ type: "pkh", hash: addressHash });
|
|
20345
21042
|
const sighash = toSign.preimageWitnessV0(0, scriptCode, sighashType, 0n);
|
|
@@ -20392,7 +21089,7 @@ function encodeCompactSize(n) {
|
|
|
20392
21089
|
return buf;
|
|
20393
21090
|
}
|
|
20394
21091
|
function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
|
|
20395
|
-
const tx = new
|
|
21092
|
+
const tx = new chunk2JV4VQ7C_cjs.Transaction({ version: 0 });
|
|
20396
21093
|
tx.addInput({
|
|
20397
21094
|
txid: toSpend.id,
|
|
20398
21095
|
index: 0,
|
|
@@ -20406,12 +21103,12 @@ function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
|
|
|
20406
21103
|
});
|
|
20407
21104
|
tx.addOutput({
|
|
20408
21105
|
amount: 0n,
|
|
20409
|
-
script:
|
|
21106
|
+
script: chunk2JV4VQ7C_cjs.OP_RETURN_EMPTY_PKSCRIPT
|
|
20410
21107
|
});
|
|
20411
21108
|
return tx;
|
|
20412
21109
|
}
|
|
20413
21110
|
function craftBIP322ToSignSimple(toSpend, pkScript) {
|
|
20414
|
-
const tx = new
|
|
21111
|
+
const tx = new chunk2JV4VQ7C_cjs.Transaction({ version: 0 });
|
|
20415
21112
|
tx.addInput({
|
|
20416
21113
|
txid: toSpend.id,
|
|
20417
21114
|
index: 0,
|
|
@@ -20423,7 +21120,7 @@ function craftBIP322ToSignSimple(toSpend, pkScript) {
|
|
|
20423
21120
|
});
|
|
20424
21121
|
tx.addOutput({
|
|
20425
21122
|
amount: 0n,
|
|
20426
|
-
script:
|
|
21123
|
+
script: chunk2JV4VQ7C_cjs.OP_RETURN_EMPTY_PKSCRIPT
|
|
20427
21124
|
});
|
|
20428
21125
|
return tx;
|
|
20429
21126
|
}
|
|
@@ -20554,7 +21251,7 @@ var RestEmulatorProvider = class {
|
|
|
20554
21251
|
}
|
|
20555
21252
|
};
|
|
20556
21253
|
function finalizeVirtualTx(type, psbtBase64) {
|
|
20557
|
-
const tx =
|
|
21254
|
+
const tx = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
|
|
20558
21255
|
if (type === "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */) {
|
|
20559
21256
|
const input = tx.getInput(0);
|
|
20560
21257
|
if (!input) {
|
|
@@ -20581,14 +21278,14 @@ var ExitPathError = class extends Error {
|
|
|
20581
21278
|
reason;
|
|
20582
21279
|
};
|
|
20583
21280
|
function delayWeight(sequence) {
|
|
20584
|
-
const t =
|
|
21281
|
+
const t = chunk2JV4VQ7C_cjs.sequenceToTimelock(sequence);
|
|
20585
21282
|
return t.type === "blocks" ? Number(t.value) : Number(t.value) / 600;
|
|
20586
21283
|
}
|
|
20587
21284
|
async function resolveUnilateralPath(params) {
|
|
20588
21285
|
const { vtxo, scriptHex, contractRepository } = params;
|
|
20589
21286
|
const contract = contractRepository ? (await contractRepository.getContracts({ script: scriptHex }))[0] : void 0;
|
|
20590
21287
|
if (contract) {
|
|
20591
|
-
const handler =
|
|
21288
|
+
const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
|
|
20592
21289
|
if (!handler) {
|
|
20593
21290
|
throw new ExitPathError(
|
|
20594
21291
|
"no-handler",
|
|
@@ -20611,12 +21308,12 @@ async function resolveUnilateralPath(params) {
|
|
|
20611
21308
|
paths.sort((a, b) => delayWeight(a.sequence) - delayWeight(b.sequence));
|
|
20612
21309
|
return { selection: paths[0], label: `${contract.type}:unilateral` };
|
|
20613
21310
|
}
|
|
20614
|
-
const decoded =
|
|
21311
|
+
const decoded = chunk2JV4VQ7C_cjs.VtxoScript.decode(vtxo.tapTree);
|
|
20615
21312
|
let best;
|
|
20616
21313
|
for (const exit of decoded.exitPaths()) {
|
|
20617
21314
|
const leaf = decoded.findLeaf(base.hex.encode(exit.script));
|
|
20618
21315
|
if (!leaf) continue;
|
|
20619
|
-
const sequence =
|
|
21316
|
+
const sequence = chunk2JV4VQ7C_cjs.timelockToSequence(exit.params.timelock);
|
|
20620
21317
|
const weight = delayWeight(sequence);
|
|
20621
21318
|
if (!best || weight < best.weight) {
|
|
20622
21319
|
best = { selection: { leaf, sequence }, weight };
|
|
@@ -20631,6 +21328,22 @@ async function resolveUnilateralPath(params) {
|
|
|
20631
21328
|
return { selection: best.selection, label: "default:exit" };
|
|
20632
21329
|
}
|
|
20633
21330
|
|
|
21331
|
+
// src/wallet/exitObserver.ts
|
|
21332
|
+
function exitObserverFor(manager) {
|
|
21333
|
+
return (outpoint) => manager.refreshOutpoints([outpoint]);
|
|
21334
|
+
}
|
|
21335
|
+
async function notifyExitObserved(onExitObserved, outpoint) {
|
|
21336
|
+
if (!onExitObserved) return;
|
|
21337
|
+
try {
|
|
21338
|
+
await onExitObserved(outpoint);
|
|
21339
|
+
} catch (e) {
|
|
21340
|
+
console.error(
|
|
21341
|
+
`exit observer failed for ${outpoint.txid}:${outpoint.vout} \u2014 the exit is unaffected`,
|
|
21342
|
+
e
|
|
21343
|
+
);
|
|
21344
|
+
}
|
|
21345
|
+
}
|
|
21346
|
+
|
|
20634
21347
|
// src/wallet/unroll.ts
|
|
20635
21348
|
function chainTxTypeToChainedExit2(t) {
|
|
20636
21349
|
switch (t) {
|
|
@@ -20655,27 +21368,30 @@ exports.Unroll = void 0;
|
|
|
20655
21368
|
})(Unroll2.StepType || (Unroll2.StepType = {}));
|
|
20656
21369
|
class Session2 {
|
|
20657
21370
|
/** Create an unroll session from a virtual output outpoint and its dependency chain. */
|
|
20658
|
-
constructor(toUnroll, bumper, explorer, indexer, virtualTxRepository) {
|
|
21371
|
+
constructor(toUnroll, bumper, explorer, indexer, virtualTxRepository, onExitObserved) {
|
|
20659
21372
|
this.toUnroll = toUnroll;
|
|
20660
21373
|
this.bumper = bumper;
|
|
20661
21374
|
this.explorer = explorer;
|
|
20662
21375
|
this.indexer = indexer;
|
|
20663
21376
|
this.virtualTxRepository = virtualTxRepository;
|
|
21377
|
+
this.onExitObserved = onExitObserved;
|
|
20664
21378
|
}
|
|
20665
21379
|
toUnroll;
|
|
20666
21380
|
bumper;
|
|
20667
21381
|
explorer;
|
|
20668
21382
|
indexer;
|
|
20669
21383
|
virtualTxRepository;
|
|
21384
|
+
onExitObserved;
|
|
20670
21385
|
/** Create an unroll session by loading the virtual output chain from the indexer. */
|
|
20671
|
-
static async create(toUnroll, bumper, explorer, indexer, virtualTxRepository) {
|
|
21386
|
+
static async create(toUnroll, bumper, explorer, indexer, virtualTxRepository, onExitObserved) {
|
|
20672
21387
|
const { chain } = await indexer.getVtxoChain(toUnroll);
|
|
20673
21388
|
return new Session2(
|
|
20674
21389
|
{ ...toUnroll, chain },
|
|
20675
21390
|
bumper,
|
|
20676
21391
|
explorer,
|
|
20677
21392
|
indexer,
|
|
20678
|
-
virtualTxRepository
|
|
21393
|
+
virtualTxRepository,
|
|
21394
|
+
onExitObserved
|
|
20679
21395
|
);
|
|
20680
21396
|
}
|
|
20681
21397
|
/**
|
|
@@ -20711,6 +21427,14 @@ exports.Unroll = void 0;
|
|
|
20711
21427
|
}
|
|
20712
21428
|
/**
|
|
20713
21429
|
* Get the next step to be executed
|
|
21430
|
+
*
|
|
21431
|
+
* @remarks
|
|
21432
|
+
* `do()` is the step, not a formality: every effect lives there, and at
|
|
21433
|
+
* `StepType.DONE` that includes firing {@link onExitObserved}. A caller
|
|
21434
|
+
* driving `next()` by hand must always await it — the async iterator
|
|
21435
|
+
* below does. Reading `type` and skipping `do()` leaves the exit
|
|
21436
|
+
* unobserved, and on the other step kinds unbroadcast.
|
|
21437
|
+
*
|
|
20714
21438
|
* @returns The next step to be executed + the function to execute it
|
|
20715
21439
|
*/
|
|
20716
21440
|
async next() {
|
|
@@ -20739,7 +21463,12 @@ exports.Unroll = void 0;
|
|
|
20739
21463
|
return {
|
|
20740
21464
|
type: 2 /* DONE */,
|
|
20741
21465
|
vtxoTxid: this.toUnroll.txid,
|
|
20742
|
-
do
|
|
21466
|
+
// The observation rides on `do` rather than the iterator so
|
|
21467
|
+
// a caller driving `next()` by hand fires it too.
|
|
21468
|
+
do: () => notifyExitObserved(this.onExitObserved, {
|
|
21469
|
+
txid: this.toUnroll.txid,
|
|
21470
|
+
vout: this.toUnroll.vout
|
|
21471
|
+
})
|
|
20743
21472
|
};
|
|
20744
21473
|
}
|
|
20745
21474
|
const virtualTxBase64 = await this.resolveVirtualTxBase64(nextTxToBroadcast);
|
|
@@ -20773,9 +21502,22 @@ exports.Unroll = void 0;
|
|
|
20773
21502
|
}
|
|
20774
21503
|
}
|
|
20775
21504
|
Unroll2.Session = Session2;
|
|
21505
|
+
async function sessionFor(wallet, toUnroll, bumper) {
|
|
21506
|
+
const manager = await wallet.getContractManager();
|
|
21507
|
+
return Session2.create(
|
|
21508
|
+
toUnroll,
|
|
21509
|
+
bumper,
|
|
21510
|
+
wallet.onchainProvider,
|
|
21511
|
+
wallet.indexerProvider,
|
|
21512
|
+
wallet.virtualTxRepository,
|
|
21513
|
+
exitObserverFor(manager)
|
|
21514
|
+
);
|
|
21515
|
+
}
|
|
21516
|
+
Unroll2.sessionFor = sessionFor;
|
|
20776
21517
|
async function completeUnroll(wallet, vtxoTxids, outputAddress) {
|
|
20777
21518
|
const signedTx = await prepareUnrollTransaction(wallet, vtxoTxids, outputAddress);
|
|
20778
21519
|
await wallet.onchainProvider.broadcastTransaction(signedTx.hex);
|
|
21520
|
+
await refreshSpentExitOutputs(wallet, signedTx);
|
|
20779
21521
|
return signedTx.id;
|
|
20780
21522
|
}
|
|
20781
21523
|
Unroll2.completeUnroll = completeUnroll;
|
|
@@ -20791,9 +21533,9 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
20791
21533
|
let totalAmount = 0n;
|
|
20792
21534
|
const txWeightEstimator = TxWeightEstimator.create();
|
|
20793
21535
|
for (const vtxo of vtxos) {
|
|
20794
|
-
if (!vtxo
|
|
21536
|
+
if (!chunk2JV4VQ7C_cjs.canSweepOnchain(vtxo)) {
|
|
20795
21537
|
throw new Error(
|
|
20796
|
-
`Vtxo ${vtxo.txid}:${vtxo.vout} is not fully unrolled
|
|
21538
|
+
`Vtxo ${vtxo.txid}:${vtxo.vout} cannot be swept onchain: it is not fully unrolled (use unroll first), or its exit output was already spent`
|
|
20797
21539
|
);
|
|
20798
21540
|
}
|
|
20799
21541
|
const txStatus = await wallet.onchainProvider.getTxStatus(vtxo.txid);
|
|
@@ -20802,14 +21544,14 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
20802
21544
|
}
|
|
20803
21545
|
const resolved = await resolveUnilateralPath({
|
|
20804
21546
|
vtxo,
|
|
20805
|
-
scriptHex: base.hex.encode(
|
|
21547
|
+
scriptHex: base.hex.encode(chunk2JV4VQ7C_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
|
|
20806
21548
|
contractRepository: wallet.contractRepository,
|
|
20807
21549
|
walletPubKeyHex: base.hex.encode(await wallet.identity.xOnlyPublicKey()),
|
|
20808
21550
|
currentTime: Date.now()
|
|
20809
21551
|
});
|
|
20810
21552
|
const spendingLeaf = resolved.selection.leaf;
|
|
20811
21553
|
const sequence = resolved.selection.sequence;
|
|
20812
|
-
const timelock =
|
|
21554
|
+
const timelock = chunk2JV4VQ7C_cjs.sequenceToTimelock(sequence);
|
|
20813
21555
|
const elapsed = timelock.type === "blocks" ? chainTip.height >= txStatus.blockHeight + Number(timelock.value) : chainTip.time >= txStatus.blockTime + Number(timelock.value);
|
|
20814
21556
|
if (!elapsed) {
|
|
20815
21557
|
throw new Error(`no available exit path found for vtxo ${vtxo.txid}:${vtxo.vout}`);
|
|
@@ -20822,7 +21564,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
20822
21564
|
sequence,
|
|
20823
21565
|
witnessUtxo: {
|
|
20824
21566
|
amount: BigInt(vtxo.value),
|
|
20825
|
-
script:
|
|
21567
|
+
script: chunk2JV4VQ7C_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
|
|
20826
21568
|
},
|
|
20827
21569
|
sighashType: btcSigner.SigHash.DEFAULT
|
|
20828
21570
|
});
|
|
@@ -20832,7 +21574,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
20832
21574
|
btcSigner.TaprootControlBlock.encode(spendingLeaf[0]).length
|
|
20833
21575
|
);
|
|
20834
21576
|
}
|
|
20835
|
-
const tx = new
|
|
21577
|
+
const tx = new chunk2JV4VQ7C_cjs.Transaction({ version: 2 });
|
|
20836
21578
|
for (const input of inputs) {
|
|
20837
21579
|
tx.addInput(input);
|
|
20838
21580
|
}
|
|
@@ -20854,6 +21596,22 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
20854
21596
|
signedTx.finalize();
|
|
20855
21597
|
return signedTx;
|
|
20856
21598
|
}
|
|
21599
|
+
async function refreshSpentExitOutputs(wallet, signedTx) {
|
|
21600
|
+
const outpoints = [];
|
|
21601
|
+
for (let i = 0; i < signedTx.inputsLength; i++) {
|
|
21602
|
+
const input = signedTx.getInput(i);
|
|
21603
|
+
if (input.txid && input.index !== void 0) {
|
|
21604
|
+
outpoints.push({ txid: base.hex.encode(input.txid), vout: input.index });
|
|
21605
|
+
}
|
|
21606
|
+
}
|
|
21607
|
+
if (outpoints.length === 0) return;
|
|
21608
|
+
try {
|
|
21609
|
+
const manager = await wallet.getContractManager();
|
|
21610
|
+
await manager.refreshOutpoints(outpoints);
|
|
21611
|
+
} catch (e) {
|
|
21612
|
+
console.error("completeUnroll: failed to refresh the spent exit outputs", e);
|
|
21613
|
+
}
|
|
21614
|
+
}
|
|
20857
21615
|
function sleep2(ms) {
|
|
20858
21616
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
20859
21617
|
}
|
|
@@ -20899,7 +21657,7 @@ async function buildSignedSweep(params) {
|
|
|
20899
21657
|
`uneconomic vtxo ${vtxo.txid}:${vtxo.vout}: value ${vtxo.value} - fee ${fee} < dust`
|
|
20900
21658
|
);
|
|
20901
21659
|
}
|
|
20902
|
-
const tx = new
|
|
21660
|
+
const tx = new chunk2JV4VQ7C_cjs.Transaction({ version: 2 });
|
|
20903
21661
|
tx.addInput({
|
|
20904
21662
|
txid: vtxo.txid,
|
|
20905
21663
|
index: vtxo.vout,
|
|
@@ -20924,7 +21682,7 @@ async function buildSignedSweep(params) {
|
|
|
20924
21682
|
finalScriptWitness: [
|
|
20925
21683
|
tapScriptSig[0][1],
|
|
20926
21684
|
...path.extraWitness,
|
|
20927
|
-
|
|
21685
|
+
chunk2JV4VQ7C_cjs.scriptFromTapLeafScript(path.leaf),
|
|
20928
21686
|
btcSigner.TaprootControlBlock.encode(controlBlock)
|
|
20929
21687
|
]
|
|
20930
21688
|
});
|
|
@@ -20932,7 +21690,7 @@ async function buildSignedSweep(params) {
|
|
|
20932
21690
|
}
|
|
20933
21691
|
|
|
20934
21692
|
// src/wallet/exit/estimate.ts
|
|
20935
|
-
var CHILD_OUTPUT_DUST =
|
|
21693
|
+
var CHILD_OUTPUT_DUST = CHILD_DUST_AMOUNT;
|
|
20936
21694
|
function stepFundingAmount(stepFee) {
|
|
20937
21695
|
return stepFee + CHILD_OUTPUT_DUST;
|
|
20938
21696
|
}
|
|
@@ -20954,7 +21712,7 @@ async function resolveFeeRate(opts) {
|
|
|
20954
21712
|
}
|
|
20955
21713
|
async function selectExitVtxos(opts) {
|
|
20956
21714
|
if (!opts.vtxos) return opts.wallet.getVtxos();
|
|
20957
|
-
const res = await
|
|
21715
|
+
const res = await chunk2JV4VQ7C_cjs.getNormalizedVtxos(opts.wallet.indexerProvider, { outpoints: opts.vtxos });
|
|
20958
21716
|
const tapTrees = /* @__PURE__ */ new Map();
|
|
20959
21717
|
const out = [];
|
|
20960
21718
|
for (const vtxo of res.vtxos) {
|
|
@@ -20969,7 +21727,7 @@ async function selectExitVtxos(opts) {
|
|
|
20969
21727
|
`no contract registered for vtxo script ${vtxo.script} \u2014 register the contract before exiting`
|
|
20970
21728
|
);
|
|
20971
21729
|
}
|
|
20972
|
-
const handler =
|
|
21730
|
+
const handler = chunkOIZ2V2VD_cjs.contractHandlers.get(contract.type);
|
|
20973
21731
|
if (!handler) {
|
|
20974
21732
|
throw new Error(`no contract handler registered for type '${contract.type}'`);
|
|
20975
21733
|
}
|
|
@@ -20999,7 +21757,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
20999
21757
|
if (pendingNodes.length > 0) {
|
|
21000
21758
|
const txs = await resolver.getVirtualTxs(pendingNodes.map((n) => n.txid));
|
|
21001
21759
|
for (const psbt of txs) {
|
|
21002
|
-
psbts.set(
|
|
21760
|
+
psbts.set(chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
21003
21761
|
}
|
|
21004
21762
|
}
|
|
21005
21763
|
const childVsize = Number(
|
|
@@ -21035,7 +21793,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
21035
21793
|
try {
|
|
21036
21794
|
const resolved = await resolveUnilateralPath({
|
|
21037
21795
|
vtxo,
|
|
21038
|
-
scriptHex: base.hex.encode(
|
|
21796
|
+
scriptHex: base.hex.encode(chunk2JV4VQ7C_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
|
|
21039
21797
|
contractRepository: wallet.contractRepository,
|
|
21040
21798
|
walletPubKeyHex,
|
|
21041
21799
|
currentTime: Date.now()
|
|
@@ -21054,7 +21812,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
21054
21812
|
});
|
|
21055
21813
|
continue;
|
|
21056
21814
|
}
|
|
21057
|
-
const t =
|
|
21815
|
+
const t = chunk2JV4VQ7C_cjs.sequenceToTimelock(resolved.selection.sequence);
|
|
21058
21816
|
const delay = { type: t.type, value: Number(t.value) };
|
|
21059
21817
|
infos.push({ outpoint, value: vtxo.value, sweepFee, path: resolved.label, delay });
|
|
21060
21818
|
sweeps.push({ vtxo, resolved, sweepFee, delay });
|
|
@@ -21093,10 +21851,18 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
21093
21851
|
// splitter. funded: + 1 splitter tx and pre-signed children.
|
|
21094
21852
|
txCount: (graph ? 0 : steps.length > 0 ? 1 : 0) + steps.length * 2 + sweeps.length,
|
|
21095
21853
|
totalFeeSats: splitterFee + stepFees + sweepFees,
|
|
21096
|
-
// graph funding is what the executor sends to its own fee address:
|
|
21097
|
-
//
|
|
21098
|
-
//
|
|
21099
|
-
|
|
21854
|
+
// graph funding is what the executor sends to its own fee address: the
|
|
21855
|
+
// CPFP fees, plus one dust floor. Change recycles through that single
|
|
21856
|
+
// address, so each bump hands its remainder to the next and only the
|
|
21857
|
+
// *final* change has to clear `CHILD_DUST_AMOUNT` — but it does have to,
|
|
21858
|
+
// and `buildAnchorChild` throws rather than absorbing a short remainder
|
|
21859
|
+
// into the fee. Quoting bare fees quotes an amount that strands the last
|
|
21860
|
+
// bump and every sweep behind it.
|
|
21861
|
+
//
|
|
21862
|
+
// funded reserves the same floor per step instead of once overall (see
|
|
21863
|
+
// `stepFundingAmount`), because it pre-funds each child separately
|
|
21864
|
+
// through the splitter rather than recycling one output.
|
|
21865
|
+
fundingRequiredSats: graph ? steps.length > 0 ? stepFees + CHILD_OUTPUT_DUST : 0 : splitterFee + fundingTotal,
|
|
21100
21866
|
recoveredSats: sweeps.reduce((s, x) => s + (x.vtxo.value - x.sweepFee), 0)
|
|
21101
21867
|
};
|
|
21102
21868
|
const expiries = pendingNodes.map((n) => n.expiresAt).filter((x) => x !== void 0);
|
|
@@ -21156,12 +21922,32 @@ var Executor = class {
|
|
|
21156
21922
|
this.pollIntervalMs = opts?.pollIntervalMs ?? 5e3;
|
|
21157
21923
|
this.feeWallet = opts?.feeWallet;
|
|
21158
21924
|
this.signal = opts?.signal;
|
|
21925
|
+
this.onExitObserved = opts?.onExitObserved;
|
|
21159
21926
|
}
|
|
21160
21927
|
pkg;
|
|
21161
21928
|
provider;
|
|
21162
21929
|
pollIntervalMs;
|
|
21163
21930
|
feeWallet;
|
|
21164
21931
|
signal;
|
|
21932
|
+
onExitObserved;
|
|
21933
|
+
/**
|
|
21934
|
+
* Per-VTXO branch progress, which the executor otherwise does not track:
|
|
21935
|
+
* `dead` / `done` are per-step, and a VTXO is only onchain once EVERY
|
|
21936
|
+
* `package`/`bump` step naming it has confirmed. (`broadcast` — the funding
|
|
21937
|
+
* splitter — carries no `forVtxos` and serves no single VTXO.)
|
|
21938
|
+
*/
|
|
21939
|
+
branchSteps() {
|
|
21940
|
+
const byVtxo = /* @__PURE__ */ new Map();
|
|
21941
|
+
this.pkg.steps.forEach((step, i) => {
|
|
21942
|
+
if (step.kind !== "package" && step.kind !== "bump") return;
|
|
21943
|
+
for (const vtxo of step.forVtxos) {
|
|
21944
|
+
let steps = byVtxo.get(vtxo);
|
|
21945
|
+
if (!steps) byVtxo.set(vtxo, steps = /* @__PURE__ */ new Set());
|
|
21946
|
+
steps.add(i);
|
|
21947
|
+
}
|
|
21948
|
+
});
|
|
21949
|
+
return byVtxo;
|
|
21950
|
+
}
|
|
21165
21951
|
/**
|
|
21166
21952
|
* Poll delay. Nearly all wall-clock time is spent here, so it must be the
|
|
21167
21953
|
* thing that reacts to abort — checking only between polls would leave
|
|
@@ -21201,6 +21987,19 @@ var Executor = class {
|
|
|
21201
21987
|
async *[Symbol.asyncIterator]() {
|
|
21202
21988
|
throwIfAborted(this.signal);
|
|
21203
21989
|
const dead = /* @__PURE__ */ new Set();
|
|
21990
|
+
const branchSteps = this.branchSteps();
|
|
21991
|
+
const onchainSteps = /* @__PURE__ */ new Set();
|
|
21992
|
+
const branchObserved = /* @__PURE__ */ new Set();
|
|
21993
|
+
const observeBranch = async (stepIndex, forVtxos) => {
|
|
21994
|
+
onchainSteps.add(stepIndex);
|
|
21995
|
+
for (const vtxo of forVtxos ?? []) {
|
|
21996
|
+
if (branchObserved.has(vtxo)) continue;
|
|
21997
|
+
const steps = branchSteps.get(vtxo);
|
|
21998
|
+
if (!steps || ![...steps].every((i) => onchainSteps.has(i))) continue;
|
|
21999
|
+
branchObserved.add(vtxo);
|
|
22000
|
+
await this.observe(vtxo);
|
|
22001
|
+
}
|
|
22002
|
+
};
|
|
21204
22003
|
if (this.pkg.validUntil && Date.now() / 1e3 > this.pkg.validUntil) {
|
|
21205
22004
|
yield {
|
|
21206
22005
|
stepIndex: -1,
|
|
@@ -21230,6 +22029,7 @@ var Executor = class {
|
|
|
21230
22029
|
const anchorTxid = step.kind === "package" || step.kind === "bump" ? step.parentTxid : step.txid;
|
|
21231
22030
|
const existing = await this.status(anchorTxid);
|
|
21232
22031
|
if (existing?.confirmed) {
|
|
22032
|
+
await observeBranch(i, forVtxos);
|
|
21233
22033
|
yield {
|
|
21234
22034
|
stepIndex: i,
|
|
21235
22035
|
kind: step.kind,
|
|
@@ -21285,6 +22085,7 @@ var Executor = class {
|
|
|
21285
22085
|
}
|
|
21286
22086
|
}
|
|
21287
22087
|
await this.waitConfirmed(anchorTxid);
|
|
22088
|
+
await observeBranch(i, forVtxos);
|
|
21288
22089
|
yield {
|
|
21289
22090
|
stepIndex: i,
|
|
21290
22091
|
kind: step.kind,
|
|
@@ -21315,6 +22116,7 @@ var Executor = class {
|
|
|
21315
22116
|
const swept = await this.status(step.txid);
|
|
21316
22117
|
if (swept?.confirmed) {
|
|
21317
22118
|
done.add(index);
|
|
22119
|
+
await this.observe(step.vtxo);
|
|
21318
22120
|
yield {
|
|
21319
22121
|
stepIndex: index,
|
|
21320
22122
|
kind: "sweep",
|
|
@@ -21371,7 +22173,25 @@ var Executor = class {
|
|
|
21371
22173
|
if (done.size < pending.length) await this.sleep();
|
|
21372
22174
|
}
|
|
21373
22175
|
}
|
|
22176
|
+
/** `"txid:vout"` -> outpoint, then hand it to the hook. A malformed entry is skipped. */
|
|
22177
|
+
async observe(outpoint) {
|
|
22178
|
+
if (!this.onExitObserved) return;
|
|
22179
|
+
const sep = outpoint.lastIndexOf(":");
|
|
22180
|
+
const rest = outpoint.slice(sep + 1);
|
|
22181
|
+
const vout = Number(rest);
|
|
22182
|
+
if (sep <= 0 || rest === "" || !Number.isInteger(vout)) return;
|
|
22183
|
+
await notifyExitObserved(this.onExitObserved, { txid: outpoint.slice(0, sep), vout });
|
|
22184
|
+
}
|
|
21374
22185
|
};
|
|
22186
|
+
|
|
22187
|
+
// src/wallet/exit/execute.ts
|
|
22188
|
+
async function execute(wallet, pkg, opts) {
|
|
22189
|
+
const manager = await wallet.getContractManager();
|
|
22190
|
+
return new Executor(pkg, opts?.provider ?? wallet.onchainProvider, {
|
|
22191
|
+
...opts,
|
|
22192
|
+
onExitObserved: opts?.onExitObserved ?? exitObserverFor(manager)
|
|
22193
|
+
});
|
|
22194
|
+
}
|
|
21375
22195
|
async function prepare(opts) {
|
|
21376
22196
|
const { wallet, onchainWallet } = opts;
|
|
21377
22197
|
const feeRate = await resolveFeeRate(opts);
|
|
@@ -21393,7 +22213,7 @@ async function prepare(opts) {
|
|
|
21393
22213
|
txid: sweep.vtxo.txid,
|
|
21394
22214
|
vout: sweep.vtxo.vout,
|
|
21395
22215
|
value: sweep.vtxo.value,
|
|
21396
|
-
pkScript:
|
|
22216
|
+
pkScript: chunk2JV4VQ7C_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
|
|
21397
22217
|
},
|
|
21398
22218
|
path: sweep.resolved.selection,
|
|
21399
22219
|
outputAddress: opts.sweepAddress,
|
|
@@ -21446,7 +22266,10 @@ async function prepare(opts) {
|
|
|
21446
22266
|
totals: {
|
|
21447
22267
|
txCount: bumpSteps.length * 2 + sweepSteps.length,
|
|
21448
22268
|
totalFeeSats: stepFees2 + sweepFees2,
|
|
21449
|
-
|
|
22269
|
+
// Fees plus the single dust floor the recycling change output
|
|
22270
|
+
// must keep clear; see the note in `estimate.ts`. Must match
|
|
22271
|
+
// the quote `estimate` gives for the same package.
|
|
22272
|
+
fundingRequiredSats: bumpSteps.length > 0 ? stepFees2 + CHILD_OUTPUT_DUST : 0,
|
|
21450
22273
|
recoveredSats: recovered2
|
|
21451
22274
|
},
|
|
21452
22275
|
vtxos: layout.infos,
|
|
@@ -21478,7 +22301,7 @@ async function prepare(opts) {
|
|
|
21478
22301
|
if (newFee <= splitterFee) break;
|
|
21479
22302
|
splitterFee = newFee;
|
|
21480
22303
|
}
|
|
21481
|
-
const splitter = new
|
|
22304
|
+
const splitter = new chunk2JV4VQ7C_cjs.Transaction({ version: 2 });
|
|
21482
22305
|
for (const coin of selected.inputs) {
|
|
21483
22306
|
splitter.addInput({
|
|
21484
22307
|
txid: coin.txid,
|
|
@@ -21615,47 +22438,48 @@ function isValidStep(step) {
|
|
|
21615
22438
|
var UnilateralExit = {
|
|
21616
22439
|
estimate,
|
|
21617
22440
|
prepare,
|
|
22441
|
+
execute,
|
|
21618
22442
|
Executor
|
|
21619
22443
|
};
|
|
21620
22444
|
|
|
21621
22445
|
// src/arkade/index.ts
|
|
21622
22446
|
var arkade_exports = {};
|
|
21623
22447
|
chunk5BLDMQED_cjs.__export(arkade_exports, {
|
|
21624
|
-
ARKADE_OP: () =>
|
|
21625
|
-
ARKADE_OPCODES: () =>
|
|
21626
|
-
ARKADE_OPCODE_NAMES: () =>
|
|
21627
|
-
ARKADE_OPCODE_VALUES: () =>
|
|
21628
|
-
ARKADE_OPS: () =>
|
|
22448
|
+
ARKADE_OP: () => chunkOIZ2V2VD_cjs.ARKADE_OP,
|
|
22449
|
+
ARKADE_OPCODES: () => chunkOIZ2V2VD_cjs.ARKADE_OPCODES,
|
|
22450
|
+
ARKADE_OPCODE_NAMES: () => chunkOIZ2V2VD_cjs.ARKADE_OPCODE_NAMES,
|
|
22451
|
+
ARKADE_OPCODE_VALUES: () => chunkOIZ2V2VD_cjs.ARKADE_OPCODE_VALUES,
|
|
22452
|
+
ARKADE_OPS: () => chunkOIZ2V2VD_cjs.ARKADE_OPS,
|
|
21629
22453
|
Arkade: () => Arkade,
|
|
21630
22454
|
ArkadeContract: () => ArkadeContract,
|
|
21631
|
-
ArkadeProgramScript: () =>
|
|
21632
|
-
ArkadeScript: () =>
|
|
22455
|
+
ArkadeProgramScript: () => chunkOIZ2V2VD_cjs.ArkadeProgramScript,
|
|
22456
|
+
ArkadeScript: () => chunkOIZ2V2VD_cjs.ArkadeScript,
|
|
21633
22457
|
ArkadeTransactionBuilder: () => ArkadeTransactionBuilder,
|
|
21634
|
-
BigNum: () =>
|
|
22458
|
+
BigNum: () => chunkOIZ2V2VD_cjs.bignum_exports,
|
|
21635
22459
|
OP: () => btcSigner.OP,
|
|
21636
|
-
OPCODE_NAMES: () =>
|
|
21637
|
-
OPCODE_VALUES: () =>
|
|
21638
|
-
SUPPORTED_PROGRAM_VERSION: () =>
|
|
22460
|
+
OPCODE_NAMES: () => chunkOIZ2V2VD_cjs.OPCODE_NAMES,
|
|
22461
|
+
OPCODE_VALUES: () => chunkOIZ2V2VD_cjs.OPCODE_VALUES,
|
|
22462
|
+
SUPPORTED_PROGRAM_VERSION: () => chunkOIZ2V2VD_cjs.SUPPORTED_PROGRAM_VERSION,
|
|
21639
22463
|
Script: () => btcSigner.Script,
|
|
21640
|
-
arkadeScriptHash: () =>
|
|
21641
|
-
arkadeWitnessHash: () =>
|
|
21642
|
-
asmToBytes: () =>
|
|
21643
|
-
bytesToASM: () =>
|
|
21644
|
-
computeArkadeScriptPublicKey: () =>
|
|
22464
|
+
arkadeScriptHash: () => chunkOIZ2V2VD_cjs.arkadeScriptHash,
|
|
22465
|
+
arkadeWitnessHash: () => chunkOIZ2V2VD_cjs.arkadeWitnessHash,
|
|
22466
|
+
asmToBytes: () => chunkOIZ2V2VD_cjs.asmToBytes,
|
|
22467
|
+
bytesToASM: () => chunkOIZ2V2VD_cjs.bytesToASM,
|
|
22468
|
+
computeArkadeScriptPublicKey: () => chunkOIZ2V2VD_cjs.computeArkadeScriptPublicKey,
|
|
21645
22469
|
createArkadeBatchHandler: () => createArkadeBatchHandler,
|
|
21646
|
-
deserializeArkadeContractParams: () =>
|
|
21647
|
-
fromASM: () =>
|
|
21648
|
-
getOpcodeName: () =>
|
|
21649
|
-
getOpcodeValue: () =>
|
|
21650
|
-
parseArtifact: () =>
|
|
21651
|
-
resolveAsm: () =>
|
|
21652
|
-
serializeArkadeContractParams: () =>
|
|
21653
|
-
stringifyArtifact: () =>
|
|
21654
|
-
toASM: () =>
|
|
21655
|
-
validateProgram: () =>
|
|
21656
|
-
witnessRefToBytes: () =>
|
|
22470
|
+
deserializeArkadeContractParams: () => chunkOIZ2V2VD_cjs.deserializeArkadeContractParams,
|
|
22471
|
+
fromASM: () => chunkOIZ2V2VD_cjs.fromASM,
|
|
22472
|
+
getOpcodeName: () => chunkOIZ2V2VD_cjs.getOpcodeName,
|
|
22473
|
+
getOpcodeValue: () => chunkOIZ2V2VD_cjs.getOpcodeValue,
|
|
22474
|
+
parseArtifact: () => chunkOIZ2V2VD_cjs.parseArtifact,
|
|
22475
|
+
resolveAsm: () => chunkOIZ2V2VD_cjs.resolveAsm,
|
|
22476
|
+
serializeArkadeContractParams: () => chunkOIZ2V2VD_cjs.serializeArkadeContractParams,
|
|
22477
|
+
stringifyArtifact: () => chunkOIZ2V2VD_cjs.stringifyArtifact,
|
|
22478
|
+
toASM: () => chunkOIZ2V2VD_cjs.toASM,
|
|
22479
|
+
validateProgram: () => chunkOIZ2V2VD_cjs.validateProgram,
|
|
22480
|
+
witnessRefToBytes: () => chunkOIZ2V2VD_cjs.witnessRefToBytes
|
|
21657
22481
|
});
|
|
21658
|
-
var isVtxoCoin = (input) =>
|
|
22482
|
+
var isVtxoCoin = (input) => chunk2JV4VQ7C_cjs.isVirtualCoin(input);
|
|
21659
22483
|
function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message, session, arkProvider, emulator, network, recipients, batchExpiryPolicy) {
|
|
21660
22484
|
let batchId;
|
|
21661
22485
|
let sweepTapTreeRoot;
|
|
@@ -21676,21 +22500,23 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
|
|
|
21676
22500
|
);
|
|
21677
22501
|
await arkProvider.confirmRegistration(intentId);
|
|
21678
22502
|
batchId = event.id;
|
|
21679
|
-
const sweepTapscript =
|
|
22503
|
+
const sweepTapscript = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.encode({
|
|
21680
22504
|
timelock,
|
|
21681
|
-
pubkeys: [base.hex.decode(info.forfeitPubkey)
|
|
22505
|
+
pubkeys: [chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(info.forfeitPubkey), "forfeit key")]
|
|
21682
22506
|
}).script;
|
|
21683
22507
|
sweepTapTreeRoot = payment_js.tapLeafHash(sweepTapscript);
|
|
21684
22508
|
return { skip: false };
|
|
21685
22509
|
},
|
|
21686
22510
|
onTreeSigningStarted: async (event, vtxoTree) => {
|
|
21687
22511
|
const signerPubKey = await session.getPublicKey();
|
|
21688
|
-
const xonlySignerPubKey =
|
|
21689
|
-
const xOnlyPubkeys = event.cosignersPublicKeys.map(
|
|
22512
|
+
const xonlySignerPubKey = chunkOIZ2V2VD_cjs.toXOnly(signerPubKey, "signer key");
|
|
22513
|
+
const xOnlyPubkeys = event.cosignersPublicKeys.map(
|
|
22514
|
+
(k) => base.hex.encode(chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(k), "cosigner key"))
|
|
22515
|
+
);
|
|
21690
22516
|
if (!xOnlyPubkeys.includes(base.hex.encode(xonlySignerPubKey))) {
|
|
21691
22517
|
return { skip: true };
|
|
21692
22518
|
}
|
|
21693
|
-
const commitmentTx =
|
|
22519
|
+
const commitmentTx = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(event.unsignedCommitmentTx));
|
|
21694
22520
|
validateVtxoTxGraph(vtxoTree, commitmentTx, sweepTapTreeRoot);
|
|
21695
22521
|
if (recipients && recipients.length > 0) {
|
|
21696
22522
|
validateBatchRecipients(commitmentTx, vtxoTree.leaves(), recipients, network);
|
|
@@ -21722,7 +22548,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
|
|
|
21722
22548
|
if (connectorTree) {
|
|
21723
22549
|
validateConnectorsTxGraph(event.commitmentTx, connectorTree);
|
|
21724
22550
|
}
|
|
21725
|
-
let commitmentPsbt =
|
|
22551
|
+
let commitmentPsbt = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
|
|
21726
22552
|
assertFinalCommitmentMatchesValidated(
|
|
21727
22553
|
commitmentPsbt,
|
|
21728
22554
|
validatedCommitmentTxid,
|
|
@@ -21757,7 +22583,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
|
|
|
21757
22583
|
boardingIndices.push(boardingIdx);
|
|
21758
22584
|
continue;
|
|
21759
22585
|
}
|
|
21760
|
-
if (
|
|
22586
|
+
if (chunk2JV4VQ7C_cjs.isRecoverable(input) || isSubdust(input, info.dust)) {
|
|
21761
22587
|
continue;
|
|
21762
22588
|
}
|
|
21763
22589
|
if (connectorIndex >= connectorLeaves.length) {
|
|
@@ -21778,7 +22604,7 @@ function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message
|
|
|
21778
22604
|
index: input.vout,
|
|
21779
22605
|
witnessUtxo: {
|
|
21780
22606
|
amount: BigInt(input.value),
|
|
21781
|
-
script:
|
|
22607
|
+
script: chunk2JV4VQ7C_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
21782
22608
|
},
|
|
21783
22609
|
sighashType: btcSigner.SigHash.DEFAULT,
|
|
21784
22610
|
tapLeafScript: [input.forfeitTapLeafScript]
|
|
@@ -21869,17 +22695,16 @@ var Arkade = class _Arkade {
|
|
|
21869
22695
|
/** Connect and resolve the server key, checkpoint closure and (if present) the co-signer key. */
|
|
21870
22696
|
static async connect(opts) {
|
|
21871
22697
|
const info = await opts.arkade.getInfo();
|
|
21872
|
-
const serverKey = base.hex.decode(info.signerPubkey)
|
|
21873
|
-
const checkpoint =
|
|
21874
|
-
const network = opts.network ??
|
|
22698
|
+
const serverKey = chunkOIZ2V2VD_cjs.toXOnly(base.hex.decode(info.signerPubkey), "ark signer key");
|
|
22699
|
+
const checkpoint = chunk2JV4VQ7C_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
|
|
22700
|
+
const network = opts.network ?? chunk2JV4VQ7C_cjs.DEFAULT_NETWORK;
|
|
21875
22701
|
let emulatorKey;
|
|
21876
22702
|
if (opts.emulator) {
|
|
21877
|
-
emulatorKey = base.hex.decode(
|
|
22703
|
+
emulatorKey = base.hex.decode(chunk2JV4VQ7C_cjs.resolveEmulatorPubkey(network, opts.emulatorPubkey));
|
|
21878
22704
|
}
|
|
21879
22705
|
let userKey;
|
|
21880
22706
|
if (opts.identity) {
|
|
21881
|
-
|
|
21882
|
-
userKey = pub.length === 33 ? pub.slice(1) : pub;
|
|
22707
|
+
userKey = chunkOIZ2V2VD_cjs.toXOnly(await opts.identity.xOnlyPublicKey(), "identity key");
|
|
21883
22708
|
}
|
|
21884
22709
|
return new _Arkade({
|
|
21885
22710
|
arkProvider: opts.arkade,
|
|
@@ -21905,7 +22730,7 @@ var Arkade = class _Arkade {
|
|
|
21905
22730
|
* key respectively; explicit args always win.
|
|
21906
22731
|
*/
|
|
21907
22732
|
contract(program, args = {}) {
|
|
21908
|
-
const declared = (program.params ?? []).map(
|
|
22733
|
+
const declared = (program.params ?? []).map(chunkOIZ2V2VD_cjs.inputName);
|
|
21909
22734
|
if (declared.includes("server") && args.server === void 0) {
|
|
21910
22735
|
args = { ...args, server: this.serverKey };
|
|
21911
22736
|
}
|
|
@@ -21925,7 +22750,7 @@ var ArkadeContract = class _ArkadeContract {
|
|
|
21925
22750
|
userKey: client.userKey,
|
|
21926
22751
|
emulatorKey: client.emulatorKey
|
|
21927
22752
|
};
|
|
21928
|
-
this.vtxoScript = new
|
|
22753
|
+
this.vtxoScript = new chunkOIZ2V2VD_cjs.ArkadeProgramScript(program, args, this.keys);
|
|
21929
22754
|
this.tapTree = this.vtxoScript.encode();
|
|
21930
22755
|
this.compiled = this.vtxoScript.compiled;
|
|
21931
22756
|
}
|
|
@@ -21953,7 +22778,7 @@ var ArkadeContract = class _ArkadeContract {
|
|
|
21953
22778
|
`ArkadeContract.fromContract: expected contract type 'arkade', got '${contract.type}'`
|
|
21954
22779
|
);
|
|
21955
22780
|
}
|
|
21956
|
-
const typed =
|
|
22781
|
+
const typed = chunkOIZ2V2VD_cjs.deserializeArkadeContractParams(contract.params);
|
|
21957
22782
|
return new _ArkadeContract(client, typed.program, typed.args, {
|
|
21958
22783
|
serverKey: typed.serverKey,
|
|
21959
22784
|
userKey: typed.userKey,
|
|
@@ -21994,7 +22819,7 @@ var ArkadeContract = class _ArkadeContract {
|
|
|
21994
22819
|
toContractParams() {
|
|
21995
22820
|
return {
|
|
21996
22821
|
type: "arkade",
|
|
21997
|
-
params:
|
|
22822
|
+
params: chunkOIZ2V2VD_cjs.serializeArkadeContractParams({
|
|
21998
22823
|
program: this.program,
|
|
21999
22824
|
args: this.args,
|
|
22000
22825
|
serverKey: this.keys.serverKey,
|
|
@@ -22039,13 +22864,15 @@ var ArkadeContract = class _ArkadeContract {
|
|
|
22039
22864
|
const [registered] = await manager.getContracts({ script: scriptHex });
|
|
22040
22865
|
if (registered) {
|
|
22041
22866
|
const [withVtxos] = await manager.getContractsWithVtxos({ script: scriptHex });
|
|
22042
|
-
return (withVtxos?.vtxos ?? []).filter(
|
|
22867
|
+
return (withVtxos?.vtxos ?? []).filter(
|
|
22868
|
+
(v) => !chunk2JV4VQ7C_cjs.hasTerminalSpend(v) && !v.isUnrolled
|
|
22869
|
+
);
|
|
22043
22870
|
}
|
|
22044
22871
|
}
|
|
22045
22872
|
if (!this.client.indexer) {
|
|
22046
22873
|
throw new Error("ArkadeContract.getUtxos: an indexer is required");
|
|
22047
22874
|
}
|
|
22048
|
-
const { vtxos } = await
|
|
22875
|
+
const { vtxos } = await chunk2JV4VQ7C_cjs.getNormalizedVtxos(this.client.indexer, {
|
|
22049
22876
|
scripts: [scriptHex],
|
|
22050
22877
|
spendableOnly: true
|
|
22051
22878
|
});
|
|
@@ -22147,12 +22974,25 @@ var ArkadeTransactionBuilder = class {
|
|
|
22147
22974
|
this.contract.client.checkpoint
|
|
22148
22975
|
);
|
|
22149
22976
|
if (coin.sourceTx) {
|
|
22150
|
-
|
|
22977
|
+
chunk2JV4VQ7C_cjs.setArkPsbtField(arkTx, 0, chunk2JV4VQ7C_cjs.PrevArkTxField, coin.sourceTx);
|
|
22978
|
+
}
|
|
22979
|
+
if (this.fn.arkadeScript) {
|
|
22980
|
+
const indexer = this.contract.client.indexer;
|
|
22981
|
+
if (!indexer) {
|
|
22982
|
+
throw new PrevTxUnavailableError(
|
|
22983
|
+
"covenant spends require an `indexer` on the Arkade client to resolve the previous ark tx of each input"
|
|
22984
|
+
);
|
|
22985
|
+
}
|
|
22986
|
+
await attachPrevArkTxs(
|
|
22987
|
+
arkTx,
|
|
22988
|
+
[coin.txid, ...this.fundingCoins.map((c) => c.txid)],
|
|
22989
|
+
indexer
|
|
22990
|
+
);
|
|
22151
22991
|
}
|
|
22152
22992
|
const condition = (def.tapscript.witness ?? []).map((w) => this.witnessBytes(w));
|
|
22153
22993
|
if (condition.length > 0) {
|
|
22154
|
-
|
|
22155
|
-
|
|
22994
|
+
chunk2JV4VQ7C_cjs.setArkPsbtField(arkTx, 0, chunk2JV4VQ7C_cjs.ConditionWitness, condition);
|
|
22995
|
+
chunk2JV4VQ7C_cjs.setArkPsbtField(checkpoints[0], 0, chunk2JV4VQ7C_cjs.ConditionWitness, condition);
|
|
22156
22996
|
}
|
|
22157
22997
|
const packets = [];
|
|
22158
22998
|
if (this.assetSpecs.length > 0) {
|
|
@@ -22191,7 +23031,7 @@ var ArkadeTransactionBuilder = class {
|
|
|
22191
23031
|
base.base64.encode(signedArk2.toPSBT()),
|
|
22192
23032
|
signedCps.map((c) => base.base64.encode(c.toPSBT()))
|
|
22193
23033
|
);
|
|
22194
|
-
const txid =
|
|
23034
|
+
const txid = chunk2JV4VQ7C_cjs.Transaction.fromPSBT(base.base64.decode(res2.signedArkTx)).id;
|
|
22195
23035
|
return {
|
|
22196
23036
|
txid,
|
|
22197
23037
|
signedArkTx: res2.signedArkTx,
|
|
@@ -22250,23 +23090,23 @@ var ArkadeTransactionBuilder = class {
|
|
|
22250
23090
|
}
|
|
22251
23091
|
buildAssetPacket() {
|
|
22252
23092
|
const groups = this.assetSpecs.map((s) => {
|
|
22253
|
-
const id = typeof s.assetId === "string" ?
|
|
22254
|
-
return
|
|
23093
|
+
const id = typeof s.assetId === "string" ? chunkCO3KKSWM_cjs.AssetId.fromString(s.assetId) : chunkCO3KKSWM_cjs.AssetId.fromBytes(s.assetId);
|
|
23094
|
+
return chunkCO3KKSWM_cjs.AssetGroup.create(
|
|
22255
23095
|
id,
|
|
22256
23096
|
null,
|
|
22257
|
-
s.inputs.map((i) =>
|
|
22258
|
-
s.outputs.map((o) =>
|
|
22259
|
-
(s.metadata ?? []).map((m) =>
|
|
23097
|
+
s.inputs.map((i) => chunkCO3KKSWM_cjs.AssetInput.create(i.vin, i.amount)),
|
|
23098
|
+
s.outputs.map((o) => chunkCO3KKSWM_cjs.AssetOutput.create(o.vout, o.amount)),
|
|
23099
|
+
(s.metadata ?? []).map((m) => chunkCO3KKSWM_cjs.Metadata.create(m.key, m.value))
|
|
22260
23100
|
);
|
|
22261
23101
|
});
|
|
22262
|
-
return
|
|
23102
|
+
return chunkCO3KKSWM_cjs.Packet.create(groups);
|
|
22263
23103
|
}
|
|
22264
23104
|
witnessBytes(ref) {
|
|
22265
|
-
return
|
|
23105
|
+
return chunkOIZ2V2VD_cjs.witnessRefToBytes(ref, this.args, this.contract.args);
|
|
22266
23106
|
}
|
|
22267
23107
|
};
|
|
22268
23108
|
function bindInputs(fn, callArgs) {
|
|
22269
|
-
const names = (fn.def.inputs ?? []).map(
|
|
23109
|
+
const names = (fn.def.inputs ?? []).map(chunkOIZ2V2VD_cjs.inputName);
|
|
22270
23110
|
if (callArgs.length !== names.length) {
|
|
22271
23111
|
throw new Error(`${fn.name}: expected ${names.length} argument(s), got ${callArgs.length}`);
|
|
22272
23112
|
}
|
|
@@ -22666,6 +23506,7 @@ exports.AssetManager = AssetManager;
|
|
|
22666
23506
|
exports.BIP21 = BIP21;
|
|
22667
23507
|
exports.BIP21Error = BIP21Error;
|
|
22668
23508
|
exports.BLOCKED_UPGRADE_TIMEOUT_MS = BLOCKED_UPGRADE_TIMEOUT_MS;
|
|
23509
|
+
exports.CachingArkProvider = CachingArkProvider;
|
|
22669
23510
|
exports.ChainedTxType = ChainedTxType;
|
|
22670
23511
|
exports.ConnectionDisposedError = ConnectionDisposedError;
|
|
22671
23512
|
exports.ContractManager = ContractManager;
|
|
@@ -22716,6 +23557,7 @@ exports.MnemonicIdentity = MnemonicIdentity;
|
|
|
22716
23557
|
exports.OnchainWallet = OnchainWallet;
|
|
22717
23558
|
exports.P2A = P2A;
|
|
22718
23559
|
exports.PaymentRouter = PaymentRouter;
|
|
23560
|
+
exports.PrevTxUnavailableError = PrevTxUnavailableError;
|
|
22719
23561
|
exports.REGTEST_MIN_BATCH_EXPIRY_SECONDS = REGTEST_MIN_BATCH_EXPIRY_SECONDS;
|
|
22720
23562
|
exports.REGTEST_MIN_CHECKPOINT_EXIT_DELAY_SECONDS = REGTEST_MIN_CHECKPOINT_EXIT_DELAY_SECONDS;
|
|
22721
23563
|
exports.Ramps = Ramps;
|
|
@@ -22741,6 +23583,7 @@ exports.UnilateralExit = UnilateralExit;
|
|
|
22741
23583
|
exports.UnknownPacket = UnknownPacket;
|
|
22742
23584
|
exports.VtxoManager = VtxoManager;
|
|
22743
23585
|
exports.Wallet = Wallet2;
|
|
23586
|
+
exports.WalletCannotAllocateAddressError = WalletCannotAllocateAddressError;
|
|
22744
23587
|
exports.WalletCannotSignError = WalletCannotSignError;
|
|
22745
23588
|
exports.WalletMessageHandler = WalletMessageHandler;
|
|
22746
23589
|
exports.WalletNotInitializedError = WalletNotInitializedError;
|
|
@@ -22757,6 +23600,8 @@ exports.assertSubmittedArkTxid = assertSubmittedArkTxid;
|
|
|
22757
23600
|
exports.assertValidBatchExpiry = assertValidBatchExpiry;
|
|
22758
23601
|
exports.assertValidServerUnrollScript = assertValidServerUnrollScript;
|
|
22759
23602
|
exports.assetMintResolver = assetMintResolver;
|
|
23603
|
+
exports.attachPrevArkTxs = attachPrevArkTxs;
|
|
23604
|
+
exports.attachPrevoutTxs = attachPrevoutTxs;
|
|
22760
23605
|
exports.awaitTransaction = awaitTransaction;
|
|
22761
23606
|
exports.boardingResolver = boardingResolver;
|
|
22762
23607
|
exports.btcTarget = btcTarget;
|
|
@@ -22788,7 +23633,9 @@ exports.deserializeExitPackage = deserializeExitPackage;
|
|
|
22788
23633
|
exports.deserializeUtxo = deserializeUtxo;
|
|
22789
23634
|
exports.deserializeVtxo = deserializeVtxo;
|
|
22790
23635
|
exports.encodeArkContract = encodeArkContract;
|
|
23636
|
+
exports.exitObserverFor = exitObserverFor;
|
|
22791
23637
|
exports.extendVirtualCoinForContract = extendVirtualCoinForContract;
|
|
23638
|
+
exports.extractArkProviderUrl = extractArkProviderUrl;
|
|
22792
23639
|
exports.gateExclusion = gateExclusion;
|
|
22793
23640
|
exports.gatedContracts = gatedContracts;
|
|
22794
23641
|
exports.getAllByIndexValues = getAllByIndexValues;
|
|
@@ -22799,6 +23646,7 @@ exports.hasCandidates = hasCandidates;
|
|
|
22799
23646
|
exports.intentMatchesFilter = intentMatchesFilter;
|
|
22800
23647
|
exports.intentPageBounds = intentPageBounds;
|
|
22801
23648
|
exports.invoiceTarget = invoiceTarget;
|
|
23649
|
+
exports.isAddressAllocationCapable = isAddressAllocationCapable;
|
|
22802
23650
|
exports.isArkContract = isArkContract;
|
|
22803
23651
|
exports.isBatchSignable = isBatchSignable;
|
|
22804
23652
|
exports.isBtcAddress = isBtcAddress;
|
|
@@ -22826,6 +23674,7 @@ exports.makeHandle = makeHandle;
|
|
|
22826
23674
|
exports.matchServerCheckpoints = matchServerCheckpoints;
|
|
22827
23675
|
exports.mergeChainedTxType = mergeChainedTxType;
|
|
22828
23676
|
exports.migrateWalletRepository = migrateWalletRepository;
|
|
23677
|
+
exports.notifyExitObserved = notifyExitObserved;
|
|
22829
23678
|
exports.onchainRail = onchainRail;
|
|
22830
23679
|
exports.openDatabase = openDatabase;
|
|
22831
23680
|
exports.outpointExclusion = outpointExclusion;
|
|
@@ -22837,6 +23686,7 @@ exports.requiresMigration = requiresMigration;
|
|
|
22837
23686
|
exports.resolveBatchExpiryPolicy = resolveBatchExpiryPolicy;
|
|
22838
23687
|
exports.resolveCheckpointExitDelayPolicy = resolveCheckpointExitDelayPolicy;
|
|
22839
23688
|
exports.resolveDescriptorSigner = resolveDescriptorSigner;
|
|
23689
|
+
exports.resolvePrevTxs = resolvePrevTxs;
|
|
22840
23690
|
exports.resolveSendAmount = resolveSendAmount;
|
|
22841
23691
|
exports.rollbackMigration = rollbackMigration;
|
|
22842
23692
|
exports.saveVtxosForContract = saveVtxosForContract;
|
|
@@ -22860,5 +23710,6 @@ exports.validateVtxoTxGraph = validateVtxoTxGraph;
|
|
|
22860
23710
|
exports.verifyTapscriptSignatures = verifyTapscriptSignatures;
|
|
22861
23711
|
exports.waitForIncomingFunds = waitForIncomingFunds;
|
|
22862
23712
|
exports.warnAndFilterVtxosForScript = warnAndFilterVtxosForScript;
|
|
22863
|
-
|
|
22864
|
-
//# sourceMappingURL=chunk-
|
|
23713
|
+
exports.withPrevTxs = withPrevTxs;
|
|
23714
|
+
//# sourceMappingURL=chunk-MJUTO3PY.cjs.map
|
|
23715
|
+
//# sourceMappingURL=chunk-MJUTO3PY.cjs.map
|