@arkade-os/sdk 0.4.46 → 0.4.48-rc.0
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/dist/adapters/expo.cjs +5 -5
- package/dist/adapters/expo.d.cts +2 -2
- package/dist/adapters/expo.d.ts +2 -2
- package/dist/adapters/expo.js +3 -3
- package/dist/adapters/indexedDB.cjs +5 -5
- package/dist/adapters/indexedDB.js +4 -4
- package/dist/{ark-C9ognsOV.d.cts → ark-CoJgwTi_.d.cts} +26 -2
- package/dist/{ark-C9ognsOV.d.ts → ark-CoJgwTi_.d.ts} +26 -2
- package/dist/{asyncStorageTaskQueue-CmBYVlxw.d.cts → asyncStorageTaskQueue-CwknfM_j.d.cts} +1 -1
- package/dist/{asyncStorageTaskQueue-BAKZ5cS5.d.ts → asyncStorageTaskQueue-D2Zl7yAB.d.ts} +1 -1
- package/dist/{chunk-SOXGAA52.cjs → chunk-3HUZAIKI.cjs} +14 -14
- package/dist/{chunk-SOXGAA52.cjs.map → chunk-3HUZAIKI.cjs.map} +1 -1
- package/dist/{chunk-R2SVAM5Q.js → chunk-4AIHKC65.js} +3 -3
- package/dist/{chunk-R2SVAM5Q.js.map → chunk-4AIHKC65.js.map} +1 -1
- package/dist/{chunk-FWG4TSPN.js → chunk-C7TXXTMS.js} +4 -5
- package/dist/chunk-C7TXXTMS.js.map +1 -0
- package/dist/{chunk-7IYIFMF4.cjs → chunk-CFQO5MCM.cjs} +94 -20
- package/dist/chunk-CFQO5MCM.cjs.map +1 -0
- package/dist/{chunk-6TQJOD72.cjs → chunk-EA3IWZ4W.cjs} +7 -7
- package/dist/{chunk-6TQJOD72.cjs.map → chunk-EA3IWZ4W.cjs.map} +1 -1
- package/dist/{chunk-CWJ7ZCP7.js → chunk-GM6JRQP5.js} +87 -16
- package/dist/chunk-GM6JRQP5.js.map +1 -0
- package/dist/{chunk-MQB5H4X5.cjs → chunk-L5ND2FJJ.cjs} +4 -5
- package/dist/chunk-L5ND2FJJ.cjs.map +1 -0
- package/dist/{chunk-D46YDM36.cjs → chunk-RJMFTTRJ.cjs} +1586 -286
- package/dist/chunk-RJMFTTRJ.cjs.map +1 -0
- package/dist/chunk-RQSA7ADZ.cjs +2286 -0
- package/dist/chunk-RQSA7ADZ.cjs.map +1 -0
- package/dist/{chunk-P6VBP3CT.js → chunk-SV4PCGKM.js} +1388 -100
- package/dist/chunk-SV4PCGKM.js.map +1 -0
- package/dist/chunk-XN3554FT.js +2244 -0
- package/dist/chunk-XN3554FT.js.map +1 -0
- package/dist/{chunk-JTCQ6QXQ.js → chunk-ZRY2KSK5.js} +4 -4
- package/dist/{chunk-JTCQ6QXQ.js.map → chunk-ZRY2KSK5.js.map} +1 -1
- package/dist/contracts/handlers/index.cjs +11 -7
- package/dist/contracts/handlers/index.d.cts +3 -3
- package/dist/contracts/handlers/index.d.ts +3 -3
- package/dist/contracts/handlers/index.js +2 -2
- package/dist/{delegate-aOd5qINr.d.ts → delegate-CuaDqqQi.d.ts} +1 -1
- package/dist/{delegate-DVEgyRwI.d.cts → delegate-Dl87_zMA.d.cts} +1 -1
- package/dist/index-BC_G0VTh.d.cts +512 -0
- package/dist/index-CKwpZEpw.d.ts +512 -0
- package/dist/index.cjs +221 -161
- package/dist/index.d.cts +3129 -2089
- package/dist/index.d.ts +3129 -2089
- 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-B48-V-Pb.d.ts → taskRunner-Df8YQpn1.d.ts} +1 -1
- package/dist/{taskRunner-nNecmQ2C.d.cts → taskRunner-RYihSj9E.d.cts} +1 -1
- 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 +14 -14
- package/dist/wallet/expo/index.d.cts +4 -4
- package/dist/wallet/expo/index.d.ts +4 -4
- package/dist/wallet/expo/index.js +5 -5
- package/dist/{wallet-BUg3D4WJ.d.cts → wallet-B6s7_5bJ.d.cts} +136 -3
- package/dist/{wallet-DM0oShTu.d.ts → wallet-C61huH8i.d.ts} +136 -3
- package/dist/worker/expo/index.cjs +9 -9
- package/dist/worker/expo/index.d.cts +4 -4
- package/dist/worker/expo/index.d.ts +4 -4
- package/dist/worker/expo/index.js +5 -5
- package/package.json +1 -1
- package/dist/chunk-4KXOCVXP.cjs +0 -973
- package/dist/chunk-4KXOCVXP.cjs.map +0 -1
- package/dist/chunk-7IYIFMF4.cjs.map +0 -1
- package/dist/chunk-CWJ7ZCP7.js.map +0 -1
- package/dist/chunk-D46YDM36.cjs.map +0 -1
- package/dist/chunk-FWG4TSPN.js.map +0 -1
- package/dist/chunk-MQB5H4X5.cjs.map +0 -1
- package/dist/chunk-P6VBP3CT.js.map +0 -1
- package/dist/chunk-QKC2T54O.js +0 -960
- package/dist/chunk-QKC2T54O.js.map +0 -1
- package/dist/index-CPzL4tqg.d.ts +0 -259
- package/dist/index-D8vmtWWO.d.cts +0 -259
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
var
|
|
3
|
+
var chunkCFQO5MCM_cjs = require('./chunk-CFQO5MCM.cjs');
|
|
4
|
+
var chunkRQSA7ADZ_cjs = require('./chunk-RQSA7ADZ.cjs');
|
|
5
|
+
var chunkL5ND2FJJ_cjs = require('./chunk-L5ND2FJJ.cjs');
|
|
6
|
+
var chunk5BLDMQED_cjs = require('./chunk-5BLDMQED.cjs');
|
|
6
7
|
var utils_js = require('@scure/btc-signer/utils.js');
|
|
7
8
|
var btcSigner = require('@scure/btc-signer');
|
|
8
9
|
var base = require('@scure/base');
|
|
@@ -184,7 +185,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
184
185
|
noncesByPubkey.set(base.hex.encode(myPublicKey.subarray(1)), myNonce);
|
|
185
186
|
const tx = this.graph.find(txid);
|
|
186
187
|
if (!tx) throw new Error(`missing tx for txid ${txid}`);
|
|
187
|
-
const cosigners =
|
|
188
|
+
const cosigners = chunkCFQO5MCM_cjs.getArkPsbtFields(tx.root, 0, chunkCFQO5MCM_cjs.CosignerPublicKey).map(
|
|
188
189
|
(c) => base.hex.encode(c.key.subarray(1))
|
|
189
190
|
// xonly pubkey
|
|
190
191
|
);
|
|
@@ -236,7 +237,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
236
237
|
if (!aggNonce) throw new Error("missing aggregate nonce");
|
|
237
238
|
const prevoutAmounts = [];
|
|
238
239
|
const prevoutScripts = [];
|
|
239
|
-
const cosigners =
|
|
240
|
+
const cosigners = chunkCFQO5MCM_cjs.getArkPsbtFields(g.root, 0, chunkCFQO5MCM_cjs.CosignerPublicKey).map((c) => c.key);
|
|
240
241
|
const { finalKey } = aggregateKeys(cosigners, true, {
|
|
241
242
|
taprootTweak: this.scriptRoot
|
|
242
243
|
});
|
|
@@ -415,7 +416,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
415
416
|
let network;
|
|
416
417
|
if ("descriptor" in opts && typeof opts.descriptor === "string") {
|
|
417
418
|
descriptor = opts.descriptor;
|
|
418
|
-
network =
|
|
419
|
+
network = chunkRQSA7ADZ_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
419
420
|
} else {
|
|
420
421
|
network = opts.isMainnet ?? true ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
421
422
|
descriptor = descriptorsScure.scriptExpressions.trBIP32({
|
|
@@ -500,7 +501,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
500
501
|
* `StaticDescriptorProvider` for legacy single-key wallets.
|
|
501
502
|
*/
|
|
502
503
|
isOurs(descriptor) {
|
|
503
|
-
return
|
|
504
|
+
return chunkRQSA7ADZ_cjs.descriptorIsOurs(descriptor, this.descriptor, utils_js.pubSchnorr(this.derivedKey));
|
|
504
505
|
}
|
|
505
506
|
/**
|
|
506
507
|
* Signs each request with the key derived from its descriptor.
|
|
@@ -537,7 +538,7 @@ var SeedIdentity = class _SeedIdentity {
|
|
|
537
538
|
}
|
|
538
539
|
// ── internal helpers ─────────────────────────────────────────────
|
|
539
540
|
derivePrivateKeyForDescriptor(descriptor) {
|
|
540
|
-
const network =
|
|
541
|
+
const network = chunkRQSA7ADZ_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
541
542
|
const expansion = descriptorsScure.expand({ descriptor, network });
|
|
542
543
|
if (expansion.isRanged) {
|
|
543
544
|
throw new Error(
|
|
@@ -623,7 +624,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
|
|
|
623
624
|
*/
|
|
624
625
|
descriptor;
|
|
625
626
|
constructor(descriptor) {
|
|
626
|
-
const network =
|
|
627
|
+
const network = chunkRQSA7ADZ_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
627
628
|
let expansion;
|
|
628
629
|
try {
|
|
629
630
|
expansion = descriptorsScure.expand({ descriptor, network, index: 0 });
|
|
@@ -673,7 +674,7 @@ var ReadonlyDescriptorIdentity = class _ReadonlyDescriptorIdentity {
|
|
|
673
674
|
* `StaticDescriptorProvider` for legacy single-key wallets.
|
|
674
675
|
*/
|
|
675
676
|
isOurs(descriptor) {
|
|
676
|
-
return
|
|
677
|
+
return chunkRQSA7ADZ_cjs.descriptorIsOurs(descriptor, this.descriptor, this.indexZero.pubkey);
|
|
677
678
|
}
|
|
678
679
|
};
|
|
679
680
|
function serializeSeedOwnedSigningIdentity(identity) {
|
|
@@ -985,14 +986,14 @@ var RestDelegateProvider = class {
|
|
|
985
986
|
*/
|
|
986
987
|
async delegate(intent, forfeitTxs, options) {
|
|
987
988
|
const url = `${this.url}/v1/delegate`;
|
|
988
|
-
const response = await
|
|
989
|
+
const response = await chunkCFQO5MCM_cjs.baseFetch(url, {
|
|
989
990
|
method: "POST",
|
|
990
991
|
headers: {
|
|
991
992
|
"Content-Type": "application/json"
|
|
992
993
|
},
|
|
993
994
|
body: JSON.stringify({
|
|
994
995
|
intent: {
|
|
995
|
-
message:
|
|
996
|
+
message: chunkCFQO5MCM_cjs.Intent.encodeMessage(intent.message),
|
|
996
997
|
proof: intent.proof
|
|
997
998
|
},
|
|
998
999
|
forfeit_txs: forfeitTxs,
|
|
@@ -1012,7 +1013,7 @@ var RestDelegateProvider = class {
|
|
|
1012
1013
|
*/
|
|
1013
1014
|
async getDelegateInfo() {
|
|
1014
1015
|
const url = `${this.url}/v1/delegator/info`;
|
|
1015
|
-
const response = await
|
|
1016
|
+
const response = await chunkCFQO5MCM_cjs.baseFetch(url);
|
|
1016
1017
|
if (!response.ok) {
|
|
1017
1018
|
const errorText2 = await response.text();
|
|
1018
1019
|
throw new Error(`Failed to get delegate info: ${errorText2}`);
|
|
@@ -1039,7 +1040,7 @@ var ESPLORA_URL = {
|
|
|
1039
1040
|
regtest: "http://localhost:3000/api"
|
|
1040
1041
|
};
|
|
1041
1042
|
var EsploraProvider = class {
|
|
1042
|
-
constructor(baseUrl = ESPLORA_URL[
|
|
1043
|
+
constructor(baseUrl = ESPLORA_URL[chunkL5ND2FJJ_cjs.DEFAULT_NETWORK_NAME], opts) {
|
|
1043
1044
|
this.baseUrl = baseUrl;
|
|
1044
1045
|
this.pollingInterval = opts?.pollingInterval ?? 15e3;
|
|
1045
1046
|
this.forcePolling = opts?.forcePolling ?? false;
|
|
@@ -1048,14 +1049,14 @@ var EsploraProvider = class {
|
|
|
1048
1049
|
pollingInterval;
|
|
1049
1050
|
forcePolling;
|
|
1050
1051
|
async getCoins(address) {
|
|
1051
|
-
const response = await
|
|
1052
|
+
const response = await chunkCFQO5MCM_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
|
|
1052
1053
|
if (!response.ok) {
|
|
1053
1054
|
throw new Error(`Failed to fetch UTXOs: ${response.statusText}`);
|
|
1054
1055
|
}
|
|
1055
1056
|
return response.json();
|
|
1056
1057
|
}
|
|
1057
1058
|
async getFeeRate() {
|
|
1058
|
-
const response = await
|
|
1059
|
+
const response = await chunkCFQO5MCM_cjs.baseFetch(`${this.baseUrl}/fee-estimates`);
|
|
1059
1060
|
if (response.status === 404) {
|
|
1060
1061
|
return void 0;
|
|
1061
1062
|
}
|
|
@@ -1076,7 +1077,7 @@ var EsploraProvider = class {
|
|
|
1076
1077
|
}
|
|
1077
1078
|
}
|
|
1078
1079
|
async getTxOutspends(txid) {
|
|
1079
|
-
const response = await
|
|
1080
|
+
const response = await chunkCFQO5MCM_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
|
|
1080
1081
|
if (!response.ok) {
|
|
1081
1082
|
const error = await response.text();
|
|
1082
1083
|
throw new Error(`Failed to get transaction outspends: ${error}`);
|
|
@@ -1084,7 +1085,7 @@ var EsploraProvider = class {
|
|
|
1084
1085
|
return response.json();
|
|
1085
1086
|
}
|
|
1086
1087
|
async getTransactions(address) {
|
|
1087
|
-
const response = await
|
|
1088
|
+
const response = await chunkCFQO5MCM_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
|
|
1088
1089
|
if (!response.ok) {
|
|
1089
1090
|
const error = await response.text();
|
|
1090
1091
|
throw new Error(`Failed to get transactions: ${error}`);
|
|
@@ -1092,7 +1093,7 @@ var EsploraProvider = class {
|
|
|
1092
1093
|
return response.json();
|
|
1093
1094
|
}
|
|
1094
1095
|
async getTxStatus(txid) {
|
|
1095
|
-
const txresponse = await
|
|
1096
|
+
const txresponse = await chunkCFQO5MCM_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
|
|
1096
1097
|
if (!txresponse.ok) {
|
|
1097
1098
|
throw new Error(txresponse.statusText);
|
|
1098
1099
|
}
|
|
@@ -1100,7 +1101,7 @@ var EsploraProvider = class {
|
|
|
1100
1101
|
if (!tx.status.confirmed) {
|
|
1101
1102
|
return { confirmed: false };
|
|
1102
1103
|
}
|
|
1103
|
-
const response = await
|
|
1104
|
+
const response = await chunkCFQO5MCM_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
|
|
1104
1105
|
if (!response.ok) {
|
|
1105
1106
|
throw new Error(`Failed to get transaction status: ${response.statusText}`);
|
|
1106
1107
|
}
|
|
@@ -1184,7 +1185,7 @@ var EsploraProvider = class {
|
|
|
1184
1185
|
return stopFunc;
|
|
1185
1186
|
}
|
|
1186
1187
|
async getChainTip() {
|
|
1187
|
-
const tipBlocks = await
|
|
1188
|
+
const tipBlocks = await chunkCFQO5MCM_cjs.baseFetch(`${this.baseUrl}/blocks`);
|
|
1188
1189
|
if (!tipBlocks.ok) {
|
|
1189
1190
|
throw new Error(`Failed to get chain tip: ${tipBlocks.statusText}`);
|
|
1190
1191
|
}
|
|
@@ -1203,7 +1204,7 @@ var EsploraProvider = class {
|
|
|
1203
1204
|
};
|
|
1204
1205
|
}
|
|
1205
1206
|
async broadcastPackage(parent, child) {
|
|
1206
|
-
const response = await
|
|
1207
|
+
const response = await chunkCFQO5MCM_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
|
|
1207
1208
|
method: "POST",
|
|
1208
1209
|
headers: {
|
|
1209
1210
|
"Content-Type": "application/json"
|
|
@@ -1217,7 +1218,7 @@ var EsploraProvider = class {
|
|
|
1217
1218
|
return response.json();
|
|
1218
1219
|
}
|
|
1219
1220
|
async broadcastTx(tx) {
|
|
1220
|
-
const response = await
|
|
1221
|
+
const response = await chunkCFQO5MCM_cjs.baseFetch(`${this.baseUrl}/tx`, {
|
|
1221
1222
|
method: "POST",
|
|
1222
1223
|
headers: {
|
|
1223
1224
|
"Content-Type": "text/plain"
|
|
@@ -1379,7 +1380,7 @@ function findP2AOutput(tx) {
|
|
|
1379
1380
|
var CHILD_DUST_AMOUNT = 546;
|
|
1380
1381
|
function buildAnchorChild(params) {
|
|
1381
1382
|
const { parent, feeRate, fundingCoins, changeAddress, tapInternalKey, network } = params;
|
|
1382
|
-
const child = new
|
|
1383
|
+
const child = new chunkCFQO5MCM_cjs.Transaction({ version: 3, allowLegacyWitnessUtxo: true });
|
|
1383
1384
|
child.addInput(findP2AOutput(parent));
|
|
1384
1385
|
const estimator = TxWeightEstimator.create().addP2AInput();
|
|
1385
1386
|
for (const _ of fundingCoins) {
|
|
@@ -1427,7 +1428,7 @@ function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
|
|
|
1427
1428
|
);
|
|
1428
1429
|
}
|
|
1429
1430
|
function buildForfeitTxWithOutput(inputs, output, txLocktime) {
|
|
1430
|
-
const tx = new
|
|
1431
|
+
const tx = new chunkCFQO5MCM_cjs.Transaction({
|
|
1431
1432
|
version: 3,
|
|
1432
1433
|
lockTime: txLocktime
|
|
1433
1434
|
});
|
|
@@ -1503,7 +1504,7 @@ function validateVtxoTxGraph(graph, roundTransaction, sweepTapTreeRoot) {
|
|
|
1503
1504
|
if (previousScriptKey.length !== 32) {
|
|
1504
1505
|
throw new Error(`parent output ${childIndex} has invalid script`);
|
|
1505
1506
|
}
|
|
1506
|
-
const cosigners =
|
|
1507
|
+
const cosigners = chunkCFQO5MCM_cjs.getArkPsbtFields(child.root, 0, chunkCFQO5MCM_cjs.CosignerPublicKey);
|
|
1507
1508
|
if (cosigners.length === 0) {
|
|
1508
1509
|
throw ErrMissingCosignersPublicKeys;
|
|
1509
1510
|
}
|
|
@@ -1534,6 +1535,62 @@ var UnknownPacket = class {
|
|
|
1534
1535
|
}
|
|
1535
1536
|
};
|
|
1536
1537
|
|
|
1538
|
+
// src/extension/emulator/packet.ts
|
|
1539
|
+
var EmulatorPacket = class _EmulatorPacket {
|
|
1540
|
+
constructor(entries) {
|
|
1541
|
+
this.entries = entries;
|
|
1542
|
+
}
|
|
1543
|
+
entries;
|
|
1544
|
+
/** PACKET_TYPE is the 1-byte TLV type tag used in the Extension envelope. */
|
|
1545
|
+
static PACKET_TYPE = 1;
|
|
1546
|
+
static create(entries) {
|
|
1547
|
+
if (entries.length === 0) {
|
|
1548
|
+
throw new Error("empty emulator packet");
|
|
1549
|
+
}
|
|
1550
|
+
for (const entry of entries) {
|
|
1551
|
+
if (entry.script.length === 0) {
|
|
1552
|
+
throw new Error(`empty script for vin ${entry.vin}`);
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1556
|
+
for (const entry of entries) {
|
|
1557
|
+
if (seen.has(entry.vin)) {
|
|
1558
|
+
throw new Error(`duplicate vin ${entry.vin}`);
|
|
1559
|
+
}
|
|
1560
|
+
seen.add(entry.vin);
|
|
1561
|
+
}
|
|
1562
|
+
return new _EmulatorPacket(entries);
|
|
1563
|
+
}
|
|
1564
|
+
static fromBytes(data) {
|
|
1565
|
+
const reader = new chunkCFQO5MCM_cjs.BufferReader(data);
|
|
1566
|
+
const entryCount = reader.readCompactSize();
|
|
1567
|
+
const entries = [];
|
|
1568
|
+
for (let i = 0; i < entryCount; i++) {
|
|
1569
|
+
const vin = reader.readUint16LE();
|
|
1570
|
+
const script = reader.readCompactSlice();
|
|
1571
|
+
const witness = reader.readCompactSlice();
|
|
1572
|
+
entries.push({ vin, script, witness });
|
|
1573
|
+
}
|
|
1574
|
+
if (reader.remaining() > 0) {
|
|
1575
|
+
throw new Error(`unexpected ${reader.remaining()} trailing bytes`);
|
|
1576
|
+
}
|
|
1577
|
+
return _EmulatorPacket.create(entries);
|
|
1578
|
+
}
|
|
1579
|
+
type() {
|
|
1580
|
+
return _EmulatorPacket.PACKET_TYPE;
|
|
1581
|
+
}
|
|
1582
|
+
serialize() {
|
|
1583
|
+
const writer = new chunkCFQO5MCM_cjs.BufferWriter();
|
|
1584
|
+
writer.writeCompactSize(this.entries.length);
|
|
1585
|
+
for (const entry of this.entries) {
|
|
1586
|
+
writer.writeUint16LE(entry.vin);
|
|
1587
|
+
writer.writeCompactSlice(entry.script);
|
|
1588
|
+
writer.writeCompactSlice(entry.witness ?? new Uint8Array(0));
|
|
1589
|
+
}
|
|
1590
|
+
return writer.toBytes();
|
|
1591
|
+
}
|
|
1592
|
+
};
|
|
1593
|
+
|
|
1537
1594
|
// src/extension/index.ts
|
|
1538
1595
|
var ARKADE_MAGIC = new Uint8Array([65, 82, 75]);
|
|
1539
1596
|
var ExtensionNotFoundError = class extends Error {
|
|
@@ -1553,10 +1610,14 @@ var Extension = class _Extension {
|
|
|
1553
1610
|
}
|
|
1554
1611
|
const seen = /* @__PURE__ */ new Set();
|
|
1555
1612
|
for (const p of packets) {
|
|
1556
|
-
|
|
1557
|
-
|
|
1613
|
+
const type = p.type();
|
|
1614
|
+
if (!Number.isInteger(type) || type < 0 || type > 255) {
|
|
1615
|
+
throw new Error(`invalid packet type ${type}: must be an integer in [0, 255]`);
|
|
1558
1616
|
}
|
|
1559
|
-
seen.
|
|
1617
|
+
if (seen.has(type)) {
|
|
1618
|
+
throw new Error(`duplicate packet type ${type}`);
|
|
1619
|
+
}
|
|
1620
|
+
seen.add(type);
|
|
1560
1621
|
}
|
|
1561
1622
|
return new _Extension(packets);
|
|
1562
1623
|
}
|
|
@@ -1606,7 +1667,7 @@ var Extension = class _Extension {
|
|
|
1606
1667
|
`expected magic prefix ${base.hex.encode(ARKADE_MAGIC)}, got ${base.hex.encode(payload.slice(0, Math.min(payload.length, ARKADE_MAGIC.length)))}`
|
|
1607
1668
|
);
|
|
1608
1669
|
}
|
|
1609
|
-
const reader = new
|
|
1670
|
+
const reader = new chunkCFQO5MCM_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
|
|
1610
1671
|
const packets = [];
|
|
1611
1672
|
while (reader.remaining() > 0) {
|
|
1612
1673
|
const packetType = reader.readByte();
|
|
@@ -1680,18 +1741,51 @@ var Extension = class _Extension {
|
|
|
1680
1741
|
*/
|
|
1681
1742
|
getAssetPacket() {
|
|
1682
1743
|
for (const p of this.packets) {
|
|
1683
|
-
if (p instanceof
|
|
1744
|
+
if (p instanceof chunkCFQO5MCM_cjs.Packet) {
|
|
1745
|
+
return p;
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
1748
|
+
return null;
|
|
1749
|
+
}
|
|
1750
|
+
/**
|
|
1751
|
+
* getEmulatorPacket returns the embedded EmulatorPacket, or null if not present.
|
|
1752
|
+
*/
|
|
1753
|
+
getEmulatorPacket() {
|
|
1754
|
+
for (const p of this.packets) {
|
|
1755
|
+
if (p instanceof EmulatorPacket) {
|
|
1756
|
+
return p;
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
return null;
|
|
1760
|
+
}
|
|
1761
|
+
/**
|
|
1762
|
+
* getPacketByType returns the first packet matching the given type tag, or null.
|
|
1763
|
+
*/
|
|
1764
|
+
getPacketByType(packetType) {
|
|
1765
|
+
for (const p of this.packets) {
|
|
1766
|
+
if (p.type() === packetType) {
|
|
1684
1767
|
return p;
|
|
1685
1768
|
}
|
|
1686
1769
|
}
|
|
1687
1770
|
return null;
|
|
1688
1771
|
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Returns all embedded packets in insertion order. Used when callers need
|
|
1774
|
+
* to rebuild an Extension from an existing one (e.g. appending a new packet).
|
|
1775
|
+
*/
|
|
1776
|
+
getPackets() {
|
|
1777
|
+
return this.packets;
|
|
1778
|
+
}
|
|
1689
1779
|
};
|
|
1690
1780
|
function parsePacket(packetType, data) {
|
|
1691
|
-
|
|
1692
|
-
|
|
1781
|
+
switch (packetType) {
|
|
1782
|
+
case chunkCFQO5MCM_cjs.Packet.PACKET_TYPE:
|
|
1783
|
+
return chunkCFQO5MCM_cjs.Packet.fromBytes(data);
|
|
1784
|
+
case EmulatorPacket.PACKET_TYPE:
|
|
1785
|
+
return EmulatorPacket.fromBytes(data);
|
|
1786
|
+
default:
|
|
1787
|
+
return new UnknownPacket(packetType, data);
|
|
1693
1788
|
}
|
|
1694
|
-
return new UnknownPacket(packetType, data);
|
|
1695
1789
|
}
|
|
1696
1790
|
function encodeVarUint(value) {
|
|
1697
1791
|
const bytes = [];
|
|
@@ -1747,7 +1841,7 @@ function validateBatchRecipients(commitmentTx, vtxoTreeLeaves, recipients, netwo
|
|
|
1747
1841
|
for (const recipient of recipients) {
|
|
1748
1842
|
let arkAddress;
|
|
1749
1843
|
try {
|
|
1750
|
-
arkAddress =
|
|
1844
|
+
arkAddress = chunkL5ND2FJJ_cjs.ArkAddress.decode(recipient.address);
|
|
1751
1845
|
} catch {
|
|
1752
1846
|
validateOnchainRecipient(commitmentTx, recipient, network, usedOnchainOutputs);
|
|
1753
1847
|
continue;
|
|
@@ -1997,7 +2091,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
1997
2091
|
const existing = inputsByAssetId.get(asset.assetId);
|
|
1998
2092
|
inputsByAssetId.set(asset.assetId, [
|
|
1999
2093
|
...existing ?? [],
|
|
2000
|
-
|
|
2094
|
+
chunkCFQO5MCM_cjs.AssetInput.create(inputIndex, asset.amount)
|
|
2001
2095
|
]);
|
|
2002
2096
|
}
|
|
2003
2097
|
}
|
|
@@ -2009,7 +2103,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
2009
2103
|
const existing = outputsByAssetId.get(asset.assetId);
|
|
2010
2104
|
outputsByAssetId.set(asset.assetId, [
|
|
2011
2105
|
...existing ?? [],
|
|
2012
|
-
|
|
2106
|
+
chunkCFQO5MCM_cjs.AssetOutput.create(outputIndex, asset.amount)
|
|
2013
2107
|
]);
|
|
2014
2108
|
}
|
|
2015
2109
|
}
|
|
@@ -2020,7 +2114,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
2020
2114
|
const existing = outputsByAssetId.get(asset.assetId);
|
|
2021
2115
|
outputsByAssetId.set(asset.assetId, [
|
|
2022
2116
|
...existing ?? [],
|
|
2023
|
-
|
|
2117
|
+
chunkCFQO5MCM_cjs.AssetOutput.create(outputIndex, asset.amount)
|
|
2024
2118
|
]);
|
|
2025
2119
|
}
|
|
2026
2120
|
}
|
|
@@ -2029,11 +2123,11 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
2029
2123
|
for (const assetIdStr of allAssetIds) {
|
|
2030
2124
|
const inputs = inputsByAssetId.get(assetIdStr);
|
|
2031
2125
|
const outputs = outputsByAssetId.get(assetIdStr);
|
|
2032
|
-
const assetId =
|
|
2033
|
-
const group =
|
|
2126
|
+
const assetId = chunkCFQO5MCM_cjs.AssetId.fromString(assetIdStr);
|
|
2127
|
+
const group = chunkCFQO5MCM_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
|
|
2034
2128
|
groups.push(group);
|
|
2035
2129
|
}
|
|
2036
|
-
return
|
|
2130
|
+
return chunkCFQO5MCM_cjs.Packet.create(groups);
|
|
2037
2131
|
}
|
|
2038
2132
|
function selectCoinsWithAsset(coins, assetId, requiredAmount) {
|
|
2039
2133
|
const coinsWithAsset = coins.filter((coin) => coin.assets?.some((a) => a.assetId === assetId));
|
|
@@ -2138,8 +2232,8 @@ function buildOffchainTx(inputs, outputs, serverUnrollScript) {
|
|
|
2138
2232
|
function buildVirtualTx(inputs, outputs) {
|
|
2139
2233
|
let lockTime = 0n;
|
|
2140
2234
|
for (const input of inputs) {
|
|
2141
|
-
const tapscript =
|
|
2142
|
-
if (
|
|
2235
|
+
const tapscript = chunkL5ND2FJJ_cjs.decodeTapscript(chunkL5ND2FJJ_cjs.scriptFromTapLeafScript(input.tapLeafScript));
|
|
2236
|
+
if (chunkL5ND2FJJ_cjs.CLTVMultisigTapscript.is(tapscript)) {
|
|
2143
2237
|
if (lockTime !== 0n) {
|
|
2144
2238
|
if (isSeconds(lockTime) !== isSeconds(tapscript.params.absoluteTimelock)) {
|
|
2145
2239
|
throw new Error("cannot mix seconds and blocks locktime");
|
|
@@ -2150,7 +2244,7 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
2150
2244
|
}
|
|
2151
2245
|
}
|
|
2152
2246
|
}
|
|
2153
|
-
const tx = new
|
|
2247
|
+
const tx = new chunkCFQO5MCM_cjs.Transaction({
|
|
2154
2248
|
version: 3,
|
|
2155
2249
|
lockTime: Number(lockTime)
|
|
2156
2250
|
});
|
|
@@ -2160,12 +2254,12 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
2160
2254
|
index: input.vout,
|
|
2161
2255
|
sequence: lockTime ? btcSigner.DEFAULT_SEQUENCE - 1 : void 0,
|
|
2162
2256
|
witnessUtxo: {
|
|
2163
|
-
script:
|
|
2257
|
+
script: chunkL5ND2FJJ_cjs.VtxoScript.decode(input.tapTree).pkScript,
|
|
2164
2258
|
amount: BigInt(input.value)
|
|
2165
2259
|
},
|
|
2166
2260
|
tapLeafScript: [input.tapLeafScript]
|
|
2167
2261
|
});
|
|
2168
|
-
|
|
2262
|
+
chunkCFQO5MCM_cjs.setArkPsbtField(tx, i, chunkCFQO5MCM_cjs.VtxoTaprootTree, input.tapTree);
|
|
2169
2263
|
}
|
|
2170
2264
|
for (const output of outputs) {
|
|
2171
2265
|
tx.addOutput(output);
|
|
@@ -2174,8 +2268,8 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
2174
2268
|
return tx;
|
|
2175
2269
|
}
|
|
2176
2270
|
function buildCheckpointTx(vtxo, serverUnrollScript) {
|
|
2177
|
-
const collaborativeClosure =
|
|
2178
|
-
const checkpointVtxoScript = new
|
|
2271
|
+
const collaborativeClosure = chunkL5ND2FJJ_cjs.decodeTapscript(chunkL5ND2FJJ_cjs.scriptFromTapLeafScript(vtxo.tapLeafScript));
|
|
2272
|
+
const checkpointVtxoScript = new chunkL5ND2FJJ_cjs.VtxoScript([
|
|
2179
2273
|
serverUnrollScript.script,
|
|
2180
2274
|
collaborativeClosure.script
|
|
2181
2275
|
]);
|
|
@@ -2319,12 +2413,61 @@ function combineTapscriptSigs(signedTx, originalTx) {
|
|
|
2319
2413
|
}
|
|
2320
2414
|
function isValidArkAddress(address) {
|
|
2321
2415
|
try {
|
|
2322
|
-
|
|
2416
|
+
chunkL5ND2FJJ_cjs.ArkAddress.decode(address);
|
|
2323
2417
|
return true;
|
|
2324
2418
|
} catch (e) {
|
|
2325
2419
|
return false;
|
|
2326
2420
|
}
|
|
2327
2421
|
}
|
|
2422
|
+
async function submitOffchainTx(provider, offchainTx, signer, hooks) {
|
|
2423
|
+
const { arkTx: signedArkTx, userSignedCheckpoints } = await signer.signArkTx(
|
|
2424
|
+
offchainTx.arkTx,
|
|
2425
|
+
offchainTx.checkpoints
|
|
2426
|
+
);
|
|
2427
|
+
if (userSignedCheckpoints && userSignedCheckpoints.length !== offchainTx.checkpoints.length) {
|
|
2428
|
+
throw new Error(
|
|
2429
|
+
`signer returned ${userSignedCheckpoints.length} signed checkpoints, expected ${offchainTx.checkpoints.length}`
|
|
2430
|
+
);
|
|
2431
|
+
}
|
|
2432
|
+
await hooks?.beforeSubmit?.();
|
|
2433
|
+
const { arkTxid, signedCheckpointTxs } = await provider.submitTx(
|
|
2434
|
+
base.base64.encode(signedArkTx.toPSBT()),
|
|
2435
|
+
offchainTx.checkpoints.map((c) => base.base64.encode(c.toPSBT()))
|
|
2436
|
+
);
|
|
2437
|
+
if (signedCheckpointTxs.length !== offchainTx.checkpoints.length) {
|
|
2438
|
+
throw new Error(
|
|
2439
|
+
`submitTx returned ${signedCheckpointTxs.length} checkpoints, expected ${offchainTx.checkpoints.length}`
|
|
2440
|
+
);
|
|
2441
|
+
}
|
|
2442
|
+
let finalCheckpoints;
|
|
2443
|
+
if (userSignedCheckpoints) {
|
|
2444
|
+
finalCheckpoints = signedCheckpointTxs.map((c, i) => {
|
|
2445
|
+
const serverSigned = chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(c));
|
|
2446
|
+
combineTapscriptSigs(userSignedCheckpoints[i], serverSigned);
|
|
2447
|
+
return base.base64.encode(serverSigned.toPSBT());
|
|
2448
|
+
});
|
|
2449
|
+
} else {
|
|
2450
|
+
finalCheckpoints = await Promise.all(
|
|
2451
|
+
signedCheckpointTxs.map(async (c) => {
|
|
2452
|
+
const tx = chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(c));
|
|
2453
|
+
const signed = await signer.signCheckpoint(tx);
|
|
2454
|
+
return base.base64.encode(signed.toPSBT());
|
|
2455
|
+
})
|
|
2456
|
+
);
|
|
2457
|
+
}
|
|
2458
|
+
await provider.finalizeTx(arkTxid, finalCheckpoints);
|
|
2459
|
+
await hooks?.afterFinalize?.();
|
|
2460
|
+
return { arkTxid, signedCheckpointTxs };
|
|
2461
|
+
}
|
|
2462
|
+
async function signAndSubmitOffchainTx(params) {
|
|
2463
|
+
const offchainTx = buildOffchainTx(params.inputs, params.outputs, params.serverUnrollScript);
|
|
2464
|
+
const signer = {
|
|
2465
|
+
signArkTx: async (arkTx) => ({ arkTx: await params.identity.sign(arkTx) }),
|
|
2466
|
+
signCheckpoint: (checkpoint) => params.identity.sign(checkpoint)
|
|
2467
|
+
};
|
|
2468
|
+
const { arkTxid } = await submitOffchainTx(params.provider, offchainTx, signer);
|
|
2469
|
+
return arkTxid;
|
|
2470
|
+
}
|
|
2328
2471
|
var AmountVariableName = "amount";
|
|
2329
2472
|
var ExpiryVariableName = "expiry";
|
|
2330
2473
|
var BirthVariableName = "birth";
|
|
@@ -2480,6 +2623,14 @@ function parseProgram(text, env) {
|
|
|
2480
2623
|
}
|
|
2481
2624
|
return { program, text };
|
|
2482
2625
|
}
|
|
2626
|
+
|
|
2627
|
+
// src/contracts/types.ts
|
|
2628
|
+
function isDiscoverable(handler) {
|
|
2629
|
+
return !!handler && typeof handler.discoverAt === "function";
|
|
2630
|
+
}
|
|
2631
|
+
function isTapscriptDeriving(handler) {
|
|
2632
|
+
return !!handler && typeof handler.deriveTapscripts === "function";
|
|
2633
|
+
}
|
|
2483
2634
|
var DUST_AMOUNT = 546;
|
|
2484
2635
|
var FALLBACK_WALLET_DUST_AMOUNT = 330n;
|
|
2485
2636
|
function getDustAmount(wallet) {
|
|
@@ -2494,15 +2645,19 @@ function extendCoinWithTapscript(boardingTapscript, utxo) {
|
|
|
2494
2645
|
};
|
|
2495
2646
|
}
|
|
2496
2647
|
function deriveContractTapscripts(contract) {
|
|
2497
|
-
const handler =
|
|
2648
|
+
const handler = chunkRQSA7ADZ_cjs.contractHandlers.get(contract.type);
|
|
2498
2649
|
if (!handler) {
|
|
2499
2650
|
throw new Error(`No handler for contract type '${contract.type}'`);
|
|
2500
2651
|
}
|
|
2501
2652
|
const script = handler.createScript(contract.params);
|
|
2653
|
+
if (isTapscriptDeriving(handler)) {
|
|
2654
|
+
return handler.deriveTapscripts(script, contract);
|
|
2655
|
+
}
|
|
2656
|
+
const legacy = script;
|
|
2502
2657
|
return {
|
|
2503
|
-
forfeitTapLeafScript:
|
|
2504
|
-
intentTapLeafScript:
|
|
2505
|
-
tapTree:
|
|
2658
|
+
forfeitTapLeafScript: legacy.forfeit(),
|
|
2659
|
+
intentTapLeafScript: legacy.forfeit(),
|
|
2660
|
+
tapTree: legacy.encode()
|
|
2506
2661
|
};
|
|
2507
2662
|
}
|
|
2508
2663
|
function cloneTapLeafScript([
|
|
@@ -2564,7 +2719,7 @@ function validateRecipients(recipients, dustAmount) {
|
|
|
2564
2719
|
for (const recipient of recipients) {
|
|
2565
2720
|
let address;
|
|
2566
2721
|
try {
|
|
2567
|
-
address =
|
|
2722
|
+
address = chunkL5ND2FJJ_cjs.ArkAddress.decode(recipient.address);
|
|
2568
2723
|
} catch (e) {
|
|
2569
2724
|
throw new Error(`Invalid Arkade address: ${recipient.address}`);
|
|
2570
2725
|
}
|
|
@@ -2620,6 +2775,7 @@ async function runWithCrossInstanceLock(name, fn) {
|
|
|
2620
2775
|
});
|
|
2621
2776
|
}
|
|
2622
2777
|
var MAX_VTXOS_PER_SETTLEMENT = 50;
|
|
2778
|
+
var MAX_INPUTS_PER_INTENT = 20;
|
|
2623
2779
|
function byValueDescending(vtxos) {
|
|
2624
2780
|
return [...vtxos].sort((a, b) => b.value - a.value);
|
|
2625
2781
|
}
|
|
@@ -3171,11 +3327,11 @@ var VtxoManager = class _VtxoManager {
|
|
|
3171
3327
|
`Sweep not economical: output ${outputAmount} sats after ${fee} sats fee is below dust (${dustAmount} sats)`
|
|
3172
3328
|
);
|
|
3173
3329
|
}
|
|
3174
|
-
const tx = new
|
|
3330
|
+
const tx = new chunkCFQO5MCM_cjs.Transaction();
|
|
3175
3331
|
for (const utxo of expiredUtxos) {
|
|
3176
|
-
const utxoScript =
|
|
3332
|
+
const utxoScript = chunkL5ND2FJJ_cjs.VtxoScript.decode(utxo.tapTree);
|
|
3177
3333
|
const utxoExitLeaf = utxoScript.leaves.find(
|
|
3178
|
-
(leaf) =>
|
|
3334
|
+
(leaf) => chunkL5ND2FJJ_cjs.CSVMultisigTapscript.isScriptValid(chunkL5ND2FJJ_cjs.scriptFromTapLeafScript(leaf)) === true
|
|
3179
3335
|
);
|
|
3180
3336
|
if (!utxoExitLeaf) {
|
|
3181
3337
|
throw new Error(
|
|
@@ -3190,7 +3346,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
3190
3346
|
amount: BigInt(utxo.value)
|
|
3191
3347
|
},
|
|
3192
3348
|
tapLeafScript: [utxoExitLeaf],
|
|
3193
|
-
sequence:
|
|
3349
|
+
sequence: chunkL5ND2FJJ_cjs.getSequence(utxoExitLeaf)
|
|
3194
3350
|
});
|
|
3195
3351
|
}
|
|
3196
3352
|
tx.addOutputAddress(boardingAddress, outputAmount, this.getNetwork());
|
|
@@ -3679,7 +3835,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
3679
3835
|
/** Decodes the boarding tapscript exit path to extract the CSV timelock. */
|
|
3680
3836
|
getBoardingTimelock() {
|
|
3681
3837
|
const wallet = this.getSweepWallet();
|
|
3682
|
-
const exitScript =
|
|
3838
|
+
const exitScript = chunkL5ND2FJJ_cjs.CSVMultisigTapscript.decode(
|
|
3683
3839
|
base.hex.decode(wallet.boardingTapscript.exitScript)
|
|
3684
3840
|
);
|
|
3685
3841
|
return exitScript.params.timelock;
|
|
@@ -3810,8 +3966,8 @@ var VtxoManager = class _VtxoManager {
|
|
|
3810
3966
|
* or doesn't carry the metadata.
|
|
3811
3967
|
*/
|
|
3812
3968
|
extractSpentOutpoint(error) {
|
|
3813
|
-
const ark =
|
|
3814
|
-
if (!
|
|
3969
|
+
const ark = chunkCFQO5MCM_cjs.maybeArkError(error);
|
|
3970
|
+
if (!chunkCFQO5MCM_cjs.isArkError(ark, chunkCFQO5MCM_cjs.ArkErrorName.VTXO_ALREADY_SPENT)) return void 0;
|
|
3815
3971
|
const raw = ark.metadata?.vtxo_outpoint;
|
|
3816
3972
|
if (typeof raw !== "string") return void 0;
|
|
3817
3973
|
const [txid, voutStr] = raw.split(":");
|
|
@@ -4025,7 +4181,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
4025
4181
|
const arkAddress = await this.wallet.getAddress();
|
|
4026
4182
|
const outputFee = estimator.evalOffchainOutput({
|
|
4027
4183
|
amount: totalAmount,
|
|
4028
|
-
script: base.hex.encode(
|
|
4184
|
+
script: base.hex.encode(chunkL5ND2FJJ_cjs.ArkAddress.decode(arkAddress).pkScript)
|
|
4029
4185
|
});
|
|
4030
4186
|
totalAmount -= BigInt(outputFee.satoshis);
|
|
4031
4187
|
if (totalAmount < dustAmount) return;
|
|
@@ -4105,7 +4261,7 @@ var ArkNote = class _ArkNote {
|
|
|
4105
4261
|
this.value = value;
|
|
4106
4262
|
this.HRP = HRP;
|
|
4107
4263
|
const preimageHash = utils_js.sha256(this.preimage);
|
|
4108
|
-
this.vtxoScript = new
|
|
4264
|
+
this.vtxoScript = new chunkL5ND2FJJ_cjs.VtxoScript([noteTapscript(preimageHash)]);
|
|
4109
4265
|
const leaf = this.vtxoScript.leaves[0];
|
|
4110
4266
|
this.txid = base.hex.encode(new Uint8Array(preimageHash).reverse());
|
|
4111
4267
|
this.tapTree = this.vtxoScript.encode();
|
|
@@ -4209,6 +4365,96 @@ function readUInt32BE(array, offset) {
|
|
|
4209
4365
|
function noteTapscript(preimageHash) {
|
|
4210
4366
|
return btcSigner.Script.encode(["SHA256", preimageHash, "EQUAL"]);
|
|
4211
4367
|
}
|
|
4368
|
+
var ArkCash = class _ArkCash {
|
|
4369
|
+
constructor(privateKey, serverPubKey, csvTimelock, hrp = _ArkCash.DefaultHRP) {
|
|
4370
|
+
this.csvTimelock = csvTimelock;
|
|
4371
|
+
this.hrp = hrp;
|
|
4372
|
+
if (privateKey.length !== 32) {
|
|
4373
|
+
throw new Error(
|
|
4374
|
+
`Invalid private key length: expected 32 bytes, got ${privateKey.length}`
|
|
4375
|
+
);
|
|
4376
|
+
}
|
|
4377
|
+
if (serverPubKey.length !== 32) {
|
|
4378
|
+
throw new Error(
|
|
4379
|
+
`Invalid server public key length: expected 32 bytes, got ${serverPubKey.length}`
|
|
4380
|
+
);
|
|
4381
|
+
}
|
|
4382
|
+
this._privateKey = privateKey.slice();
|
|
4383
|
+
this._serverPubKey = serverPubKey.slice();
|
|
4384
|
+
this._publicKey = utils_js.pubSchnorr(this._privateKey);
|
|
4385
|
+
}
|
|
4386
|
+
csvTimelock;
|
|
4387
|
+
hrp;
|
|
4388
|
+
static DefaultHRP = "arkcash";
|
|
4389
|
+
static Version = 0;
|
|
4390
|
+
static PayloadLength = 1 + 32 + 32 + 4;
|
|
4391
|
+
// 69 bytes
|
|
4392
|
+
// Keys are held as private copies so a caller mutating the array it passed
|
|
4393
|
+
// in — or one it reads back from a getter — cannot alter this note's
|
|
4394
|
+
// identity or the outputs derived from it.
|
|
4395
|
+
_privateKey;
|
|
4396
|
+
_serverPubKey;
|
|
4397
|
+
_publicKey;
|
|
4398
|
+
/** The note's private key. Returns a fresh copy; mutating it is a no-op. */
|
|
4399
|
+
get privateKey() {
|
|
4400
|
+
return this._privateKey.slice();
|
|
4401
|
+
}
|
|
4402
|
+
/** The server's public key. Returns a fresh copy; mutating it is a no-op. */
|
|
4403
|
+
get serverPubKey() {
|
|
4404
|
+
return this._serverPubKey.slice();
|
|
4405
|
+
}
|
|
4406
|
+
/** The note's public key. Returns a fresh copy; mutating it is a no-op. */
|
|
4407
|
+
get publicKey() {
|
|
4408
|
+
return this._publicKey.slice();
|
|
4409
|
+
}
|
|
4410
|
+
static generate(serverPubKey, csvTimelock, hrp) {
|
|
4411
|
+
return new _ArkCash(utils_js.randomPrivateKeyBytes(), serverPubKey, csvTimelock, hrp);
|
|
4412
|
+
}
|
|
4413
|
+
static fromString(encoded) {
|
|
4414
|
+
const decoded = base.bech32m.decodeUnsafe(encoded.trim().toLowerCase(), 1023);
|
|
4415
|
+
if (!decoded) {
|
|
4416
|
+
throw new Error("Invalid arkcash string: failed to decode bech32m");
|
|
4417
|
+
}
|
|
4418
|
+
const data = new Uint8Array(base.bech32m.fromWords(decoded.words));
|
|
4419
|
+
if (data.length !== _ArkCash.PayloadLength) {
|
|
4420
|
+
throw new Error(
|
|
4421
|
+
`Invalid arkcash data length: expected ${_ArkCash.PayloadLength} bytes, got ${data.length}`
|
|
4422
|
+
);
|
|
4423
|
+
}
|
|
4424
|
+
const version = data[0];
|
|
4425
|
+
if (version !== _ArkCash.Version) {
|
|
4426
|
+
throw new Error(`Unsupported arkcash version: ${version}`);
|
|
4427
|
+
}
|
|
4428
|
+
const privateKey = data.slice(1, 33);
|
|
4429
|
+
const serverPubKey = data.slice(33, 65);
|
|
4430
|
+
const sequence = new DataView(data.buffer, data.byteOffset + 65, 4).getUint32(0, false);
|
|
4431
|
+
const csvTimelock = chunkL5ND2FJJ_cjs.sequenceToTimelock(sequence);
|
|
4432
|
+
return new _ArkCash(privateKey, serverPubKey, csvTimelock, decoded.prefix);
|
|
4433
|
+
}
|
|
4434
|
+
toString() {
|
|
4435
|
+
const data = new Uint8Array(_ArkCash.PayloadLength);
|
|
4436
|
+
data[0] = _ArkCash.Version;
|
|
4437
|
+
data.set(this._privateKey, 1);
|
|
4438
|
+
data.set(this._serverPubKey, 33);
|
|
4439
|
+
const sequence = chunkL5ND2FJJ_cjs.timelockToSequence(this.csvTimelock);
|
|
4440
|
+
new DataView(data.buffer, data.byteOffset + 65, 4).setUint32(0, sequence, false);
|
|
4441
|
+
const words = base.bech32m.toWords(data);
|
|
4442
|
+
return base.bech32m.encode(this.hrp, words, 1023);
|
|
4443
|
+
}
|
|
4444
|
+
get identity() {
|
|
4445
|
+
return SingleKey.fromPrivateKey(this._privateKey);
|
|
4446
|
+
}
|
|
4447
|
+
get vtxoScript() {
|
|
4448
|
+
return new chunkRQSA7ADZ_cjs.DefaultVtxo.Script({
|
|
4449
|
+
pubKey: this._publicKey,
|
|
4450
|
+
serverPubKey: this._serverPubKey,
|
|
4451
|
+
csvTimelock: this.csvTimelock
|
|
4452
|
+
});
|
|
4453
|
+
}
|
|
4454
|
+
address(addressHrp) {
|
|
4455
|
+
return this.vtxoScript.address(addressHrp, this._serverPubKey);
|
|
4456
|
+
}
|
|
4457
|
+
};
|
|
4212
4458
|
|
|
4213
4459
|
// src/repositories/intentRepository.ts
|
|
4214
4460
|
var ALL_INTENT_STATES = [
|
|
@@ -4460,7 +4706,7 @@ async function captureExitBranch(params) {
|
|
|
4460
4706
|
const nonCommitment = ordered.filter((c) => chainTxTypeToChainedExit(c.type) !== 1 /* Commitment */).map((c) => c.txid);
|
|
4461
4707
|
if (nonCommitment.length > 0) {
|
|
4462
4708
|
for (const psbt of await resolver.getVirtualTxs(nonCommitment)) {
|
|
4463
|
-
psbtByTxid.set(
|
|
4709
|
+
psbtByTxid.set(chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
4464
4710
|
}
|
|
4465
4711
|
}
|
|
4466
4712
|
}
|
|
@@ -4503,10 +4749,10 @@ var IndexerExitDataSource = class {
|
|
|
4503
4749
|
while (hasMore) {
|
|
4504
4750
|
const { chain: page, page: meta } = await this.indexer.getVtxoChain(
|
|
4505
4751
|
{ txid: vtxo.txid, vout: vtxo.vout },
|
|
4506
|
-
{ pageIndex, pageSize:
|
|
4752
|
+
{ pageIndex, pageSize: chunkRQSA7ADZ_cjs.DEFAULT_PAGE_SIZE }
|
|
4507
4753
|
);
|
|
4508
4754
|
chain.push(...page);
|
|
4509
|
-
hasMore = meta ? page.length ===
|
|
4755
|
+
hasMore = meta ? page.length === chunkRQSA7ADZ_cjs.DEFAULT_PAGE_SIZE : false;
|
|
4510
4756
|
pageIndex++;
|
|
4511
4757
|
}
|
|
4512
4758
|
return chain;
|
|
@@ -4518,12 +4764,12 @@ var IndexerExitDataSource = class {
|
|
|
4518
4764
|
while (hasMore) {
|
|
4519
4765
|
const { txs, page } = await this.indexer.getVirtualTxs(txids, {
|
|
4520
4766
|
pageIndex,
|
|
4521
|
-
pageSize:
|
|
4767
|
+
pageSize: chunkRQSA7ADZ_cjs.DEFAULT_PAGE_SIZE
|
|
4522
4768
|
});
|
|
4523
4769
|
for (const psbt of txs) {
|
|
4524
|
-
out.set(
|
|
4770
|
+
out.set(chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
4525
4771
|
}
|
|
4526
|
-
hasMore = page ? txs.length ===
|
|
4772
|
+
hasMore = page ? txs.length === chunkRQSA7ADZ_cjs.DEFAULT_PAGE_SIZE : false;
|
|
4527
4773
|
pageIndex++;
|
|
4528
4774
|
}
|
|
4529
4775
|
return out;
|
|
@@ -4544,7 +4790,7 @@ function chainedTxTypeToChainTxType(t) {
|
|
|
4544
4790
|
}
|
|
4545
4791
|
}
|
|
4546
4792
|
function psbtInputTxids(psbtBase64) {
|
|
4547
|
-
const tx =
|
|
4793
|
+
const tx = chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
|
|
4548
4794
|
const ids = [];
|
|
4549
4795
|
for (let i = 0; i < tx.inputsLength; i++) {
|
|
4550
4796
|
const txid = tx.getInput(i).txid;
|
|
@@ -4647,7 +4893,7 @@ function createExitChainResolver(params) {
|
|
|
4647
4893
|
|
|
4648
4894
|
// src/providers/availability.ts
|
|
4649
4895
|
function isRetryableProviderError(error) {
|
|
4650
|
-
return error instanceof
|
|
4896
|
+
return error instanceof chunkCFQO5MCM_cjs.ProviderUnavailableError || error instanceof chunkCFQO5MCM_cjs.FetchError || chunkCFQO5MCM_cjs.isFetchTimeoutError(error);
|
|
4651
4897
|
}
|
|
4652
4898
|
|
|
4653
4899
|
// src/utils/syncCursors.ts
|
|
@@ -4900,7 +5146,7 @@ async function resolveArkInfo(arkProvider, walletRepository) {
|
|
|
4900
5146
|
if (!isRetryableProviderError(err)) throw err;
|
|
4901
5147
|
const snapshot = await loadArkInfoSnapshot(walletRepository);
|
|
4902
5148
|
if (!snapshot) {
|
|
4903
|
-
throw new
|
|
5149
|
+
throw new chunkCFQO5MCM_cjs.ProviderUnavailableError(
|
|
4904
5150
|
"Arkade server info is unavailable and no cached snapshot exists",
|
|
4905
5151
|
{ cause: err }
|
|
4906
5152
|
);
|
|
@@ -5435,7 +5681,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
5435
5681
|
const virtualCoins = await this.wallet.getVtxos({
|
|
5436
5682
|
withRecoverable: false
|
|
5437
5683
|
});
|
|
5438
|
-
const controlAssetRef = params.controlAssetId ?
|
|
5684
|
+
const controlAssetRef = params.controlAssetId ? chunkCFQO5MCM_cjs.AssetRef.fromId(chunkCFQO5MCM_cjs.AssetId.fromString(params.controlAssetId)) : null;
|
|
5439
5685
|
const coinSelection = selectVirtualCoins(virtualCoins, Number(this.wallet.dustAmount));
|
|
5440
5686
|
let totalBtcSelected = 0n;
|
|
5441
5687
|
const assetChanges = /* @__PURE__ */ new Map();
|
|
@@ -5448,8 +5694,8 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
5448
5694
|
}
|
|
5449
5695
|
}
|
|
5450
5696
|
const groups = [];
|
|
5451
|
-
const issuedAssetOutput =
|
|
5452
|
-
const issuedAssetGroup =
|
|
5697
|
+
const issuedAssetOutput = chunkCFQO5MCM_cjs.AssetOutput.create(0, params.amount);
|
|
5698
|
+
const issuedAssetGroup = chunkCFQO5MCM_cjs.AssetGroup.create(
|
|
5453
5699
|
null,
|
|
5454
5700
|
controlAssetRef,
|
|
5455
5701
|
[],
|
|
@@ -5464,28 +5710,28 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
5464
5710
|
for (const [inputIndex, assets] of assetInputs) {
|
|
5465
5711
|
for (const asset of assets) {
|
|
5466
5712
|
if (asset.assetId !== assetId) continue;
|
|
5467
|
-
changeInputs.push(
|
|
5713
|
+
changeInputs.push(chunkCFQO5MCM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
5468
5714
|
}
|
|
5469
5715
|
}
|
|
5470
5716
|
groups.push(
|
|
5471
|
-
|
|
5472
|
-
|
|
5717
|
+
chunkCFQO5MCM_cjs.AssetGroup.create(
|
|
5718
|
+
chunkCFQO5MCM_cjs.AssetId.fromString(assetId),
|
|
5473
5719
|
null,
|
|
5474
5720
|
changeInputs,
|
|
5475
|
-
[
|
|
5721
|
+
[chunkCFQO5MCM_cjs.AssetOutput.create(0, amount)],
|
|
5476
5722
|
[]
|
|
5477
5723
|
)
|
|
5478
5724
|
);
|
|
5479
5725
|
}
|
|
5480
5726
|
}
|
|
5481
5727
|
const address = await this.wallet.getAddress();
|
|
5482
|
-
const outputAddress =
|
|
5728
|
+
const outputAddress = chunkL5ND2FJJ_cjs.ArkAddress.decode(address);
|
|
5483
5729
|
const outputs = [
|
|
5484
5730
|
{
|
|
5485
5731
|
script: outputAddress.pkScript,
|
|
5486
5732
|
amount: BigInt(totalBtcSelected)
|
|
5487
5733
|
},
|
|
5488
|
-
Extension.create([
|
|
5734
|
+
Extension.create([chunkCFQO5MCM_cjs.Packet.create(groups)]).txOut()
|
|
5489
5735
|
];
|
|
5490
5736
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(
|
|
5491
5737
|
coinSelection.inputs,
|
|
@@ -5493,7 +5739,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
5493
5739
|
);
|
|
5494
5740
|
return {
|
|
5495
5741
|
arkTxId: arkTxid,
|
|
5496
|
-
assetId:
|
|
5742
|
+
assetId: chunkCFQO5MCM_cjs.AssetId.create(arkTxid, 0).toString()
|
|
5497
5743
|
};
|
|
5498
5744
|
}
|
|
5499
5745
|
/**
|
|
@@ -5565,16 +5811,16 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
5565
5811
|
for (const [inputIndex, assets] of assetInputs) {
|
|
5566
5812
|
for (const asset of assets) {
|
|
5567
5813
|
if (asset.assetId !== params.assetId) continue;
|
|
5568
|
-
reissueInputs.push(
|
|
5814
|
+
reissueInputs.push(chunkCFQO5MCM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
5569
5815
|
}
|
|
5570
5816
|
}
|
|
5571
5817
|
const totalAssetAmount = assetToReissueAmount + params.amount;
|
|
5572
|
-
const reissueAssetIdObj =
|
|
5573
|
-
const reissueAssetGroup =
|
|
5818
|
+
const reissueAssetIdObj = chunkCFQO5MCM_cjs.AssetId.fromString(params.assetId);
|
|
5819
|
+
const reissueAssetGroup = chunkCFQO5MCM_cjs.AssetGroup.create(
|
|
5574
5820
|
reissueAssetIdObj,
|
|
5575
5821
|
null,
|
|
5576
5822
|
reissueInputs,
|
|
5577
|
-
[
|
|
5823
|
+
[chunkCFQO5MCM_cjs.AssetOutput.create(0, totalAssetAmount)],
|
|
5578
5824
|
[]
|
|
5579
5825
|
);
|
|
5580
5826
|
const groups = [reissueAssetGroup];
|
|
@@ -5583,27 +5829,27 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
5583
5829
|
for (const [inputIndex, assets] of assetInputs) {
|
|
5584
5830
|
for (const asset of assets) {
|
|
5585
5831
|
if (asset.assetId !== assetId) continue;
|
|
5586
|
-
changeInputs.push(
|
|
5832
|
+
changeInputs.push(chunkCFQO5MCM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
5587
5833
|
}
|
|
5588
5834
|
}
|
|
5589
5835
|
groups.push(
|
|
5590
|
-
|
|
5591
|
-
|
|
5836
|
+
chunkCFQO5MCM_cjs.AssetGroup.create(
|
|
5837
|
+
chunkCFQO5MCM_cjs.AssetId.fromString(assetId),
|
|
5592
5838
|
null,
|
|
5593
5839
|
changeInputs,
|
|
5594
|
-
[
|
|
5840
|
+
[chunkCFQO5MCM_cjs.AssetOutput.create(0, amount)],
|
|
5595
5841
|
[]
|
|
5596
5842
|
)
|
|
5597
5843
|
);
|
|
5598
5844
|
}
|
|
5599
5845
|
const address = await this.wallet.getAddress();
|
|
5600
|
-
const outputAddress =
|
|
5846
|
+
const outputAddress = chunkL5ND2FJJ_cjs.ArkAddress.decode(address);
|
|
5601
5847
|
const outputs = [
|
|
5602
5848
|
{
|
|
5603
5849
|
script: outputAddress.pkScript,
|
|
5604
5850
|
amount: BigInt(totalBtcSelected)
|
|
5605
5851
|
},
|
|
5606
|
-
Extension.create([
|
|
5852
|
+
Extension.create([chunkCFQO5MCM_cjs.Packet.create(groups)]).txOut()
|
|
5607
5853
|
];
|
|
5608
5854
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
|
|
5609
5855
|
return arkTxid;
|
|
@@ -5670,27 +5916,27 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
5670
5916
|
for (const [inputIndex, assets] of assetInputs) {
|
|
5671
5917
|
for (const asset of assets) {
|
|
5672
5918
|
if (asset.assetId !== assetId) continue;
|
|
5673
|
-
changeInputs.push(
|
|
5919
|
+
changeInputs.push(chunkCFQO5MCM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
5674
5920
|
}
|
|
5675
5921
|
}
|
|
5676
5922
|
groups.push(
|
|
5677
|
-
|
|
5678
|
-
|
|
5923
|
+
chunkCFQO5MCM_cjs.AssetGroup.create(
|
|
5924
|
+
chunkCFQO5MCM_cjs.AssetId.fromString(assetId),
|
|
5679
5925
|
null,
|
|
5680
5926
|
changeInputs,
|
|
5681
|
-
amount > 0n ? [
|
|
5927
|
+
amount > 0n ? [chunkCFQO5MCM_cjs.AssetOutput.create(0, amount)] : [],
|
|
5682
5928
|
[]
|
|
5683
5929
|
)
|
|
5684
5930
|
);
|
|
5685
5931
|
}
|
|
5686
5932
|
const address = await this.wallet.getAddress();
|
|
5687
|
-
const outputAddress =
|
|
5933
|
+
const outputAddress = chunkL5ND2FJJ_cjs.ArkAddress.decode(address);
|
|
5688
5934
|
const outputs = [
|
|
5689
5935
|
{
|
|
5690
5936
|
script: outputAddress.pkScript,
|
|
5691
5937
|
amount: BigInt(totalBtcSelected)
|
|
5692
5938
|
},
|
|
5693
|
-
Extension.create([
|
|
5939
|
+
Extension.create([chunkCFQO5MCM_cjs.Packet.create(groups)]).txOut()
|
|
5694
5940
|
];
|
|
5695
5941
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
|
|
5696
5942
|
return arkTxid;
|
|
@@ -5715,7 +5961,7 @@ function castMetadata(metadata) {
|
|
|
5715
5961
|
} else {
|
|
5716
5962
|
throw new Error("Invalid metadata value type");
|
|
5717
5963
|
}
|
|
5718
|
-
md.push(
|
|
5964
|
+
md.push(chunkCFQO5MCM_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
|
|
5719
5965
|
}
|
|
5720
5966
|
return md;
|
|
5721
5967
|
}
|
|
@@ -5736,7 +5982,7 @@ var DelegateManagerImpl = class {
|
|
|
5736
5982
|
if (vtxos.length === 0) {
|
|
5737
5983
|
return { delegated: [], failed: [] };
|
|
5738
5984
|
}
|
|
5739
|
-
const destinationScript =
|
|
5985
|
+
const destinationScript = chunkL5ND2FJJ_cjs.ArkAddress.decode(destination).pkScript;
|
|
5740
5986
|
const arkInfo = await this.arkInfoProvider.getInfo();
|
|
5741
5987
|
const delegateInfo = await this.delegateProvider.getDelegateInfo();
|
|
5742
5988
|
const eligible = vtxos.filter(
|
|
@@ -5884,7 +6130,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
5884
6130
|
const delegateFee = BigInt(Number(fee));
|
|
5885
6131
|
if (delegateFee > 0n) {
|
|
5886
6132
|
outputs.push({
|
|
5887
|
-
script:
|
|
6133
|
+
script: chunkL5ND2FJJ_cjs.ArkAddress.decode(delegateAddress).pkScript,
|
|
5888
6134
|
amount: delegateFee
|
|
5889
6135
|
});
|
|
5890
6136
|
}
|
|
@@ -5917,7 +6163,7 @@ async function delegate(identity, delegateProvider, arkInfo, delegateInfo, vtxos
|
|
|
5917
6163
|
destinationScript
|
|
5918
6164
|
);
|
|
5919
6165
|
const forfeitOutputScript = btcSigner.OutScript.encode(
|
|
5920
|
-
btcSigner.Address(
|
|
6166
|
+
btcSigner.Address(chunkL5ND2FJJ_cjs.getNetwork(network)).decode(forfeitAddress)
|
|
5921
6167
|
);
|
|
5922
6168
|
const forfeits = await Promise.all(
|
|
5923
6169
|
vtxos.filter((v) => !isRecoverable(v)).map(async (coin) => {
|
|
@@ -5945,7 +6191,7 @@ async function makeDelegateForfeitTx(input, connectorAmount, delegatePubkey, for
|
|
|
5945
6191
|
index: input.vout,
|
|
5946
6192
|
witnessUtxo: {
|
|
5947
6193
|
amount: BigInt(input.value),
|
|
5948
|
-
script:
|
|
6194
|
+
script: chunkL5ND2FJJ_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
5949
6195
|
},
|
|
5950
6196
|
sighashType: btcSigner.SigHash.ALL_ANYONECANPAY,
|
|
5951
6197
|
tapLeafScript: [delegateTapLeaf]
|
|
@@ -6003,7 +6249,7 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
6003
6249
|
expire_at: 0,
|
|
6004
6250
|
cosigners_public_keys: cosignerPubKeys
|
|
6005
6251
|
};
|
|
6006
|
-
const proof =
|
|
6252
|
+
const proof = chunkCFQO5MCM_cjs.Intent.create(message, coins, outputs);
|
|
6007
6253
|
const signedProof = await identity.sign(proof);
|
|
6008
6254
|
return {
|
|
6009
6255
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -6021,10 +6267,10 @@ function getDayTimestamp(timestamp) {
|
|
|
6021
6267
|
function findDelegateTapLeaf(vtxo, delegatePubkey) {
|
|
6022
6268
|
if (!vtxo.tapTree) return void 0;
|
|
6023
6269
|
const pk = delegatePubkey.length === 66 ? delegatePubkey.slice(2) : delegatePubkey;
|
|
6024
|
-
const vtxoScript =
|
|
6270
|
+
const vtxoScript = chunkL5ND2FJJ_cjs.VtxoScript.decode(vtxo.tapTree);
|
|
6025
6271
|
return vtxoScript.leaves.find((tapLeaf) => {
|
|
6026
|
-
const arkTapscript =
|
|
6027
|
-
if (!
|
|
6272
|
+
const arkTapscript = chunkL5ND2FJJ_cjs.decodeTapscript(chunkL5ND2FJJ_cjs.scriptFromTapLeafScript(tapLeaf));
|
|
6273
|
+
if (!chunkL5ND2FJJ_cjs.MultisigTapscript.is(arkTapscript)) return false;
|
|
6028
6274
|
return arkTapscript.params.pubkeys.map(base.hex.encode).includes(pk);
|
|
6029
6275
|
});
|
|
6030
6276
|
}
|
|
@@ -6212,7 +6458,7 @@ async function closeDatabase(dbName) {
|
|
|
6212
6458
|
return true;
|
|
6213
6459
|
}
|
|
6214
6460
|
function scriptFromArkAddress(address) {
|
|
6215
|
-
return base.hex.encode(
|
|
6461
|
+
return base.hex.encode(chunkL5ND2FJJ_cjs.ArkAddress.decode(address).pkScript);
|
|
6216
6462
|
}
|
|
6217
6463
|
|
|
6218
6464
|
// src/repositories/indexedDB/schema.ts
|
|
@@ -7863,11 +8109,6 @@ var ContractRepositoryImpl = class {
|
|
|
7863
8109
|
}
|
|
7864
8110
|
};
|
|
7865
8111
|
|
|
7866
|
-
// src/contracts/types.ts
|
|
7867
|
-
function isDiscoverable(handler) {
|
|
7868
|
-
return !!handler && typeof handler.discoverAt === "function";
|
|
7869
|
-
}
|
|
7870
|
-
|
|
7871
8112
|
// src/contracts/contractWatcher.ts
|
|
7872
8113
|
function computeReconnectDelay(attempt, baseMs, maxMs) {
|
|
7873
8114
|
return Math.min(baseMs * Math.pow(2, attempt - 1), maxMs);
|
|
@@ -8091,7 +8332,7 @@ var ContractWatcher = class {
|
|
|
8091
8332
|
this.connectionState = "connected";
|
|
8092
8333
|
this.reconnectAttempts = 0;
|
|
8093
8334
|
this.listenLoop().catch((e) => {
|
|
8094
|
-
if (
|
|
8335
|
+
if (chunkCFQO5MCM_cjs.isEventSourceError(e)) {
|
|
8095
8336
|
console.debug("ContractWatcher subscription disconnected; reconnecting");
|
|
8096
8337
|
} else {
|
|
8097
8338
|
console.error(e);
|
|
@@ -8617,7 +8858,7 @@ var ContractManager = class _ContractManager {
|
|
|
8617
8858
|
* `persisted` is `true`.
|
|
8618
8859
|
*/
|
|
8619
8860
|
async upsertContract(params) {
|
|
8620
|
-
const handler =
|
|
8861
|
+
const handler = chunkRQSA7ADZ_cjs.contractHandlers.get(params.type);
|
|
8621
8862
|
if (!handler) {
|
|
8622
8863
|
throw new Error(`No handler registered for contract type '${params.type}'`);
|
|
8623
8864
|
}
|
|
@@ -8700,7 +8941,7 @@ var ContractManager = class _ContractManager {
|
|
|
8700
8941
|
`scanContracts: batchSize must be a positive integer (got ${String(opts.batchSize)})`
|
|
8701
8942
|
);
|
|
8702
8943
|
}
|
|
8703
|
-
const registered =
|
|
8944
|
+
const registered = chunkRQSA7ADZ_cjs.contractHandlers.getRegisteredTypes().map((t) => chunkRQSA7ADZ_cjs.contractHandlers.get(t)).filter(isDiscoverable);
|
|
8704
8945
|
const discoverables = [
|
|
8705
8946
|
...registered.filter((h) => h.type === "boarding"),
|
|
8706
8947
|
...registered.filter((h) => h.type !== "boarding")
|
|
@@ -8890,7 +9131,7 @@ var ContractManager = class _ContractManager {
|
|
|
8890
9131
|
const { contractScript, collaborative = true, walletPubKey, vtxo } = options;
|
|
8891
9132
|
const [contract] = await this.getContracts({ script: contractScript });
|
|
8892
9133
|
if (!contract) return [];
|
|
8893
|
-
const handler =
|
|
9134
|
+
const handler = chunkRQSA7ADZ_cjs.contractHandlers.get(contract.type);
|
|
8894
9135
|
if (!handler) return [];
|
|
8895
9136
|
const script = handler.createScript(contract.params);
|
|
8896
9137
|
const context = {
|
|
@@ -8910,7 +9151,7 @@ var ContractManager = class _ContractManager {
|
|
|
8910
9151
|
const { contractScript, collaborative = true, walletPubKey } = options;
|
|
8911
9152
|
const [contract] = await this.getContracts({ script: contractScript });
|
|
8912
9153
|
if (!contract) return [];
|
|
8913
|
-
const handler =
|
|
9154
|
+
const handler = chunkRQSA7ADZ_cjs.contractHandlers.get(contract.type);
|
|
8914
9155
|
if (!handler) return [];
|
|
8915
9156
|
const script = handler.createScript(contract.params);
|
|
8916
9157
|
const context = {
|
|
@@ -9177,7 +9418,7 @@ var ContractManager = class _ContractManager {
|
|
|
9177
9418
|
}
|
|
9178
9419
|
return result;
|
|
9179
9420
|
}
|
|
9180
|
-
async fetchContractVtxosBulk(contracts, pageSize =
|
|
9421
|
+
async fetchContractVtxosBulk(contracts, pageSize = chunkRQSA7ADZ_cjs.DEFAULT_PAGE_SIZE, syncWindow) {
|
|
9181
9422
|
if (contracts.length === 0) {
|
|
9182
9423
|
return /* @__PURE__ */ new Map();
|
|
9183
9424
|
}
|
|
@@ -9355,7 +9596,7 @@ var HDDescriptorProvider = class _HDDescriptorProvider {
|
|
|
9355
9596
|
*/
|
|
9356
9597
|
materializeDescriptorAt(index) {
|
|
9357
9598
|
const descriptor = this.identity.descriptor;
|
|
9358
|
-
const network =
|
|
9599
|
+
const network = chunkRQSA7ADZ_cjs.isMainnetDescriptor(descriptor) ? descriptorsScure.networks.bitcoin : descriptorsScure.networks.testnet;
|
|
9359
9600
|
const expansion = descriptorsScure.expand({ descriptor, network, index });
|
|
9360
9601
|
const keyInfo = expansion.expansionMap?.["@0"];
|
|
9361
9602
|
if (!keyInfo?.keyExpression) {
|
|
@@ -9499,7 +9740,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
9499
9740
|
const provider = await resolveDescriptorProvider(config, setup.walletRepository);
|
|
9500
9741
|
if (!provider) return void 0;
|
|
9501
9742
|
const allowSilentFallback = (config.walletMode ?? "auto") === "auto";
|
|
9502
|
-
const expectedContractType = setup.offchainTapscript instanceof
|
|
9743
|
+
const expectedContractType = setup.offchainTapscript instanceof chunkRQSA7ADZ_cjs.DelegateVtxo.Script ? "delegate" : "default";
|
|
9503
9744
|
const factoryOpts = {
|
|
9504
9745
|
walletRepository: setup.walletRepository,
|
|
9505
9746
|
contractRepository: setup.contractRepository,
|
|
@@ -9682,7 +9923,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
9682
9923
|
const newAddress = newTapscript.address(wallet.network.hrp, wallet.arkServerPublicKey).encode();
|
|
9683
9924
|
const manager = await wallet.getContractManager();
|
|
9684
9925
|
const csvTimelock = newTapscript.options.csvTimelock;
|
|
9685
|
-
const csvTimelockStr =
|
|
9926
|
+
const csvTimelockStr = chunkL5ND2FJJ_cjs.timelockToSequence(csvTimelock).toString();
|
|
9686
9927
|
const serverPubKeyHex = base.hex.encode(newTapscript.options.serverPubKey);
|
|
9687
9928
|
const baseParams = {
|
|
9688
9929
|
script: newScript,
|
|
@@ -9696,11 +9937,11 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
9696
9937
|
// produce unsigned PSBTs that the server rejects with
|
|
9697
9938
|
// `INVALID_PSBT_INPUT (5): missing tapscript spend sig`.
|
|
9698
9939
|
metadata: {
|
|
9699
|
-
source:
|
|
9940
|
+
source: chunkRQSA7ADZ_cjs.WALLET_RECEIVE_SOURCE,
|
|
9700
9941
|
signingDescriptor: descriptor
|
|
9701
9942
|
}
|
|
9702
9943
|
};
|
|
9703
|
-
if (newTapscript instanceof
|
|
9944
|
+
if (newTapscript instanceof chunkRQSA7ADZ_cjs.DelegateVtxo.Script) {
|
|
9704
9945
|
await manager.createContract({
|
|
9705
9946
|
...baseParams,
|
|
9706
9947
|
type: "delegate",
|
|
@@ -9732,7 +9973,7 @@ var WalletReceiveRotator = class _WalletReceiveRotator {
|
|
|
9732
9973
|
};
|
|
9733
9974
|
function deriveLeafPubkey(descriptor) {
|
|
9734
9975
|
try {
|
|
9735
|
-
return
|
|
9976
|
+
return chunkRQSA7ADZ_cjs.deriveDescriptorLeafPubKey(descriptor);
|
|
9736
9977
|
} catch (e) {
|
|
9737
9978
|
throw new NonRangeableDescriptorError(
|
|
9738
9979
|
"Cannot derive leaf pubkey: descriptor is not a materialized, parsable tr(...) shape.",
|
|
@@ -9741,10 +9982,10 @@ function deriveLeafPubkey(descriptor) {
|
|
|
9741
9982
|
}
|
|
9742
9983
|
}
|
|
9743
9984
|
function rebuildTapscript(current, pubKey) {
|
|
9744
|
-
if (current instanceof
|
|
9745
|
-
return new
|
|
9985
|
+
if (current instanceof chunkRQSA7ADZ_cjs.DelegateVtxo.Script) {
|
|
9986
|
+
return new chunkRQSA7ADZ_cjs.DelegateVtxo.Script({ ...current.options, pubKey });
|
|
9746
9987
|
}
|
|
9747
|
-
return new
|
|
9988
|
+
return new chunkRQSA7ADZ_cjs.DefaultVtxo.Script({ ...current.options, pubKey });
|
|
9748
9989
|
}
|
|
9749
9990
|
async function pickActiveReceive(contractRepository, serverPubKey, expectedType) {
|
|
9750
9991
|
const candidates = await contractRepository.getContracts({
|
|
@@ -9753,7 +9994,7 @@ async function pickActiveReceive(contractRepository, serverPubKey, expectedType)
|
|
|
9753
9994
|
});
|
|
9754
9995
|
const serverPubKeyHex = base.hex.encode(serverPubKey);
|
|
9755
9996
|
const matching = candidates.filter(
|
|
9756
|
-
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source ===
|
|
9997
|
+
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkRQSA7ADZ_cjs.WALLET_RECEIVE_SOURCE
|
|
9757
9998
|
).sort((a, b) => {
|
|
9758
9999
|
if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
|
|
9759
10000
|
return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
|
|
@@ -9929,12 +10170,12 @@ var InputSignerRouter = class {
|
|
|
9929
10170
|
};
|
|
9930
10171
|
|
|
9931
10172
|
// src/wallet/wallet.ts
|
|
9932
|
-
var getArkadeServerUrl = ({ arkServerUrl }) => arkServerUrl ||
|
|
10173
|
+
var getArkadeServerUrl = ({ arkServerUrl }) => arkServerUrl || chunkL5ND2FJJ_cjs.DEFAULT_ARKADE_SERVER_URL;
|
|
9933
10174
|
function intentProofJobs(coins) {
|
|
9934
10175
|
if (coins.length === 0) return [];
|
|
9935
10176
|
const coinJobs = coins.map((coin, i) => ({
|
|
9936
10177
|
index: i + 1,
|
|
9937
|
-
lookupScript:
|
|
10178
|
+
lookupScript: chunkL5ND2FJJ_cjs.VtxoScript.decode(coin.tapTree).pkScript
|
|
9938
10179
|
}));
|
|
9939
10180
|
return [{ index: 0, lookupScript: coinJobs[0].lookupScript }, ...coinJobs];
|
|
9940
10181
|
}
|
|
@@ -9958,7 +10199,7 @@ function dedupeTimelocks(timelocks) {
|
|
|
9958
10199
|
const seen = /* @__PURE__ */ new Set();
|
|
9959
10200
|
const deduped = [];
|
|
9960
10201
|
for (const timelock of timelocks) {
|
|
9961
|
-
const sequence =
|
|
10202
|
+
const sequence = chunkL5ND2FJJ_cjs.timelockToSequence(timelock).toString();
|
|
9962
10203
|
if (seen.has(sequence)) continue;
|
|
9963
10204
|
seen.add(sequence);
|
|
9964
10205
|
deduped.push(timelock);
|
|
@@ -9975,7 +10216,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
|
|
|
9975
10216
|
state: "active"
|
|
9976
10217
|
});
|
|
9977
10218
|
const newest = candidates.filter(
|
|
9978
|
-
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source ===
|
|
10219
|
+
(c) => c.params.serverPubKey === serverPubKeyHex && c.metadata?.source === chunkRQSA7ADZ_cjs.WALLET_RECEIVE_SOURCE
|
|
9979
10220
|
).sort((a, b) => {
|
|
9980
10221
|
if (b.createdAt !== a.createdAt) return b.createdAt - a.createdAt;
|
|
9981
10222
|
return signingDescriptorIndex(b.metadata?.signingDescriptor) - signingDescriptorIndex(a.metadata?.signingDescriptor);
|
|
@@ -9983,7 +10224,7 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
|
|
|
9983
10224
|
if (!newest?.params.pubKey) return baseline;
|
|
9984
10225
|
try {
|
|
9985
10226
|
const pubKey = base.hex.decode(newest.params.pubKey);
|
|
9986
|
-
return new
|
|
10227
|
+
return new chunkRQSA7ADZ_cjs.DefaultVtxo.Script({ ...baseline.options, pubKey });
|
|
9987
10228
|
} catch (e) {
|
|
9988
10229
|
console.warn("Skipping malformed boarding contract at boot", newest.script, e);
|
|
9989
10230
|
return baseline;
|
|
@@ -10008,6 +10249,24 @@ async function spendableVtxosExcludingLocked(vtxos, intentRepository) {
|
|
|
10008
10249
|
}
|
|
10009
10250
|
return excludeLockedOutpoints(vtxos, locked);
|
|
10010
10251
|
}
|
|
10252
|
+
var cashReport = (vtxo, reason) => ({
|
|
10253
|
+
txid: vtxo.txid,
|
|
10254
|
+
vout: vtxo.vout,
|
|
10255
|
+
value: vtxo.value,
|
|
10256
|
+
reason
|
|
10257
|
+
});
|
|
10258
|
+
var ArkCashCreateError = class extends Error {
|
|
10259
|
+
constructor(cash, cause) {
|
|
10260
|
+
super(
|
|
10261
|
+
`Failed to create ArkCash: send failed after the note may have been submitted. Recover with claimCash using the token on this error's \`cash\` field.`
|
|
10262
|
+
);
|
|
10263
|
+
this.cash = cash;
|
|
10264
|
+
this.cause = cause;
|
|
10265
|
+
this.name = "ArkCashCreateError";
|
|
10266
|
+
}
|
|
10267
|
+
cash;
|
|
10268
|
+
cause;
|
|
10269
|
+
};
|
|
10011
10270
|
var ReadonlyWallet = class _ReadonlyWallet {
|
|
10012
10271
|
constructor(identity, network, onchainProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, dustAmount, walletRepository, contractRepository, delegateProvider, watcherConfig, walletContractTimelocks) {
|
|
10013
10272
|
this.identity = identity;
|
|
@@ -10285,7 +10544,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10285
10544
|
*/
|
|
10286
10545
|
static async setupWalletConfig(config, pubKey) {
|
|
10287
10546
|
const arkadeServerUrl = getArkadeServerUrl(config);
|
|
10288
|
-
const arkProvider = config.arkProvider || new
|
|
10547
|
+
const arkProvider = config.arkProvider || new chunkCFQO5MCM_cjs.RestArkProvider(arkadeServerUrl);
|
|
10289
10548
|
let indexerProvider = config.indexerProvider;
|
|
10290
10549
|
if (!indexerProvider) {
|
|
10291
10550
|
let indexerUrl = config.indexerUrl;
|
|
@@ -10302,7 +10561,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10302
10561
|
indexerUrl = arkadeServerUrl;
|
|
10303
10562
|
}
|
|
10304
10563
|
}
|
|
10305
|
-
indexerProvider = new
|
|
10564
|
+
indexerProvider = new chunkCFQO5MCM_cjs.RestIndexerProvider(indexerUrl);
|
|
10306
10565
|
}
|
|
10307
10566
|
const walletRepository = config.storage?.walletRepository ?? new IndexedDBWalletRepository();
|
|
10308
10567
|
const contractRepository = config.storage?.contractRepository ?? new IndexedDBContractRepository();
|
|
@@ -10311,7 +10570,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10311
10570
|
source: serverInfoSource,
|
|
10312
10571
|
lastOnlineAt: serverInfoLastOnlineAt
|
|
10313
10572
|
} = await resolveArkInfo(arkProvider, walletRepository);
|
|
10314
|
-
const network =
|
|
10573
|
+
const network = chunkL5ND2FJJ_cjs.getNetwork(info.network);
|
|
10315
10574
|
if ("descriptor" in config.identity) {
|
|
10316
10575
|
const descriptor = config.identity.descriptor;
|
|
10317
10576
|
const identityIsMainnet = !descriptor.includes("tpub");
|
|
@@ -10358,11 +10617,11 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10358
10617
|
serverPubKey,
|
|
10359
10618
|
csvTimelock: exitTimelock
|
|
10360
10619
|
};
|
|
10361
|
-
const offchainTapscript = !delegatePubKey ? new
|
|
10362
|
-
const boardingTapscript =
|
|
10620
|
+
const offchainTapscript = !delegatePubKey ? new chunkRQSA7ADZ_cjs.DefaultVtxo.Script(offchainOptions) : new chunkRQSA7ADZ_cjs.DelegateVtxo.Script({ ...offchainOptions, delegatePubKey });
|
|
10621
|
+
const boardingTapscript = chunkRQSA7ADZ_cjs.BoardingContractHandler.createScript({
|
|
10363
10622
|
pubKey: base.hex.encode(pubKey),
|
|
10364
10623
|
serverPubKey: base.hex.encode(serverPubKey),
|
|
10365
|
-
csvTimelock:
|
|
10624
|
+
csvTimelock: chunkL5ND2FJJ_cjs.timelockToSequence(boardingTimelock).toString()
|
|
10366
10625
|
});
|
|
10367
10626
|
return {
|
|
10368
10627
|
arkProvider,
|
|
@@ -10696,9 +10955,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10696
10955
|
async getBoardingTapscripts(allowedSigners) {
|
|
10697
10956
|
const byScript = /* @__PURE__ */ new Map();
|
|
10698
10957
|
const add = (s) => byScript.set(base.hex.encode(s.pkScript), s);
|
|
10699
|
-
const boardingCsv = this.boardingTapscript.options.csvTimelock ??
|
|
10958
|
+
const boardingCsv = this.boardingTapscript.options.csvTimelock ?? chunkRQSA7ADZ_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
10700
10959
|
add(
|
|
10701
|
-
new
|
|
10960
|
+
new chunkRQSA7ADZ_cjs.DefaultVtxo.Script({
|
|
10702
10961
|
pubKey: await this.identity.xOnlyPublicKey(),
|
|
10703
10962
|
serverPubKey: this.boardingTapscript.options.serverPubKey,
|
|
10704
10963
|
csvTimelock: boardingCsv
|
|
@@ -10713,7 +10972,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10713
10972
|
for (const c of boardingContracts) {
|
|
10714
10973
|
if (!allowed.has(toXOnlySignerHex(c.params.serverPubKey))) continue;
|
|
10715
10974
|
try {
|
|
10716
|
-
add(
|
|
10975
|
+
add(chunkRQSA7ADZ_cjs.BoardingContractHandler.createScript(c.params));
|
|
10717
10976
|
} catch (e) {
|
|
10718
10977
|
console.warn("Skipping malformed boarding contract", c.script, e);
|
|
10719
10978
|
}
|
|
@@ -10751,7 +11010,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10751
11010
|
// Per-row CSV delay decoded from THIS tapscript's exit leaf —
|
|
10752
11011
|
// not the wallet's current boarding timelock, which a signer
|
|
10753
11012
|
// rotation may have changed.
|
|
10754
|
-
csvTimelock:
|
|
11013
|
+
csvTimelock: chunkL5ND2FJJ_cjs.CSVMultisigTapscript.decode(base.hex.decode(tapscript.exitScript)).params.timelock,
|
|
10755
11014
|
coins: utxos
|
|
10756
11015
|
});
|
|
10757
11016
|
}
|
|
@@ -10917,7 +11176,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
10917
11176
|
});
|
|
10918
11177
|
for (const contract of contracts) {
|
|
10919
11178
|
if (map.has(contract.script)) continue;
|
|
10920
|
-
const handler =
|
|
11179
|
+
const handler = chunkRQSA7ADZ_cjs.contractHandlers.get(contract.type);
|
|
10921
11180
|
if (handler) {
|
|
10922
11181
|
const script = handler.createScript(contract.params);
|
|
10923
11182
|
map.set(contract.script, script);
|
|
@@ -11011,7 +11270,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
11011
11270
|
watcherConfig: this.watcherConfig
|
|
11012
11271
|
});
|
|
11013
11272
|
const baselinePubkey = await this.identity.xOnlyPublicKey();
|
|
11014
|
-
const delegatePubKey = this.offchainTapscript instanceof
|
|
11273
|
+
const delegatePubKey = this.offchainTapscript instanceof chunkRQSA7ADZ_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
|
|
11015
11274
|
const baselineSigners = [
|
|
11016
11275
|
this.offchainTapscript.options.serverPubKey,
|
|
11017
11276
|
...[...this._deprecatedSigners.keys()].map((h) => base.hex.decode(h))
|
|
@@ -11019,8 +11278,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
11019
11278
|
const seenBaselineScripts = /* @__PURE__ */ new Set();
|
|
11020
11279
|
for (const serverPubKey of baselineSigners) {
|
|
11021
11280
|
for (const csvTimelock of this.walletContractTimelocks) {
|
|
11022
|
-
const csvTimelockStr =
|
|
11023
|
-
const defaultScript = new
|
|
11281
|
+
const csvTimelockStr = chunkL5ND2FJJ_cjs.timelockToSequence(csvTimelock).toString();
|
|
11282
|
+
const defaultScript = new chunkRQSA7ADZ_cjs.DefaultVtxo.Script({
|
|
11024
11283
|
pubKey: baselinePubkey,
|
|
11025
11284
|
serverPubKey,
|
|
11026
11285
|
csvTimelock
|
|
@@ -11041,7 +11300,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
11041
11300
|
});
|
|
11042
11301
|
}
|
|
11043
11302
|
if (delegatePubKey) {
|
|
11044
|
-
const delegateScript = new
|
|
11303
|
+
const delegateScript = new chunkRQSA7ADZ_cjs.DelegateVtxo.Script({
|
|
11045
11304
|
pubKey: baselinePubkey,
|
|
11046
11305
|
serverPubKey,
|
|
11047
11306
|
delegatePubKey,
|
|
@@ -11065,9 +11324,9 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
11065
11324
|
}
|
|
11066
11325
|
}
|
|
11067
11326
|
}
|
|
11068
|
-
const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ??
|
|
11327
|
+
const boardingCsvTimelock = this.boardingTapscript.options.csvTimelock ?? chunkRQSA7ADZ_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
11069
11328
|
for (const serverPubKey of baselineSigners) {
|
|
11070
|
-
const baselineBoarding = new
|
|
11329
|
+
const baselineBoarding = new chunkRQSA7ADZ_cjs.DefaultVtxo.Script({
|
|
11071
11330
|
pubKey: baselinePubkey,
|
|
11072
11331
|
serverPubKey,
|
|
11073
11332
|
csvTimelock: boardingCsvTimelock
|
|
@@ -11080,7 +11339,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
11080
11339
|
params: {
|
|
11081
11340
|
pubKey: base.hex.encode(baselineBoarding.options.pubKey),
|
|
11082
11341
|
serverPubKey: base.hex.encode(serverPubKey),
|
|
11083
|
-
csvTimelock:
|
|
11342
|
+
csvTimelock: chunkL5ND2FJJ_cjs.timelockToSequence(boardingCsvTimelock).toString()
|
|
11084
11343
|
},
|
|
11085
11344
|
script: boardingScriptHex,
|
|
11086
11345
|
address: baselineBoarding.address(this.network.hrp, serverPubKey).encode(),
|
|
@@ -11303,25 +11562,25 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11303
11562
|
return this.getBoardingAddress();
|
|
11304
11563
|
}
|
|
11305
11564
|
const descriptor = await provider.getNextSigningDescriptor();
|
|
11306
|
-
const pubKey =
|
|
11307
|
-
const newBoarding = new
|
|
11565
|
+
const pubKey = chunkRQSA7ADZ_cjs.deriveDescriptorLeafPubKey(descriptor);
|
|
11566
|
+
const newBoarding = new chunkRQSA7ADZ_cjs.DefaultVtxo.Script({
|
|
11308
11567
|
...this._boardingTapscript.options,
|
|
11309
11568
|
pubKey
|
|
11310
11569
|
});
|
|
11311
|
-
const csvTimelock = newBoarding.options.csvTimelock ??
|
|
11570
|
+
const csvTimelock = newBoarding.options.csvTimelock ?? chunkRQSA7ADZ_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
11312
11571
|
const manager = await this.getContractManager();
|
|
11313
11572
|
await manager.createContract({
|
|
11314
11573
|
type: "boarding",
|
|
11315
11574
|
params: {
|
|
11316
11575
|
pubKey: base.hex.encode(pubKey),
|
|
11317
11576
|
serverPubKey: base.hex.encode(newBoarding.options.serverPubKey),
|
|
11318
|
-
csvTimelock:
|
|
11577
|
+
csvTimelock: chunkL5ND2FJJ_cjs.timelockToSequence(csvTimelock).toString()
|
|
11319
11578
|
},
|
|
11320
11579
|
script: base.hex.encode(newBoarding.pkScript),
|
|
11321
11580
|
address: newBoarding.address(this.network.hrp, this.arkServerPublicKey).encode(),
|
|
11322
11581
|
state: "active",
|
|
11323
11582
|
metadata: {
|
|
11324
|
-
source:
|
|
11583
|
+
source: chunkRQSA7ADZ_cjs.WALLET_RECEIVE_SOURCE,
|
|
11325
11584
|
signingDescriptor: descriptor
|
|
11326
11585
|
}
|
|
11327
11586
|
});
|
|
@@ -11360,7 +11619,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11360
11619
|
const xonly = toXOnlyPubKey(newServerPubKey);
|
|
11361
11620
|
let newServerUnrollScript;
|
|
11362
11621
|
try {
|
|
11363
|
-
newServerUnrollScript =
|
|
11622
|
+
newServerUnrollScript = chunkL5ND2FJJ_cjs.CSVMultisigTapscript.decode(base.hex.decode(checkpointTapscript));
|
|
11364
11623
|
} catch (e) {
|
|
11365
11624
|
throw new Error("Invalid checkpointTapscript from server");
|
|
11366
11625
|
}
|
|
@@ -11388,21 +11647,21 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11388
11647
|
const [currentBoardingRow] = await manager.getContracts({
|
|
11389
11648
|
script: currentBoardingScript
|
|
11390
11649
|
});
|
|
11391
|
-
const newOffchain = this.offchainTapscript instanceof
|
|
11650
|
+
const newOffchain = this.offchainTapscript instanceof chunkRQSA7ADZ_cjs.DelegateVtxo.Script ? new chunkRQSA7ADZ_cjs.DelegateVtxo.Script({
|
|
11392
11651
|
...this.offchainTapscript.options,
|
|
11393
11652
|
serverPubKey: xonly
|
|
11394
|
-
}) : new
|
|
11653
|
+
}) : new chunkRQSA7ADZ_cjs.DefaultVtxo.Script({
|
|
11395
11654
|
...this.offchainTapscript.options,
|
|
11396
11655
|
serverPubKey: xonly
|
|
11397
11656
|
});
|
|
11398
|
-
const newBoarding = new
|
|
11657
|
+
const newBoarding = new chunkRQSA7ADZ_cjs.DefaultVtxo.Script({
|
|
11399
11658
|
...this._boardingTapscript.options,
|
|
11400
11659
|
serverPubKey: xonly
|
|
11401
11660
|
});
|
|
11402
|
-
const offchainCsv =
|
|
11661
|
+
const offchainCsv = chunkL5ND2FJJ_cjs.timelockToSequence(newOffchain.options.csvTimelock).toString();
|
|
11403
11662
|
const newOffchainScript = base.hex.encode(newOffchain.pkScript);
|
|
11404
11663
|
const newOffchainAddress = newOffchain.address(this.network.hrp, xonly).encode();
|
|
11405
|
-
if (newOffchain instanceof
|
|
11664
|
+
if (newOffchain instanceof chunkRQSA7ADZ_cjs.DelegateVtxo.Script) {
|
|
11406
11665
|
await manager.createContract({
|
|
11407
11666
|
type: "delegate",
|
|
11408
11667
|
params: {
|
|
@@ -11430,13 +11689,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11430
11689
|
metadata: currentOffchainRow?.metadata
|
|
11431
11690
|
});
|
|
11432
11691
|
}
|
|
11433
|
-
const boardingCsv = newBoarding.options.csvTimelock ??
|
|
11692
|
+
const boardingCsv = newBoarding.options.csvTimelock ?? chunkRQSA7ADZ_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK;
|
|
11434
11693
|
await manager.createContract({
|
|
11435
11694
|
type: "boarding",
|
|
11436
11695
|
params: {
|
|
11437
11696
|
pubKey: base.hex.encode(newBoarding.options.pubKey),
|
|
11438
11697
|
serverPubKey: base.hex.encode(xonly),
|
|
11439
|
-
csvTimelock:
|
|
11698
|
+
csvTimelock: chunkL5ND2FJJ_cjs.timelockToSequence(boardingCsv).toString()
|
|
11440
11699
|
},
|
|
11441
11700
|
script: base.hex.encode(newBoarding.pkScript),
|
|
11442
11701
|
address: newBoarding.address(this.network.hrp, xonly).encode(),
|
|
@@ -11531,7 +11790,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11531
11790
|
const hd = provider instanceof HDDescriptorProvider;
|
|
11532
11791
|
const staticDescriptor = hd ? void 0 : `tr(${base.hex.encode(await this.identity.xOnlyPublicKey())})`;
|
|
11533
11792
|
const materialize = (index) => hd ? provider.materializeDescriptorAt(index) : staticDescriptor;
|
|
11534
|
-
const delegatePubKey = this.offchainTapscript instanceof
|
|
11793
|
+
const delegatePubKey = this.offchainTapscript instanceof chunkRQSA7ADZ_cjs.DelegateVtxo.Script ? this.offchainTapscript.options.delegatePubKey : void 0;
|
|
11535
11794
|
const arkInfo = await this.arkProvider.getInfo();
|
|
11536
11795
|
const currentSignerPubKey = toXOnlyPubKey(base.hex.decode(arkInfo.signerPubkey));
|
|
11537
11796
|
const deprecatedSignerPubKeys = arkInfo.deprecatedSigners.map(
|
|
@@ -11550,7 +11809,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11550
11809
|
csvTimelocks: this.walletContractTimelocks,
|
|
11551
11810
|
// Boarding-exit CSV so the boarding handler can build its
|
|
11552
11811
|
// candidate script (distinct from the unilateral-exit matrix).
|
|
11553
|
-
boardingTimelock: this.boardingTapscript.options.csvTimelock ??
|
|
11812
|
+
boardingTimelock: this.boardingTapscript.options.csvTimelock ?? chunkRQSA7ADZ_cjs.DefaultVtxo.Script.DEFAULT_TIMELOCK,
|
|
11554
11813
|
delegatePubKey
|
|
11555
11814
|
};
|
|
11556
11815
|
const result = await manager.scanContracts({
|
|
@@ -11654,7 +11913,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11654
11913
|
let serverUnrollScript;
|
|
11655
11914
|
try {
|
|
11656
11915
|
const raw = base.hex.decode(setup.info.checkpointTapscript);
|
|
11657
|
-
serverUnrollScript =
|
|
11916
|
+
serverUnrollScript = chunkL5ND2FJJ_cjs.CSVMultisigTapscript.decode(raw);
|
|
11658
11917
|
} catch (e) {
|
|
11659
11918
|
throw new Error("Invalid checkpointTapscript from server");
|
|
11660
11919
|
}
|
|
@@ -11791,7 +12050,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11791
12050
|
inputs: params.selectedVtxos,
|
|
11792
12051
|
changeAmount: BigInt(changeAmount)
|
|
11793
12052
|
};
|
|
11794
|
-
const outputAddress =
|
|
12053
|
+
const outputAddress = chunkL5ND2FJJ_cjs.ArkAddress.decode(params.address);
|
|
11795
12054
|
const outputScript = BigInt(params.amount) < this.dustAmount ? outputAddress.subdustPkScript : outputAddress.pkScript;
|
|
11796
12055
|
const outputs = [
|
|
11797
12056
|
{
|
|
@@ -11844,13 +12103,13 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11844
12103
|
}
|
|
11845
12104
|
}
|
|
11846
12105
|
const offchainAddress = await this.getAddress();
|
|
11847
|
-
const offchainPkScript =
|
|
12106
|
+
const offchainPkScript = chunkL5ND2FJJ_cjs.ArkAddress.decode(offchainAddress).pkScript;
|
|
11848
12107
|
const offchainOutputScript = base.hex.encode(offchainPkScript);
|
|
11849
12108
|
if (!params) {
|
|
11850
12109
|
const { fees, vtxoMaxAmount } = await this.arkProvider.getInfo();
|
|
11851
12110
|
const estimator = new Estimator(fees.intentFee);
|
|
11852
12111
|
let amount = 0;
|
|
11853
|
-
const exitScript =
|
|
12112
|
+
const exitScript = chunkL5ND2FJJ_cjs.CSVMultisigTapscript.decode(
|
|
11854
12113
|
base.hex.decode(this.boardingTapscript.exitScript)
|
|
11855
12114
|
);
|
|
11856
12115
|
const boardingTimelock = exitScript.params.timelock;
|
|
@@ -11930,7 +12189,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
11930
12189
|
for (const [index, output] of params.outputs.entries()) {
|
|
11931
12190
|
let script;
|
|
11932
12191
|
try {
|
|
11933
|
-
const addr =
|
|
12192
|
+
const addr = chunkL5ND2FJJ_cjs.ArkAddress.decode(output.address);
|
|
11934
12193
|
script = addr.pkScript;
|
|
11935
12194
|
hasOffchainOutputs = true;
|
|
11936
12195
|
} catch {
|
|
@@ -12192,7 +12451,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12192
12451
|
index: input.vout,
|
|
12193
12452
|
witnessUtxo: {
|
|
12194
12453
|
amount: BigInt(input.value),
|
|
12195
|
-
script:
|
|
12454
|
+
script: chunkL5ND2FJJ_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
12196
12455
|
},
|
|
12197
12456
|
sighashType: btcSigner.SigHash.DEFAULT,
|
|
12198
12457
|
tapLeafScript: [input.forfeitTapLeafScript]
|
|
@@ -12211,7 +12470,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12211
12470
|
forfeitTx = await this._signerRouter.sign(forfeitTx, [
|
|
12212
12471
|
{
|
|
12213
12472
|
index: 0,
|
|
12214
|
-
lookupScript:
|
|
12473
|
+
lookupScript: chunkL5ND2FJJ_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
12215
12474
|
}
|
|
12216
12475
|
]);
|
|
12217
12476
|
signedForfeits.push(base.base64.encode(forfeitTx.toPSBT()));
|
|
@@ -12269,7 +12528,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12269
12528
|
if (skip) {
|
|
12270
12529
|
return { skip };
|
|
12271
12530
|
}
|
|
12272
|
-
const sweepTapscript =
|
|
12531
|
+
const sweepTapscript = chunkL5ND2FJJ_cjs.CSVMultisigTapscript.encode({
|
|
12273
12532
|
timelock: {
|
|
12274
12533
|
value: event.batchExpiry,
|
|
12275
12534
|
type: event.batchExpiry >= 512n ? "seconds" : "blocks"
|
|
@@ -12375,9 +12634,9 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12375
12634
|
...existing ?? {},
|
|
12376
12635
|
intentTxId,
|
|
12377
12636
|
registerProof: intent.proof,
|
|
12378
|
-
registerProofMessage:
|
|
12637
|
+
registerProofMessage: chunkCFQO5MCM_cjs.Intent.encodeMessage(intent.message),
|
|
12379
12638
|
deleteProof: deleteIntent.proof,
|
|
12380
|
-
deleteProofMessage:
|
|
12639
|
+
deleteProofMessage: chunkCFQO5MCM_cjs.Intent.encodeMessage(deleteIntent.message),
|
|
12381
12640
|
intentVtxos: inputs.map((i) => ({
|
|
12382
12641
|
txid: i.txid,
|
|
12383
12642
|
vout: i.vout
|
|
@@ -12409,7 +12668,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12409
12668
|
try {
|
|
12410
12669
|
return await this.arkProvider.registerIntent(intent);
|
|
12411
12670
|
} catch (error) {
|
|
12412
|
-
if (error instanceof
|
|
12671
|
+
if (error instanceof chunkCFQO5MCM_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
|
|
12413
12672
|
const deleteIntent = await this.makeDeleteIntentSignature(inputs);
|
|
12414
12673
|
await this.arkProvider.deleteIntent(deleteIntent);
|
|
12415
12674
|
return this.arkProvider.registerIntent(intent);
|
|
@@ -12425,7 +12684,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12425
12684
|
expire_at: 0,
|
|
12426
12685
|
cosigners_public_keys: cosignerPubKeys
|
|
12427
12686
|
};
|
|
12428
|
-
const proof =
|
|
12687
|
+
const proof = chunkCFQO5MCM_cjs.Intent.create(message, coins, outputs);
|
|
12429
12688
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
12430
12689
|
return {
|
|
12431
12690
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -12437,7 +12696,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12437
12696
|
type: "delete",
|
|
12438
12697
|
expire_at: 0
|
|
12439
12698
|
};
|
|
12440
|
-
const proof =
|
|
12699
|
+
const proof = chunkCFQO5MCM_cjs.Intent.create(message, coins, []);
|
|
12441
12700
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
12442
12701
|
return {
|
|
12443
12702
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -12449,7 +12708,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12449
12708
|
type: "get-pending-tx",
|
|
12450
12709
|
expire_at: 0
|
|
12451
12710
|
};
|
|
12452
|
-
const proof =
|
|
12711
|
+
const proof = chunkCFQO5MCM_cjs.Intent.create(message, coins, []);
|
|
12453
12712
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
12454
12713
|
return {
|
|
12455
12714
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -12467,7 +12726,6 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12467
12726
|
if (!hasPending) {
|
|
12468
12727
|
return { finalized: [], pending: [] };
|
|
12469
12728
|
}
|
|
12470
|
-
const MAX_INPUTS_PER_INTENT = 20;
|
|
12471
12729
|
if (!vtxos || vtxos.length === 0) {
|
|
12472
12730
|
const scriptMap = await this.getScriptMap();
|
|
12473
12731
|
const allExtended = [];
|
|
@@ -12577,6 +12835,265 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12577
12835
|
settings: { ...state.settings, hasPendingTx: value }
|
|
12578
12836
|
}));
|
|
12579
12837
|
}
|
|
12838
|
+
/**
|
|
12839
|
+
* Create an ArkCash bearer instrument.
|
|
12840
|
+
*
|
|
12841
|
+
* Generates a fresh keypair, sends the specified amount to a DefaultVtxo
|
|
12842
|
+
* controlled by the new key, and returns the encoded arkcash string.
|
|
12843
|
+
* The receiver can claim the funds using `claimCash()` without ever
|
|
12844
|
+
* sharing their address.
|
|
12845
|
+
*
|
|
12846
|
+
* ArkCash is a short-lived instrument: it carries a private key, so it is
|
|
12847
|
+
* meant to be handed over and claimed promptly, not held. A note left
|
|
12848
|
+
* unclaimed past its batch expiry is swept by the server and `claimCash`
|
|
12849
|
+
* can only report it, not move it.
|
|
12850
|
+
*
|
|
12851
|
+
* @param amount - Amount in satoshis to send. Must be a whole number of
|
|
12852
|
+
* sats at or above the dust threshold — a below-dust amount would mint an
|
|
12853
|
+
* OP_RETURN output that is unspendable as cash.
|
|
12854
|
+
* @returns The encoded arkcash string (e.g., "arkcash1...")
|
|
12855
|
+
*/
|
|
12856
|
+
async createCash(amount) {
|
|
12857
|
+
if (!Number.isSafeInteger(amount) || amount < Number(this.dustAmount)) {
|
|
12858
|
+
throw new Error(
|
|
12859
|
+
`Invalid ArkCash amount ${amount}: must be a whole number of sats >= dust (${this.dustAmount})`
|
|
12860
|
+
);
|
|
12861
|
+
}
|
|
12862
|
+
const cashHrp = this.network.hrp.replace(/ark$/, "arkcash");
|
|
12863
|
+
const cash = ArkCash.generate(
|
|
12864
|
+
this.arkServerPublicKey,
|
|
12865
|
+
this.offchainTapscript.options.csvTimelock,
|
|
12866
|
+
cashHrp
|
|
12867
|
+
);
|
|
12868
|
+
const address = cash.address(this.network.hrp).encode();
|
|
12869
|
+
const cashStr = cash.toString();
|
|
12870
|
+
try {
|
|
12871
|
+
await this.send({ address, amount });
|
|
12872
|
+
} catch (error) {
|
|
12873
|
+
throw new ArkCashCreateError(cashStr, error);
|
|
12874
|
+
}
|
|
12875
|
+
return cashStr;
|
|
12876
|
+
}
|
|
12877
|
+
/**
|
|
12878
|
+
* Claim an ArkCash bearer instrument: sweep what can be swept, report the
|
|
12879
|
+
* rest.
|
|
12880
|
+
*
|
|
12881
|
+
* Every spendable VTXO at the arkcash address is swept to this wallet in
|
|
12882
|
+
* its own offchain transaction, signed with the key carried by the arkcash
|
|
12883
|
+
* string. Nothing is ever persisted: no contract is imported, and the
|
|
12884
|
+
* arkcash key is not stored. Anything that cannot be swept — server-swept,
|
|
12885
|
+
* subdust, already claimed, or asset-bearing — is returned in `unclaimed`
|
|
12886
|
+
* with a per-VTXO reason and otherwise ignored.
|
|
12887
|
+
*
|
|
12888
|
+
* The arkcash string is the recovery token: a claim interrupted between
|
|
12889
|
+
* submit and finalize is completed by simply re-running `claimCash`, which
|
|
12890
|
+
* drains any pending arkcash transaction on the server before sweeping.
|
|
12891
|
+
*
|
|
12892
|
+
* @param cashStr - The encoded arkcash string (e.g., "arkcash1...")
|
|
12893
|
+
* @returns The swept total and the report of what was left behind. The
|
|
12894
|
+
* shape is open: further buckets may be added alongside `unclaimed`.
|
|
12895
|
+
*/
|
|
12896
|
+
async claimCash(cashStr) {
|
|
12897
|
+
const cash = ArkCash.fromString(cashStr);
|
|
12898
|
+
const cashScript = cash.vtxoScript;
|
|
12899
|
+
const cashPkScript = base.hex.encode(cashScript.pkScript);
|
|
12900
|
+
const scripts = [cashPkScript];
|
|
12901
|
+
let vtxos = await this.fetchAllVtxos(scripts);
|
|
12902
|
+
if (vtxos.length === 0) {
|
|
12903
|
+
throw new Error("No VTXOs found for this arkcash");
|
|
12904
|
+
}
|
|
12905
|
+
const myPkScript = chunkL5ND2FJJ_cjs.ArkAddress.decode(await this.getAddress()).pkScript;
|
|
12906
|
+
let { spendable, unclaimed } = this.classifyCashVtxos(vtxos);
|
|
12907
|
+
let swept = 0;
|
|
12908
|
+
const drainable = vtxos.filter((vtxo) => !isSubdust(vtxo, this.dustAmount));
|
|
12909
|
+
if (drainable.length > 0) {
|
|
12910
|
+
let drained = { count: 0, swept: 0, claimed: /* @__PURE__ */ new Set() };
|
|
12911
|
+
try {
|
|
12912
|
+
drained = await this.finalizePendingCashTxs(
|
|
12913
|
+
cash,
|
|
12914
|
+
drainable,
|
|
12915
|
+
cashScript,
|
|
12916
|
+
myPkScript
|
|
12917
|
+
);
|
|
12918
|
+
} catch (error) {
|
|
12919
|
+
console.error("Failed to drain pending arkcash txs:", error);
|
|
12920
|
+
}
|
|
12921
|
+
if (drained.count > 0) {
|
|
12922
|
+
vtxos = await this.fetchAllVtxos(scripts);
|
|
12923
|
+
({ spendable, unclaimed } = this.classifyCashVtxos(vtxos));
|
|
12924
|
+
swept += drained.swept;
|
|
12925
|
+
unclaimed = unclaimed.filter(
|
|
12926
|
+
(vtxo) => !drained.claimed.has(`${vtxo.txid}:${vtxo.vout}`)
|
|
12927
|
+
);
|
|
12928
|
+
}
|
|
12929
|
+
}
|
|
12930
|
+
if (spendable.length > 0) {
|
|
12931
|
+
const info = await this.arkProvider.getInfo();
|
|
12932
|
+
const serverUnrollScript = chunkL5ND2FJJ_cjs.CSVMultisigTapscript.decode(
|
|
12933
|
+
base.hex.decode(info.checkpointTapscript)
|
|
12934
|
+
);
|
|
12935
|
+
for (const vtxo of spendable) {
|
|
12936
|
+
try {
|
|
12937
|
+
await signAndSubmitOffchainTx({
|
|
12938
|
+
identity: cash.identity,
|
|
12939
|
+
provider: this.arkProvider,
|
|
12940
|
+
inputs: [
|
|
12941
|
+
{
|
|
12942
|
+
txid: vtxo.txid,
|
|
12943
|
+
vout: vtxo.vout,
|
|
12944
|
+
value: vtxo.value,
|
|
12945
|
+
tapLeafScript: cashScript.forfeit(),
|
|
12946
|
+
tapTree: cashScript.encode()
|
|
12947
|
+
}
|
|
12948
|
+
],
|
|
12949
|
+
outputs: [{ script: myPkScript, amount: BigInt(vtxo.value) }],
|
|
12950
|
+
serverUnrollScript
|
|
12951
|
+
});
|
|
12952
|
+
swept += vtxo.value;
|
|
12953
|
+
} catch (error) {
|
|
12954
|
+
console.error(`Failed to sweep arkcash VTXO ${vtxo.txid}:${vtxo.vout}:`, error);
|
|
12955
|
+
unclaimed.push(cashReport(vtxo, "sweep-failed"));
|
|
12956
|
+
}
|
|
12957
|
+
}
|
|
12958
|
+
}
|
|
12959
|
+
return {
|
|
12960
|
+
swept,
|
|
12961
|
+
unclaimed: {
|
|
12962
|
+
amount: unclaimed.reduce((total, vtxo) => total + vtxo.value, 0),
|
|
12963
|
+
vtxos: unclaimed
|
|
12964
|
+
}
|
|
12965
|
+
};
|
|
12966
|
+
}
|
|
12967
|
+
/**
|
|
12968
|
+
* Split the VTXOs at an arkcash address into the ones the thin sweep can
|
|
12969
|
+
* move and the ones it can only report.
|
|
12970
|
+
*/
|
|
12971
|
+
classifyCashVtxos(vtxos) {
|
|
12972
|
+
const spendable = [];
|
|
12973
|
+
const unclaimed = [];
|
|
12974
|
+
for (const vtxo of vtxos) {
|
|
12975
|
+
if (!isSpendable(vtxo)) {
|
|
12976
|
+
unclaimed.push(cashReport(vtxo, "already-spent"));
|
|
12977
|
+
} else if (isSubdust(vtxo, this.dustAmount)) {
|
|
12978
|
+
unclaimed.push(cashReport(vtxo, "subdust"));
|
|
12979
|
+
} else if (isRecoverable(vtxo)) {
|
|
12980
|
+
unclaimed.push(cashReport(vtxo, "swept"));
|
|
12981
|
+
} else if (vtxo.assets && vtxo.assets.length > 0) {
|
|
12982
|
+
unclaimed.push(cashReport(vtxo, "has-assets"));
|
|
12983
|
+
} else {
|
|
12984
|
+
spendable.push(vtxo);
|
|
12985
|
+
}
|
|
12986
|
+
}
|
|
12987
|
+
return { spendable, unclaimed };
|
|
12988
|
+
}
|
|
12989
|
+
/** Read every page of an unfiltered VTXO query for the given scripts. */
|
|
12990
|
+
async fetchAllVtxos(scripts) {
|
|
12991
|
+
const pageSize = 100;
|
|
12992
|
+
const all = [];
|
|
12993
|
+
const seen = /* @__PURE__ */ new Set();
|
|
12994
|
+
for (let pageIndex = 0; ; pageIndex++) {
|
|
12995
|
+
const { vtxos, page } = await this.indexerProvider.getVtxos({
|
|
12996
|
+
scripts,
|
|
12997
|
+
pageIndex,
|
|
12998
|
+
pageSize
|
|
12999
|
+
});
|
|
13000
|
+
for (const vtxo of vtxos) {
|
|
13001
|
+
const outpoint = `${vtxo.txid}:${vtxo.vout}`;
|
|
13002
|
+
if (seen.has(outpoint)) continue;
|
|
13003
|
+
seen.add(outpoint);
|
|
13004
|
+
all.push(vtxo);
|
|
13005
|
+
}
|
|
13006
|
+
if (!page || vtxos.length < pageSize) return all;
|
|
13007
|
+
}
|
|
13008
|
+
}
|
|
13009
|
+
/**
|
|
13010
|
+
* Complete any sweep a previous `claimCash` registered but never finalized.
|
|
13011
|
+
* A thin variant of {@link finalizePendingTxs}, scoped to the arkcash key:
|
|
13012
|
+
* the intent is signed with it, and so are the returned checkpoints.
|
|
13013
|
+
*
|
|
13014
|
+
* A drained sweep is not automatically *ours*. Whoever registered it chose
|
|
13015
|
+
* the destination, so a tx a different claimer left half-finished pays that
|
|
13016
|
+
* claimer — finalizing it is still right (the input is spent either way, and
|
|
13017
|
+
* completing it unsticks the funds), but only the value it actually pays to
|
|
13018
|
+
* `myPkScript` may be counted as claimed here.
|
|
13019
|
+
*
|
|
13020
|
+
* @param vtxos - VTXOs at the arkcash contract's own pkScript, spent ones
|
|
13021
|
+
* included (a registered sweep marks its input spent). Any other outpoint —
|
|
13022
|
+
* subdust above all — would make the proof invalid, since it describes every
|
|
13023
|
+
* input by that pkScript.
|
|
13024
|
+
* @returns The number of pending txs finalized, the sats among them paid to
|
|
13025
|
+
* this wallet, and the outpoints those txs consumed to pay it.
|
|
13026
|
+
*/
|
|
13027
|
+
async finalizePendingCashTxs(cash, vtxos, cashScript, myPkScript) {
|
|
13028
|
+
const result = { count: 0, swept: 0, claimed: /* @__PURE__ */ new Set() };
|
|
13029
|
+
const inputs = vtxos.map((vtxo) => ({
|
|
13030
|
+
...vtxo,
|
|
13031
|
+
forfeitTapLeafScript: cashScript.forfeit(),
|
|
13032
|
+
intentTapLeafScript: cashScript.forfeit(),
|
|
13033
|
+
tapTree: cashScript.encode()
|
|
13034
|
+
}));
|
|
13035
|
+
if (inputs.length === 0) return result;
|
|
13036
|
+
const identity = cash.identity;
|
|
13037
|
+
const seenTxids = /* @__PURE__ */ new Set();
|
|
13038
|
+
const pendingTxs = [];
|
|
13039
|
+
for (let i = 0; i < inputs.length; i += MAX_INPUTS_PER_INTENT) {
|
|
13040
|
+
const batch = inputs.slice(i, i + MAX_INPUTS_PER_INTENT);
|
|
13041
|
+
const message = { type: "get-pending-tx", expire_at: 0 };
|
|
13042
|
+
const proof = chunkCFQO5MCM_cjs.Intent.create(message, batch, []);
|
|
13043
|
+
const signedProof = await identity.sign(
|
|
13044
|
+
proof,
|
|
13045
|
+
Array.from({ length: batch.length + 1 }, (_, j) => j)
|
|
13046
|
+
);
|
|
13047
|
+
const batchPending = await this.arkProvider.getPendingTxs({
|
|
13048
|
+
proof: base.base64.encode(signedProof.toPSBT()),
|
|
13049
|
+
message
|
|
13050
|
+
});
|
|
13051
|
+
for (const pendingTx of batchPending) {
|
|
13052
|
+
if (seenTxids.has(pendingTx.arkTxid)) continue;
|
|
13053
|
+
seenTxids.add(pendingTx.arkTxid);
|
|
13054
|
+
pendingTxs.push(pendingTx);
|
|
13055
|
+
}
|
|
13056
|
+
}
|
|
13057
|
+
const myPkScriptHex = base.hex.encode(myPkScript);
|
|
13058
|
+
for (const pendingTx of pendingTxs) {
|
|
13059
|
+
try {
|
|
13060
|
+
const checkpointTxs = pendingTx.signedCheckpointTxs.map(
|
|
13061
|
+
(checkpoint) => btcSigner.Transaction.fromPSBT(base.base64.decode(checkpoint))
|
|
13062
|
+
);
|
|
13063
|
+
const finalCheckpoints = await Promise.all(
|
|
13064
|
+
checkpointTxs.map(
|
|
13065
|
+
async (checkpoint) => base.base64.encode((await identity.sign(checkpoint)).toPSBT())
|
|
13066
|
+
)
|
|
13067
|
+
);
|
|
13068
|
+
await this.arkProvider.finalizeTx(pendingTx.arkTxid, finalCheckpoints);
|
|
13069
|
+
result.count++;
|
|
13070
|
+
const paidToMe = this.arkTxAmountPaidTo(pendingTx.finalArkTx, myPkScriptHex);
|
|
13071
|
+
if (paidToMe === 0) continue;
|
|
13072
|
+
result.swept += paidToMe;
|
|
13073
|
+
for (const checkpoint of checkpointTxs) {
|
|
13074
|
+
for (let i = 0; i < checkpoint.inputsLength; i++) {
|
|
13075
|
+
const input = checkpoint.getInput(i);
|
|
13076
|
+
if (!input.txid) continue;
|
|
13077
|
+
result.claimed.add(`${base.hex.encode(input.txid)}:${input.index}`);
|
|
13078
|
+
}
|
|
13079
|
+
}
|
|
13080
|
+
} catch (error) {
|
|
13081
|
+
console.error(`Failed to finalize pending arkcash tx ${pendingTx.arkTxid}:`, error);
|
|
13082
|
+
}
|
|
13083
|
+
}
|
|
13084
|
+
return result;
|
|
13085
|
+
}
|
|
13086
|
+
/** Sum the outputs of an ark tx PSBT that pay the given scriptPubKey. */
|
|
13087
|
+
arkTxAmountPaidTo(arkTxPsbt, pkScriptHex) {
|
|
13088
|
+
const arkTx = btcSigner.Transaction.fromPSBT(base.base64.decode(arkTxPsbt));
|
|
13089
|
+
let total = 0;
|
|
13090
|
+
for (let i = 0; i < arkTx.outputsLength; i++) {
|
|
13091
|
+
const output = arkTx.getOutput(i);
|
|
13092
|
+
if (!output.script || output.amount === void 0) continue;
|
|
13093
|
+
if (base.hex.encode(output.script) === pkScriptHex) total += Number(output.amount);
|
|
13094
|
+
}
|
|
13095
|
+
return total;
|
|
13096
|
+
}
|
|
12580
13097
|
/**
|
|
12581
13098
|
* Send BTC and/or assets to one or more recipients.
|
|
12582
13099
|
*
|
|
@@ -12726,9 +13243,24 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12726
13243
|
}
|
|
12727
13244
|
const assetInputs = selectedCoinsToAssetInputs(selectedCoins);
|
|
12728
13245
|
const hasAssets = assetInputs.size > 0 || recipients.some((r) => r.assets && r.assets.length > 0);
|
|
13246
|
+
const customExtPackets = [];
|
|
13247
|
+
for (const r of args) {
|
|
13248
|
+
if (r.extensions) {
|
|
13249
|
+
for (const ext of r.extensions) {
|
|
13250
|
+
customExtPackets.push({
|
|
13251
|
+
type: () => ext.type,
|
|
13252
|
+
serialize: () => ext.payload
|
|
13253
|
+
});
|
|
13254
|
+
}
|
|
13255
|
+
}
|
|
13256
|
+
}
|
|
13257
|
+
const allExtPackets = [];
|
|
12729
13258
|
if (hasAssets) {
|
|
12730
|
-
|
|
12731
|
-
|
|
13259
|
+
allExtPackets.push(createAssetPacket(assetInputs, recipients, changeReceiver));
|
|
13260
|
+
}
|
|
13261
|
+
allExtPackets.push(...customExtPackets);
|
|
13262
|
+
if (allExtPackets.length > 0) {
|
|
13263
|
+
outputs.push(Extension.create(allExtPackets).txOut());
|
|
12732
13264
|
}
|
|
12733
13265
|
const sentAmount = recipients.reduce((sum, r) => sum + r.amount, 0);
|
|
12734
13266
|
return this._submitOffchainSpend(selectedCoins, outputs, {
|
|
@@ -12865,74 +13397,54 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
12865
13397
|
);
|
|
12866
13398
|
const arkTxJobs = inputs.map((input, index) => ({
|
|
12867
13399
|
index,
|
|
12868
|
-
lookupScript:
|
|
13400
|
+
lookupScript: chunkL5ND2FJJ_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
12869
13401
|
}));
|
|
12870
|
-
const checkpointJobs = offchainTx.checkpoints.map(
|
|
12871
|
-
(c) => this.inputSigningJobsFromWitnessUtxos(c)
|
|
12872
|
-
);
|
|
12873
|
-
let signedVirtualTx;
|
|
12874
|
-
let userSignedCheckpoints;
|
|
12875
13402
|
const identity = this.identity;
|
|
12876
|
-
const
|
|
12877
|
-
|
|
12878
|
-
|
|
12879
|
-
|
|
12880
|
-
tx: offchainTx.arkTx.clone(),
|
|
12881
|
-
inputIndexes: arkTxJobs.map((j) => j.index)
|
|
12882
|
-
},
|
|
12883
|
-
...offchainTx.checkpoints.map((c, i) => ({
|
|
12884
|
-
tx: c.clone(),
|
|
12885
|
-
inputIndexes: checkpointJobs[i].map((j) => j.index)
|
|
12886
|
-
}))
|
|
12887
|
-
];
|
|
12888
|
-
const signed = await identity.signMultiple(requests);
|
|
12889
|
-
if (signed.length !== requests.length) {
|
|
12890
|
-
throw new Error(
|
|
12891
|
-
`signMultiple returned ${signed.length} transactions, expected ${requests.length}`
|
|
12892
|
-
);
|
|
12893
|
-
}
|
|
12894
|
-
const [firstSignedTx, ...signedCheckpoints] = signed;
|
|
12895
|
-
signedVirtualTx = firstSignedTx;
|
|
12896
|
-
userSignedCheckpoints = signedCheckpoints;
|
|
12897
|
-
} else {
|
|
12898
|
-
signedVirtualTx = await this._signerRouter.sign(offchainTx.arkTx, arkTxJobs);
|
|
12899
|
-
}
|
|
12900
|
-
await this.setPendingTxFlag(true);
|
|
12901
|
-
const { arkTxid, signedCheckpointTxs } = await this.arkProvider.submitTx(
|
|
12902
|
-
base.base64.encode(signedVirtualTx.toPSBT()),
|
|
12903
|
-
offchainTx.checkpoints.map((c) => base.base64.encode(c.toPSBT()))
|
|
12904
|
-
);
|
|
12905
|
-
let finalCheckpoints;
|
|
12906
|
-
if (userSignedCheckpoints) {
|
|
12907
|
-
if (signedCheckpointTxs.length !== userSignedCheckpoints.length) {
|
|
12908
|
-
throw new Error(
|
|
12909
|
-
`submitTx returned ${signedCheckpointTxs.length} checkpoints, expected ${userSignedCheckpoints.length}`
|
|
13403
|
+
const signer = {
|
|
13404
|
+
signArkTx: async (arkTx, checkpoints) => {
|
|
13405
|
+
const checkpointJobs = checkpoints.map(
|
|
13406
|
+
(c) => this.inputSigningJobsFromWitnessUtxos(c)
|
|
12910
13407
|
);
|
|
13408
|
+
const batchEligible = isBatchSignable(identity) && await this._signerRouter.canBatch(arkTxJobs, ...checkpointJobs);
|
|
13409
|
+
if (batchEligible) {
|
|
13410
|
+
const requests = [
|
|
13411
|
+
{
|
|
13412
|
+
tx: arkTx.clone(),
|
|
13413
|
+
inputIndexes: arkTxJobs.map((j) => j.index)
|
|
13414
|
+
},
|
|
13415
|
+
...checkpoints.map((c, i) => ({
|
|
13416
|
+
tx: c.clone(),
|
|
13417
|
+
inputIndexes: checkpointJobs[i].map((j) => j.index)
|
|
13418
|
+
}))
|
|
13419
|
+
];
|
|
13420
|
+
const signed = await identity.signMultiple(requests);
|
|
13421
|
+
if (signed.length !== requests.length) {
|
|
13422
|
+
throw new Error(
|
|
13423
|
+
`signMultiple returned ${signed.length} transactions, expected ${requests.length}`
|
|
13424
|
+
);
|
|
13425
|
+
}
|
|
13426
|
+
const [firstSignedTx, ...signedCheckpoints] = signed;
|
|
13427
|
+
return { arkTx: firstSignedTx, userSignedCheckpoints: signedCheckpoints };
|
|
13428
|
+
}
|
|
13429
|
+
return { arkTx: await this._signerRouter.sign(arkTx, arkTxJobs) };
|
|
13430
|
+
},
|
|
13431
|
+
signCheckpoint: (checkpoint) => this._signerRouter.sign(
|
|
13432
|
+
checkpoint,
|
|
13433
|
+
this.inputSigningJobsFromWitnessUtxos(checkpoint)
|
|
13434
|
+
)
|
|
13435
|
+
};
|
|
13436
|
+
return submitOffchainTx(this.arkProvider, offchainTx, signer, {
|
|
13437
|
+
// Mark pending before submitting — if we crash between submit and
|
|
13438
|
+
// finalize, the next init recovers via finalizePendingTxs.
|
|
13439
|
+
beforeSubmit: () => this.setPendingTxFlag(true),
|
|
13440
|
+
afterFinalize: async () => {
|
|
13441
|
+
try {
|
|
13442
|
+
await this.setPendingTxFlag(false);
|
|
13443
|
+
} catch (error) {
|
|
13444
|
+
console.error("Failed to clear pending tx flag:", error);
|
|
13445
|
+
}
|
|
12911
13446
|
}
|
|
12912
|
-
|
|
12913
|
-
const serverSigned = btcSigner.Transaction.fromPSBT(base.base64.decode(c));
|
|
12914
|
-
combineTapscriptSigs(userSignedCheckpoints[i], serverSigned);
|
|
12915
|
-
return base.base64.encode(serverSigned.toPSBT());
|
|
12916
|
-
});
|
|
12917
|
-
} else {
|
|
12918
|
-
finalCheckpoints = await Promise.all(
|
|
12919
|
-
signedCheckpointTxs.map(async (c) => {
|
|
12920
|
-
const tx = btcSigner.Transaction.fromPSBT(base.base64.decode(c));
|
|
12921
|
-
const signedCheckpoint = await this._signerRouter.sign(
|
|
12922
|
-
tx,
|
|
12923
|
-
this.inputSigningJobsFromWitnessUtxos(tx)
|
|
12924
|
-
);
|
|
12925
|
-
return base.base64.encode(signedCheckpoint.toPSBT());
|
|
12926
|
-
})
|
|
12927
|
-
);
|
|
12928
|
-
}
|
|
12929
|
-
await this.arkProvider.finalizeTx(arkTxid, finalCheckpoints);
|
|
12930
|
-
try {
|
|
12931
|
-
await this.setPendingTxFlag(false);
|
|
12932
|
-
} catch (error) {
|
|
12933
|
-
console.error("Failed to clear pending tx flag:", error);
|
|
12934
|
-
}
|
|
12935
|
-
return { arkTxid, signedCheckpointTxs };
|
|
13447
|
+
});
|
|
12936
13448
|
}
|
|
12937
13449
|
// mark virtual outputs as spent, save change outputs if any.
|
|
12938
13450
|
// `offchainTapscript` and `serverPubKey` are the epoch snapshot the
|
|
@@ -13098,7 +13610,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
13098
13610
|
} else {
|
|
13099
13611
|
let sourceAddress;
|
|
13100
13612
|
try {
|
|
13101
|
-
sourceAddress =
|
|
13613
|
+
sourceAddress = chunkL5ND2FJJ_cjs.VtxoScript.decode(input.tapTree).onchainAddress(
|
|
13102
13614
|
this.network
|
|
13103
13615
|
);
|
|
13104
13616
|
} catch {
|
|
@@ -13409,7 +13921,7 @@ var MessageBus = class {
|
|
|
13409
13921
|
this.initialized = true;
|
|
13410
13922
|
}
|
|
13411
13923
|
async buildServices(config) {
|
|
13412
|
-
const arkProvider = new
|
|
13924
|
+
const arkProvider = new chunkCFQO5MCM_cjs.RestArkProvider(config.arkServer.url);
|
|
13413
13925
|
const storage = {
|
|
13414
13926
|
walletRepository: this.walletRepository,
|
|
13415
13927
|
contractRepository: this.contractRepository
|
|
@@ -13792,7 +14304,7 @@ var Ramps = class {
|
|
|
13792
14304
|
}
|
|
13793
14305
|
amount = amount ?? totalAmount;
|
|
13794
14306
|
const offchainAddress = await this.wallet.getAddress();
|
|
13795
|
-
const offchainAddr =
|
|
14307
|
+
const offchainAddr = chunkL5ND2FJJ_cjs.ArkAddress.decode(offchainAddress);
|
|
13796
14308
|
const offchainScript = base.hex.encode(offchainAddr.pkScript);
|
|
13797
14309
|
const outputFee = estimator.evalOffchainOutput({
|
|
13798
14310
|
amount,
|
|
@@ -13890,7 +14402,7 @@ var Ramps = class {
|
|
|
13890
14402
|
let destinationScript;
|
|
13891
14403
|
for (const networkName of networkNames) {
|
|
13892
14404
|
try {
|
|
13893
|
-
const network =
|
|
14405
|
+
const network = chunkL5ND2FJJ_cjs.networks[networkName];
|
|
13894
14406
|
const addr = btcSigner.Address(network).decode(destinationAddress);
|
|
13895
14407
|
destinationScript = btcSigner.OutScript.encode(addr);
|
|
13896
14408
|
break;
|
|
@@ -14575,7 +15087,7 @@ var WalletMessageHandler = class {
|
|
|
14575
15087
|
// Wallet methods
|
|
14576
15088
|
async handleInitWallet({ payload }) {
|
|
14577
15089
|
const { arkServerUrl } = payload;
|
|
14578
|
-
this.indexerProvider = new
|
|
15090
|
+
this.indexerProvider = new chunkCFQO5MCM_cjs.RestIndexerProvider(arkServerUrl);
|
|
14579
15091
|
await this.onWalletInitialized();
|
|
14580
15092
|
}
|
|
14581
15093
|
async handleGetBalance() {
|
|
@@ -16330,12 +16842,12 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
16330
16842
|
* @returns Configured onchain wallet
|
|
16331
16843
|
* @throws Error if the configured identity cannot produce a valid x-only public key
|
|
16332
16844
|
*/
|
|
16333
|
-
static async create(identity, networkName =
|
|
16845
|
+
static async create(identity, networkName = chunkL5ND2FJJ_cjs.DEFAULT_NETWORK_NAME, provider) {
|
|
16334
16846
|
const pubkey = await identity.xOnlyPublicKey();
|
|
16335
16847
|
if (!pubkey) {
|
|
16336
16848
|
throw new Error("Invalid configured public key");
|
|
16337
16849
|
}
|
|
16338
|
-
const network =
|
|
16850
|
+
const network = chunkL5ND2FJJ_cjs.getNetwork(networkName);
|
|
16339
16851
|
const onchainProvider = provider || new EsploraProvider(ESPLORA_URL[networkName]);
|
|
16340
16852
|
const onchainP2TR = btcSigner.p2tr(pubkey, void 0, network);
|
|
16341
16853
|
return new _OnchainWallet(identity, network, onchainP2TR, onchainProvider);
|
|
@@ -16441,7 +16953,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
16441
16953
|
if (!inputs) {
|
|
16442
16954
|
throw new Error("Fee estimation failed");
|
|
16443
16955
|
}
|
|
16444
|
-
let tx = new
|
|
16956
|
+
let tx = new chunkCFQO5MCM_cjs.Transaction();
|
|
16445
16957
|
for (const input of inputs) {
|
|
16446
16958
|
tx.addInput({
|
|
16447
16959
|
txid: input.txid,
|
|
@@ -16499,7 +17011,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
16499
17011
|
* @throws If the parent has no anchor, or funding cannot be selected/signed
|
|
16500
17012
|
*/
|
|
16501
17013
|
async bumpAnchor(parentHex, feeRate) {
|
|
16502
|
-
const parent =
|
|
17014
|
+
const parent = chunkCFQO5MCM_cjs.Transaction.fromRaw(base.hex.decode(parentHex));
|
|
16503
17015
|
const coins = (await this.getCoins()).filter((c) => c.status.confirmed);
|
|
16504
17016
|
const child = await this.buildBumpPackage(parent, feeRate, coins);
|
|
16505
17017
|
return [parent.hex, child.hex];
|
|
@@ -17264,7 +17776,7 @@ exports.BIP322 = void 0;
|
|
|
17264
17776
|
async function sign2(message, identity, network) {
|
|
17265
17777
|
const xOnlyPubKey = await identity.xOnlyPublicKey();
|
|
17266
17778
|
const payment = btcSigner.p2tr(xOnlyPubKey, void 0, network);
|
|
17267
|
-
const toSpend =
|
|
17779
|
+
const toSpend = chunkCFQO5MCM_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
|
|
17268
17780
|
const toSign = craftBIP322ToSignP2TR(toSpend, payment.script, xOnlyPubKey);
|
|
17269
17781
|
const signed = await identity.sign(toSign, [0]);
|
|
17270
17782
|
signed.finalizeIdx(0);
|
|
@@ -17322,7 +17834,7 @@ function verifyP2TR(message, witnessItems, pkScript, pubkey) {
|
|
|
17322
17834
|
if (sighashType !== btcSigner.SigHash.DEFAULT && sighashType !== btcSigner.SigHash.ALL) {
|
|
17323
17835
|
return false;
|
|
17324
17836
|
}
|
|
17325
|
-
const toSpend =
|
|
17837
|
+
const toSpend = chunkCFQO5MCM_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
|
|
17326
17838
|
const toSign = craftBIP322ToSignP2TR(toSpend, pkScript, pubkey);
|
|
17327
17839
|
const sighash = toSign.preimageWitnessV1(0, [pkScript], sighashType, [0n]);
|
|
17328
17840
|
const rawSig = sig.length === 65 ? sig.subarray(0, 64) : sig;
|
|
@@ -17343,7 +17855,7 @@ function verifyP2WPKH(message, witnessItems, pkScript, addressHash) {
|
|
|
17343
17855
|
}
|
|
17344
17856
|
const sighashType = sigWithHash[sigWithHash.length - 1];
|
|
17345
17857
|
const derSig = sigWithHash.subarray(0, sigWithHash.length - 1);
|
|
17346
|
-
const toSpend =
|
|
17858
|
+
const toSpend = chunkCFQO5MCM_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
|
|
17347
17859
|
const toSign = craftBIP322ToSignSimple(toSpend, pkScript);
|
|
17348
17860
|
const scriptCode = btcSigner.OutScript.encode({ type: "pkh", hash: addressHash });
|
|
17349
17861
|
const sighash = toSign.preimageWitnessV0(0, scriptCode, sighashType, 0n);
|
|
@@ -17396,7 +17908,7 @@ function encodeCompactSize(n) {
|
|
|
17396
17908
|
return buf;
|
|
17397
17909
|
}
|
|
17398
17910
|
function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
|
|
17399
|
-
const tx = new
|
|
17911
|
+
const tx = new chunkCFQO5MCM_cjs.Transaction({ version: 0 });
|
|
17400
17912
|
tx.addInput({
|
|
17401
17913
|
txid: toSpend.id,
|
|
17402
17914
|
index: 0,
|
|
@@ -17410,12 +17922,12 @@ function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
|
|
|
17410
17922
|
});
|
|
17411
17923
|
tx.addOutput({
|
|
17412
17924
|
amount: 0n,
|
|
17413
|
-
script:
|
|
17925
|
+
script: chunkCFQO5MCM_cjs.OP_RETURN_EMPTY_PKSCRIPT
|
|
17414
17926
|
});
|
|
17415
17927
|
return tx;
|
|
17416
17928
|
}
|
|
17417
17929
|
function craftBIP322ToSignSimple(toSpend, pkScript) {
|
|
17418
|
-
const tx = new
|
|
17930
|
+
const tx = new chunkCFQO5MCM_cjs.Transaction({ version: 0 });
|
|
17419
17931
|
tx.addInput({
|
|
17420
17932
|
txid: toSpend.id,
|
|
17421
17933
|
index: 0,
|
|
@@ -17427,12 +17939,138 @@ function craftBIP322ToSignSimple(toSpend, pkScript) {
|
|
|
17427
17939
|
});
|
|
17428
17940
|
tx.addOutput({
|
|
17429
17941
|
amount: 0n,
|
|
17430
|
-
script:
|
|
17942
|
+
script: chunkCFQO5MCM_cjs.OP_RETURN_EMPTY_PKSCRIPT
|
|
17431
17943
|
});
|
|
17432
17944
|
return tx;
|
|
17433
17945
|
}
|
|
17946
|
+
|
|
17947
|
+
// src/providers/emulator.ts
|
|
17948
|
+
var RestEmulatorProvider = class {
|
|
17949
|
+
constructor(serverUrl) {
|
|
17950
|
+
this.serverUrl = serverUrl;
|
|
17951
|
+
}
|
|
17952
|
+
serverUrl;
|
|
17953
|
+
async getInfo() {
|
|
17954
|
+
const url = `${this.serverUrl}/v1/info`;
|
|
17955
|
+
const response = await fetch(url);
|
|
17956
|
+
if (!response.ok) {
|
|
17957
|
+
const errorText2 = await response.text();
|
|
17958
|
+
throw new Error(`Failed to get emulator info: ${errorText2}`);
|
|
17959
|
+
}
|
|
17960
|
+
const data = await response.json();
|
|
17961
|
+
const signerPubkey = data.signerPubkey;
|
|
17962
|
+
if (typeof signerPubkey !== "string" || !signerPubkey) {
|
|
17963
|
+
throw new Error("Invalid emulator info response: missing signerPubkey");
|
|
17964
|
+
}
|
|
17965
|
+
return { signerPubkey };
|
|
17966
|
+
}
|
|
17967
|
+
async submitTx(arkTx, checkpointTxs) {
|
|
17968
|
+
const url = `${this.serverUrl}/v1/tx`;
|
|
17969
|
+
const response = await fetch(url, {
|
|
17970
|
+
method: "POST",
|
|
17971
|
+
headers: { "Content-Type": "application/json" },
|
|
17972
|
+
body: JSON.stringify({
|
|
17973
|
+
arkTx,
|
|
17974
|
+
checkpointTxs
|
|
17975
|
+
})
|
|
17976
|
+
});
|
|
17977
|
+
if (!response.ok) {
|
|
17978
|
+
const errorText2 = await response.text();
|
|
17979
|
+
throw new Error(`Failed to submit tx to emulator: ${errorText2}`);
|
|
17980
|
+
}
|
|
17981
|
+
const data = await response.json();
|
|
17982
|
+
if (typeof data.signedArkTx !== "string" || !data.signedArkTx) {
|
|
17983
|
+
throw new Error("Invalid emulator submitTx response: missing signedArkTx");
|
|
17984
|
+
}
|
|
17985
|
+
if (!Array.isArray(data.signedCheckpointTxs) || !data.signedCheckpointTxs.every((item) => typeof item === "string")) {
|
|
17986
|
+
throw new Error(
|
|
17987
|
+
"Invalid emulator submitTx response: signedCheckpointTxs must be an array of strings"
|
|
17988
|
+
);
|
|
17989
|
+
}
|
|
17990
|
+
return {
|
|
17991
|
+
signedArkTx: data.signedArkTx,
|
|
17992
|
+
signedCheckpointTxs: data.signedCheckpointTxs
|
|
17993
|
+
};
|
|
17994
|
+
}
|
|
17995
|
+
async submitIntent(intent) {
|
|
17996
|
+
const url = `${this.serverUrl}/v1/intent`;
|
|
17997
|
+
const response = await fetch(url, {
|
|
17998
|
+
method: "POST",
|
|
17999
|
+
headers: { "Content-Type": "application/json" },
|
|
18000
|
+
body: JSON.stringify({
|
|
18001
|
+
intent: {
|
|
18002
|
+
proof: intent.proof,
|
|
18003
|
+
message: JSON.stringify(intent.message)
|
|
18004
|
+
}
|
|
18005
|
+
})
|
|
18006
|
+
});
|
|
18007
|
+
if (!response.ok) {
|
|
18008
|
+
const errorText2 = await response.text();
|
|
18009
|
+
throw new Error(`Failed to submit intent to emulator: ${errorText2}`);
|
|
18010
|
+
}
|
|
18011
|
+
const data = await response.json();
|
|
18012
|
+
if (typeof data.signedProof !== "string" || !data.signedProof) {
|
|
18013
|
+
throw new Error("Invalid emulator submitIntent response: missing signedProof");
|
|
18014
|
+
}
|
|
18015
|
+
return data.signedProof;
|
|
18016
|
+
}
|
|
18017
|
+
async submitFinalization(intent, forfeits, connectorTree, commitmentTx) {
|
|
18018
|
+
const url = `${this.serverUrl}/v1/finalization`;
|
|
18019
|
+
const response = await fetch(url, {
|
|
18020
|
+
method: "POST",
|
|
18021
|
+
headers: { "Content-Type": "application/json" },
|
|
18022
|
+
// Uses "signedIntent" (not "intent") because the proof was already
|
|
18023
|
+
// co-signed by the emulator via submitIntent in a prior step.
|
|
18024
|
+
body: JSON.stringify({
|
|
18025
|
+
signedIntent: {
|
|
18026
|
+
proof: intent.proof,
|
|
18027
|
+
message: JSON.stringify(intent.message)
|
|
18028
|
+
},
|
|
18029
|
+
forfeits,
|
|
18030
|
+
connectorTree,
|
|
18031
|
+
commitmentTx
|
|
18032
|
+
})
|
|
18033
|
+
});
|
|
18034
|
+
if (!response.ok) {
|
|
18035
|
+
const errorText2 = await response.text();
|
|
18036
|
+
throw new Error(`Failed to submit finalization to emulator: ${errorText2}`);
|
|
18037
|
+
}
|
|
18038
|
+
const data = await response.json();
|
|
18039
|
+
if (!Array.isArray(data.signedForfeits) || !data.signedForfeits.every((item) => typeof item === "string")) {
|
|
18040
|
+
throw new Error(
|
|
18041
|
+
"Invalid emulator submitFinalization response: signedForfeits must be an array of strings"
|
|
18042
|
+
);
|
|
18043
|
+
}
|
|
18044
|
+
if ("signedCommitmentTx" in data && typeof data.signedCommitmentTx !== "string") {
|
|
18045
|
+
throw new Error(
|
|
18046
|
+
"Invalid emulator submitFinalization response: invalid signedCommitmentTx"
|
|
18047
|
+
);
|
|
18048
|
+
}
|
|
18049
|
+
return {
|
|
18050
|
+
signedForfeits: data.signedForfeits,
|
|
18051
|
+
signedCommitmentTx: data.signedCommitmentTx
|
|
18052
|
+
};
|
|
18053
|
+
}
|
|
18054
|
+
async submitOnchainTx(tx) {
|
|
18055
|
+
const url = `${this.serverUrl}/v1/onchain-tx`;
|
|
18056
|
+
const response = await fetch(url, {
|
|
18057
|
+
method: "POST",
|
|
18058
|
+
headers: { "Content-Type": "application/json" },
|
|
18059
|
+
body: JSON.stringify({ tx })
|
|
18060
|
+
});
|
|
18061
|
+
if (!response.ok) {
|
|
18062
|
+
const errorText2 = await response.text();
|
|
18063
|
+
throw new Error(`Failed to submit onchain tx to emulator: ${errorText2}`);
|
|
18064
|
+
}
|
|
18065
|
+
const data = await response.json();
|
|
18066
|
+
if (typeof data.signedTx !== "string" || !data.signedTx) {
|
|
18067
|
+
throw new Error("Invalid emulator submitOnchainTx response: missing signedTx");
|
|
18068
|
+
}
|
|
18069
|
+
return { signedTx: data.signedTx };
|
|
18070
|
+
}
|
|
18071
|
+
};
|
|
17434
18072
|
function finalizeVirtualTx(type, psbtBase64) {
|
|
17435
|
-
const tx =
|
|
18073
|
+
const tx = chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(psbtBase64));
|
|
17436
18074
|
if (type === "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */) {
|
|
17437
18075
|
const input = tx.getInput(0);
|
|
17438
18076
|
if (!input) {
|
|
@@ -17459,14 +18097,14 @@ var ExitPathError = class extends Error {
|
|
|
17459
18097
|
reason;
|
|
17460
18098
|
};
|
|
17461
18099
|
function delayWeight(sequence) {
|
|
17462
|
-
const t =
|
|
18100
|
+
const t = chunkL5ND2FJJ_cjs.sequenceToTimelock(sequence);
|
|
17463
18101
|
return t.type === "blocks" ? Number(t.value) : Number(t.value) / 600;
|
|
17464
18102
|
}
|
|
17465
18103
|
async function resolveUnilateralPath(params) {
|
|
17466
18104
|
const { vtxo, scriptHex, contractRepository } = params;
|
|
17467
18105
|
const contract = contractRepository ? (await contractRepository.getContracts({ script: scriptHex }))[0] : void 0;
|
|
17468
18106
|
if (contract) {
|
|
17469
|
-
const handler =
|
|
18107
|
+
const handler = chunkRQSA7ADZ_cjs.contractHandlers.get(contract.type);
|
|
17470
18108
|
if (!handler) {
|
|
17471
18109
|
throw new ExitPathError(
|
|
17472
18110
|
"no-handler",
|
|
@@ -17489,12 +18127,12 @@ async function resolveUnilateralPath(params) {
|
|
|
17489
18127
|
paths.sort((a, b) => delayWeight(a.sequence) - delayWeight(b.sequence));
|
|
17490
18128
|
return { selection: paths[0], label: `${contract.type}:unilateral` };
|
|
17491
18129
|
}
|
|
17492
|
-
const decoded =
|
|
18130
|
+
const decoded = chunkL5ND2FJJ_cjs.VtxoScript.decode(vtxo.tapTree);
|
|
17493
18131
|
let best;
|
|
17494
18132
|
for (const exit of decoded.exitPaths()) {
|
|
17495
18133
|
const leaf = decoded.findLeaf(base.hex.encode(exit.script));
|
|
17496
18134
|
if (!leaf) continue;
|
|
17497
|
-
const sequence =
|
|
18135
|
+
const sequence = chunkL5ND2FJJ_cjs.timelockToSequence(exit.params.timelock);
|
|
17498
18136
|
const weight = delayWeight(sequence);
|
|
17499
18137
|
if (!best || weight < best.weight) {
|
|
17500
18138
|
best = { selection: { leaf, sequence }, weight };
|
|
@@ -17680,14 +18318,14 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
17680
18318
|
}
|
|
17681
18319
|
const resolved = await resolveUnilateralPath({
|
|
17682
18320
|
vtxo,
|
|
17683
|
-
scriptHex: base.hex.encode(
|
|
18321
|
+
scriptHex: base.hex.encode(chunkL5ND2FJJ_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
|
|
17684
18322
|
contractRepository: wallet.contractRepository,
|
|
17685
18323
|
walletPubKeyHex: base.hex.encode(await wallet.identity.xOnlyPublicKey()),
|
|
17686
18324
|
currentTime: Date.now()
|
|
17687
18325
|
});
|
|
17688
18326
|
const spendingLeaf = resolved.selection.leaf;
|
|
17689
18327
|
const sequence = resolved.selection.sequence;
|
|
17690
|
-
const timelock =
|
|
18328
|
+
const timelock = chunkL5ND2FJJ_cjs.sequenceToTimelock(sequence);
|
|
17691
18329
|
const elapsed = timelock.type === "blocks" ? chainTip.height >= txStatus.blockHeight + Number(timelock.value) : chainTip.time >= txStatus.blockTime + Number(timelock.value);
|
|
17692
18330
|
if (!elapsed) {
|
|
17693
18331
|
throw new Error(`no available exit path found for vtxo ${vtxo.txid}:${vtxo.vout}`);
|
|
@@ -17700,7 +18338,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
17700
18338
|
sequence,
|
|
17701
18339
|
witnessUtxo: {
|
|
17702
18340
|
amount: BigInt(vtxo.value),
|
|
17703
|
-
script:
|
|
18341
|
+
script: chunkL5ND2FJJ_cjs.VtxoScript.decode(vtxo.tapTree).pkScript
|
|
17704
18342
|
},
|
|
17705
18343
|
sighashType: btcSigner.SigHash.DEFAULT
|
|
17706
18344
|
});
|
|
@@ -17710,7 +18348,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
17710
18348
|
btcSigner.TaprootControlBlock.encode(spendingLeaf[0]).length
|
|
17711
18349
|
);
|
|
17712
18350
|
}
|
|
17713
|
-
const tx = new
|
|
18351
|
+
const tx = new chunkCFQO5MCM_cjs.Transaction({ version: 2 });
|
|
17714
18352
|
for (const input of inputs) {
|
|
17715
18353
|
tx.addInput(input);
|
|
17716
18354
|
}
|
|
@@ -17777,7 +18415,7 @@ async function buildSignedSweep(params) {
|
|
|
17777
18415
|
`uneconomic vtxo ${vtxo.txid}:${vtxo.vout}: value ${vtxo.value} - fee ${fee} < dust`
|
|
17778
18416
|
);
|
|
17779
18417
|
}
|
|
17780
|
-
const tx = new
|
|
18418
|
+
const tx = new chunkCFQO5MCM_cjs.Transaction({ version: 2 });
|
|
17781
18419
|
tx.addInput({
|
|
17782
18420
|
txid: vtxo.txid,
|
|
17783
18421
|
index: vtxo.vout,
|
|
@@ -17802,7 +18440,7 @@ async function buildSignedSweep(params) {
|
|
|
17802
18440
|
finalScriptWitness: [
|
|
17803
18441
|
tapScriptSig[0][1],
|
|
17804
18442
|
...path.extraWitness,
|
|
17805
|
-
|
|
18443
|
+
chunkL5ND2FJJ_cjs.scriptFromTapLeafScript(path.leaf),
|
|
17806
18444
|
btcSigner.TaprootControlBlock.encode(controlBlock)
|
|
17807
18445
|
]
|
|
17808
18446
|
});
|
|
@@ -17847,7 +18485,7 @@ async function selectExitVtxos(opts) {
|
|
|
17847
18485
|
`no contract registered for vtxo script ${vtxo.script} \u2014 register the contract before exiting`
|
|
17848
18486
|
);
|
|
17849
18487
|
}
|
|
17850
|
-
const handler =
|
|
18488
|
+
const handler = chunkRQSA7ADZ_cjs.contractHandlers.get(contract.type);
|
|
17851
18489
|
if (!handler) {
|
|
17852
18490
|
throw new Error(`no contract handler registered for type '${contract.type}'`);
|
|
17853
18491
|
}
|
|
@@ -17877,7 +18515,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
17877
18515
|
if (pendingNodes.length > 0) {
|
|
17878
18516
|
const txs = await resolver.getVirtualTxs(pendingNodes.map((n) => n.txid));
|
|
17879
18517
|
for (const psbt of txs) {
|
|
17880
|
-
psbts.set(
|
|
18518
|
+
psbts.set(chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(psbt)).id, psbt);
|
|
17881
18519
|
}
|
|
17882
18520
|
}
|
|
17883
18521
|
const childVsize = Number(
|
|
@@ -17913,7 +18551,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
17913
18551
|
try {
|
|
17914
18552
|
const resolved = await resolveUnilateralPath({
|
|
17915
18553
|
vtxo,
|
|
17916
|
-
scriptHex: base.hex.encode(
|
|
18554
|
+
scriptHex: base.hex.encode(chunkL5ND2FJJ_cjs.VtxoScript.decode(vtxo.tapTree).pkScript),
|
|
17917
18555
|
contractRepository: wallet.contractRepository,
|
|
17918
18556
|
walletPubKeyHex,
|
|
17919
18557
|
currentTime: Date.now()
|
|
@@ -17932,7 +18570,7 @@ async function computeExitLayout(opts, feeRate) {
|
|
|
17932
18570
|
});
|
|
17933
18571
|
continue;
|
|
17934
18572
|
}
|
|
17935
|
-
const t =
|
|
18573
|
+
const t = chunkL5ND2FJJ_cjs.sequenceToTimelock(resolved.selection.sequence);
|
|
17936
18574
|
const delay = { type: t.type, value: Number(t.value) };
|
|
17937
18575
|
infos.push({ outpoint, value: vtxo.value, sweepFee, path: resolved.label, delay });
|
|
17938
18576
|
sweeps.push({ vtxo, resolved, sweepFee, delay });
|
|
@@ -18239,7 +18877,7 @@ async function prepare(opts) {
|
|
|
18239
18877
|
txid: sweep.vtxo.txid,
|
|
18240
18878
|
vout: sweep.vtxo.vout,
|
|
18241
18879
|
value: sweep.vtxo.value,
|
|
18242
|
-
pkScript:
|
|
18880
|
+
pkScript: chunkL5ND2FJJ_cjs.VtxoScript.decode(sweep.vtxo.tapTree).pkScript
|
|
18243
18881
|
},
|
|
18244
18882
|
path: sweep.resolved.selection,
|
|
18245
18883
|
outputAddress: opts.sweepAddress,
|
|
@@ -18324,7 +18962,7 @@ async function prepare(opts) {
|
|
|
18324
18962
|
if (newFee <= splitterFee) break;
|
|
18325
18963
|
splitterFee = newFee;
|
|
18326
18964
|
}
|
|
18327
|
-
const splitter = new
|
|
18965
|
+
const splitter = new chunkCFQO5MCM_cjs.Transaction({ version: 2 });
|
|
18328
18966
|
for (const coin of selected.inputs) {
|
|
18329
18967
|
splitter.addInput({
|
|
18330
18968
|
txid: coin.txid,
|
|
@@ -18463,6 +19101,656 @@ var UnilateralExit = {
|
|
|
18463
19101
|
prepare,
|
|
18464
19102
|
Executor
|
|
18465
19103
|
};
|
|
19104
|
+
|
|
19105
|
+
// src/arkade/index.ts
|
|
19106
|
+
var arkade_exports = {};
|
|
19107
|
+
chunk5BLDMQED_cjs.__export(arkade_exports, {
|
|
19108
|
+
ARKADE_OP: () => chunkRQSA7ADZ_cjs.ARKADE_OP,
|
|
19109
|
+
ARKADE_OPCODES: () => chunkRQSA7ADZ_cjs.ARKADE_OPCODES,
|
|
19110
|
+
ARKADE_OPCODE_NAMES: () => chunkRQSA7ADZ_cjs.ARKADE_OPCODE_NAMES,
|
|
19111
|
+
ARKADE_OPCODE_VALUES: () => chunkRQSA7ADZ_cjs.ARKADE_OPCODE_VALUES,
|
|
19112
|
+
ARKADE_OPS: () => chunkRQSA7ADZ_cjs.ARKADE_OPS,
|
|
19113
|
+
Arkade: () => Arkade,
|
|
19114
|
+
ArkadeContract: () => ArkadeContract,
|
|
19115
|
+
ArkadeProgramScript: () => chunkRQSA7ADZ_cjs.ArkadeProgramScript,
|
|
19116
|
+
ArkadeScript: () => chunkRQSA7ADZ_cjs.ArkadeScript,
|
|
19117
|
+
ArkadeTransactionBuilder: () => ArkadeTransactionBuilder,
|
|
19118
|
+
BigNum: () => chunkRQSA7ADZ_cjs.bignum_exports,
|
|
19119
|
+
OP: () => btcSigner.OP,
|
|
19120
|
+
OPCODE_NAMES: () => chunkRQSA7ADZ_cjs.OPCODE_NAMES,
|
|
19121
|
+
OPCODE_VALUES: () => chunkRQSA7ADZ_cjs.OPCODE_VALUES,
|
|
19122
|
+
SUPPORTED_PROGRAM_VERSION: () => chunkRQSA7ADZ_cjs.SUPPORTED_PROGRAM_VERSION,
|
|
19123
|
+
Script: () => btcSigner.Script,
|
|
19124
|
+
arkadeScriptHash: () => chunkRQSA7ADZ_cjs.arkadeScriptHash,
|
|
19125
|
+
arkadeWitnessHash: () => chunkRQSA7ADZ_cjs.arkadeWitnessHash,
|
|
19126
|
+
asmToBytes: () => chunkRQSA7ADZ_cjs.asmToBytes,
|
|
19127
|
+
bytesToASM: () => chunkRQSA7ADZ_cjs.bytesToASM,
|
|
19128
|
+
computeArkadeScriptPublicKey: () => chunkRQSA7ADZ_cjs.computeArkadeScriptPublicKey,
|
|
19129
|
+
createArkadeBatchHandler: () => createArkadeBatchHandler,
|
|
19130
|
+
deserializeArkadeContractParams: () => chunkRQSA7ADZ_cjs.deserializeArkadeContractParams,
|
|
19131
|
+
fromASM: () => chunkRQSA7ADZ_cjs.fromASM,
|
|
19132
|
+
getOpcodeName: () => chunkRQSA7ADZ_cjs.getOpcodeName,
|
|
19133
|
+
getOpcodeValue: () => chunkRQSA7ADZ_cjs.getOpcodeValue,
|
|
19134
|
+
parseArtifact: () => chunkRQSA7ADZ_cjs.parseArtifact,
|
|
19135
|
+
resolveAsm: () => chunkRQSA7ADZ_cjs.resolveAsm,
|
|
19136
|
+
serializeArkadeContractParams: () => chunkRQSA7ADZ_cjs.serializeArkadeContractParams,
|
|
19137
|
+
stringifyArtifact: () => chunkRQSA7ADZ_cjs.stringifyArtifact,
|
|
19138
|
+
toASM: () => chunkRQSA7ADZ_cjs.toASM,
|
|
19139
|
+
validateProgram: () => chunkRQSA7ADZ_cjs.validateProgram,
|
|
19140
|
+
witnessRefToBytes: () => chunkRQSA7ADZ_cjs.witnessRefToBytes
|
|
19141
|
+
});
|
|
19142
|
+
var isVtxoCoin = (input) => "virtualStatus" in input;
|
|
19143
|
+
function createArkadeBatchHandler(intentId, inputs, signer, signedProof, message, session, arkProvider, emulator, network, recipients) {
|
|
19144
|
+
let batchId;
|
|
19145
|
+
let sweepTapTreeRoot;
|
|
19146
|
+
return {
|
|
19147
|
+
onBatchStarted: async (event) => {
|
|
19148
|
+
const utf8IntentId = new TextEncoder().encode(intentId);
|
|
19149
|
+
const intentIdHash = utils_js.sha256(utf8IntentId);
|
|
19150
|
+
const intentIdHashStr = base.hex.encode(intentIdHash);
|
|
19151
|
+
if (!event.intentIdHashes.includes(intentIdHashStr)) return { skip: true };
|
|
19152
|
+
await arkProvider.confirmRegistration(intentId);
|
|
19153
|
+
batchId = event.id;
|
|
19154
|
+
const sweepTapscript = chunkL5ND2FJJ_cjs.CSVMultisigTapscript.encode({
|
|
19155
|
+
timelock: {
|
|
19156
|
+
value: event.batchExpiry,
|
|
19157
|
+
// BIP-65: values >= 512 are interpreted as seconds, below as blocks
|
|
19158
|
+
type: event.batchExpiry >= 512n ? "seconds" : "blocks"
|
|
19159
|
+
},
|
|
19160
|
+
pubkeys: [base.hex.decode((await arkProvider.getInfo()).forfeitPubkey).subarray(1)]
|
|
19161
|
+
}).script;
|
|
19162
|
+
sweepTapTreeRoot = payment_js.tapLeafHash(sweepTapscript);
|
|
19163
|
+
return { skip: false };
|
|
19164
|
+
},
|
|
19165
|
+
onTreeSigningStarted: async (event, vtxoTree) => {
|
|
19166
|
+
const signerPubKey = await session.getPublicKey();
|
|
19167
|
+
const xonlySignerPubKey = signerPubKey.subarray(1);
|
|
19168
|
+
const xOnlyPubkeys = event.cosignersPublicKeys.map((k) => k.slice(2));
|
|
19169
|
+
if (!xOnlyPubkeys.includes(base.hex.encode(xonlySignerPubKey))) {
|
|
19170
|
+
return { skip: true };
|
|
19171
|
+
}
|
|
19172
|
+
const commitmentTx = chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(event.unsignedCommitmentTx));
|
|
19173
|
+
validateVtxoTxGraph(vtxoTree, commitmentTx, sweepTapTreeRoot);
|
|
19174
|
+
if (recipients && recipients.length > 0) {
|
|
19175
|
+
validateBatchRecipients(commitmentTx, vtxoTree.leaves(), recipients, network);
|
|
19176
|
+
}
|
|
19177
|
+
const sharedOutput = commitmentTx.getOutput(0);
|
|
19178
|
+
if (!sharedOutput?.amount) {
|
|
19179
|
+
throw new Error("Shared output not found");
|
|
19180
|
+
}
|
|
19181
|
+
await session.init(vtxoTree, sweepTapTreeRoot, sharedOutput.amount);
|
|
19182
|
+
const pubkey = base.hex.encode(await session.getPublicKey());
|
|
19183
|
+
const nonces = await session.getNonces();
|
|
19184
|
+
await arkProvider.submitTreeNonces(batchId, pubkey, nonces);
|
|
19185
|
+
return { skip: false };
|
|
19186
|
+
},
|
|
19187
|
+
onTreeNonces: async (event) => {
|
|
19188
|
+
const { hasAllNonces } = await session.aggregatedNonces(event.txid, event.nonces);
|
|
19189
|
+
if (!hasAllNonces) return { fullySigned: false };
|
|
19190
|
+
const signatures = await session.sign();
|
|
19191
|
+
const pubkey = base.hex.encode(await session.getPublicKey());
|
|
19192
|
+
await arkProvider.submitTreeSignatures(batchId, pubkey, signatures);
|
|
19193
|
+
return { fullySigned: true };
|
|
19194
|
+
},
|
|
19195
|
+
onBatchFinalization: async (event, _vtxoTree, connectorTree) => {
|
|
19196
|
+
const info = await arkProvider.getInfo();
|
|
19197
|
+
const forfeitOutputScript = btcSigner.OutScript.encode(
|
|
19198
|
+
btcSigner.Address(network).decode(info.forfeitAddress)
|
|
19199
|
+
);
|
|
19200
|
+
if (connectorTree) {
|
|
19201
|
+
validateConnectorsTxGraph(event.commitmentTx, connectorTree);
|
|
19202
|
+
}
|
|
19203
|
+
let commitmentPsbt = chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(event.commitmentTx));
|
|
19204
|
+
const signedForfeits = [];
|
|
19205
|
+
let connectorIndex = 0;
|
|
19206
|
+
const connectorLeaves = connectorTree?.leaves() || [];
|
|
19207
|
+
const boardingIndices = [];
|
|
19208
|
+
for (const input of inputs) {
|
|
19209
|
+
if (!isVtxoCoin(input)) {
|
|
19210
|
+
let boardingIdx = null;
|
|
19211
|
+
for (let i = 0; i < commitmentPsbt.inputsLength; i++) {
|
|
19212
|
+
const psbtInput = commitmentPsbt.getInput(i);
|
|
19213
|
+
if (!psbtInput.txid) continue;
|
|
19214
|
+
if (base.hex.encode(psbtInput.txid) === input.txid && psbtInput.index === input.vout) {
|
|
19215
|
+
boardingIdx = i;
|
|
19216
|
+
break;
|
|
19217
|
+
}
|
|
19218
|
+
}
|
|
19219
|
+
if (boardingIdx === null) continue;
|
|
19220
|
+
commitmentPsbt.updateInput(boardingIdx, {
|
|
19221
|
+
tapLeafScript: [input.forfeitTapLeafScript]
|
|
19222
|
+
});
|
|
19223
|
+
boardingIndices.push(boardingIdx);
|
|
19224
|
+
continue;
|
|
19225
|
+
}
|
|
19226
|
+
if (isRecoverable(input) || isSubdust(input, info.dust)) {
|
|
19227
|
+
continue;
|
|
19228
|
+
}
|
|
19229
|
+
if (connectorIndex >= connectorLeaves.length) {
|
|
19230
|
+
throw new Error("not enough connectors received");
|
|
19231
|
+
}
|
|
19232
|
+
const connectorLeaf = connectorLeaves[connectorIndex++];
|
|
19233
|
+
const connectorTxId = connectorLeaf.id;
|
|
19234
|
+
const connectorOutput = connectorLeaf.getOutput(0);
|
|
19235
|
+
if (!connectorOutput?.amount || !connectorOutput?.script) {
|
|
19236
|
+
throw new Error(
|
|
19237
|
+
`Invalid connector output at index ${connectorIndex - 1}: missing amount or script`
|
|
19238
|
+
);
|
|
19239
|
+
}
|
|
19240
|
+
let forfeitTx = buildForfeitTx(
|
|
19241
|
+
[
|
|
19242
|
+
{
|
|
19243
|
+
txid: input.txid,
|
|
19244
|
+
index: input.vout,
|
|
19245
|
+
witnessUtxo: {
|
|
19246
|
+
amount: BigInt(input.value),
|
|
19247
|
+
script: chunkL5ND2FJJ_cjs.VtxoScript.decode(input.tapTree).pkScript
|
|
19248
|
+
},
|
|
19249
|
+
sighashType: btcSigner.SigHash.DEFAULT,
|
|
19250
|
+
tapLeafScript: [input.forfeitTapLeafScript]
|
|
19251
|
+
},
|
|
19252
|
+
{
|
|
19253
|
+
txid: connectorTxId,
|
|
19254
|
+
index: 0,
|
|
19255
|
+
witnessUtxo: {
|
|
19256
|
+
amount: connectorOutput.amount,
|
|
19257
|
+
script: connectorOutput.script
|
|
19258
|
+
}
|
|
19259
|
+
}
|
|
19260
|
+
],
|
|
19261
|
+
forfeitOutputScript
|
|
19262
|
+
);
|
|
19263
|
+
forfeitTx = await signer.sign(forfeitTx, [0]);
|
|
19264
|
+
signedForfeits.push(base.base64.encode(forfeitTx.toPSBT()));
|
|
19265
|
+
}
|
|
19266
|
+
if (boardingIndices.length > 0) {
|
|
19267
|
+
commitmentPsbt = await signer.sign(commitmentPsbt, boardingIndices);
|
|
19268
|
+
}
|
|
19269
|
+
let connectorTreeNodes = null;
|
|
19270
|
+
if (connectorTree) {
|
|
19271
|
+
connectorTreeNodes = [];
|
|
19272
|
+
for (const subtree of connectorTree.iterator()) {
|
|
19273
|
+
const children = {};
|
|
19274
|
+
for (const [outputIndex, child] of subtree.children) {
|
|
19275
|
+
children[String(outputIndex)] = child.txid;
|
|
19276
|
+
}
|
|
19277
|
+
connectorTreeNodes.push({
|
|
19278
|
+
txid: subtree.txid,
|
|
19279
|
+
tx: base.base64.encode(subtree.root.toPSBT()),
|
|
19280
|
+
children
|
|
19281
|
+
});
|
|
19282
|
+
}
|
|
19283
|
+
}
|
|
19284
|
+
const hasBoardingInputs = boardingIndices.length > 0;
|
|
19285
|
+
const commitmentB64 = hasBoardingInputs ? base.base64.encode(commitmentPsbt.toPSBT()) : event.commitmentTx;
|
|
19286
|
+
const emuResult = await emulator.submitFinalization(
|
|
19287
|
+
{ proof: signedProof, message },
|
|
19288
|
+
signedForfeits,
|
|
19289
|
+
connectorTreeNodes,
|
|
19290
|
+
commitmentB64
|
|
19291
|
+
);
|
|
19292
|
+
await arkProvider.submitSignedForfeitTxs(
|
|
19293
|
+
emuResult.signedForfeits,
|
|
19294
|
+
emuResult.signedCommitmentTx || (hasBoardingInputs ? commitmentB64 : void 0)
|
|
19295
|
+
);
|
|
19296
|
+
}
|
|
19297
|
+
};
|
|
19298
|
+
}
|
|
19299
|
+
var Arkade = class _Arkade {
|
|
19300
|
+
arkProvider;
|
|
19301
|
+
/** The co-signing service, or undefined for emulator-less (pure tapscript) usage. */
|
|
19302
|
+
emulator;
|
|
19303
|
+
network;
|
|
19304
|
+
serverKey;
|
|
19305
|
+
/** The co-signer's x-only key, present only when an emulator is configured. */
|
|
19306
|
+
emulatorKey;
|
|
19307
|
+
checkpoint;
|
|
19308
|
+
indexer;
|
|
19309
|
+
identity;
|
|
19310
|
+
/** The signing identity's x-only public key, resolved at connect — identifies which inputs the wallet signs. */
|
|
19311
|
+
userKey;
|
|
19312
|
+
/** The wallet's contract manager, when contract persistence is wired up. */
|
|
19313
|
+
contractManager;
|
|
19314
|
+
constructor(fields) {
|
|
19315
|
+
this.arkProvider = fields.arkProvider;
|
|
19316
|
+
this.emulator = fields.emulator;
|
|
19317
|
+
this.network = fields.network;
|
|
19318
|
+
this.serverKey = fields.serverKey;
|
|
19319
|
+
this.emulatorKey = fields.emulatorKey;
|
|
19320
|
+
this.checkpoint = fields.checkpoint;
|
|
19321
|
+
this.indexer = fields.indexer;
|
|
19322
|
+
this.identity = fields.identity;
|
|
19323
|
+
this.userKey = fields.userKey;
|
|
19324
|
+
this.contractManager = fields.contractManager;
|
|
19325
|
+
}
|
|
19326
|
+
/** Connect and resolve the server key, checkpoint closure and (if present) the co-signer key. */
|
|
19327
|
+
static async connect(opts) {
|
|
19328
|
+
const info = await opts.arkade.getInfo();
|
|
19329
|
+
const serverKey = base.hex.decode(info.signerPubkey).slice(1);
|
|
19330
|
+
const checkpoint = chunkL5ND2FJJ_cjs.CSVMultisigTapscript.decode(base.hex.decode(info.checkpointTapscript));
|
|
19331
|
+
let emulatorKey;
|
|
19332
|
+
if (opts.emulator) {
|
|
19333
|
+
const eInfo = await opts.emulator.getInfo();
|
|
19334
|
+
emulatorKey = base.hex.decode(eInfo.signerPubkey);
|
|
19335
|
+
}
|
|
19336
|
+
let userKey;
|
|
19337
|
+
if (opts.identity) {
|
|
19338
|
+
const pub = await opts.identity.xOnlyPublicKey();
|
|
19339
|
+
userKey = pub.length === 33 ? pub.slice(1) : pub;
|
|
19340
|
+
}
|
|
19341
|
+
return new _Arkade({
|
|
19342
|
+
arkProvider: opts.arkade,
|
|
19343
|
+
emulator: opts.emulator,
|
|
19344
|
+
network: opts.network ?? chunkL5ND2FJJ_cjs.DEFAULT_NETWORK,
|
|
19345
|
+
serverKey,
|
|
19346
|
+
emulatorKey,
|
|
19347
|
+
checkpoint,
|
|
19348
|
+
indexer: opts.indexer,
|
|
19349
|
+
identity: opts.identity,
|
|
19350
|
+
userKey,
|
|
19351
|
+
contractManager: opts.contractManager
|
|
19352
|
+
});
|
|
19353
|
+
}
|
|
19354
|
+
/**
|
|
19355
|
+
* Instantiate a contract from a program and its constructor arguments. The
|
|
19356
|
+
* `program`'s literal type is preserved (`const` inference) so the resulting
|
|
19357
|
+
* contract's `functions` map is strongly typed — `functions.<name>(...)`
|
|
19358
|
+
* knows each argument's type from the function's `inputs` descriptors.
|
|
19359
|
+
*
|
|
19360
|
+
* When the program declares a `server` or `user` param and the caller does
|
|
19361
|
+
* not bind it, it defaults to the client's server key or the identity's
|
|
19362
|
+
* key respectively; explicit args always win.
|
|
19363
|
+
*/
|
|
19364
|
+
contract(program, args = {}) {
|
|
19365
|
+
const declared = (program.params ?? []).map(chunkRQSA7ADZ_cjs.inputName);
|
|
19366
|
+
if (declared.includes("server") && args.server === void 0) {
|
|
19367
|
+
args = { ...args, server: this.serverKey };
|
|
19368
|
+
}
|
|
19369
|
+
if (declared.includes("user") && args.user === void 0 && this.userKey) {
|
|
19370
|
+
args = { ...args, user: this.userKey };
|
|
19371
|
+
}
|
|
19372
|
+
return new ArkadeContract(this, program, args);
|
|
19373
|
+
}
|
|
19374
|
+
};
|
|
19375
|
+
var ArkadeContract = class _ArkadeContract {
|
|
19376
|
+
constructor(client, program, args = {}, keys) {
|
|
19377
|
+
this.client = client;
|
|
19378
|
+
this.program = program;
|
|
19379
|
+
this.args = args;
|
|
19380
|
+
this.keys = keys ?? {
|
|
19381
|
+
serverKey: client.serverKey,
|
|
19382
|
+
userKey: client.userKey,
|
|
19383
|
+
emulatorKey: client.emulatorKey
|
|
19384
|
+
};
|
|
19385
|
+
this.vtxoScript = new chunkRQSA7ADZ_cjs.ArkadeProgramScript(program, args, this.keys);
|
|
19386
|
+
this.tapTree = this.vtxoScript.encode();
|
|
19387
|
+
this.compiled = this.vtxoScript.compiled;
|
|
19388
|
+
}
|
|
19389
|
+
client;
|
|
19390
|
+
program;
|
|
19391
|
+
args;
|
|
19392
|
+
/** The compiled taproot tree of spending-path leaves. */
|
|
19393
|
+
vtxoScript;
|
|
19394
|
+
/** Encoded taproot tree (shared spend context for every path). */
|
|
19395
|
+
tapTree;
|
|
19396
|
+
/** The signer keys the program was compiled against. */
|
|
19397
|
+
keys;
|
|
19398
|
+
/** Spending paths in declaration order. */
|
|
19399
|
+
compiled;
|
|
19400
|
+
/**
|
|
19401
|
+
* Rebuild a callable contract from a persisted `"arkade"` contract row
|
|
19402
|
+
* (see {@link ArkadeContract.register}). The stored keys are used for
|
|
19403
|
+
* compilation — not the client's current ones — so the derived script and
|
|
19404
|
+
* address stay identical to the registered contract even after a server
|
|
19405
|
+
* signer rotation.
|
|
19406
|
+
*/
|
|
19407
|
+
static fromContract(client, contract) {
|
|
19408
|
+
if (contract.type !== "arkade") {
|
|
19409
|
+
throw new Error(
|
|
19410
|
+
`ArkadeContract.fromContract: expected contract type 'arkade', got '${contract.type}'`
|
|
19411
|
+
);
|
|
19412
|
+
}
|
|
19413
|
+
const typed = chunkRQSA7ADZ_cjs.deserializeArkadeContractParams(contract.params);
|
|
19414
|
+
return new _ArkadeContract(client, typed.program, typed.args, {
|
|
19415
|
+
serverKey: typed.serverKey,
|
|
19416
|
+
userKey: typed.userKey,
|
|
19417
|
+
emulatorKey: typed.emulatorKey
|
|
19418
|
+
});
|
|
19419
|
+
}
|
|
19420
|
+
/** Resolve the {@link TapLeafScript} for a spending path by its index. */
|
|
19421
|
+
leafScript(index) {
|
|
19422
|
+
const fn = this.compiled[index];
|
|
19423
|
+
if (!fn) throw new Error(`leaf index ${index} out of range`);
|
|
19424
|
+
return fn.tapLeafScript;
|
|
19425
|
+
}
|
|
19426
|
+
/** Arkade funding address. */
|
|
19427
|
+
get address() {
|
|
19428
|
+
return this.vtxoScript.address(this.client.network.hrp, this.keys.serverKey).encode();
|
|
19429
|
+
}
|
|
19430
|
+
/** Taproot output script. */
|
|
19431
|
+
get pkScript() {
|
|
19432
|
+
return this.vtxoScript.pkScript;
|
|
19433
|
+
}
|
|
19434
|
+
/**
|
|
19435
|
+
* Callable spending paths: `contract.functions.<name>(...args)`. Strongly
|
|
19436
|
+
* typed from the program's literal type — each function's argument types are
|
|
19437
|
+
* derived from its `inputs` descriptors (see {@link ContractFunctions}).
|
|
19438
|
+
*/
|
|
19439
|
+
get functions() {
|
|
19440
|
+
const out = {};
|
|
19441
|
+
for (const fn of this.compiled) {
|
|
19442
|
+
out[fn.name] = (...callArgs) => new ArkadeTransactionBuilder(this, fn, bindInputs(fn, callArgs));
|
|
19443
|
+
}
|
|
19444
|
+
return out;
|
|
19445
|
+
}
|
|
19446
|
+
/**
|
|
19447
|
+
* The `createContract` payload for this contract — the serialized program,
|
|
19448
|
+
* args and keys plus the derived script/address. Useful when registering
|
|
19449
|
+
* through a manager the client does not hold.
|
|
19450
|
+
*/
|
|
19451
|
+
toContractParams() {
|
|
19452
|
+
return {
|
|
19453
|
+
type: "arkade",
|
|
19454
|
+
params: chunkRQSA7ADZ_cjs.serializeArkadeContractParams({
|
|
19455
|
+
program: this.program,
|
|
19456
|
+
args: this.args,
|
|
19457
|
+
serverKey: this.keys.serverKey,
|
|
19458
|
+
userKey: this.keys.userKey,
|
|
19459
|
+
emulatorKey: this.keys.emulatorKey
|
|
19460
|
+
}),
|
|
19461
|
+
script: base.hex.encode(this.pkScript),
|
|
19462
|
+
address: this.address
|
|
19463
|
+
};
|
|
19464
|
+
}
|
|
19465
|
+
/**
|
|
19466
|
+
* Persist this contract through the wallet's {@link IContractManager} so it
|
|
19467
|
+
* is tracked like any other contract type: stored in the contract
|
|
19468
|
+
* repository, watched for VTXO events, counted in repository-backed
|
|
19469
|
+
* balances, and re-derivable offline via the `"arkade"` contract handler.
|
|
19470
|
+
* Idempotent — re-registering the same script is a no-op.
|
|
19471
|
+
*/
|
|
19472
|
+
async register(options) {
|
|
19473
|
+
const manager = this.client.contractManager;
|
|
19474
|
+
if (!manager) {
|
|
19475
|
+
throw new Error(
|
|
19476
|
+
"ArkadeContract.register requires a `contractManager` on the Arkade client \u2014 pass one to Arkade.connect"
|
|
19477
|
+
);
|
|
19478
|
+
}
|
|
19479
|
+
return manager.createContract({
|
|
19480
|
+
...this.toContractParams(),
|
|
19481
|
+
label: options?.label,
|
|
19482
|
+
metadata: options?.metadata
|
|
19483
|
+
});
|
|
19484
|
+
}
|
|
19485
|
+
/**
|
|
19486
|
+
* Spendable VTXOs locked by this contract.
|
|
19487
|
+
*
|
|
19488
|
+
* When a `contractManager` is configured and this contract is registered,
|
|
19489
|
+
* reads the repository-backed state (offline-first, kept fresh by the
|
|
19490
|
+
* contract watcher). Otherwise falls back to a direct indexer query.
|
|
19491
|
+
*/
|
|
19492
|
+
async getUtxos() {
|
|
19493
|
+
const manager = this.client.contractManager;
|
|
19494
|
+
const scriptHex = base.hex.encode(this.pkScript);
|
|
19495
|
+
if (manager) {
|
|
19496
|
+
const [registered] = await manager.getContracts({ script: scriptHex });
|
|
19497
|
+
if (registered) {
|
|
19498
|
+
const [withVtxos] = await manager.getContractsWithVtxos({ script: scriptHex });
|
|
19499
|
+
return (withVtxos?.vtxos ?? []).filter(isSpendable);
|
|
19500
|
+
}
|
|
19501
|
+
}
|
|
19502
|
+
if (!this.client.indexer) {
|
|
19503
|
+
throw new Error("ArkadeContract.getUtxos: an indexer is required");
|
|
19504
|
+
}
|
|
19505
|
+
const { vtxos } = await this.client.indexer.getVtxos({
|
|
19506
|
+
scripts: [scriptHex],
|
|
19507
|
+
spendableOnly: true
|
|
19508
|
+
});
|
|
19509
|
+
return vtxos;
|
|
19510
|
+
}
|
|
19511
|
+
/** Total spendable balance (requires an indexer). */
|
|
19512
|
+
async getBalance() {
|
|
19513
|
+
const utxos = await this.getUtxos();
|
|
19514
|
+
return utxos.reduce((sum, u) => sum + BigInt(u.value), 0n);
|
|
19515
|
+
}
|
|
19516
|
+
};
|
|
19517
|
+
var ArkadeTransactionBuilder = class {
|
|
19518
|
+
/** @internal */
|
|
19519
|
+
constructor(contract, fn, args) {
|
|
19520
|
+
this.contract = contract;
|
|
19521
|
+
this.fn = fn;
|
|
19522
|
+
this.args = args;
|
|
19523
|
+
}
|
|
19524
|
+
contract;
|
|
19525
|
+
fn;
|
|
19526
|
+
args;
|
|
19527
|
+
outputs = [];
|
|
19528
|
+
fundingCoins = [];
|
|
19529
|
+
assetSpecs = [];
|
|
19530
|
+
coin;
|
|
19531
|
+
changeScript;
|
|
19532
|
+
from(coin) {
|
|
19533
|
+
this.coin = coin;
|
|
19534
|
+
return this;
|
|
19535
|
+
}
|
|
19536
|
+
/**
|
|
19537
|
+
* Add extra inputs the caller funds (e.g. a taker's own coins in a swap).
|
|
19538
|
+
* These become inputs 1..n and are signed with the client identity.
|
|
19539
|
+
*/
|
|
19540
|
+
fund(coins) {
|
|
19541
|
+
this.fundingCoins.push(...coins);
|
|
19542
|
+
return this;
|
|
19543
|
+
}
|
|
19544
|
+
/** Transfer an asset group: which inputs supply it and which outputs receive it. */
|
|
19545
|
+
withAsset(spec) {
|
|
19546
|
+
this.assetSpecs.push(spec);
|
|
19547
|
+
return this;
|
|
19548
|
+
}
|
|
19549
|
+
/** Destination for any surplus (inputs − outputs). Required when the spend is not exact. */
|
|
19550
|
+
change(script) {
|
|
19551
|
+
this.changeScript = script;
|
|
19552
|
+
return this;
|
|
19553
|
+
}
|
|
19554
|
+
to(scriptOrOutputs, amount) {
|
|
19555
|
+
if (Array.isArray(scriptOrOutputs)) {
|
|
19556
|
+
for (const [i, out] of scriptOrOutputs.entries()) {
|
|
19557
|
+
if (out.amount === void 0) {
|
|
19558
|
+
throw new Error(`to(outputs): output ${i} is missing an amount`);
|
|
19559
|
+
}
|
|
19560
|
+
}
|
|
19561
|
+
this.outputs.push(...scriptOrOutputs);
|
|
19562
|
+
} else {
|
|
19563
|
+
if (amount === void 0) throw new Error("to(script, amount): amount is required");
|
|
19564
|
+
this.outputs.push({ script: scriptOrOutputs, amount });
|
|
19565
|
+
}
|
|
19566
|
+
return this;
|
|
19567
|
+
}
|
|
19568
|
+
/** Assemble the unsigned ark transaction and its checkpoints. */
|
|
19569
|
+
async build() {
|
|
19570
|
+
if (this.outputs.length === 0) {
|
|
19571
|
+
throw new Error("ArkadeTransactionBuilder: at least one output is required");
|
|
19572
|
+
}
|
|
19573
|
+
const outputsSum = this.outputs.reduce((s, o) => s + (o.amount ?? 0n), 0n);
|
|
19574
|
+
const coin = this.coin ?? await this.selectCoin(outputsSum);
|
|
19575
|
+
const def = this.fn.def;
|
|
19576
|
+
const outputs = [...this.outputs];
|
|
19577
|
+
const fundingSum = this.fundingCoins.reduce((s, f) => s + BigInt(f.value), 0n);
|
|
19578
|
+
const surplus = BigInt(coin.value) + fundingSum - outputsSum;
|
|
19579
|
+
if (surplus < 0n) {
|
|
19580
|
+
throw new Error(
|
|
19581
|
+
`ArkadeTransactionBuilder: insufficient inputs \u2014 outputs ${outputsSum} exceed inputs ${BigInt(coin.value) + fundingSum}`
|
|
19582
|
+
);
|
|
19583
|
+
}
|
|
19584
|
+
if (surplus > 0n) {
|
|
19585
|
+
if (!this.changeScript) {
|
|
19586
|
+
throw new Error(
|
|
19587
|
+
`ArkadeTransactionBuilder: ${surplus} sats surplus with no change output \u2014 call .change(script)`
|
|
19588
|
+
);
|
|
19589
|
+
}
|
|
19590
|
+
outputs.push({ script: this.changeScript, amount: surplus });
|
|
19591
|
+
}
|
|
19592
|
+
const { arkTx, checkpoints } = buildOffchainTx(
|
|
19593
|
+
[
|
|
19594
|
+
{
|
|
19595
|
+
txid: coin.txid,
|
|
19596
|
+
vout: coin.vout,
|
|
19597
|
+
value: coin.value,
|
|
19598
|
+
tapLeafScript: this.fn.tapLeafScript,
|
|
19599
|
+
tapTree: this.contract.tapTree
|
|
19600
|
+
},
|
|
19601
|
+
...this.fundingCoins
|
|
19602
|
+
],
|
|
19603
|
+
outputs,
|
|
19604
|
+
this.contract.client.checkpoint
|
|
19605
|
+
);
|
|
19606
|
+
if (coin.sourceTx) {
|
|
19607
|
+
chunkCFQO5MCM_cjs.setArkPsbtField(arkTx, 0, chunkCFQO5MCM_cjs.PrevArkTxField, coin.sourceTx);
|
|
19608
|
+
}
|
|
19609
|
+
const condition = (def.tapscript.witness ?? []).map((w) => this.witnessBytes(w));
|
|
19610
|
+
if (condition.length > 0) {
|
|
19611
|
+
chunkCFQO5MCM_cjs.setArkPsbtField(arkTx, 0, chunkCFQO5MCM_cjs.ConditionWitness, condition);
|
|
19612
|
+
chunkCFQO5MCM_cjs.setArkPsbtField(checkpoints[0], 0, chunkCFQO5MCM_cjs.ConditionWitness, condition);
|
|
19613
|
+
}
|
|
19614
|
+
const packets = [];
|
|
19615
|
+
if (this.assetSpecs.length > 0) {
|
|
19616
|
+
packets.push(this.buildAssetPacket());
|
|
19617
|
+
}
|
|
19618
|
+
const arkadeScript = this.fn.arkadeScript;
|
|
19619
|
+
if (arkadeScript) {
|
|
19620
|
+
const stack = (def.arkadeScript?.witness ?? []).map((w) => this.witnessBytes(w));
|
|
19621
|
+
packets.push(
|
|
19622
|
+
EmulatorPacket.create([
|
|
19623
|
+
{ vin: 0, script: arkadeScript, witness: btcSigner.RawWitness.encode(stack) }
|
|
19624
|
+
])
|
|
19625
|
+
);
|
|
19626
|
+
}
|
|
19627
|
+
if (packets.length > 0) {
|
|
19628
|
+
attachExtension(arkTx, packets);
|
|
19629
|
+
}
|
|
19630
|
+
return { arkTx, checkpoints };
|
|
19631
|
+
}
|
|
19632
|
+
/** Build, submit and return the finalized transaction. */
|
|
19633
|
+
async send() {
|
|
19634
|
+
const { arkTx, checkpoints } = await this.build();
|
|
19635
|
+
const client = this.contract.client;
|
|
19636
|
+
const userInputs = this.userInputIndexes();
|
|
19637
|
+
if (this.fn.arkadeScript) {
|
|
19638
|
+
if (!client.emulator) {
|
|
19639
|
+
throw new Error("covenant spends require an `emulator` on the Arkade client");
|
|
19640
|
+
}
|
|
19641
|
+
const signedArk2 = await this.signArk(arkTx, userInputs);
|
|
19642
|
+
const signedCps = userInputs.length > 0 ? await Promise.all(
|
|
19643
|
+
checkpoints.map(
|
|
19644
|
+
(c, i) => userInputs.includes(i) ? client.identity.sign(c, [0]) : c
|
|
19645
|
+
)
|
|
19646
|
+
) : checkpoints;
|
|
19647
|
+
const res2 = await client.emulator.submitTx(
|
|
19648
|
+
base.base64.encode(signedArk2.toPSBT()),
|
|
19649
|
+
signedCps.map((c) => base.base64.encode(c.toPSBT()))
|
|
19650
|
+
);
|
|
19651
|
+
const txid = chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(res2.signedArkTx)).id;
|
|
19652
|
+
return {
|
|
19653
|
+
txid,
|
|
19654
|
+
signedArkTx: res2.signedArkTx,
|
|
19655
|
+
signedCheckpointTxs: res2.signedCheckpointTxs
|
|
19656
|
+
};
|
|
19657
|
+
}
|
|
19658
|
+
if (!client.identity) {
|
|
19659
|
+
throw new Error("a signing identity is required for non-covenant spends");
|
|
19660
|
+
}
|
|
19661
|
+
const signedArk = await this.signArk(arkTx, userInputs);
|
|
19662
|
+
const res = await client.arkProvider.submitTx(
|
|
19663
|
+
base.base64.encode(signedArk.toPSBT()),
|
|
19664
|
+
checkpoints.map((c) => base.base64.encode(c.toPSBT()))
|
|
19665
|
+
);
|
|
19666
|
+
const finalCps = await Promise.all(
|
|
19667
|
+
res.signedCheckpointTxs.map(
|
|
19668
|
+
async (b) => base.base64.encode(
|
|
19669
|
+
(await client.identity.sign(chunkCFQO5MCM_cjs.Transaction.fromPSBT(base.base64.decode(b)), [0])).toPSBT()
|
|
19670
|
+
)
|
|
19671
|
+
)
|
|
19672
|
+
);
|
|
19673
|
+
await client.arkProvider.finalizeTx(res.arkTxid, finalCps);
|
|
19674
|
+
return {
|
|
19675
|
+
txid: res.arkTxid,
|
|
19676
|
+
signedArkTx: res.finalArkTx,
|
|
19677
|
+
signedCheckpointTxs: res.signedCheckpointTxs
|
|
19678
|
+
};
|
|
19679
|
+
}
|
|
19680
|
+
/** Sign the client-owned inputs of the ark tx (no-op when there are none). */
|
|
19681
|
+
async signArk(arkTx, userInputs) {
|
|
19682
|
+
if (userInputs.length === 0) return arkTx;
|
|
19683
|
+
const { identity } = this.contract.client;
|
|
19684
|
+
if (!identity) {
|
|
19685
|
+
throw new Error("this spend requires an `identity` to sign its user/funding inputs");
|
|
19686
|
+
}
|
|
19687
|
+
return identity.sign(arkTx, userInputs);
|
|
19688
|
+
}
|
|
19689
|
+
/** Indexes of inputs the client owns and must sign (contract input + funded inputs). */
|
|
19690
|
+
userInputIndexes() {
|
|
19691
|
+
const idxs = [];
|
|
19692
|
+
const userKey = this.contract.keys.userKey;
|
|
19693
|
+
if (userKey && this.fn.signerKeys.some((k) => utils_js.equalBytes(k, userKey))) {
|
|
19694
|
+
idxs.push(0);
|
|
19695
|
+
}
|
|
19696
|
+
for (let i = 0; i < this.fundingCoins.length; i++) {
|
|
19697
|
+
idxs.push(i + 1);
|
|
19698
|
+
}
|
|
19699
|
+
return idxs;
|
|
19700
|
+
}
|
|
19701
|
+
async selectCoin(amount) {
|
|
19702
|
+
const utxos = await this.contract.getUtxos();
|
|
19703
|
+
if (utxos.length === 0) throw new Error("no spendable coins for this contract");
|
|
19704
|
+
const covering = utxos.filter((u) => BigInt(u.value) >= amount).sort((a, b) => a.value - b.value);
|
|
19705
|
+
if (covering.length > 0) return covering[0];
|
|
19706
|
+
return [...utxos].sort((a, b) => b.value - a.value)[0];
|
|
19707
|
+
}
|
|
19708
|
+
buildAssetPacket() {
|
|
19709
|
+
const groups = this.assetSpecs.map((s) => {
|
|
19710
|
+
const id = typeof s.assetId === "string" ? chunkCFQO5MCM_cjs.AssetId.fromString(s.assetId) : chunkCFQO5MCM_cjs.AssetId.fromBytes(s.assetId);
|
|
19711
|
+
return chunkCFQO5MCM_cjs.AssetGroup.create(
|
|
19712
|
+
id,
|
|
19713
|
+
null,
|
|
19714
|
+
s.inputs.map((i) => chunkCFQO5MCM_cjs.AssetInput.create(i.vin, i.amount)),
|
|
19715
|
+
s.outputs.map((o) => chunkCFQO5MCM_cjs.AssetOutput.create(o.vout, o.amount)),
|
|
19716
|
+
(s.metadata ?? []).map((m) => chunkCFQO5MCM_cjs.Metadata.create(m.key, m.value))
|
|
19717
|
+
);
|
|
19718
|
+
});
|
|
19719
|
+
return chunkCFQO5MCM_cjs.Packet.create(groups);
|
|
19720
|
+
}
|
|
19721
|
+
witnessBytes(ref) {
|
|
19722
|
+
return chunkRQSA7ADZ_cjs.witnessRefToBytes(ref, this.args, this.contract.args);
|
|
19723
|
+
}
|
|
19724
|
+
};
|
|
19725
|
+
function bindInputs(fn, callArgs) {
|
|
19726
|
+
const names = (fn.def.inputs ?? []).map(chunkRQSA7ADZ_cjs.inputName);
|
|
19727
|
+
if (callArgs.length !== names.length) {
|
|
19728
|
+
throw new Error(`${fn.name}: expected ${names.length} argument(s), got ${callArgs.length}`);
|
|
19729
|
+
}
|
|
19730
|
+
const bound = {};
|
|
19731
|
+
names.forEach((n, i) => bound[n] = callArgs[i]);
|
|
19732
|
+
return bound;
|
|
19733
|
+
}
|
|
19734
|
+
function attachExtension(tx, newPackets) {
|
|
19735
|
+
for (let i = 0; i < tx.outputsLength; i++) {
|
|
19736
|
+
const out = tx.getOutput(i);
|
|
19737
|
+
if (!out?.script || !Extension.isExtension(out.script)) continue;
|
|
19738
|
+
const existing = Extension.fromBytes(out.script);
|
|
19739
|
+
const merged = Extension.create([...existing.getPackets(), ...newPackets]);
|
|
19740
|
+
tx.updateOutput(i, { script: merged.serialize(), amount: 0n });
|
|
19741
|
+
return;
|
|
19742
|
+
}
|
|
19743
|
+
const ext = Extension.create(newPackets);
|
|
19744
|
+
const newOut = ext.txOut();
|
|
19745
|
+
const lastIdx = tx.outputsLength - 1;
|
|
19746
|
+
const lastOut = tx.getOutput(lastIdx);
|
|
19747
|
+
if (lastOut?.script && lastOut.script.length === ANCHOR_PKSCRIPT.length && lastOut.script.every((b, j) => b === ANCHOR_PKSCRIPT[j])) {
|
|
19748
|
+
tx.updateOutput(lastIdx, { script: newOut.script, amount: newOut.amount });
|
|
19749
|
+
tx.addOutput({ script: lastOut.script, amount: lastOut.amount ?? 0n });
|
|
19750
|
+
return;
|
|
19751
|
+
}
|
|
19752
|
+
tx.addOutput({ script: newOut.script, amount: newOut.amount });
|
|
19753
|
+
}
|
|
18466
19754
|
var ARKCONTRACT_PREFIX = "arkcontract";
|
|
18467
19755
|
function encodeArkContract(contract) {
|
|
18468
19756
|
const params = new URLSearchParams();
|
|
@@ -18488,7 +19776,7 @@ function decodeArkContract(encoded) {
|
|
|
18488
19776
|
}
|
|
18489
19777
|
function contractFromArkContract(encoded, options = {}) {
|
|
18490
19778
|
const parsed = decodeArkContract(encoded);
|
|
18491
|
-
const handler =
|
|
19779
|
+
const handler = chunkRQSA7ADZ_cjs.contractHandlers.get(parsed.type);
|
|
18492
19780
|
if (!handler) {
|
|
18493
19781
|
throw new Error(`No handler registered for contract type '${parsed.type}'`);
|
|
18494
19782
|
}
|
|
@@ -18502,9 +19790,9 @@ function contractFromArkContract(encoded, options = {}) {
|
|
|
18502
19790
|
metadata: options.metadata
|
|
18503
19791
|
};
|
|
18504
19792
|
}
|
|
18505
|
-
function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix =
|
|
19793
|
+
function contractFromArkContractWithAddress(encoded, serverPubKey, addressPrefix = chunkL5ND2FJJ_cjs.DEFAULT_NETWORK.hrp, options = {}) {
|
|
18506
19794
|
const parsed = decodeArkContract(encoded);
|
|
18507
|
-
const handler =
|
|
19795
|
+
const handler = chunkRQSA7ADZ_cjs.contractHandlers.getOrThrow(parsed.type);
|
|
18508
19796
|
const params = parsed.data;
|
|
18509
19797
|
const vtxoScript = handler.createScript(params);
|
|
18510
19798
|
return {
|
|
@@ -18522,7 +19810,10 @@ function isArkContract(str) {
|
|
|
18522
19810
|
return str.startsWith(ARKCONTRACT_PREFIX + "=");
|
|
18523
19811
|
}
|
|
18524
19812
|
|
|
19813
|
+
exports.ARKADE_MAGIC = ARKADE_MAGIC;
|
|
18525
19814
|
exports.ActivityRegistry = ActivityRegistry;
|
|
19815
|
+
exports.ArkCash = ArkCash;
|
|
19816
|
+
exports.ArkCashCreateError = ArkCashCreateError;
|
|
18526
19817
|
exports.ArkNote = ArkNote;
|
|
18527
19818
|
exports.AssetManager = AssetManager;
|
|
18528
19819
|
exports.ChainedTxType = ChainedTxType;
|
|
@@ -18541,8 +19832,11 @@ exports.ELECTRUM_TCP_HOST = ELECTRUM_TCP_HOST;
|
|
|
18541
19832
|
exports.ELECTRUM_WS_URL = ELECTRUM_WS_URL;
|
|
18542
19833
|
exports.ESPLORA_URL = ESPLORA_URL;
|
|
18543
19834
|
exports.ElectrumOnchainProvider = ElectrumOnchainProvider;
|
|
19835
|
+
exports.EmulatorPacket = EmulatorPacket;
|
|
18544
19836
|
exports.EsploraProvider = EsploraProvider;
|
|
18545
19837
|
exports.Estimator = Estimator;
|
|
19838
|
+
exports.Extension = Extension;
|
|
19839
|
+
exports.ExtensionNotFoundError = ExtensionNotFoundError;
|
|
18546
19840
|
exports.HDDescriptorProvider = HDDescriptorProvider;
|
|
18547
19841
|
exports.INTENT_TERMINAL_STATES = INTENT_TERMINAL_STATES;
|
|
18548
19842
|
exports.InMemoryContractRepository = InMemoryContractRepository;
|
|
@@ -18571,6 +19865,7 @@ exports.ReadonlyWallet = ReadonlyWallet;
|
|
|
18571
19865
|
exports.ReadonlyWalletError = ReadonlyWalletError;
|
|
18572
19866
|
exports.RestDelegateProvider = RestDelegateProvider;
|
|
18573
19867
|
exports.RestDelegatorProvider = RestDelegatorProvider;
|
|
19868
|
+
exports.RestEmulatorProvider = RestEmulatorProvider;
|
|
18574
19869
|
exports.SeedIdentity = SeedIdentity;
|
|
18575
19870
|
exports.ServiceWorkerReadonlyWallet = ServiceWorkerReadonlyWallet;
|
|
18576
19871
|
exports.ServiceWorkerTimeoutError = ServiceWorkerTimeoutError;
|
|
@@ -18580,12 +19875,14 @@ exports.TxTree = TxTree;
|
|
|
18580
19875
|
exports.TxType = TxType;
|
|
18581
19876
|
exports.TxWeightEstimator = TxWeightEstimator;
|
|
18582
19877
|
exports.UnilateralExit = UnilateralExit;
|
|
19878
|
+
exports.UnknownPacket = UnknownPacket;
|
|
18583
19879
|
exports.VtxoManager = VtxoManager;
|
|
18584
19880
|
exports.Wallet = Wallet2;
|
|
18585
19881
|
exports.WalletMessageHandler = WalletMessageHandler;
|
|
18586
19882
|
exports.WalletNotInitializedError = WalletNotInitializedError;
|
|
18587
19883
|
exports.WalletRepositoryImpl = WalletRepositoryImpl;
|
|
18588
19884
|
exports.WsElectrumChainSource = WsElectrumChainSource;
|
|
19885
|
+
exports.arkade_exports = arkade_exports;
|
|
18589
19886
|
exports.assertIntentIdUnique = assertIntentIdUnique;
|
|
18590
19887
|
exports.boardingResolver = boardingResolver;
|
|
18591
19888
|
exports.buildForfeitTx = buildForfeitTx;
|
|
@@ -18596,6 +19893,7 @@ exports.closeDatabase = closeDatabase;
|
|
|
18596
19893
|
exports.combineTapscriptSigs = combineTapscriptSigs;
|
|
18597
19894
|
exports.contractFromArkContract = contractFromArkContract;
|
|
18598
19895
|
exports.contractFromArkContractWithAddress = contractFromArkContractWithAddress;
|
|
19896
|
+
exports.createAssetPacket = createAssetPacket;
|
|
18599
19897
|
exports.createDefaultActivityRegistry = createDefaultActivityRegistry;
|
|
18600
19898
|
exports.createExitChainResolver = createExitChainResolver;
|
|
18601
19899
|
exports.decodeArkContract = decodeArkContract;
|
|
@@ -18630,6 +19928,8 @@ exports.requiresMigration = requiresMigration;
|
|
|
18630
19928
|
exports.rollbackMigration = rollbackMigration;
|
|
18631
19929
|
exports.saveVtxosForContract = saveVtxosForContract;
|
|
18632
19930
|
exports.scriptFromArkAddress = scriptFromArkAddress;
|
|
19931
|
+
exports.selectCoinsWithAsset = selectCoinsWithAsset;
|
|
19932
|
+
exports.selectVirtualCoins = selectVirtualCoins;
|
|
18633
19933
|
exports.serializeAssets = serializeAssets;
|
|
18634
19934
|
exports.serializeExitPackage = serializeExitPackage;
|
|
18635
19935
|
exports.serializeUtxo = serializeUtxo;
|
|
@@ -18642,5 +19942,5 @@ exports.validateVtxoTxGraph = validateVtxoTxGraph;
|
|
|
18642
19942
|
exports.verifyTapscriptSignatures = verifyTapscriptSignatures;
|
|
18643
19943
|
exports.waitForIncomingFunds = waitForIncomingFunds;
|
|
18644
19944
|
exports.warnAndFilterVtxosForScript = warnAndFilterVtxosForScript;
|
|
18645
|
-
//# sourceMappingURL=chunk-
|
|
18646
|
-
//# sourceMappingURL=chunk-
|
|
19945
|
+
//# sourceMappingURL=chunk-RJMFTTRJ.cjs.map
|
|
19946
|
+
//# sourceMappingURL=chunk-RJMFTTRJ.cjs.map
|