@arkade-os/sdk 0.4.42 → 0.4.43
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 +4 -4
- package/dist/adapters/expo.d.cts +2 -2
- package/dist/adapters/expo.d.ts +2 -2
- package/dist/adapters/expo.js +2 -2
- package/dist/adapters/indexedDB.cjs +3 -3
- package/dist/adapters/indexedDB.js +2 -2
- package/dist/{ark-CKDWpuGL.d.cts → ark-I8jfe5VE.d.cts} +157 -2
- package/dist/{ark-CKDWpuGL.d.ts → ark-I8jfe5VE.d.ts} +157 -2
- package/dist/{asyncStorageTaskQueue-BB2MffwG.d.ts → asyncStorageTaskQueue-CjoL-35w.d.ts} +1 -1
- package/dist/{asyncStorageTaskQueue-BpN8RRHR.d.cts → asyncStorageTaskQueue-D1FfHfgK.d.cts} +1 -1
- package/dist/{chunk-YEF5FL6E.cjs → chunk-3AQNLQPM.cjs} +39 -4
- package/dist/chunk-3AQNLQPM.cjs.map +1 -0
- package/dist/{chunk-5X5YMZHB.js → chunk-763XHDAJ.js} +39 -5
- package/dist/chunk-763XHDAJ.js.map +1 -0
- package/dist/{chunk-V3FCNVJE.js → chunk-B4R36PRN.js} +1105 -356
- package/dist/chunk-B4R36PRN.js.map +1 -0
- package/dist/{chunk-HHPUCCB3.cjs → chunk-JIWCE2IK.cjs} +7 -7
- package/dist/{chunk-HHPUCCB3.cjs.map → chunk-JIWCE2IK.cjs.map} +1 -1
- package/dist/{chunk-T2ACJD22.cjs → chunk-PLJZRIFZ.cjs} +11 -11
- package/dist/{chunk-T2ACJD22.cjs.map → chunk-PLJZRIFZ.cjs.map} +1 -1
- package/dist/{chunk-ED7JDFX4.cjs → chunk-QGNTDGMN.cjs} +1189 -429
- package/dist/chunk-QGNTDGMN.cjs.map +1 -0
- package/dist/{chunk-FLPPSRYH.js → chunk-US274KZO.js} +3 -3
- package/dist/{chunk-FLPPSRYH.js.map → chunk-US274KZO.js.map} +1 -1
- package/dist/{chunk-2V3BU2X6.js → chunk-VKKLOT2E.js} +3 -3
- package/dist/{chunk-2V3BU2X6.js.map → chunk-VKKLOT2E.js.map} +1 -1
- package/dist/contracts/handlers/index.d.cts +3 -3
- package/dist/contracts/handlers/index.d.ts +3 -3
- package/dist/{delegate-yjhcR9n4.d.cts → delegate-BRqbh2fW.d.cts} +1 -1
- package/dist/{delegate-DllAQ3Eu.d.ts → delegate-CgjVjYOP.d.ts} +1 -1
- package/dist/{index-D1te-ZR6.d.cts → index-DHuXlDEg.d.cts} +2 -2
- package/dist/{index-DVdCGyyH.d.ts → index-DvWNB_rl.d.ts} +2 -2
- package/dist/index.cjs +150 -118
- package/dist/index.d.cts +113 -9
- package/dist/index.d.ts +113 -9
- package/dist/index.js +2 -2
- package/dist/repositories/realm/index.cjs +268 -12
- package/dist/repositories/realm/index.cjs.map +1 -1
- package/dist/repositories/realm/index.d.cts +101 -3
- package/dist/repositories/realm/index.d.ts +101 -3
- package/dist/repositories/realm/index.js +254 -4
- package/dist/repositories/realm/index.js.map +1 -1
- package/dist/repositories/sqlite/index.cjs +366 -40
- package/dist/repositories/sqlite/index.cjs.map +1 -1
- package/dist/repositories/sqlite/index.d.cts +52 -6
- package/dist/repositories/sqlite/index.d.ts +52 -6
- package/dist/repositories/sqlite/index.js +353 -32
- package/dist/repositories/sqlite/index.js.map +1 -1
- package/dist/{taskRunner-CuTk8RYg.d.cts → taskRunner-BSnslNmq.d.cts} +1 -1
- package/dist/{taskRunner-BdiRy4iI.d.ts → taskRunner-Djlhfgi1.d.ts} +1 -1
- package/dist/wallet/expo/background.cjs +12 -12
- package/dist/wallet/expo/background.d.cts +3 -3
- package/dist/wallet/expo/background.d.ts +3 -3
- package/dist/wallet/expo/background.js +4 -4
- package/dist/wallet/expo/index.cjs +12 -12
- package/dist/wallet/expo/index.d.cts +4 -4
- package/dist/wallet/expo/index.d.ts +4 -4
- package/dist/wallet/expo/index.js +3 -3
- package/dist/{wallet-CyPOQ0oM.d.cts → wallet-BsqRU8KM.d.cts} +29 -5
- package/dist/{wallet-CrIVUQMb.d.ts → wallet-D9z7wssl.d.ts} +29 -5
- package/dist/worker/expo/index.cjs +7 -7
- package/dist/worker/expo/index.d.cts +4 -4
- package/dist/worker/expo/index.d.ts +4 -4
- package/dist/worker/expo/index.js +3 -3
- package/package.json +2 -2
- package/dist/chunk-5X5YMZHB.js.map +0 -1
- package/dist/chunk-ED7JDFX4.cjs.map +0 -1
- package/dist/chunk-V3FCNVJE.js.map +0 -1
- package/dist/chunk-YEF5FL6E.cjs.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunk3AQNLQPM_cjs = require('./chunk-3AQNLQPM.cjs');
|
|
4
4
|
var chunk32YKLQPS_cjs = require('./chunk-32YKLQPS.cjs');
|
|
5
5
|
var chunkHXDZ2QTW_cjs = require('./chunk-HXDZ2QTW.cjs');
|
|
6
6
|
var utils_js = require('@scure/btc-signer/utils.js');
|
|
@@ -181,7 +181,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
181
181
|
noncesByPubkey.set(base.hex.encode(myPublicKey.subarray(1)), myNonce);
|
|
182
182
|
const tx = this.graph.find(txid);
|
|
183
183
|
if (!tx) throw new Error(`missing tx for txid ${txid}`);
|
|
184
|
-
const cosigners =
|
|
184
|
+
const cosigners = chunk3AQNLQPM_cjs.getArkPsbtFields(tx.root, 0, chunk3AQNLQPM_cjs.CosignerPublicKey).map(
|
|
185
185
|
(c) => base.hex.encode(c.key.subarray(1))
|
|
186
186
|
// xonly pubkey
|
|
187
187
|
);
|
|
@@ -233,7 +233,7 @@ var TreeSignerSession = class _TreeSignerSession {
|
|
|
233
233
|
if (!aggNonce) throw new Error("missing aggregate nonce");
|
|
234
234
|
const prevoutAmounts = [];
|
|
235
235
|
const prevoutScripts = [];
|
|
236
|
-
const cosigners =
|
|
236
|
+
const cosigners = chunk3AQNLQPM_cjs.getArkPsbtFields(g.root, 0, chunk3AQNLQPM_cjs.CosignerPublicKey).map((c) => c.key);
|
|
237
237
|
const { finalKey } = aggregateKeys(cosigners, true, {
|
|
238
238
|
taprootTweak: this.scriptRoot
|
|
239
239
|
});
|
|
@@ -980,14 +980,14 @@ var RestDelegateProvider = class {
|
|
|
980
980
|
*/
|
|
981
981
|
async delegate(intent, forfeitTxs, options) {
|
|
982
982
|
const url = `${this.url}/v1/delegate`;
|
|
983
|
-
const response = await
|
|
983
|
+
const response = await chunk3AQNLQPM_cjs.baseFetch(url, {
|
|
984
984
|
method: "POST",
|
|
985
985
|
headers: {
|
|
986
986
|
"Content-Type": "application/json"
|
|
987
987
|
},
|
|
988
988
|
body: JSON.stringify({
|
|
989
989
|
intent: {
|
|
990
|
-
message:
|
|
990
|
+
message: chunk3AQNLQPM_cjs.Intent.encodeMessage(intent.message),
|
|
991
991
|
proof: intent.proof
|
|
992
992
|
},
|
|
993
993
|
forfeit_txs: forfeitTxs,
|
|
@@ -1007,7 +1007,7 @@ var RestDelegateProvider = class {
|
|
|
1007
1007
|
*/
|
|
1008
1008
|
async getDelegateInfo() {
|
|
1009
1009
|
const url = `${this.url}/v1/delegator/info`;
|
|
1010
|
-
const response = await
|
|
1010
|
+
const response = await chunk3AQNLQPM_cjs.baseFetch(url);
|
|
1011
1011
|
if (!response.ok) {
|
|
1012
1012
|
const errorText2 = await response.text();
|
|
1013
1013
|
throw new Error(`Failed to get delegate info: ${errorText2}`);
|
|
@@ -1042,14 +1042,14 @@ var EsploraProvider = class {
|
|
|
1042
1042
|
pollingInterval;
|
|
1043
1043
|
forcePolling;
|
|
1044
1044
|
async getCoins(address) {
|
|
1045
|
-
const response = await
|
|
1045
|
+
const response = await chunk3AQNLQPM_cjs.baseFetch(`${this.baseUrl}/address/${address}/utxo`);
|
|
1046
1046
|
if (!response.ok) {
|
|
1047
1047
|
throw new Error(`Failed to fetch UTXOs: ${response.statusText}`);
|
|
1048
1048
|
}
|
|
1049
1049
|
return response.json();
|
|
1050
1050
|
}
|
|
1051
1051
|
async getFeeRate() {
|
|
1052
|
-
const response = await
|
|
1052
|
+
const response = await chunk3AQNLQPM_cjs.baseFetch(`${this.baseUrl}/fee-estimates`);
|
|
1053
1053
|
if (response.status === 404) {
|
|
1054
1054
|
return void 0;
|
|
1055
1055
|
}
|
|
@@ -1070,7 +1070,7 @@ var EsploraProvider = class {
|
|
|
1070
1070
|
}
|
|
1071
1071
|
}
|
|
1072
1072
|
async getTxOutspends(txid) {
|
|
1073
|
-
const response = await
|
|
1073
|
+
const response = await chunk3AQNLQPM_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/outspends`);
|
|
1074
1074
|
if (!response.ok) {
|
|
1075
1075
|
const error = await response.text();
|
|
1076
1076
|
throw new Error(`Failed to get transaction outspends: ${error}`);
|
|
@@ -1078,7 +1078,7 @@ var EsploraProvider = class {
|
|
|
1078
1078
|
return response.json();
|
|
1079
1079
|
}
|
|
1080
1080
|
async getTransactions(address) {
|
|
1081
|
-
const response = await
|
|
1081
|
+
const response = await chunk3AQNLQPM_cjs.baseFetch(`${this.baseUrl}/address/${address}/txs`);
|
|
1082
1082
|
if (!response.ok) {
|
|
1083
1083
|
const error = await response.text();
|
|
1084
1084
|
throw new Error(`Failed to get transactions: ${error}`);
|
|
@@ -1086,7 +1086,7 @@ var EsploraProvider = class {
|
|
|
1086
1086
|
return response.json();
|
|
1087
1087
|
}
|
|
1088
1088
|
async getTxStatus(txid) {
|
|
1089
|
-
const txresponse = await
|
|
1089
|
+
const txresponse = await chunk3AQNLQPM_cjs.baseFetch(`${this.baseUrl}/tx/${txid}`);
|
|
1090
1090
|
if (!txresponse.ok) {
|
|
1091
1091
|
throw new Error(txresponse.statusText);
|
|
1092
1092
|
}
|
|
@@ -1094,7 +1094,7 @@ var EsploraProvider = class {
|
|
|
1094
1094
|
if (!tx.status.confirmed) {
|
|
1095
1095
|
return { confirmed: false };
|
|
1096
1096
|
}
|
|
1097
|
-
const response = await
|
|
1097
|
+
const response = await chunk3AQNLQPM_cjs.baseFetch(`${this.baseUrl}/tx/${txid}/status`);
|
|
1098
1098
|
if (!response.ok) {
|
|
1099
1099
|
throw new Error(`Failed to get transaction status: ${response.statusText}`);
|
|
1100
1100
|
}
|
|
@@ -1178,7 +1178,7 @@ var EsploraProvider = class {
|
|
|
1178
1178
|
return stopFunc;
|
|
1179
1179
|
}
|
|
1180
1180
|
async getChainTip() {
|
|
1181
|
-
const tipBlocks = await
|
|
1181
|
+
const tipBlocks = await chunk3AQNLQPM_cjs.baseFetch(`${this.baseUrl}/blocks`);
|
|
1182
1182
|
if (!tipBlocks.ok) {
|
|
1183
1183
|
throw new Error(`Failed to get chain tip: ${tipBlocks.statusText}`);
|
|
1184
1184
|
}
|
|
@@ -1197,7 +1197,7 @@ var EsploraProvider = class {
|
|
|
1197
1197
|
};
|
|
1198
1198
|
}
|
|
1199
1199
|
async broadcastPackage(parent, child) {
|
|
1200
|
-
const response = await
|
|
1200
|
+
const response = await chunk3AQNLQPM_cjs.baseFetch(`${this.baseUrl}/txs/package`, {
|
|
1201
1201
|
method: "POST",
|
|
1202
1202
|
headers: {
|
|
1203
1203
|
"Content-Type": "application/json"
|
|
@@ -1211,7 +1211,7 @@ var EsploraProvider = class {
|
|
|
1211
1211
|
return response.json();
|
|
1212
1212
|
}
|
|
1213
1213
|
async broadcastTx(tx) {
|
|
1214
|
-
const response = await
|
|
1214
|
+
const response = await chunk3AQNLQPM_cjs.baseFetch(`${this.baseUrl}/tx`, {
|
|
1215
1215
|
method: "POST",
|
|
1216
1216
|
headers: {
|
|
1217
1217
|
"Content-Type": "text/plain"
|
|
@@ -1282,7 +1282,7 @@ function buildForfeitTx(inputs, forfeitPkScript, txLocktime) {
|
|
|
1282
1282
|
);
|
|
1283
1283
|
}
|
|
1284
1284
|
function buildForfeitTxWithOutput(inputs, output, txLocktime) {
|
|
1285
|
-
const tx = new
|
|
1285
|
+
const tx = new chunk3AQNLQPM_cjs.Transaction({
|
|
1286
1286
|
version: 3,
|
|
1287
1287
|
lockTime: txLocktime
|
|
1288
1288
|
});
|
|
@@ -1358,7 +1358,7 @@ function validateVtxoTxGraph(graph, roundTransaction, sweepTapTreeRoot) {
|
|
|
1358
1358
|
if (previousScriptKey.length !== 32) {
|
|
1359
1359
|
throw new Error(`parent output ${childIndex} has invalid script`);
|
|
1360
1360
|
}
|
|
1361
|
-
const cosigners =
|
|
1361
|
+
const cosigners = chunk3AQNLQPM_cjs.getArkPsbtFields(child.root, 0, chunk3AQNLQPM_cjs.CosignerPublicKey);
|
|
1362
1362
|
if (cosigners.length === 0) {
|
|
1363
1363
|
throw ErrMissingCosignersPublicKeys;
|
|
1364
1364
|
}
|
|
@@ -1458,7 +1458,7 @@ var Extension = class _Extension {
|
|
|
1458
1458
|
`expected magic prefix ${base.hex.encode(ARKADE_MAGIC)}, got ${base.hex.encode(payload.slice(0, Math.min(payload.length, ARKADE_MAGIC.length)))}`
|
|
1459
1459
|
);
|
|
1460
1460
|
}
|
|
1461
|
-
const reader = new
|
|
1461
|
+
const reader = new chunk3AQNLQPM_cjs.BufferReader(payload.slice(ARKADE_MAGIC.length));
|
|
1462
1462
|
const packets = [];
|
|
1463
1463
|
while (reader.remaining() > 0) {
|
|
1464
1464
|
const packetType = reader.readByte();
|
|
@@ -1532,7 +1532,7 @@ var Extension = class _Extension {
|
|
|
1532
1532
|
*/
|
|
1533
1533
|
getAssetPacket() {
|
|
1534
1534
|
for (const p of this.packets) {
|
|
1535
|
-
if (p instanceof
|
|
1535
|
+
if (p instanceof chunk3AQNLQPM_cjs.Packet) {
|
|
1536
1536
|
return p;
|
|
1537
1537
|
}
|
|
1538
1538
|
}
|
|
@@ -1540,8 +1540,8 @@ var Extension = class _Extension {
|
|
|
1540
1540
|
}
|
|
1541
1541
|
};
|
|
1542
1542
|
function parsePacket(packetType, data) {
|
|
1543
|
-
if (packetType ===
|
|
1544
|
-
return
|
|
1543
|
+
if (packetType === chunk3AQNLQPM_cjs.Packet.PACKET_TYPE) {
|
|
1544
|
+
return chunk3AQNLQPM_cjs.Packet.fromBytes(data);
|
|
1545
1545
|
}
|
|
1546
1546
|
return new UnknownPacket(packetType, data);
|
|
1547
1547
|
}
|
|
@@ -1848,7 +1848,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
1848
1848
|
const existing = inputsByAssetId.get(asset.assetId);
|
|
1849
1849
|
inputsByAssetId.set(asset.assetId, [
|
|
1850
1850
|
...existing ?? [],
|
|
1851
|
-
|
|
1851
|
+
chunk3AQNLQPM_cjs.AssetInput.create(inputIndex, asset.amount)
|
|
1852
1852
|
]);
|
|
1853
1853
|
}
|
|
1854
1854
|
}
|
|
@@ -1860,7 +1860,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
1860
1860
|
const existing = outputsByAssetId.get(asset.assetId);
|
|
1861
1861
|
outputsByAssetId.set(asset.assetId, [
|
|
1862
1862
|
...existing ?? [],
|
|
1863
|
-
|
|
1863
|
+
chunk3AQNLQPM_cjs.AssetOutput.create(outputIndex, asset.amount)
|
|
1864
1864
|
]);
|
|
1865
1865
|
}
|
|
1866
1866
|
}
|
|
@@ -1871,7 +1871,7 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
1871
1871
|
const existing = outputsByAssetId.get(asset.assetId);
|
|
1872
1872
|
outputsByAssetId.set(asset.assetId, [
|
|
1873
1873
|
...existing ?? [],
|
|
1874
|
-
|
|
1874
|
+
chunk3AQNLQPM_cjs.AssetOutput.create(outputIndex, asset.amount)
|
|
1875
1875
|
]);
|
|
1876
1876
|
}
|
|
1877
1877
|
}
|
|
@@ -1880,11 +1880,11 @@ function createAssetPacket(assetInputs, receivers, changeReceiver) {
|
|
|
1880
1880
|
for (const assetIdStr of allAssetIds) {
|
|
1881
1881
|
const inputs = inputsByAssetId.get(assetIdStr);
|
|
1882
1882
|
const outputs = outputsByAssetId.get(assetIdStr);
|
|
1883
|
-
const assetId =
|
|
1884
|
-
const group =
|
|
1883
|
+
const assetId = chunk3AQNLQPM_cjs.AssetId.fromString(assetIdStr);
|
|
1884
|
+
const group = chunk3AQNLQPM_cjs.AssetGroup.create(assetId, null, inputs ?? [], outputs ?? [], []);
|
|
1885
1885
|
groups.push(group);
|
|
1886
1886
|
}
|
|
1887
|
-
return
|
|
1887
|
+
return chunk3AQNLQPM_cjs.Packet.create(groups);
|
|
1888
1888
|
}
|
|
1889
1889
|
function selectCoinsWithAsset(coins, assetId, requiredAmount) {
|
|
1890
1890
|
const coinsWithAsset = coins.filter((coin) => coin.assets?.some((a) => a.assetId === assetId));
|
|
@@ -2001,7 +2001,7 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
2001
2001
|
}
|
|
2002
2002
|
}
|
|
2003
2003
|
}
|
|
2004
|
-
const tx = new
|
|
2004
|
+
const tx = new chunk3AQNLQPM_cjs.Transaction({
|
|
2005
2005
|
version: 3,
|
|
2006
2006
|
lockTime: Number(lockTime)
|
|
2007
2007
|
});
|
|
@@ -2016,7 +2016,7 @@ function buildVirtualTx(inputs, outputs) {
|
|
|
2016
2016
|
},
|
|
2017
2017
|
tapLeafScript: [input.tapLeafScript]
|
|
2018
2018
|
});
|
|
2019
|
-
|
|
2019
|
+
chunk3AQNLQPM_cjs.setArkPsbtField(tx, i, chunk3AQNLQPM_cjs.VtxoTaprootTree, input.tapTree);
|
|
2020
2020
|
}
|
|
2021
2021
|
for (const output of outputs) {
|
|
2022
2022
|
tx.addOutput(output);
|
|
@@ -2666,7 +2666,7 @@ function getExpiringAndRecoverableVtxos(vtxos, thresholdMs, dustAmount) {
|
|
|
2666
2666
|
);
|
|
2667
2667
|
}
|
|
2668
2668
|
function isMigrationCapable(wallet) {
|
|
2669
|
-
return "arkProvider" in wallet && "arkServerPublicKey" in wallet && "onchainProvider" in wallet && typeof wallet.rotateServerSigner === "function" && typeof wallet.sendSelectedVtxosToSelf === "function" && typeof wallet.getBoardingUtxosForSigners === "function";
|
|
2669
|
+
return "arkProvider" in wallet && "arkServerPublicKey" in wallet && "onchainProvider" in wallet && typeof wallet.rotateServerSigner === "function" && typeof wallet.refreshDeprecatedSigners === "function" && typeof wallet.sendSelectedVtxosToSelf === "function" && typeof wallet.getBoardingUtxosForSigners === "function";
|
|
2670
2670
|
}
|
|
2671
2671
|
function classifiedToRef(c) {
|
|
2672
2672
|
return {
|
|
@@ -3124,7 +3124,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
3124
3124
|
`Sweep not economical: output ${outputAmount} sats after ${fee} sats fee is below dust (${dustAmount} sats)`
|
|
3125
3125
|
);
|
|
3126
3126
|
}
|
|
3127
|
-
const tx = new
|
|
3127
|
+
const tx = new chunk3AQNLQPM_cjs.Transaction();
|
|
3128
3128
|
for (const utxo of expiredUtxos) {
|
|
3129
3129
|
const utxoScript = chunkHXDZ2QTW_cjs.VtxoScript.decode(utxo.tapTree);
|
|
3130
3130
|
const utxoExitLeaf = utxoScript.leaves.find(
|
|
@@ -3190,6 +3190,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
3190
3190
|
async migrateCore(options) {
|
|
3191
3191
|
const wallet = this.requireMigrationCapableWallet();
|
|
3192
3192
|
const info = await wallet.arkProvider.getInfo();
|
|
3193
|
+
wallet.refreshDeprecatedSigners(info);
|
|
3193
3194
|
const signerSet = signerSetFromInfo(info);
|
|
3194
3195
|
const nowSeconds = Math.floor(Date.now() / 1e3);
|
|
3195
3196
|
const walletSignerHex = base.hex.encode(wallet.arkServerPublicKey);
|
|
@@ -3762,7 +3763,7 @@ var VtxoManager = class _VtxoManager {
|
|
|
3762
3763
|
* or doesn't carry the metadata.
|
|
3763
3764
|
*/
|
|
3764
3765
|
extractSpentOutpoint(error) {
|
|
3765
|
-
const ark =
|
|
3766
|
+
const ark = chunk3AQNLQPM_cjs.maybeArkError(error);
|
|
3766
3767
|
if (!ark || ark.name !== "VTXO_ALREADY_SPENT") return void 0;
|
|
3767
3768
|
const raw = ark.metadata?.vtxo_outpoint;
|
|
3768
3769
|
if (typeof raw !== "string") return void 0;
|
|
@@ -4158,6 +4159,123 @@ function readUInt32BE(array, offset) {
|
|
|
4158
4159
|
function noteTapscript(preimageHash) {
|
|
4159
4160
|
return btcSigner.Script.encode(["SHA256", preimageHash, "EQUAL"]);
|
|
4160
4161
|
}
|
|
4162
|
+
|
|
4163
|
+
// src/repositories/intentRepository.ts
|
|
4164
|
+
var ALL_INTENT_STATES = [
|
|
4165
|
+
"waiting_to_submit",
|
|
4166
|
+
"waiting_for_batch",
|
|
4167
|
+
"batch_in_progress",
|
|
4168
|
+
"batch_failed",
|
|
4169
|
+
"batch_succeeded",
|
|
4170
|
+
"cancelled"
|
|
4171
|
+
];
|
|
4172
|
+
var INTENT_TERMINAL_STATES = /* @__PURE__ */ new Set([
|
|
4173
|
+
"batch_failed",
|
|
4174
|
+
"batch_succeeded",
|
|
4175
|
+
"cancelled"
|
|
4176
|
+
]);
|
|
4177
|
+
function isTerminalIntentState(s) {
|
|
4178
|
+
return INTENT_TERMINAL_STATES.has(s);
|
|
4179
|
+
}
|
|
4180
|
+
function assertIntentIdUnique(intent, existing) {
|
|
4181
|
+
if (intent.intentId === void 0) return;
|
|
4182
|
+
for (const e of existing) {
|
|
4183
|
+
if (e.intentTxId !== intent.intentTxId && e.intentId === intent.intentId) {
|
|
4184
|
+
throw new Error(
|
|
4185
|
+
`intentId "${intent.intentId}" is already used by intent ${e.intentTxId}`
|
|
4186
|
+
);
|
|
4187
|
+
}
|
|
4188
|
+
}
|
|
4189
|
+
}
|
|
4190
|
+
function intentMatchesFilter(i, f) {
|
|
4191
|
+
if (f.intentTxIds && !f.intentTxIds.includes(i.intentTxId)) return false;
|
|
4192
|
+
if (f.intentIds && (!i.intentId || !f.intentIds.includes(i.intentId))) return false;
|
|
4193
|
+
if (f.states && !f.states.includes(i.state)) return false;
|
|
4194
|
+
if (f.containingInputs) {
|
|
4195
|
+
const keys = new Set(i.intentVtxos.map((o) => `${o.txid}:${o.vout}`));
|
|
4196
|
+
if (!f.containingInputs.some((o) => keys.has(`${o.txid}:${o.vout}`))) return false;
|
|
4197
|
+
}
|
|
4198
|
+
if (f.validAt !== void 0) {
|
|
4199
|
+
if (i.validFrom !== void 0 && f.validAt < i.validFrom) return false;
|
|
4200
|
+
if (i.validUntil !== void 0 && f.validAt > i.validUntil) return false;
|
|
4201
|
+
}
|
|
4202
|
+
if (f.searchText) {
|
|
4203
|
+
const hay = [i.intentId, i.batchId, i.commitmentTransactionId].filter(Boolean).join(" ");
|
|
4204
|
+
if (!hay.includes(f.searchText)) return false;
|
|
4205
|
+
}
|
|
4206
|
+
return true;
|
|
4207
|
+
}
|
|
4208
|
+
function intentPageBounds(filter, total) {
|
|
4209
|
+
const skip = Math.max(0, filter?.skip ?? 0);
|
|
4210
|
+
const take = filter?.take === void 0 ? total : Math.max(0, filter.take);
|
|
4211
|
+
return { skip, end: skip + take };
|
|
4212
|
+
}
|
|
4213
|
+
|
|
4214
|
+
// src/wallet/intentStateReducer.ts
|
|
4215
|
+
function reduceIntentState(current, event) {
|
|
4216
|
+
if (isTerminalIntentState(current)) return current;
|
|
4217
|
+
switch (event.type) {
|
|
4218
|
+
case "batch_started" /* BatchStarted */:
|
|
4219
|
+
return "batch_in_progress";
|
|
4220
|
+
case "batch_finalized" /* BatchFinalized */:
|
|
4221
|
+
return "batch_succeeded";
|
|
4222
|
+
case "batch_failed" /* BatchFailed */:
|
|
4223
|
+
return "batch_failed";
|
|
4224
|
+
default:
|
|
4225
|
+
return current;
|
|
4226
|
+
}
|
|
4227
|
+
}
|
|
4228
|
+
function applySettlementEventToIntent(intent, event) {
|
|
4229
|
+
const next = reduceIntentState(intent.state, event);
|
|
4230
|
+
if (next === intent.state) return void 0;
|
|
4231
|
+
const updated = { ...intent, state: next };
|
|
4232
|
+
if ("id" in event && typeof event.id === "string") {
|
|
4233
|
+
updated.batchId = event.id;
|
|
4234
|
+
}
|
|
4235
|
+
if (event.type === "batch_finalized" /* BatchFinalized */) {
|
|
4236
|
+
updated.commitmentTransactionId = event.commitmentTxid;
|
|
4237
|
+
}
|
|
4238
|
+
if (event.type === "batch_failed" /* BatchFailed */) {
|
|
4239
|
+
updated.cancellationReason = event.reason;
|
|
4240
|
+
}
|
|
4241
|
+
return updated;
|
|
4242
|
+
}
|
|
4243
|
+
|
|
4244
|
+
// src/wallet/intentPersistenceHandler.ts
|
|
4245
|
+
async function persistTransition(deps, event) {
|
|
4246
|
+
const repo = deps.intentRepository;
|
|
4247
|
+
if (!repo) return;
|
|
4248
|
+
try {
|
|
4249
|
+
const cur = (await repo.getIntents({ intentTxIds: [deps.intentTxId] }))[0];
|
|
4250
|
+
if (!cur) return;
|
|
4251
|
+
const next = applySettlementEventToIntent(cur, event);
|
|
4252
|
+
if (next) await repo.saveIntent(next);
|
|
4253
|
+
} catch (e) {
|
|
4254
|
+
console.error(`Failed to apply settlement event to intent ${deps.intentTxId}`, e);
|
|
4255
|
+
}
|
|
4256
|
+
}
|
|
4257
|
+
function wrapHandlerWithIntentPersistence(base, deps) {
|
|
4258
|
+
return {
|
|
4259
|
+
...base,
|
|
4260
|
+
onBatchStarted: async (event) => {
|
|
4261
|
+
const result = await base.onBatchStarted(event);
|
|
4262
|
+
if (!result.skip) await persistTransition(deps, event);
|
|
4263
|
+
return result;
|
|
4264
|
+
},
|
|
4265
|
+
onBatchFinalized: async (event) => {
|
|
4266
|
+
if (base.onBatchFinalized) await base.onBatchFinalized(event);
|
|
4267
|
+
await persistTransition(deps, event);
|
|
4268
|
+
},
|
|
4269
|
+
onBatchFailed: async (event) => {
|
|
4270
|
+
await persistTransition(deps, event);
|
|
4271
|
+
if (base.onBatchFailed) {
|
|
4272
|
+
await base.onBatchFailed(event);
|
|
4273
|
+
return;
|
|
4274
|
+
}
|
|
4275
|
+
throw new Error(event.reason);
|
|
4276
|
+
}
|
|
4277
|
+
};
|
|
4278
|
+
}
|
|
4161
4279
|
var TxTree = class {
|
|
4162
4280
|
constructor(root, children = /* @__PURE__ */ new Map()) {
|
|
4163
4281
|
this.root = root;
|
|
@@ -4673,7 +4791,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4673
4791
|
const virtualCoins = await this.wallet.getVtxos({
|
|
4674
4792
|
withRecoverable: false
|
|
4675
4793
|
});
|
|
4676
|
-
const controlAssetRef = params.controlAssetId ?
|
|
4794
|
+
const controlAssetRef = params.controlAssetId ? chunk3AQNLQPM_cjs.AssetRef.fromId(chunk3AQNLQPM_cjs.AssetId.fromString(params.controlAssetId)) : null;
|
|
4677
4795
|
const coinSelection = selectVirtualCoins(virtualCoins, Number(this.wallet.dustAmount));
|
|
4678
4796
|
let totalBtcSelected = 0n;
|
|
4679
4797
|
const assetChanges = /* @__PURE__ */ new Map();
|
|
@@ -4686,8 +4804,8 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4686
4804
|
}
|
|
4687
4805
|
}
|
|
4688
4806
|
const groups = [];
|
|
4689
|
-
const issuedAssetOutput =
|
|
4690
|
-
const issuedAssetGroup =
|
|
4807
|
+
const issuedAssetOutput = chunk3AQNLQPM_cjs.AssetOutput.create(0, params.amount);
|
|
4808
|
+
const issuedAssetGroup = chunk3AQNLQPM_cjs.AssetGroup.create(
|
|
4691
4809
|
null,
|
|
4692
4810
|
controlAssetRef,
|
|
4693
4811
|
[],
|
|
@@ -4702,15 +4820,15 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4702
4820
|
for (const [inputIndex, assets] of assetInputs) {
|
|
4703
4821
|
for (const asset of assets) {
|
|
4704
4822
|
if (asset.assetId !== assetId) continue;
|
|
4705
|
-
changeInputs.push(
|
|
4823
|
+
changeInputs.push(chunk3AQNLQPM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
4706
4824
|
}
|
|
4707
4825
|
}
|
|
4708
4826
|
groups.push(
|
|
4709
|
-
|
|
4710
|
-
|
|
4827
|
+
chunk3AQNLQPM_cjs.AssetGroup.create(
|
|
4828
|
+
chunk3AQNLQPM_cjs.AssetId.fromString(assetId),
|
|
4711
4829
|
null,
|
|
4712
4830
|
changeInputs,
|
|
4713
|
-
[
|
|
4831
|
+
[chunk3AQNLQPM_cjs.AssetOutput.create(0, amount)],
|
|
4714
4832
|
[]
|
|
4715
4833
|
)
|
|
4716
4834
|
);
|
|
@@ -4723,7 +4841,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4723
4841
|
script: outputAddress.pkScript,
|
|
4724
4842
|
amount: BigInt(totalBtcSelected)
|
|
4725
4843
|
},
|
|
4726
|
-
Extension.create([
|
|
4844
|
+
Extension.create([chunk3AQNLQPM_cjs.Packet.create(groups)]).txOut()
|
|
4727
4845
|
];
|
|
4728
4846
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(
|
|
4729
4847
|
coinSelection.inputs,
|
|
@@ -4731,7 +4849,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4731
4849
|
);
|
|
4732
4850
|
return {
|
|
4733
4851
|
arkTxId: arkTxid,
|
|
4734
|
-
assetId:
|
|
4852
|
+
assetId: chunk3AQNLQPM_cjs.AssetId.create(arkTxid, 0).toString()
|
|
4735
4853
|
};
|
|
4736
4854
|
}
|
|
4737
4855
|
/**
|
|
@@ -4803,16 +4921,16 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4803
4921
|
for (const [inputIndex, assets] of assetInputs) {
|
|
4804
4922
|
for (const asset of assets) {
|
|
4805
4923
|
if (asset.assetId !== params.assetId) continue;
|
|
4806
|
-
reissueInputs.push(
|
|
4924
|
+
reissueInputs.push(chunk3AQNLQPM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
4807
4925
|
}
|
|
4808
4926
|
}
|
|
4809
4927
|
const totalAssetAmount = assetToReissueAmount + params.amount;
|
|
4810
|
-
const reissueAssetIdObj =
|
|
4811
|
-
const reissueAssetGroup =
|
|
4928
|
+
const reissueAssetIdObj = chunk3AQNLQPM_cjs.AssetId.fromString(params.assetId);
|
|
4929
|
+
const reissueAssetGroup = chunk3AQNLQPM_cjs.AssetGroup.create(
|
|
4812
4930
|
reissueAssetIdObj,
|
|
4813
4931
|
null,
|
|
4814
4932
|
reissueInputs,
|
|
4815
|
-
[
|
|
4933
|
+
[chunk3AQNLQPM_cjs.AssetOutput.create(0, totalAssetAmount)],
|
|
4816
4934
|
[]
|
|
4817
4935
|
);
|
|
4818
4936
|
const groups = [reissueAssetGroup];
|
|
@@ -4821,15 +4939,15 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4821
4939
|
for (const [inputIndex, assets] of assetInputs) {
|
|
4822
4940
|
for (const asset of assets) {
|
|
4823
4941
|
if (asset.assetId !== assetId) continue;
|
|
4824
|
-
changeInputs.push(
|
|
4942
|
+
changeInputs.push(chunk3AQNLQPM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
4825
4943
|
}
|
|
4826
4944
|
}
|
|
4827
4945
|
groups.push(
|
|
4828
|
-
|
|
4829
|
-
|
|
4946
|
+
chunk3AQNLQPM_cjs.AssetGroup.create(
|
|
4947
|
+
chunk3AQNLQPM_cjs.AssetId.fromString(assetId),
|
|
4830
4948
|
null,
|
|
4831
4949
|
changeInputs,
|
|
4832
|
-
[
|
|
4950
|
+
[chunk3AQNLQPM_cjs.AssetOutput.create(0, amount)],
|
|
4833
4951
|
[]
|
|
4834
4952
|
)
|
|
4835
4953
|
);
|
|
@@ -4841,7 +4959,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4841
4959
|
script: outputAddress.pkScript,
|
|
4842
4960
|
amount: BigInt(totalBtcSelected)
|
|
4843
4961
|
},
|
|
4844
|
-
Extension.create([
|
|
4962
|
+
Extension.create([chunk3AQNLQPM_cjs.Packet.create(groups)]).txOut()
|
|
4845
4963
|
];
|
|
4846
4964
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
|
|
4847
4965
|
return arkTxid;
|
|
@@ -4908,15 +5026,15 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4908
5026
|
for (const [inputIndex, assets] of assetInputs) {
|
|
4909
5027
|
for (const asset of assets) {
|
|
4910
5028
|
if (asset.assetId !== assetId) continue;
|
|
4911
|
-
changeInputs.push(
|
|
5029
|
+
changeInputs.push(chunk3AQNLQPM_cjs.AssetInput.create(inputIndex, asset.amount));
|
|
4912
5030
|
}
|
|
4913
5031
|
}
|
|
4914
5032
|
groups.push(
|
|
4915
|
-
|
|
4916
|
-
|
|
5033
|
+
chunk3AQNLQPM_cjs.AssetGroup.create(
|
|
5034
|
+
chunk3AQNLQPM_cjs.AssetId.fromString(assetId),
|
|
4917
5035
|
null,
|
|
4918
5036
|
changeInputs,
|
|
4919
|
-
amount > 0n ? [
|
|
5037
|
+
amount > 0n ? [chunk3AQNLQPM_cjs.AssetOutput.create(0, amount)] : [],
|
|
4920
5038
|
[]
|
|
4921
5039
|
)
|
|
4922
5040
|
);
|
|
@@ -4928,7 +5046,7 @@ var AssetManager = class extends ReadonlyAssetManager {
|
|
|
4928
5046
|
script: outputAddress.pkScript,
|
|
4929
5047
|
amount: BigInt(totalBtcSelected)
|
|
4930
5048
|
},
|
|
4931
|
-
Extension.create([
|
|
5049
|
+
Extension.create([chunk3AQNLQPM_cjs.Packet.create(groups)]).txOut()
|
|
4932
5050
|
];
|
|
4933
5051
|
const { arkTxid } = await this.wallet.buildAndSubmitOffchainTx(selectedCoins, outputs);
|
|
4934
5052
|
return arkTxid;
|
|
@@ -4953,7 +5071,7 @@ function castMetadata(metadata) {
|
|
|
4953
5071
|
} else {
|
|
4954
5072
|
throw new Error("Invalid metadata value type");
|
|
4955
5073
|
}
|
|
4956
|
-
md.push(
|
|
5074
|
+
md.push(chunk3AQNLQPM_cjs.Metadata.create(textEncoder.encode(key), valueBytes));
|
|
4957
5075
|
}
|
|
4958
5076
|
return md;
|
|
4959
5077
|
}
|
|
@@ -5238,7 +5356,7 @@ async function makeSignedDelegateIntent(identity, coins, outputs, onchainOutputs
|
|
|
5238
5356
|
expire_at: 0,
|
|
5239
5357
|
cosigners_public_keys: cosignerPubKeys
|
|
5240
5358
|
};
|
|
5241
|
-
const proof =
|
|
5359
|
+
const proof = chunk3AQNLQPM_cjs.Intent.create(message, coins, outputs);
|
|
5242
5360
|
const signedProof = await identity.sign(proof);
|
|
5243
5361
|
return {
|
|
5244
5362
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -5267,214 +5385,216 @@ function isAnnotated(v) {
|
|
|
5267
5385
|
return v.tapTree !== void 0 && v.forfeitTapLeafScript !== void 0 && v.intentTapLeafScript !== void 0;
|
|
5268
5386
|
}
|
|
5269
5387
|
|
|
5270
|
-
// src/
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
const rejected = [];
|
|
5283
|
-
for (const v of vtxos) {
|
|
5284
|
-
if (isVtxoForScript(v, script)) {
|
|
5285
|
-
matches.push(v);
|
|
5286
|
-
} else {
|
|
5287
|
-
rejected.push(`${vtxoOutpoint(v)}(script=${v.script ?? ""})`);
|
|
5288
|
-
}
|
|
5289
|
-
}
|
|
5290
|
-
if (rejected.length > 0) {
|
|
5291
|
-
console.warn(
|
|
5292
|
-
`${context}: dropped ${rejected.length} wrong-script VTXO(s) for script ${script}: ${rejected.join(", ")}`
|
|
5293
|
-
);
|
|
5294
|
-
}
|
|
5295
|
-
return matches;
|
|
5296
|
-
}
|
|
5297
|
-
function validateVtxosForScript(vtxos, script, context) {
|
|
5298
|
-
const mismatches = vtxos.filter((v) => !isVtxoForScript(v, script));
|
|
5299
|
-
if (mismatches.length === 0) return;
|
|
5300
|
-
const detail = mismatches.map((v) => `${vtxoOutpoint(v)}(script=${v.script ?? ""})`).join(", ");
|
|
5301
|
-
throw new Error(
|
|
5302
|
-
`${context}: refusing to persist ${mismatches.length} VTXO(s) whose script does not match ${script}: ${detail}`
|
|
5303
|
-
);
|
|
5304
|
-
}
|
|
5305
|
-
async function getVtxosForContract(repo, contract) {
|
|
5306
|
-
return repo.getVtxosForScript ? repo.getVtxosForScript(contract.script) : filterVtxosForScript(await repo.getVtxos(contract.address), contract.script);
|
|
5307
|
-
}
|
|
5308
|
-
async function saveVtxosForContract(repo, contract, vtxos) {
|
|
5309
|
-
if (repo.saveVtxosForScript) {
|
|
5310
|
-
return repo.saveVtxosForScript(
|
|
5311
|
-
{ script: contract.script, address: contract.address },
|
|
5312
|
-
vtxos
|
|
5313
|
-
);
|
|
5314
|
-
}
|
|
5315
|
-
validateVtxosForScript(vtxos, contract.script, "saveVtxosForContract");
|
|
5316
|
-
return repo.saveVtxos(contract.address, vtxos);
|
|
5388
|
+
// src/repositories/virtualTxRepository.ts
|
|
5389
|
+
var ChainedTxType = /* @__PURE__ */ ((ChainedTxType2) => {
|
|
5390
|
+
ChainedTxType2[ChainedTxType2["Unspecified"] = 0] = "Unspecified";
|
|
5391
|
+
ChainedTxType2[ChainedTxType2["Commitment"] = 1] = "Commitment";
|
|
5392
|
+
ChainedTxType2[ChainedTxType2["Ark"] = 2] = "Ark";
|
|
5393
|
+
ChainedTxType2[ChainedTxType2["Tree"] = 3] = "Tree";
|
|
5394
|
+
ChainedTxType2[ChainedTxType2["Checkpoint"] = 4] = "Checkpoint";
|
|
5395
|
+
return ChainedTxType2;
|
|
5396
|
+
})(ChainedTxType || {});
|
|
5397
|
+
function mergeChainedTxType(incoming, prev) {
|
|
5398
|
+
if (incoming !== 0 /* Unspecified */) return incoming;
|
|
5399
|
+
return prev ?? 0 /* Unspecified */;
|
|
5317
5400
|
}
|
|
5318
5401
|
|
|
5319
|
-
// src/repositories/inMemory/
|
|
5320
|
-
var
|
|
5402
|
+
// src/repositories/inMemory/intentRepository.ts
|
|
5403
|
+
var InMemoryIntentRepository = class {
|
|
5321
5404
|
version = 1;
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
async
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5330
|
-
|
|
5331
|
-
|
|
5332
|
-
|
|
5405
|
+
byId = /* @__PURE__ */ new Map();
|
|
5406
|
+
async clear() {
|
|
5407
|
+
this.byId.clear();
|
|
5408
|
+
}
|
|
5409
|
+
async saveIntent(intent) {
|
|
5410
|
+
assertIntentIdUnique(intent, this.byId.values());
|
|
5411
|
+
this.byId.set(intent.intentTxId, {
|
|
5412
|
+
...intent,
|
|
5413
|
+
intentVtxos: [...intent.intentVtxos],
|
|
5414
|
+
partialForfeits: [...intent.partialForfeits],
|
|
5415
|
+
updatedAt: Date.now()
|
|
5416
|
+
});
|
|
5333
5417
|
}
|
|
5334
|
-
async
|
|
5335
|
-
this.
|
|
5418
|
+
async getIntents(filter) {
|
|
5419
|
+
let out = [...this.byId.values()];
|
|
5420
|
+
if (filter) out = out.filter((i) => intentMatchesFilter(i, filter));
|
|
5421
|
+
out.sort((a, b) => a.createdAt - b.createdAt || a.intentTxId.localeCompare(b.intentTxId));
|
|
5422
|
+
const { skip, end } = intentPageBounds(filter, out.length);
|
|
5423
|
+
return out.slice(skip, end).map(clone);
|
|
5336
5424
|
}
|
|
5337
|
-
async
|
|
5338
|
-
const
|
|
5339
|
-
for (const
|
|
5340
|
-
for (const
|
|
5341
|
-
|
|
5342
|
-
allMatches.push(vtxo);
|
|
5343
|
-
}
|
|
5344
|
-
}
|
|
5345
|
-
}
|
|
5346
|
-
return mergeByKey([], allMatches, (item) => `${item.txid}:${item.vout}`);
|
|
5425
|
+
async getLockedVtxoOutpoints() {
|
|
5426
|
+
const out = [];
|
|
5427
|
+
for (const i of this.byId.values())
|
|
5428
|
+
if (!isTerminalIntentState(i.state)) for (const o of i.intentVtxos) out.push({ ...o });
|
|
5429
|
+
return out;
|
|
5347
5430
|
}
|
|
5348
|
-
async
|
|
5349
|
-
if (!key.address) {
|
|
5350
|
-
throw new Error("InMemoryWalletRepository requires an address");
|
|
5351
|
-
}
|
|
5352
|
-
for (const vtxo of vtxos) {
|
|
5353
|
-
if (!isVtxoForScript(vtxo, key.script)) {
|
|
5354
|
-
throw new Error(
|
|
5355
|
-
`VTXO ${vtxo.txid}:${vtxo.vout} script mismatch: expected ${key.script}, got ${vtxo.script}`
|
|
5356
|
-
);
|
|
5357
|
-
}
|
|
5358
|
-
}
|
|
5359
|
-
return this.saveVtxos(key.address, vtxos);
|
|
5431
|
+
async [Symbol.asyncDispose]() {
|
|
5360
5432
|
}
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5433
|
+
};
|
|
5434
|
+
var clone = (i) => ({
|
|
5435
|
+
...i,
|
|
5436
|
+
intentVtxos: i.intentVtxos.map((o) => ({ ...o })),
|
|
5437
|
+
partialForfeits: [...i.partialForfeits]
|
|
5438
|
+
});
|
|
5439
|
+
|
|
5440
|
+
// src/repositories/inMemory/virtualTxRepository.ts
|
|
5441
|
+
var opKey = (o) => `${o.txid}:${o.vout}`;
|
|
5442
|
+
var InMemoryVirtualTxRepository = class {
|
|
5443
|
+
version = 1;
|
|
5444
|
+
txs = /* @__PURE__ */ new Map();
|
|
5445
|
+
branches = /* @__PURE__ */ new Map();
|
|
5446
|
+
async clear() {
|
|
5447
|
+
this.txs.clear();
|
|
5448
|
+
this.branches.clear();
|
|
5449
|
+
}
|
|
5450
|
+
async upsertVirtualTxs(txs) {
|
|
5451
|
+
for (const t of txs) {
|
|
5452
|
+
const prev = this.txs.get(t.txid);
|
|
5453
|
+
if (!prev) {
|
|
5454
|
+
this.txs.set(t.txid, { ...t });
|
|
5455
|
+
continue;
|
|
5368
5456
|
}
|
|
5457
|
+
this.txs.set(t.txid, {
|
|
5458
|
+
txid: t.txid,
|
|
5459
|
+
psbt: t.psbt ?? prev.psbt,
|
|
5460
|
+
expiresAt: t.expiresAt ?? prev.expiresAt,
|
|
5461
|
+
type: mergeChainedTxType(t.type, prev.type)
|
|
5462
|
+
});
|
|
5369
5463
|
}
|
|
5370
5464
|
}
|
|
5371
|
-
async
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
async saveUtxos(address, utxos) {
|
|
5375
|
-
const existing = this.utxosByAddress.get(address) ?? [];
|
|
5376
|
-
const next = mergeByKey(existing, utxos, (item) => `${item.txid}:${item.vout}`);
|
|
5377
|
-
this.utxosByAddress.set(address, next);
|
|
5378
|
-
}
|
|
5379
|
-
async deleteUtxos(address) {
|
|
5380
|
-
this.utxosByAddress.delete(address);
|
|
5381
|
-
}
|
|
5382
|
-
async getTransactionHistory(address) {
|
|
5383
|
-
return this.txsByAddress.get(address) ?? [];
|
|
5384
|
-
}
|
|
5385
|
-
async saveTransactions(address, txs) {
|
|
5386
|
-
const existing = this.txsByAddress.get(address) ?? [];
|
|
5387
|
-
const next = mergeByKey(existing, txs, serializeTxKey);
|
|
5388
|
-
this.txsByAddress.set(address, next);
|
|
5465
|
+
async getVirtualTx(txid) {
|
|
5466
|
+
const t = this.txs.get(txid);
|
|
5467
|
+
return t ? { ...t } : null;
|
|
5389
5468
|
}
|
|
5390
|
-
async
|
|
5391
|
-
this.
|
|
5469
|
+
async setBranch(vtxo, branch) {
|
|
5470
|
+
this.branches.set(
|
|
5471
|
+
opKey(vtxo),
|
|
5472
|
+
[...branch].sort((a, b) => a.position - b.position)
|
|
5473
|
+
);
|
|
5392
5474
|
}
|
|
5393
|
-
async
|
|
5394
|
-
|
|
5475
|
+
async getBranch(vtxo) {
|
|
5476
|
+
const b = this.branches.get(opKey(vtxo)) ?? [];
|
|
5477
|
+
return b.map((x) => this.txs.get(x.virtualTxid)).filter((t) => !!t).map((t) => ({ ...t }));
|
|
5395
5478
|
}
|
|
5396
|
-
async
|
|
5397
|
-
this.
|
|
5479
|
+
async hasBranch(vtxo) {
|
|
5480
|
+
return (this.branches.get(opKey(vtxo)) ?? []).length > 0;
|
|
5398
5481
|
}
|
|
5399
|
-
async
|
|
5400
|
-
this.
|
|
5401
|
-
this.
|
|
5402
|
-
|
|
5403
|
-
this.
|
|
5482
|
+
async pruneForSpentVtxo(vtxo) {
|
|
5483
|
+
const removed = this.branches.get(opKey(vtxo)) ?? [];
|
|
5484
|
+
this.branches.delete(opKey(vtxo));
|
|
5485
|
+
const stillReferenced = /* @__PURE__ */ new Set();
|
|
5486
|
+
for (const b of this.branches.values())
|
|
5487
|
+
for (const e of b) stillReferenced.add(e.virtualTxid);
|
|
5488
|
+
for (const e of removed)
|
|
5489
|
+
if (!stillReferenced.has(e.virtualTxid)) this.txs.delete(e.virtualTxid);
|
|
5404
5490
|
}
|
|
5405
5491
|
async [Symbol.asyncDispose]() {
|
|
5406
|
-
return;
|
|
5407
5492
|
}
|
|
5408
5493
|
};
|
|
5409
|
-
function serializeTxKey(tx) {
|
|
5410
|
-
const key = tx.key;
|
|
5411
|
-
return `${key.boardingTxid}:${key.commitmentTxid}:${key.arkTxid}`;
|
|
5412
|
-
}
|
|
5413
|
-
function mergeByKey(existing, incoming, toKey) {
|
|
5414
|
-
const next = /* @__PURE__ */ new Map();
|
|
5415
|
-
existing.forEach((item) => {
|
|
5416
|
-
next.set(toKey(item), item);
|
|
5417
|
-
});
|
|
5418
|
-
incoming.forEach((item) => {
|
|
5419
|
-
next.set(toKey(item), item);
|
|
5420
|
-
});
|
|
5421
|
-
return Array.from(next.values());
|
|
5422
|
-
}
|
|
5423
5494
|
|
|
5424
|
-
// src/repositories/
|
|
5425
|
-
var
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
|
|
5433
|
-
|
|
5434
|
-
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
if (
|
|
5439
|
-
return
|
|
5495
|
+
// src/repositories/indexedDB/idbUtils.ts
|
|
5496
|
+
var promisifyRequest = (request) => new Promise((resolve, reject) => {
|
|
5497
|
+
request.onsuccess = () => resolve(request.result);
|
|
5498
|
+
request.onerror = () => reject(request.error);
|
|
5499
|
+
});
|
|
5500
|
+
var awaitTransaction = (transaction) => new Promise((resolve, reject) => {
|
|
5501
|
+
transaction.oncomplete = () => resolve();
|
|
5502
|
+
transaction.onerror = () => reject(transaction.error);
|
|
5503
|
+
transaction.onabort = () => reject(transaction.error ?? new Error("transaction aborted"));
|
|
5504
|
+
});
|
|
5505
|
+
|
|
5506
|
+
// src/repositories/indexedDB/manager.ts
|
|
5507
|
+
function getGlobalObject() {
|
|
5508
|
+
if (typeof globalThis !== "undefined") {
|
|
5509
|
+
if (typeof globalThis.self === "object" && globalThis.self !== null) {
|
|
5510
|
+
return { globalObject: globalThis.self };
|
|
5440
5511
|
}
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
return true;
|
|
5444
|
-
}
|
|
5445
|
-
return Array.isArray(criterion) ? criterion.includes(value) : value === criterion;
|
|
5446
|
-
};
|
|
5447
|
-
const results = [];
|
|
5448
|
-
for (const contract of contracts) {
|
|
5449
|
-
if (matches(contract.script, filter.script) && matches(contract.state, filter.state) && matches(contract.type, filter.type)) {
|
|
5450
|
-
results.push(contract);
|
|
5451
|
-
}
|
|
5512
|
+
if (typeof globalThis.window === "object" && globalThis.window !== null) {
|
|
5513
|
+
return { globalObject: globalThis.window };
|
|
5452
5514
|
}
|
|
5453
|
-
return
|
|
5454
|
-
}
|
|
5455
|
-
async saveContract(contract) {
|
|
5456
|
-
this.contractsByScript.set(contract.script, contract);
|
|
5515
|
+
return { globalObject: globalThis };
|
|
5457
5516
|
}
|
|
5458
|
-
|
|
5459
|
-
|
|
5517
|
+
throw new Error("Global object not found");
|
|
5518
|
+
}
|
|
5519
|
+
var dbCache = /* @__PURE__ */ new Map();
|
|
5520
|
+
var refCounts = /* @__PURE__ */ new Map();
|
|
5521
|
+
async function openDatabase(dbName, dbVersion, initDatabase2) {
|
|
5522
|
+
const { globalObject } = getGlobalObject();
|
|
5523
|
+
if (!globalObject.indexedDB) {
|
|
5524
|
+
throw new Error("IndexedDB is not available in this environment");
|
|
5460
5525
|
}
|
|
5461
|
-
|
|
5462
|
-
|
|
5526
|
+
const cached = dbCache.get(dbName);
|
|
5527
|
+
if (cached) {
|
|
5528
|
+
if (cached.version !== dbVersion) {
|
|
5529
|
+
throw new Error(
|
|
5530
|
+
`Database "${dbName}" already opened with version ${cached.version}; requested ${dbVersion}`
|
|
5531
|
+
);
|
|
5532
|
+
}
|
|
5533
|
+
refCounts.set(dbName, (refCounts.get(dbName) ?? 0) + 1);
|
|
5534
|
+
return cached.promise;
|
|
5463
5535
|
}
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
|
|
5536
|
+
const dbPromise = new Promise((resolve, reject) => {
|
|
5537
|
+
const request = globalObject.indexedDB.open(dbName, dbVersion);
|
|
5538
|
+
request.onerror = () => {
|
|
5539
|
+
dbCache.delete(dbName);
|
|
5540
|
+
refCounts.delete(dbName);
|
|
5541
|
+
reject(request.error);
|
|
5542
|
+
};
|
|
5543
|
+
request.onsuccess = () => {
|
|
5544
|
+
const db = request.result;
|
|
5545
|
+
db.onversionchange = () => {
|
|
5546
|
+
db.close();
|
|
5547
|
+
dbCache.delete(dbName);
|
|
5548
|
+
refCounts.delete(dbName);
|
|
5549
|
+
};
|
|
5550
|
+
resolve(db);
|
|
5551
|
+
};
|
|
5552
|
+
request.onupgradeneeded = (event) => {
|
|
5553
|
+
const db = request.result;
|
|
5554
|
+
initDatabase2(db, event.oldVersion, request.transaction);
|
|
5555
|
+
};
|
|
5556
|
+
request.onblocked = () => {
|
|
5557
|
+
console.warn("Database upgrade blocked - close other tabs/connections");
|
|
5558
|
+
};
|
|
5559
|
+
});
|
|
5560
|
+
dbCache.set(dbName, { version: dbVersion, promise: dbPromise });
|
|
5561
|
+
refCounts.set(dbName, 1);
|
|
5562
|
+
return dbPromise;
|
|
5563
|
+
}
|
|
5564
|
+
async function closeDatabase(dbName) {
|
|
5565
|
+
const cachedEntry = dbCache.get(dbName);
|
|
5566
|
+
if (!cachedEntry) return false;
|
|
5567
|
+
const count = (refCounts.get(dbName) ?? 1) - 1;
|
|
5568
|
+
if (count > 0) {
|
|
5569
|
+
refCounts.set(dbName, count);
|
|
5570
|
+
return false;
|
|
5571
|
+
}
|
|
5572
|
+
refCounts.delete(dbName);
|
|
5573
|
+
dbCache.delete(dbName);
|
|
5574
|
+
try {
|
|
5575
|
+
const db = await cachedEntry.promise;
|
|
5576
|
+
db.close();
|
|
5577
|
+
} catch {
|
|
5578
|
+
}
|
|
5579
|
+
return true;
|
|
5580
|
+
}
|
|
5581
|
+
function scriptFromArkAddress(address) {
|
|
5582
|
+
return base.hex.encode(chunkHXDZ2QTW_cjs.ArkAddress.decode(address).pkScript);
|
|
5583
|
+
}
|
|
5584
|
+
|
|
5585
|
+
// src/repositories/indexedDB/schema.ts
|
|
5586
|
+
var STORE_VTXOS = "vtxos";
|
|
5587
|
+
var STORE_UTXOS = "utxos";
|
|
5588
|
+
var STORE_TRANSACTIONS = "transactions";
|
|
5589
|
+
var STORE_WALLET_STATE = "walletState";
|
|
5590
|
+
var STORE_CONTRACTS = "contracts";
|
|
5591
|
+
var STORE_INTENTS = "intents";
|
|
5592
|
+
var STORE_VIRTUAL_TXS = "virtualTxs";
|
|
5593
|
+
var STORE_VTXO_BRANCHES = "vtxoBranches";
|
|
5594
|
+
var LEGACY_STORE_CONTRACT_COLLECTIONS = "contractsCollections";
|
|
5595
|
+
var DB_VERSION = 3;
|
|
5596
|
+
var INTENT_DB_VERSION = 5;
|
|
5597
|
+
function initDatabase(db, oldVersion, transaction) {
|
|
5478
5598
|
if (!db.objectStoreNames.contains(STORE_VTXOS)) {
|
|
5479
5599
|
const vtxosStore = db.createObjectStore(STORE_VTXOS, {
|
|
5480
5600
|
keyPath: ["address", "txid", "vout"]
|
|
@@ -5612,33 +5732,506 @@ function initDatabase(db, oldVersion, transaction) {
|
|
|
5612
5732
|
});
|
|
5613
5733
|
}
|
|
5614
5734
|
}
|
|
5615
|
-
if (!db.objectStoreNames.contains(LEGACY_STORE_CONTRACT_COLLECTIONS)) {
|
|
5616
|
-
db.createObjectStore(LEGACY_STORE_CONTRACT_COLLECTIONS, {
|
|
5617
|
-
keyPath: "key"
|
|
5618
|
-
});
|
|
5735
|
+
if (!db.objectStoreNames.contains(LEGACY_STORE_CONTRACT_COLLECTIONS)) {
|
|
5736
|
+
db.createObjectStore(LEGACY_STORE_CONTRACT_COLLECTIONS, {
|
|
5737
|
+
keyPath: "key"
|
|
5738
|
+
});
|
|
5739
|
+
}
|
|
5740
|
+
if (oldVersion >= 1 && oldVersion < 3 && transaction) {
|
|
5741
|
+
const vtxosStore = transaction.objectStore(STORE_VTXOS);
|
|
5742
|
+
if (!vtxosStore.indexNames.contains("script")) {
|
|
5743
|
+
vtxosStore.createIndex("script", "script", { unique: false });
|
|
5744
|
+
}
|
|
5745
|
+
backfillVtxoScripts(transaction);
|
|
5746
|
+
}
|
|
5747
|
+
}
|
|
5748
|
+
function initDatabaseWithIntents(db, oldVersion, transaction) {
|
|
5749
|
+
initDatabase(db, oldVersion, transaction);
|
|
5750
|
+
if (!db.objectStoreNames.contains(STORE_INTENTS)) {
|
|
5751
|
+
const intentsStore = db.createObjectStore(STORE_INTENTS, {
|
|
5752
|
+
keyPath: "intentTxId"
|
|
5753
|
+
});
|
|
5754
|
+
intentsStore.createIndex("intentId", "intentId", { unique: true });
|
|
5755
|
+
intentsStore.createIndex("state", "state", { unique: false });
|
|
5756
|
+
}
|
|
5757
|
+
if (!db.objectStoreNames.contains(STORE_VIRTUAL_TXS)) {
|
|
5758
|
+
db.createObjectStore(STORE_VIRTUAL_TXS, { keyPath: "txid" });
|
|
5759
|
+
}
|
|
5760
|
+
if (!db.objectStoreNames.contains(STORE_VTXO_BRANCHES)) {
|
|
5761
|
+
const branchesStore = db.createObjectStore(STORE_VTXO_BRANCHES, {
|
|
5762
|
+
keyPath: ["vtxoTxid", "vtxoVout", "position"]
|
|
5763
|
+
});
|
|
5764
|
+
branchesStore.createIndex("vtxo", ["vtxoTxid", "vtxoVout"], { unique: false });
|
|
5765
|
+
branchesStore.createIndex("virtualTxid", "virtualTxid", { unique: false });
|
|
5766
|
+
}
|
|
5767
|
+
if (oldVersion === 4 && transaction) {
|
|
5768
|
+
const intentsStore = transaction.objectStore(STORE_INTENTS);
|
|
5769
|
+
if (intentsStore.indexNames.contains("intentId")) {
|
|
5770
|
+
intentsStore.deleteIndex("intentId");
|
|
5771
|
+
}
|
|
5772
|
+
dedupeIntentIds(intentsStore, () => {
|
|
5773
|
+
intentsStore.createIndex("intentId", "intentId", { unique: true });
|
|
5774
|
+
});
|
|
5775
|
+
}
|
|
5776
|
+
}
|
|
5777
|
+
function dedupeIntentIds(store, onComplete) {
|
|
5778
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5779
|
+
const cursorRequest = store.openCursor();
|
|
5780
|
+
cursorRequest.onsuccess = () => {
|
|
5781
|
+
const cursor = cursorRequest.result;
|
|
5782
|
+
if (!cursor) {
|
|
5783
|
+
onComplete();
|
|
5784
|
+
return;
|
|
5785
|
+
}
|
|
5786
|
+
const id = cursor.value.intentId;
|
|
5787
|
+
if (id != null) {
|
|
5788
|
+
if (seen.has(id)) {
|
|
5789
|
+
cursor.delete();
|
|
5790
|
+
} else {
|
|
5791
|
+
seen.add(id);
|
|
5792
|
+
}
|
|
5793
|
+
}
|
|
5794
|
+
cursor.continue();
|
|
5795
|
+
};
|
|
5796
|
+
}
|
|
5797
|
+
function backfillVtxoScripts(transaction) {
|
|
5798
|
+
const store = transaction.objectStore(STORE_VTXOS);
|
|
5799
|
+
const cursorRequest = store.openCursor();
|
|
5800
|
+
cursorRequest.onsuccess = () => {
|
|
5801
|
+
const cursor = cursorRequest.result;
|
|
5802
|
+
if (!cursor) return;
|
|
5803
|
+
const value = cursor.value;
|
|
5804
|
+
if (!value.script) {
|
|
5805
|
+
value.script = scriptFromArkAddress(value.address);
|
|
5806
|
+
cursor.update(value);
|
|
5807
|
+
}
|
|
5808
|
+
cursor.continue();
|
|
5809
|
+
};
|
|
5810
|
+
}
|
|
5811
|
+
|
|
5812
|
+
// src/worker/browser/utils.ts
|
|
5813
|
+
var DEFAULT_DB_NAME = "arkade-service-worker";
|
|
5814
|
+
var DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS = 1e4;
|
|
5815
|
+
function normalizeOptions2(pathOrOptions) {
|
|
5816
|
+
if (typeof pathOrOptions === "string") {
|
|
5817
|
+
return {
|
|
5818
|
+
path: pathOrOptions,
|
|
5819
|
+
activationTimeoutMs: DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS
|
|
5820
|
+
};
|
|
5821
|
+
}
|
|
5822
|
+
return {
|
|
5823
|
+
path: pathOrOptions.path,
|
|
5824
|
+
activationTimeoutMs: pathOrOptions.activationTimeoutMs ?? DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS
|
|
5825
|
+
};
|
|
5826
|
+
}
|
|
5827
|
+
function waitForServiceWorkerReady(timeoutMs) {
|
|
5828
|
+
return new Promise((resolve, reject) => {
|
|
5829
|
+
const timeoutId = setTimeout(() => {
|
|
5830
|
+
reject(new Error(`Service worker activation timed out after ${timeoutMs}ms`));
|
|
5831
|
+
}, timeoutMs);
|
|
5832
|
+
navigator.serviceWorker.ready.then((registration) => {
|
|
5833
|
+
clearTimeout(timeoutId);
|
|
5834
|
+
resolve(registration);
|
|
5835
|
+
}).catch((error) => {
|
|
5836
|
+
clearTimeout(timeoutId);
|
|
5837
|
+
reject(error);
|
|
5838
|
+
});
|
|
5839
|
+
});
|
|
5840
|
+
}
|
|
5841
|
+
async function setupServiceWorker(pathOrOptions) {
|
|
5842
|
+
if (!("serviceWorker" in navigator)) {
|
|
5843
|
+
throw new Error("Service workers are not supported in this browser");
|
|
5844
|
+
}
|
|
5845
|
+
const { path, activationTimeoutMs } = normalizeOptions2(pathOrOptions);
|
|
5846
|
+
const registration = await navigator.serviceWorker.register(path);
|
|
5847
|
+
await registration.update();
|
|
5848
|
+
const serviceWorker = registration.active || registration.waiting || registration.installing;
|
|
5849
|
+
if (!serviceWorker) {
|
|
5850
|
+
throw new Error("Failed to get service worker instance");
|
|
5851
|
+
}
|
|
5852
|
+
if (serviceWorker.state === "activated") {
|
|
5853
|
+
return serviceWorker;
|
|
5854
|
+
}
|
|
5855
|
+
const readyRegistration = await waitForServiceWorkerReady(activationTimeoutMs);
|
|
5856
|
+
if (!readyRegistration.active) {
|
|
5857
|
+
throw new Error("Service worker registration is ready but has no active worker");
|
|
5858
|
+
}
|
|
5859
|
+
return readyRegistration.active;
|
|
5860
|
+
}
|
|
5861
|
+
|
|
5862
|
+
// src/repositories/indexedDB/virtualTxRepository.ts
|
|
5863
|
+
var IndexedDBVirtualTxRepository = class {
|
|
5864
|
+
constructor(dbName = DEFAULT_DB_NAME) {
|
|
5865
|
+
this.dbName = dbName;
|
|
5866
|
+
}
|
|
5867
|
+
version = 1;
|
|
5868
|
+
db = null;
|
|
5869
|
+
async getDB() {
|
|
5870
|
+
if (!this.db)
|
|
5871
|
+
this.db = await openDatabase(this.dbName, INTENT_DB_VERSION, initDatabaseWithIntents);
|
|
5872
|
+
return this.db;
|
|
5873
|
+
}
|
|
5874
|
+
async clear() {
|
|
5875
|
+
const db = await this.getDB();
|
|
5876
|
+
const transaction = db.transaction([STORE_VIRTUAL_TXS, STORE_VTXO_BRANCHES], "readwrite");
|
|
5877
|
+
transaction.objectStore(STORE_VIRTUAL_TXS).clear();
|
|
5878
|
+
transaction.objectStore(STORE_VTXO_BRANCHES).clear();
|
|
5879
|
+
await awaitTransaction(transaction);
|
|
5880
|
+
}
|
|
5881
|
+
async upsertVirtualTxs(txs) {
|
|
5882
|
+
if (txs.length === 0) return;
|
|
5883
|
+
const db = await this.getDB();
|
|
5884
|
+
const merged = /* @__PURE__ */ new Map();
|
|
5885
|
+
for (const tx of txs) {
|
|
5886
|
+
const acc = merged.get(tx.txid);
|
|
5887
|
+
merged.set(
|
|
5888
|
+
tx.txid,
|
|
5889
|
+
acc ? {
|
|
5890
|
+
txid: tx.txid,
|
|
5891
|
+
psbt: tx.psbt ?? acc.psbt,
|
|
5892
|
+
expiresAt: tx.expiresAt ?? acc.expiresAt,
|
|
5893
|
+
type: mergeChainedTxType(tx.type, acc.type)
|
|
5894
|
+
} : tx
|
|
5895
|
+
);
|
|
5896
|
+
}
|
|
5897
|
+
const transaction = db.transaction([STORE_VIRTUAL_TXS], "readwrite");
|
|
5898
|
+
const store = transaction.objectStore(STORE_VIRTUAL_TXS);
|
|
5899
|
+
for (const tx of merged.values()) {
|
|
5900
|
+
const getReq = store.get(tx.txid);
|
|
5901
|
+
getReq.onsuccess = () => {
|
|
5902
|
+
const prev = getReq.result;
|
|
5903
|
+
store.put({
|
|
5904
|
+
txid: tx.txid,
|
|
5905
|
+
psbt: tx.psbt ?? prev?.psbt ?? null,
|
|
5906
|
+
expiresAt: tx.expiresAt ?? prev?.expiresAt ?? null,
|
|
5907
|
+
type: mergeChainedTxType(tx.type, prev?.type)
|
|
5908
|
+
});
|
|
5909
|
+
};
|
|
5910
|
+
}
|
|
5911
|
+
await awaitTransaction(transaction);
|
|
5912
|
+
}
|
|
5913
|
+
async getVirtualTx(txid) {
|
|
5914
|
+
const db = await this.getDB();
|
|
5915
|
+
const store = db.transaction([STORE_VIRTUAL_TXS], "readonly").objectStore(STORE_VIRTUAL_TXS);
|
|
5916
|
+
const r = await promisifyRequest(store.get(txid));
|
|
5917
|
+
return r ?? null;
|
|
5918
|
+
}
|
|
5919
|
+
async setBranch(vtxo, branch) {
|
|
5920
|
+
const db = await this.getDB();
|
|
5921
|
+
const transaction = db.transaction([STORE_VTXO_BRANCHES], "readwrite");
|
|
5922
|
+
const store = transaction.objectStore(STORE_VTXO_BRANCHES);
|
|
5923
|
+
const getAllReq = store.index("vtxo").getAll(IDBKeyRange.only([vtxo.txid, vtxo.vout]));
|
|
5924
|
+
getAllReq.onsuccess = () => {
|
|
5925
|
+
const existing = getAllReq.result;
|
|
5926
|
+
for (const e of existing) store.delete([e.vtxoTxid, e.vtxoVout, e.position]);
|
|
5927
|
+
for (const b of branch) store.put(b);
|
|
5928
|
+
};
|
|
5929
|
+
await awaitTransaction(transaction);
|
|
5930
|
+
}
|
|
5931
|
+
async getBranch(vtxo) {
|
|
5932
|
+
const db = await this.getDB();
|
|
5933
|
+
const transaction = db.transaction([STORE_VTXO_BRANCHES, STORE_VIRTUAL_TXS], "readonly");
|
|
5934
|
+
const branchStore = transaction.objectStore(STORE_VTXO_BRANCHES);
|
|
5935
|
+
const txStore = transaction.objectStore(STORE_VIRTUAL_TXS);
|
|
5936
|
+
const getAllReq = branchStore.index("vtxo").getAll(IDBKeyRange.only([vtxo.txid, vtxo.vout]));
|
|
5937
|
+
const byTxid = /* @__PURE__ */ new Map();
|
|
5938
|
+
let ordered = [];
|
|
5939
|
+
getAllReq.onsuccess = () => {
|
|
5940
|
+
ordered = getAllReq.result.slice().sort((a, b) => a.position - b.position);
|
|
5941
|
+
for (const b of ordered) {
|
|
5942
|
+
const txReq = txStore.get(b.virtualTxid);
|
|
5943
|
+
txReq.onsuccess = () => {
|
|
5944
|
+
const r = txReq.result;
|
|
5945
|
+
if (r) byTxid.set(b.virtualTxid, r);
|
|
5946
|
+
};
|
|
5947
|
+
}
|
|
5948
|
+
};
|
|
5949
|
+
await awaitTransaction(transaction);
|
|
5950
|
+
const out = [];
|
|
5951
|
+
for (const b of ordered) {
|
|
5952
|
+
const tx = byTxid.get(b.virtualTxid);
|
|
5953
|
+
if (tx) out.push(tx);
|
|
5954
|
+
}
|
|
5955
|
+
return out;
|
|
5956
|
+
}
|
|
5957
|
+
async hasBranch(vtxo) {
|
|
5958
|
+
const db = await this.getDB();
|
|
5959
|
+
const vtxoIndex = db.transaction([STORE_VTXO_BRANCHES], "readonly").objectStore(STORE_VTXO_BRANCHES).index("vtxo");
|
|
5960
|
+
const count = await promisifyRequest(
|
|
5961
|
+
vtxoIndex.count(IDBKeyRange.only([vtxo.txid, vtxo.vout]))
|
|
5962
|
+
);
|
|
5963
|
+
return count > 0;
|
|
5964
|
+
}
|
|
5965
|
+
async pruneForSpentVtxo(vtxo) {
|
|
5966
|
+
const db = await this.getDB();
|
|
5967
|
+
const transaction = db.transaction([STORE_VTXO_BRANCHES, STORE_VIRTUAL_TXS], "readwrite");
|
|
5968
|
+
const branches = transaction.objectStore(STORE_VTXO_BRANCHES);
|
|
5969
|
+
const txStore = transaction.objectStore(STORE_VIRTUAL_TXS);
|
|
5970
|
+
const getAllReq = branches.index("vtxo").getAll(IDBKeyRange.only([vtxo.txid, vtxo.vout]));
|
|
5971
|
+
getAllReq.onsuccess = () => {
|
|
5972
|
+
const removed = getAllReq.result;
|
|
5973
|
+
if (removed.length === 0) return;
|
|
5974
|
+
for (const e of removed) branches.delete([e.vtxoTxid, e.vtxoVout, e.position]);
|
|
5975
|
+
for (const e of removed) {
|
|
5976
|
+
const countReq = branches.index("virtualTxid").count(IDBKeyRange.only(e.virtualTxid));
|
|
5977
|
+
countReq.onsuccess = () => {
|
|
5978
|
+
if (countReq.result === 0) txStore.delete(e.virtualTxid);
|
|
5979
|
+
};
|
|
5980
|
+
}
|
|
5981
|
+
};
|
|
5982
|
+
await awaitTransaction(transaction);
|
|
5983
|
+
}
|
|
5984
|
+
async [Symbol.asyncDispose]() {
|
|
5985
|
+
if (!this.db) return;
|
|
5986
|
+
await closeDatabase(this.dbName);
|
|
5987
|
+
this.db = null;
|
|
5988
|
+
}
|
|
5989
|
+
};
|
|
5990
|
+
|
|
5991
|
+
// src/repositories/indexedDB/intentRepository.ts
|
|
5992
|
+
var IndexedDBIntentRepository = class {
|
|
5993
|
+
constructor(dbName = DEFAULT_DB_NAME) {
|
|
5994
|
+
this.dbName = dbName;
|
|
5995
|
+
}
|
|
5996
|
+
version = 1;
|
|
5997
|
+
db = null;
|
|
5998
|
+
async getDB() {
|
|
5999
|
+
if (!this.db)
|
|
6000
|
+
this.db = await openDatabase(this.dbName, INTENT_DB_VERSION, initDatabaseWithIntents);
|
|
6001
|
+
return this.db;
|
|
6002
|
+
}
|
|
6003
|
+
async clear() {
|
|
6004
|
+
const db = await this.getDB();
|
|
6005
|
+
const transaction = db.transaction([STORE_INTENTS], "readwrite");
|
|
6006
|
+
transaction.objectStore(STORE_INTENTS).clear();
|
|
6007
|
+
await awaitTransaction(transaction);
|
|
6008
|
+
}
|
|
6009
|
+
async saveIntent(intent) {
|
|
6010
|
+
const db = await this.getDB();
|
|
6011
|
+
const transaction = db.transaction([STORE_INTENTS], "readwrite");
|
|
6012
|
+
transaction.objectStore(STORE_INTENTS).put({ ...intent, updatedAt: Date.now() });
|
|
6013
|
+
await awaitTransaction(transaction);
|
|
6014
|
+
}
|
|
6015
|
+
async getIntents(filter) {
|
|
6016
|
+
const db = await this.getDB();
|
|
6017
|
+
const store = db.transaction([STORE_INTENTS], "readonly").objectStore(STORE_INTENTS);
|
|
6018
|
+
const all = await promisifyRequest(store.getAll());
|
|
6019
|
+
all.sort((a, b) => a.createdAt - b.createdAt || a.intentTxId.localeCompare(b.intentTxId));
|
|
6020
|
+
const out = filter ? all.filter((i) => intentMatchesFilter(i, filter)) : all;
|
|
6021
|
+
const { skip, end } = intentPageBounds(filter, out.length);
|
|
6022
|
+
return out.slice(skip, end);
|
|
6023
|
+
}
|
|
6024
|
+
async getLockedVtxoOutpoints() {
|
|
6025
|
+
const db = await this.getDB();
|
|
6026
|
+
const store = db.transaction([STORE_INTENTS], "readonly").objectStore(STORE_INTENTS);
|
|
6027
|
+
const all = await promisifyRequest(store.getAll());
|
|
6028
|
+
const out = [];
|
|
6029
|
+
for (const i of all)
|
|
6030
|
+
if (!isTerminalIntentState(i.state)) for (const o of i.intentVtxos) out.push(o);
|
|
6031
|
+
return out;
|
|
6032
|
+
}
|
|
6033
|
+
async [Symbol.asyncDispose]() {
|
|
6034
|
+
if (!this.db) return;
|
|
6035
|
+
await closeDatabase(this.dbName);
|
|
6036
|
+
this.db = null;
|
|
6037
|
+
}
|
|
6038
|
+
};
|
|
6039
|
+
|
|
6040
|
+
// src/contracts/vtxoOwnership.ts
|
|
6041
|
+
function vtxoOutpoint(vtxo) {
|
|
6042
|
+
return `${vtxo.txid}:${vtxo.vout}`;
|
|
6043
|
+
}
|
|
6044
|
+
function isVtxoForScript(vtxo, script) {
|
|
6045
|
+
return !!vtxo.script && vtxo.script === script;
|
|
6046
|
+
}
|
|
6047
|
+
function filterVtxosForScript(vtxos, script) {
|
|
6048
|
+
return vtxos.filter((v) => isVtxoForScript(v, script));
|
|
6049
|
+
}
|
|
6050
|
+
function warnAndFilterVtxosForScript(vtxos, script, context) {
|
|
6051
|
+
const matches = [];
|
|
6052
|
+
const rejected = [];
|
|
6053
|
+
for (const v of vtxos) {
|
|
6054
|
+
if (isVtxoForScript(v, script)) {
|
|
6055
|
+
matches.push(v);
|
|
6056
|
+
} else {
|
|
6057
|
+
rejected.push(`${vtxoOutpoint(v)}(script=${v.script ?? ""})`);
|
|
6058
|
+
}
|
|
6059
|
+
}
|
|
6060
|
+
if (rejected.length > 0) {
|
|
6061
|
+
console.warn(
|
|
6062
|
+
`${context}: dropped ${rejected.length} wrong-script VTXO(s) for script ${script}: ${rejected.join(", ")}`
|
|
6063
|
+
);
|
|
6064
|
+
}
|
|
6065
|
+
return matches;
|
|
6066
|
+
}
|
|
6067
|
+
function validateVtxosForScript(vtxos, script, context) {
|
|
6068
|
+
const mismatches = vtxos.filter((v) => !isVtxoForScript(v, script));
|
|
6069
|
+
if (mismatches.length === 0) return;
|
|
6070
|
+
const detail = mismatches.map((v) => `${vtxoOutpoint(v)}(script=${v.script ?? ""})`).join(", ");
|
|
6071
|
+
throw new Error(
|
|
6072
|
+
`${context}: refusing to persist ${mismatches.length} VTXO(s) whose script does not match ${script}: ${detail}`
|
|
6073
|
+
);
|
|
6074
|
+
}
|
|
6075
|
+
async function getVtxosForContract(repo, contract) {
|
|
6076
|
+
return repo.getVtxosForScript ? repo.getVtxosForScript(contract.script) : filterVtxosForScript(await repo.getVtxos(contract.address), contract.script);
|
|
6077
|
+
}
|
|
6078
|
+
async function saveVtxosForContract(repo, contract, vtxos) {
|
|
6079
|
+
if (repo.saveVtxosForScript) {
|
|
6080
|
+
return repo.saveVtxosForScript(
|
|
6081
|
+
{ script: contract.script, address: contract.address },
|
|
6082
|
+
vtxos
|
|
6083
|
+
);
|
|
6084
|
+
}
|
|
6085
|
+
validateVtxosForScript(vtxos, contract.script, "saveVtxosForContract");
|
|
6086
|
+
return repo.saveVtxos(contract.address, vtxos);
|
|
6087
|
+
}
|
|
6088
|
+
|
|
6089
|
+
// src/repositories/inMemory/walletRepository.ts
|
|
6090
|
+
var InMemoryWalletRepository = class {
|
|
6091
|
+
version = 1;
|
|
6092
|
+
vtxosByAddress = /* @__PURE__ */ new Map();
|
|
6093
|
+
utxosByAddress = /* @__PURE__ */ new Map();
|
|
6094
|
+
txsByAddress = /* @__PURE__ */ new Map();
|
|
6095
|
+
walletState = null;
|
|
6096
|
+
async getVtxos(address) {
|
|
6097
|
+
return this.vtxosByAddress.get(address) ?? [];
|
|
6098
|
+
}
|
|
6099
|
+
async saveVtxos(address, vtxos) {
|
|
6100
|
+
const existing = this.vtxosByAddress.get(address) ?? [];
|
|
6101
|
+
const next = mergeByKey(existing, vtxos, (item) => `${item.txid}:${item.vout}`);
|
|
6102
|
+
this.vtxosByAddress.set(address, next);
|
|
6103
|
+
}
|
|
6104
|
+
async deleteVtxos(address) {
|
|
6105
|
+
this.vtxosByAddress.delete(address);
|
|
6106
|
+
}
|
|
6107
|
+
async getVtxosForScript(script) {
|
|
6108
|
+
const allMatches = [];
|
|
6109
|
+
for (const bucket of this.vtxosByAddress.values()) {
|
|
6110
|
+
for (const vtxo of bucket) {
|
|
6111
|
+
if (isVtxoForScript(vtxo, script)) {
|
|
6112
|
+
allMatches.push(vtxo);
|
|
6113
|
+
}
|
|
6114
|
+
}
|
|
6115
|
+
}
|
|
6116
|
+
return mergeByKey([], allMatches, (item) => `${item.txid}:${item.vout}`);
|
|
6117
|
+
}
|
|
6118
|
+
async saveVtxosForScript(key, vtxos) {
|
|
6119
|
+
if (!key.address) {
|
|
6120
|
+
throw new Error("InMemoryWalletRepository requires an address");
|
|
6121
|
+
}
|
|
6122
|
+
for (const vtxo of vtxos) {
|
|
6123
|
+
if (!isVtxoForScript(vtxo, key.script)) {
|
|
6124
|
+
throw new Error(
|
|
6125
|
+
`VTXO ${vtxo.txid}:${vtxo.vout} script mismatch: expected ${key.script}, got ${vtxo.script}`
|
|
6126
|
+
);
|
|
6127
|
+
}
|
|
6128
|
+
}
|
|
6129
|
+
return this.saveVtxos(key.address, vtxos);
|
|
6130
|
+
}
|
|
6131
|
+
async deleteVtxosForScript(script) {
|
|
6132
|
+
for (const [address, bucket] of this.vtxosByAddress.entries()) {
|
|
6133
|
+
const next = bucket.filter((v) => !isVtxoForScript(v, script));
|
|
6134
|
+
if (next.length === 0) {
|
|
6135
|
+
this.vtxosByAddress.delete(address);
|
|
6136
|
+
} else {
|
|
6137
|
+
this.vtxosByAddress.set(address, next);
|
|
6138
|
+
}
|
|
6139
|
+
}
|
|
6140
|
+
}
|
|
6141
|
+
async getUtxos(address) {
|
|
6142
|
+
return this.utxosByAddress.get(address) ?? [];
|
|
6143
|
+
}
|
|
6144
|
+
async saveUtxos(address, utxos) {
|
|
6145
|
+
const existing = this.utxosByAddress.get(address) ?? [];
|
|
6146
|
+
const next = mergeByKey(existing, utxos, (item) => `${item.txid}:${item.vout}`);
|
|
6147
|
+
this.utxosByAddress.set(address, next);
|
|
6148
|
+
}
|
|
6149
|
+
async deleteUtxos(address) {
|
|
6150
|
+
this.utxosByAddress.delete(address);
|
|
6151
|
+
}
|
|
6152
|
+
async getTransactionHistory(address) {
|
|
6153
|
+
return this.txsByAddress.get(address) ?? [];
|
|
6154
|
+
}
|
|
6155
|
+
async saveTransactions(address, txs) {
|
|
6156
|
+
const existing = this.txsByAddress.get(address) ?? [];
|
|
6157
|
+
const next = mergeByKey(existing, txs, serializeTxKey);
|
|
6158
|
+
this.txsByAddress.set(address, next);
|
|
6159
|
+
}
|
|
6160
|
+
async deleteTransactions(address) {
|
|
6161
|
+
this.txsByAddress.delete(address);
|
|
6162
|
+
}
|
|
6163
|
+
async getWalletState() {
|
|
6164
|
+
return this.walletState;
|
|
6165
|
+
}
|
|
6166
|
+
async saveWalletState(state) {
|
|
6167
|
+
this.walletState = state;
|
|
6168
|
+
}
|
|
6169
|
+
async clear() {
|
|
6170
|
+
this.vtxosByAddress.clear();
|
|
6171
|
+
this.utxosByAddress.clear();
|
|
6172
|
+
this.txsByAddress.clear();
|
|
6173
|
+
this.walletState = null;
|
|
6174
|
+
}
|
|
6175
|
+
async [Symbol.asyncDispose]() {
|
|
6176
|
+
return;
|
|
6177
|
+
}
|
|
6178
|
+
};
|
|
6179
|
+
function serializeTxKey(tx) {
|
|
6180
|
+
const key = tx.key;
|
|
6181
|
+
return `${key.boardingTxid}:${key.commitmentTxid}:${key.arkTxid}`;
|
|
6182
|
+
}
|
|
6183
|
+
function mergeByKey(existing, incoming, toKey) {
|
|
6184
|
+
const next = /* @__PURE__ */ new Map();
|
|
6185
|
+
existing.forEach((item) => {
|
|
6186
|
+
next.set(toKey(item), item);
|
|
6187
|
+
});
|
|
6188
|
+
incoming.forEach((item) => {
|
|
6189
|
+
next.set(toKey(item), item);
|
|
6190
|
+
});
|
|
6191
|
+
return Array.from(next.values());
|
|
6192
|
+
}
|
|
6193
|
+
|
|
6194
|
+
// src/repositories/inMemory/contractRepository.ts
|
|
6195
|
+
var InMemoryContractRepository = class {
|
|
6196
|
+
version = 1;
|
|
6197
|
+
contractData = /* @__PURE__ */ new Map();
|
|
6198
|
+
collections = /* @__PURE__ */ new Map();
|
|
6199
|
+
contractsByScript = /* @__PURE__ */ new Map();
|
|
6200
|
+
async clear() {
|
|
6201
|
+
this.contractData.clear();
|
|
6202
|
+
this.collections.clear();
|
|
6203
|
+
this.contractsByScript.clear();
|
|
6204
|
+
}
|
|
6205
|
+
// Contract entity management methods
|
|
6206
|
+
async getContracts(filter) {
|
|
6207
|
+
const contracts = this.contractsByScript.values();
|
|
6208
|
+
if (!filter) {
|
|
6209
|
+
return [...contracts];
|
|
6210
|
+
}
|
|
6211
|
+
const matches = (value, criterion) => {
|
|
6212
|
+
if (criterion === void 0) {
|
|
6213
|
+
return true;
|
|
6214
|
+
}
|
|
6215
|
+
return Array.isArray(criterion) ? criterion.includes(value) : value === criterion;
|
|
6216
|
+
};
|
|
6217
|
+
const results = [];
|
|
6218
|
+
for (const contract of contracts) {
|
|
6219
|
+
if (matches(contract.script, filter.script) && matches(contract.state, filter.state) && matches(contract.type, filter.type)) {
|
|
6220
|
+
results.push(contract);
|
|
6221
|
+
}
|
|
6222
|
+
}
|
|
6223
|
+
return results;
|
|
6224
|
+
}
|
|
6225
|
+
async saveContract(contract) {
|
|
6226
|
+
this.contractsByScript.set(contract.script, contract);
|
|
5619
6227
|
}
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
if (!vtxosStore.indexNames.contains("script")) {
|
|
5623
|
-
vtxosStore.createIndex("script", "script", { unique: false });
|
|
5624
|
-
}
|
|
5625
|
-
backfillVtxoScripts(transaction);
|
|
6228
|
+
async deleteContract(script) {
|
|
6229
|
+
this.contractsByScript.delete(script);
|
|
5626
6230
|
}
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
cursorRequest.onsuccess = () => {
|
|
5632
|
-
const cursor = cursorRequest.result;
|
|
5633
|
-
if (!cursor) return;
|
|
5634
|
-
const value = cursor.value;
|
|
5635
|
-
if (!value.script) {
|
|
5636
|
-
value.script = scriptFromArkAddress(value.address);
|
|
5637
|
-
cursor.update(value);
|
|
5638
|
-
}
|
|
5639
|
-
cursor.continue();
|
|
5640
|
-
};
|
|
5641
|
-
}
|
|
6231
|
+
async [Symbol.asyncDispose]() {
|
|
6232
|
+
return;
|
|
6233
|
+
}
|
|
6234
|
+
};
|
|
5642
6235
|
var serializeTapLeaf = ([cb, s]) => ({
|
|
5643
6236
|
cb: base.hex.encode(btcSigner.TaprootControlBlock.encode(cb)),
|
|
5644
6237
|
s: base.hex.encode(s)
|
|
@@ -5705,132 +6298,6 @@ var deserializeTransaction = (o) => ({
|
|
|
5705
6298
|
assets: deserializeAssets(o.assets)
|
|
5706
6299
|
});
|
|
5707
6300
|
|
|
5708
|
-
// src/repositories/indexedDB/manager.ts
|
|
5709
|
-
function getGlobalObject() {
|
|
5710
|
-
if (typeof globalThis !== "undefined") {
|
|
5711
|
-
if (typeof globalThis.self === "object" && globalThis.self !== null) {
|
|
5712
|
-
return { globalObject: globalThis.self };
|
|
5713
|
-
}
|
|
5714
|
-
if (typeof globalThis.window === "object" && globalThis.window !== null) {
|
|
5715
|
-
return { globalObject: globalThis.window };
|
|
5716
|
-
}
|
|
5717
|
-
return { globalObject: globalThis };
|
|
5718
|
-
}
|
|
5719
|
-
throw new Error("Global object not found");
|
|
5720
|
-
}
|
|
5721
|
-
var dbCache = /* @__PURE__ */ new Map();
|
|
5722
|
-
var refCounts = /* @__PURE__ */ new Map();
|
|
5723
|
-
async function openDatabase(dbName, dbVersion, initDatabase2) {
|
|
5724
|
-
const { globalObject } = getGlobalObject();
|
|
5725
|
-
if (!globalObject.indexedDB) {
|
|
5726
|
-
throw new Error("IndexedDB is not available in this environment");
|
|
5727
|
-
}
|
|
5728
|
-
const cached = dbCache.get(dbName);
|
|
5729
|
-
if (cached) {
|
|
5730
|
-
if (cached.version !== dbVersion) {
|
|
5731
|
-
throw new Error(
|
|
5732
|
-
`Database "${dbName}" already opened with version ${cached.version}; requested ${dbVersion}`
|
|
5733
|
-
);
|
|
5734
|
-
}
|
|
5735
|
-
refCounts.set(dbName, (refCounts.get(dbName) ?? 0) + 1);
|
|
5736
|
-
return cached.promise;
|
|
5737
|
-
}
|
|
5738
|
-
const dbPromise = new Promise((resolve, reject) => {
|
|
5739
|
-
const request = globalObject.indexedDB.open(dbName, dbVersion);
|
|
5740
|
-
request.onerror = () => {
|
|
5741
|
-
dbCache.delete(dbName);
|
|
5742
|
-
refCounts.delete(dbName);
|
|
5743
|
-
reject(request.error);
|
|
5744
|
-
};
|
|
5745
|
-
request.onsuccess = () => {
|
|
5746
|
-
const db = request.result;
|
|
5747
|
-
db.onversionchange = () => {
|
|
5748
|
-
db.close();
|
|
5749
|
-
dbCache.delete(dbName);
|
|
5750
|
-
refCounts.delete(dbName);
|
|
5751
|
-
};
|
|
5752
|
-
resolve(db);
|
|
5753
|
-
};
|
|
5754
|
-
request.onupgradeneeded = (event) => {
|
|
5755
|
-
const db = request.result;
|
|
5756
|
-
initDatabase2(db, event.oldVersion, request.transaction);
|
|
5757
|
-
};
|
|
5758
|
-
request.onblocked = () => {
|
|
5759
|
-
console.warn("Database upgrade blocked - close other tabs/connections");
|
|
5760
|
-
};
|
|
5761
|
-
});
|
|
5762
|
-
dbCache.set(dbName, { version: dbVersion, promise: dbPromise });
|
|
5763
|
-
refCounts.set(dbName, 1);
|
|
5764
|
-
return dbPromise;
|
|
5765
|
-
}
|
|
5766
|
-
async function closeDatabase(dbName) {
|
|
5767
|
-
const cachedEntry = dbCache.get(dbName);
|
|
5768
|
-
if (!cachedEntry) return false;
|
|
5769
|
-
const count = (refCounts.get(dbName) ?? 1) - 1;
|
|
5770
|
-
if (count > 0) {
|
|
5771
|
-
refCounts.set(dbName, count);
|
|
5772
|
-
return false;
|
|
5773
|
-
}
|
|
5774
|
-
refCounts.delete(dbName);
|
|
5775
|
-
dbCache.delete(dbName);
|
|
5776
|
-
try {
|
|
5777
|
-
const db = await cachedEntry.promise;
|
|
5778
|
-
db.close();
|
|
5779
|
-
} catch {
|
|
5780
|
-
}
|
|
5781
|
-
return true;
|
|
5782
|
-
}
|
|
5783
|
-
|
|
5784
|
-
// src/worker/browser/utils.ts
|
|
5785
|
-
var DEFAULT_DB_NAME = "arkade-service-worker";
|
|
5786
|
-
var DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS = 1e4;
|
|
5787
|
-
function normalizeOptions2(pathOrOptions) {
|
|
5788
|
-
if (typeof pathOrOptions === "string") {
|
|
5789
|
-
return {
|
|
5790
|
-
path: pathOrOptions,
|
|
5791
|
-
activationTimeoutMs: DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS
|
|
5792
|
-
};
|
|
5793
|
-
}
|
|
5794
|
-
return {
|
|
5795
|
-
path: pathOrOptions.path,
|
|
5796
|
-
activationTimeoutMs: pathOrOptions.activationTimeoutMs ?? DEFAULT_SERVICE_WORKER_ACTIVATION_TIMEOUT_MS
|
|
5797
|
-
};
|
|
5798
|
-
}
|
|
5799
|
-
function waitForServiceWorkerReady(timeoutMs) {
|
|
5800
|
-
return new Promise((resolve, reject) => {
|
|
5801
|
-
const timeoutId = setTimeout(() => {
|
|
5802
|
-
reject(new Error(`Service worker activation timed out after ${timeoutMs}ms`));
|
|
5803
|
-
}, timeoutMs);
|
|
5804
|
-
navigator.serviceWorker.ready.then((registration) => {
|
|
5805
|
-
clearTimeout(timeoutId);
|
|
5806
|
-
resolve(registration);
|
|
5807
|
-
}).catch((error) => {
|
|
5808
|
-
clearTimeout(timeoutId);
|
|
5809
|
-
reject(error);
|
|
5810
|
-
});
|
|
5811
|
-
});
|
|
5812
|
-
}
|
|
5813
|
-
async function setupServiceWorker(pathOrOptions) {
|
|
5814
|
-
if (!("serviceWorker" in navigator)) {
|
|
5815
|
-
throw new Error("Service workers are not supported in this browser");
|
|
5816
|
-
}
|
|
5817
|
-
const { path, activationTimeoutMs } = normalizeOptions2(pathOrOptions);
|
|
5818
|
-
const registration = await navigator.serviceWorker.register(path);
|
|
5819
|
-
await registration.update();
|
|
5820
|
-
const serviceWorker = registration.active || registration.waiting || registration.installing;
|
|
5821
|
-
if (!serviceWorker) {
|
|
5822
|
-
throw new Error("Failed to get service worker instance");
|
|
5823
|
-
}
|
|
5824
|
-
if (serviceWorker.state === "activated") {
|
|
5825
|
-
return serviceWorker;
|
|
5826
|
-
}
|
|
5827
|
-
const readyRegistration = await waitForServiceWorkerReady(activationTimeoutMs);
|
|
5828
|
-
if (!readyRegistration.active) {
|
|
5829
|
-
throw new Error("Service worker registration is ready but has no active worker");
|
|
5830
|
-
}
|
|
5831
|
-
return readyRegistration.active;
|
|
5832
|
-
}
|
|
5833
|
-
|
|
5834
6301
|
// src/repositories/indexedDB/contractRepository.ts
|
|
5835
6302
|
var IndexedDBContractRepository = class {
|
|
5836
6303
|
constructor(dbName = DEFAULT_DB_NAME) {
|
|
@@ -6987,7 +7454,7 @@ var ContractWatcher = class {
|
|
|
6987
7454
|
this.connectionState = "connected";
|
|
6988
7455
|
this.reconnectAttempts = 0;
|
|
6989
7456
|
this.listenLoop().catch((e) => {
|
|
6990
|
-
if (
|
|
7457
|
+
if (chunk3AQNLQPM_cjs.isEventSourceError(e)) {
|
|
6991
7458
|
console.debug("ContractWatcher subscription disconnected; reconnecting");
|
|
6992
7459
|
} else {
|
|
6993
7460
|
console.error(e);
|
|
@@ -7268,6 +7735,89 @@ var ContractWatcher = class {
|
|
|
7268
7735
|
}
|
|
7269
7736
|
};
|
|
7270
7737
|
|
|
7738
|
+
// src/wallet/intentReconciliation.ts
|
|
7739
|
+
var NON_TERMINAL_INTENT_STATES = ALL_INTENT_STATES.filter(
|
|
7740
|
+
(s) => !isTerminalIntentState(s)
|
|
7741
|
+
);
|
|
7742
|
+
function isConsumed(vtxo) {
|
|
7743
|
+
return vtxo !== void 0 && (vtxo.isSpent === true || vtxo.settledBy !== void 0);
|
|
7744
|
+
}
|
|
7745
|
+
async function classifyIntent(intent, vtxosByOutpoint, now) {
|
|
7746
|
+
if (isTerminalIntentState(intent.state)) return void 0;
|
|
7747
|
+
const inputs = intent.intentVtxos;
|
|
7748
|
+
const consumed = inputs.map((o) => vtxosByOutpoint.get(outpointKey(o)));
|
|
7749
|
+
if (inputs.length > 0 && consumed.every(isConsumed)) {
|
|
7750
|
+
const commitmentTransactionId = intent.commitmentTransactionId ?? consumed.map((v) => v?.settledBy).find((s) => !!s);
|
|
7751
|
+
return terminal(intent, "batch_succeeded", now, { commitmentTransactionId });
|
|
7752
|
+
}
|
|
7753
|
+
if (intent.state === "waiting_to_submit") {
|
|
7754
|
+
return terminal(intent, "cancelled", now, {
|
|
7755
|
+
cancellationReason: "reconciliation: intent was never submitted before restart"
|
|
7756
|
+
});
|
|
7757
|
+
}
|
|
7758
|
+
if (intent.validUntil !== void 0 && intent.validUntil < now) {
|
|
7759
|
+
return terminal(intent, "cancelled", now, {
|
|
7760
|
+
cancellationReason: "reconciliation: intent expired"
|
|
7761
|
+
});
|
|
7762
|
+
}
|
|
7763
|
+
return void 0;
|
|
7764
|
+
}
|
|
7765
|
+
async function reconcileIntents(deps) {
|
|
7766
|
+
const now = deps.now ?? Date.now;
|
|
7767
|
+
let intents;
|
|
7768
|
+
try {
|
|
7769
|
+
intents = await deps.intentRepository.getIntents({
|
|
7770
|
+
states: [...NON_TERMINAL_INTENT_STATES]
|
|
7771
|
+
});
|
|
7772
|
+
} catch (e) {
|
|
7773
|
+
console.error("reconcileIntents: failed to read non-terminal intents", e);
|
|
7774
|
+
return;
|
|
7775
|
+
}
|
|
7776
|
+
if (intents.length === 0) return;
|
|
7777
|
+
const outpoints = dedupeOutpoints(intents.flatMap((i) => i.intentVtxos));
|
|
7778
|
+
let vtxosByOutpoint = /* @__PURE__ */ new Map();
|
|
7779
|
+
if (outpoints.length > 0) {
|
|
7780
|
+
try {
|
|
7781
|
+
const { vtxos } = await deps.indexerProvider.getVtxos({ outpoints });
|
|
7782
|
+
vtxosByOutpoint = new Map(vtxos.map((v) => [outpointKey(v), v]));
|
|
7783
|
+
} catch (e) {
|
|
7784
|
+
console.error("reconcileIntents: failed to fetch input VTXO state", e);
|
|
7785
|
+
return;
|
|
7786
|
+
}
|
|
7787
|
+
}
|
|
7788
|
+
const nowMs = now();
|
|
7789
|
+
for (const intent of intents) {
|
|
7790
|
+
try {
|
|
7791
|
+
const next = await classifyIntent(intent, vtxosByOutpoint, nowMs);
|
|
7792
|
+
if (!next) continue;
|
|
7793
|
+
const [fresh] = await deps.intentRepository.getIntents({
|
|
7794
|
+
intentTxIds: [intent.intentTxId]
|
|
7795
|
+
});
|
|
7796
|
+
if (!fresh || fresh.state !== intent.state) continue;
|
|
7797
|
+
await deps.intentRepository.saveIntent(next);
|
|
7798
|
+
} catch (e) {
|
|
7799
|
+
console.error(`reconcileIntents: failed to reconcile intent ${intent.intentTxId}`, e);
|
|
7800
|
+
}
|
|
7801
|
+
}
|
|
7802
|
+
}
|
|
7803
|
+
function terminal(intent, state, now, patch) {
|
|
7804
|
+
return { ...intent, ...patch, state, updatedAt: now };
|
|
7805
|
+
}
|
|
7806
|
+
function outpointKey(o) {
|
|
7807
|
+
return `${o.txid}:${o.vout}`;
|
|
7808
|
+
}
|
|
7809
|
+
function dedupeOutpoints(outpoints) {
|
|
7810
|
+
const seen = /* @__PURE__ */ new Set();
|
|
7811
|
+
const out = [];
|
|
7812
|
+
for (const o of outpoints) {
|
|
7813
|
+
const k = outpointKey(o);
|
|
7814
|
+
if (seen.has(k)) continue;
|
|
7815
|
+
seen.add(k);
|
|
7816
|
+
out.push(o);
|
|
7817
|
+
}
|
|
7818
|
+
return out;
|
|
7819
|
+
}
|
|
7820
|
+
|
|
7271
7821
|
// src/utils/syncCursors.ts
|
|
7272
7822
|
var SAFETY_LAG_MS = 3e4;
|
|
7273
7823
|
var OVERLAP_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -7391,6 +7941,26 @@ var ContractManager = class _ContractManager {
|
|
|
7391
7941
|
if (watched.length > 0) {
|
|
7392
7942
|
await this.reconcilePendingFrontier(watched);
|
|
7393
7943
|
}
|
|
7944
|
+
await this.reconcileStaleIntents();
|
|
7945
|
+
}
|
|
7946
|
+
/**
|
|
7947
|
+
* Crash-recovery for persisted settlement intents: reconcile any
|
|
7948
|
+
* non-terminal intent left behind by a mid-settle crash against
|
|
7949
|
+
* authoritative indexer state (see {@link reconcileIntents}). Runs on the
|
|
7950
|
+
* online sync path only — boot and subscription reconnect — never from a
|
|
7951
|
+
* wallet read API. Best-effort: intent recovery is not a sync invariant, so
|
|
7952
|
+
* a failure is logged and sync continues. No-op without an intent store.
|
|
7953
|
+
*/
|
|
7954
|
+
async reconcileStaleIntents() {
|
|
7955
|
+
if (!this.config.intentRepository) return;
|
|
7956
|
+
try {
|
|
7957
|
+
await reconcileIntents({
|
|
7958
|
+
intentRepository: this.config.intentRepository,
|
|
7959
|
+
indexerProvider: this.config.indexerProvider
|
|
7960
|
+
});
|
|
7961
|
+
} catch (e) {
|
|
7962
|
+
console.error("ContractManager: intent reconciliation failed", e);
|
|
7963
|
+
}
|
|
7394
7964
|
}
|
|
7395
7965
|
/**
|
|
7396
7966
|
* Create and register a new contract.
|
|
@@ -8761,6 +9331,22 @@ async function resolveBoardingBootTapscript(contractRepository, serverPubKey, ba
|
|
|
8761
9331
|
function hasToReadonly(identity) {
|
|
8762
9332
|
return typeof identity === "object" && identity !== null && "toReadonly" in identity && typeof identity.toReadonly === "function";
|
|
8763
9333
|
}
|
|
9334
|
+
function excludeLockedOutpoints(vtxos, locked) {
|
|
9335
|
+
if (locked.length === 0) return vtxos;
|
|
9336
|
+
const lockedKeys = new Set(locked.map((o) => `${o.txid}:${o.vout}`));
|
|
9337
|
+
return vtxos.filter((v) => !lockedKeys.has(`${v.txid}:${v.vout}`));
|
|
9338
|
+
}
|
|
9339
|
+
async function spendableVtxosExcludingLocked(vtxos, intentRepository) {
|
|
9340
|
+
if (!intentRepository) return vtxos;
|
|
9341
|
+
let locked;
|
|
9342
|
+
try {
|
|
9343
|
+
locked = await intentRepository.getLockedVtxoOutpoints();
|
|
9344
|
+
} catch (e) {
|
|
9345
|
+
console.error("getLockedVtxoOutpoints failed; reporting unfiltered balance", e);
|
|
9346
|
+
return vtxos;
|
|
9347
|
+
}
|
|
9348
|
+
return excludeLockedOutpoints(vtxos, locked);
|
|
9349
|
+
}
|
|
8764
9350
|
var ReadonlyWallet = class _ReadonlyWallet {
|
|
8765
9351
|
constructor(identity, network, onchainProvider, indexerProvider, arkServerPublicKey, offchainTapscript, boardingTapscript, dustAmount, walletRepository, contractRepository, delegateProvider, watcherConfig, walletContractTimelocks) {
|
|
8766
9352
|
this.identity = identity;
|
|
@@ -8791,6 +9377,20 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
8791
9377
|
_contractManager;
|
|
8792
9378
|
_contractManagerInitializing;
|
|
8793
9379
|
watcherConfig;
|
|
9380
|
+
/**
|
|
9381
|
+
* Opt-in intent-lifecycle repository. Assigned by the `create()`
|
|
9382
|
+
* factories from `config.storage.intentRepository`; `undefined` ⇒ all
|
|
9383
|
+
* intent-persistence code paths are no-ops (default behaviour unchanged).
|
|
9384
|
+
*/
|
|
9385
|
+
intentRepository;
|
|
9386
|
+
/**
|
|
9387
|
+
* **Experimental / inert.** Opt-in virtual-tx / exit-branch repository,
|
|
9388
|
+
* exposed so callers can pass it to {@link Unroll.Session.create} as a
|
|
9389
|
+
* best-effort raw-tx cache. Assigned by `create()` from
|
|
9390
|
+
* `config.storage.virtualTxRepository`. Normal sync never writes it
|
|
9391
|
+
* (ContractManager isn't given it); `undefined` ⇒ no-op.
|
|
9392
|
+
*/
|
|
9393
|
+
virtualTxRepository;
|
|
8794
9394
|
_assetManager;
|
|
8795
9395
|
walletContractTimelocks;
|
|
8796
9396
|
// Outpoints ("txid:vout") committed to an in-flight settle/send. Filtered
|
|
@@ -8848,9 +9448,12 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
8848
9448
|
_deprecatedSigners = /* @__PURE__ */ new Map();
|
|
8849
9449
|
/**
|
|
8850
9450
|
* Refresh the cached deprecated-signer set from a fresh server-info
|
|
8851
|
-
* snapshot. Called by the create() factories at construction
|
|
8852
|
-
* server-info-change handler mid-session
|
|
8853
|
-
*
|
|
9451
|
+
* snapshot. Called by the create() factories at construction, by the
|
|
9452
|
+
* server-info-change handler mid-session, and by the deprecated-signer
|
|
9453
|
+
* migration pass (`VtxoManager.migrateDeprecatedSignerVtxos`). This set feeds
|
|
9454
|
+
* {@link pendingRecoveryOutpoints}, which drops EXPIRED (past-cutoff)
|
|
9455
|
+
* deprecated-signer VTXOs from the wallet's own coin selection. Lenient: a
|
|
9456
|
+
* malformed deprecated entry is skipped, never fatal to wallet creation.
|
|
8854
9457
|
*/
|
|
8855
9458
|
refreshDeprecatedSigners(info) {
|
|
8856
9459
|
const next = /* @__PURE__ */ new Map();
|
|
@@ -8945,7 +9548,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
8945
9548
|
*/
|
|
8946
9549
|
static async setupWalletConfig(config, pubKey) {
|
|
8947
9550
|
const arkadeServerUrl = getArkadeServerUrl(config);
|
|
8948
|
-
const arkProvider = config.arkProvider || new
|
|
9551
|
+
const arkProvider = config.arkProvider || new chunk3AQNLQPM_cjs.RestArkProvider(arkadeServerUrl);
|
|
8949
9552
|
let indexerProvider = config.indexerProvider;
|
|
8950
9553
|
if (!indexerProvider) {
|
|
8951
9554
|
let indexerUrl = config.indexerUrl;
|
|
@@ -8962,7 +9565,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
8962
9565
|
indexerUrl = arkadeServerUrl;
|
|
8963
9566
|
}
|
|
8964
9567
|
}
|
|
8965
|
-
indexerProvider = new
|
|
9568
|
+
indexerProvider = new chunk3AQNLQPM_cjs.RestIndexerProvider(indexerUrl);
|
|
8966
9569
|
}
|
|
8967
9570
|
const info = await arkProvider.getInfo();
|
|
8968
9571
|
const network = chunkHXDZ2QTW_cjs.getNetwork(info.network);
|
|
@@ -9066,6 +9669,8 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9066
9669
|
config.watcherConfig,
|
|
9067
9670
|
setup.walletContractTimelocks
|
|
9068
9671
|
);
|
|
9672
|
+
wallet.intentRepository = config.storage?.intentRepository;
|
|
9673
|
+
wallet.virtualTxRepository = config.storage?.virtualTxRepository;
|
|
9069
9674
|
wallet.refreshDeprecatedSigners(setup.info);
|
|
9070
9675
|
return wallet;
|
|
9071
9676
|
}
|
|
@@ -9097,6 +9702,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9097
9702
|
this.pendingRecoveryOutpoints()
|
|
9098
9703
|
]);
|
|
9099
9704
|
const isPendingRecovery = (coin) => pendingOutpoints.has(`${coin.txid}:${coin.vout}`);
|
|
9705
|
+
const unlockedVtxos = await spendableVtxosExcludingLocked(vtxos, this.intentRepository);
|
|
9100
9706
|
let confirmed = 0;
|
|
9101
9707
|
let unconfirmed = 0;
|
|
9102
9708
|
for (const utxo of boardingUtxos) {
|
|
@@ -9106,14 +9712,15 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9106
9712
|
unconfirmed += utxo.value;
|
|
9107
9713
|
}
|
|
9108
9714
|
}
|
|
9109
|
-
let settled = 0;
|
|
9110
|
-
let preconfirmed = 0;
|
|
9111
9715
|
let recoverable = 0;
|
|
9112
9716
|
let pendingRecovery = 0;
|
|
9113
|
-
settled = vtxos.filter((coin) => coin.virtualStatus.state === "settled" && !isPendingRecovery(coin)).reduce((sum, coin) => sum + coin.value, 0);
|
|
9114
|
-
preconfirmed = vtxos.filter(
|
|
9717
|
+
const settled = vtxos.filter((coin) => coin.virtualStatus.state === "settled" && !isPendingRecovery(coin)).reduce((sum, coin) => sum + coin.value, 0);
|
|
9718
|
+
const preconfirmed = vtxos.filter(
|
|
9115
9719
|
(coin) => coin.virtualStatus.state === "preconfirmed" && !isPendingRecovery(coin)
|
|
9116
9720
|
).reduce((sum, coin) => sum + coin.value, 0);
|
|
9721
|
+
const available = unlockedVtxos.filter(
|
|
9722
|
+
(coin) => (coin.virtualStatus.state === "settled" || coin.virtualStatus.state === "preconfirmed") && !isPendingRecovery(coin)
|
|
9723
|
+
).reduce((sum, coin) => sum + coin.value, 0);
|
|
9117
9724
|
recoverable = vtxos.filter((coin) => isSpendable(coin) && coin.virtualStatus.state === "swept").reduce((sum, coin) => sum + coin.value, 0);
|
|
9118
9725
|
pendingRecovery = vtxos.filter(isPendingRecovery).reduce((sum, coin) => sum + coin.value, 0);
|
|
9119
9726
|
const totalBoarding = confirmed + unconfirmed;
|
|
@@ -9140,7 +9747,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9140
9747
|
},
|
|
9141
9748
|
settled,
|
|
9142
9749
|
preconfirmed,
|
|
9143
|
-
available
|
|
9750
|
+
available,
|
|
9144
9751
|
recoverable,
|
|
9145
9752
|
pendingRecovery,
|
|
9146
9753
|
total: totalBoarding + totalOffchain,
|
|
@@ -9617,6 +10224,7 @@ var ReadonlyWallet = class _ReadonlyWallet {
|
|
|
9617
10224
|
indexerProvider: this.indexerProvider,
|
|
9618
10225
|
contractRepository: this.contractRepository,
|
|
9619
10226
|
walletRepository: this.walletRepository,
|
|
10227
|
+
intentRepository: this.intentRepository,
|
|
9620
10228
|
watcherConfig: this.watcherConfig
|
|
9621
10229
|
});
|
|
9622
10230
|
const baselinePubkey = await this.identity.xOnlyPublicKey();
|
|
@@ -10310,6 +10918,8 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10310
10918
|
wallet.setBoardingTapscriptForRotation(resolvedBoarding);
|
|
10311
10919
|
}
|
|
10312
10920
|
}
|
|
10921
|
+
wallet.intentRepository = config.storage?.intentRepository;
|
|
10922
|
+
wallet.virtualTxRepository = config.storage?.virtualTxRepository;
|
|
10313
10923
|
await wallet.getVtxoManager();
|
|
10314
10924
|
return wallet;
|
|
10315
10925
|
}
|
|
@@ -10589,12 +11199,26 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10589
11199
|
),
|
|
10590
11200
|
this.makeDeleteIntentSignature(params.inputs)
|
|
10591
11201
|
]);
|
|
11202
|
+
let intentTxId;
|
|
11203
|
+
try {
|
|
11204
|
+
intentTxId = btcSigner.Transaction.fromPSBT(base.base64.decode(intent.proof)).id;
|
|
11205
|
+
} catch {
|
|
11206
|
+
intentTxId = params.inputs.map((i) => `${i.txid}:${i.vout}`).sort().join("|");
|
|
11207
|
+
}
|
|
11208
|
+
await this.persistIntentSnapshot(
|
|
11209
|
+
intentTxId,
|
|
11210
|
+
"waiting_to_submit",
|
|
11211
|
+
intent,
|
|
11212
|
+
deleteIntent,
|
|
11213
|
+
params.inputs
|
|
11214
|
+
);
|
|
10592
11215
|
const topics = [
|
|
10593
11216
|
...signingPublicKeys,
|
|
10594
11217
|
...params.inputs.map((input) => `${input.txid}:${input.vout}`)
|
|
10595
11218
|
];
|
|
10596
11219
|
const abortController = new AbortController();
|
|
10597
11220
|
let stream;
|
|
11221
|
+
let committedTxid;
|
|
10598
11222
|
this._addPendingSpends(params.inputs);
|
|
10599
11223
|
try {
|
|
10600
11224
|
stream = this.arkProvider.getEventStream(abortController.signal, topics);
|
|
@@ -10609,16 +11233,43 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10609
11233
|
yield* stream;
|
|
10610
11234
|
})();
|
|
10611
11235
|
const intentId = await this.safeRegisterIntent(intent, params.inputs);
|
|
10612
|
-
|
|
11236
|
+
await this.persistIntentSnapshot(
|
|
11237
|
+
intentTxId,
|
|
11238
|
+
"waiting_for_batch",
|
|
11239
|
+
intent,
|
|
11240
|
+
deleteIntent,
|
|
11241
|
+
params.inputs,
|
|
11242
|
+
{ intentId }
|
|
11243
|
+
);
|
|
11244
|
+
const handler = wrapHandlerWithIntentPersistence(
|
|
11245
|
+
this.createBatchHandler(intentId, params.inputs, recipients, session),
|
|
11246
|
+
{ intentRepository: this.intentRepository, intentTxId }
|
|
11247
|
+
);
|
|
10613
11248
|
const commitmentTxid = await exports.Batch.join(primedStream, handler, {
|
|
10614
11249
|
abortController,
|
|
10615
11250
|
skipVtxoTreeSigning: !hasOffchainOutputs,
|
|
10616
|
-
|
|
11251
|
+
// async so a synchronous throw becomes a rejection Batch.join
|
|
11252
|
+
// swallows, keeping the observational callback off the stream path.
|
|
11253
|
+
eventCallback: eventCallback && (async (event) => {
|
|
11254
|
+
await eventCallback(event);
|
|
11255
|
+
})
|
|
10617
11256
|
});
|
|
11257
|
+
committedTxid = commitmentTxid;
|
|
10618
11258
|
await this.updateDbAfterSettle(params.inputs, commitmentTxid);
|
|
10619
11259
|
await this.maybeRotateBoardingAfterBoard(params.inputs);
|
|
10620
11260
|
return commitmentTxid;
|
|
10621
11261
|
} catch (error) {
|
|
11262
|
+
if (committedTxid !== void 0) {
|
|
11263
|
+
await this.persistIntentSnapshot(
|
|
11264
|
+
intentTxId,
|
|
11265
|
+
"batch_succeeded",
|
|
11266
|
+
intent,
|
|
11267
|
+
deleteIntent,
|
|
11268
|
+
params.inputs,
|
|
11269
|
+
{ commitmentTransactionId: committedTxid }
|
|
11270
|
+
);
|
|
11271
|
+
throw error;
|
|
11272
|
+
}
|
|
10622
11273
|
const inputIds = params.inputs.map((i) => `${i.txid}:${i.vout}`).join(",");
|
|
10623
11274
|
await this.arkProvider.deleteIntent(deleteIntent).catch((e) => {
|
|
10624
11275
|
console.warn(
|
|
@@ -10626,6 +11277,16 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10626
11277
|
e
|
|
10627
11278
|
);
|
|
10628
11279
|
});
|
|
11280
|
+
await this.persistIntentSnapshot(
|
|
11281
|
+
intentTxId,
|
|
11282
|
+
"cancelled",
|
|
11283
|
+
intent,
|
|
11284
|
+
deleteIntent,
|
|
11285
|
+
params.inputs,
|
|
11286
|
+
{
|
|
11287
|
+
cancellationReason: error instanceof Error ? error.message : String(error)
|
|
11288
|
+
}
|
|
11289
|
+
);
|
|
10629
11290
|
throw error;
|
|
10630
11291
|
} finally {
|
|
10631
11292
|
this._removePendingSpends(params.inputs);
|
|
@@ -10900,6 +11561,42 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10900
11561
|
}
|
|
10901
11562
|
return jobs;
|
|
10902
11563
|
}
|
|
11564
|
+
/**
|
|
11565
|
+
* Best-effort upsert of the current settlement intent into the optional
|
|
11566
|
+
* {@link intentRepository}. Never throws into the settle path — intent
|
|
11567
|
+
* persistence is observational and must not break money flow. Preserves
|
|
11568
|
+
* fields already written by the event reducer (state-event ordering).
|
|
11569
|
+
*/
|
|
11570
|
+
async persistIntentSnapshot(intentTxId, state, intent, deleteIntent, inputs, patch) {
|
|
11571
|
+
const repo = this.intentRepository;
|
|
11572
|
+
if (!repo) return;
|
|
11573
|
+
try {
|
|
11574
|
+
const now = Date.now();
|
|
11575
|
+
const existing = (await repo.getIntents({ intentTxIds: [intentTxId] }))[0];
|
|
11576
|
+
if (existing && isTerminalIntentState(existing.state)) {
|
|
11577
|
+
return;
|
|
11578
|
+
}
|
|
11579
|
+
await repo.saveIntent({
|
|
11580
|
+
...existing ?? {},
|
|
11581
|
+
intentTxId,
|
|
11582
|
+
registerProof: intent.proof,
|
|
11583
|
+
registerProofMessage: chunk3AQNLQPM_cjs.Intent.encodeMessage(intent.message),
|
|
11584
|
+
deleteProof: deleteIntent.proof,
|
|
11585
|
+
deleteProofMessage: chunk3AQNLQPM_cjs.Intent.encodeMessage(deleteIntent.message),
|
|
11586
|
+
intentVtxos: inputs.map((i) => ({
|
|
11587
|
+
txid: i.txid,
|
|
11588
|
+
vout: i.vout
|
|
11589
|
+
})),
|
|
11590
|
+
partialForfeits: existing?.partialForfeits ?? [],
|
|
11591
|
+
createdAt: existing?.createdAt ?? now,
|
|
11592
|
+
updatedAt: now,
|
|
11593
|
+
state,
|
|
11594
|
+
...patch
|
|
11595
|
+
});
|
|
11596
|
+
} catch (e) {
|
|
11597
|
+
console.error(`Failed to persist intent ${intentTxId} (state=${state})`, e);
|
|
11598
|
+
}
|
|
11599
|
+
}
|
|
10903
11600
|
/**
|
|
10904
11601
|
* @internal Sign an on-chain boarding exit / sweep transaction, routing
|
|
10905
11602
|
* each input to the correct key by its `witnessUtxo.script`: the identity
|
|
@@ -10917,7 +11614,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10917
11614
|
try {
|
|
10918
11615
|
return await this.arkProvider.registerIntent(intent);
|
|
10919
11616
|
} catch (error) {
|
|
10920
|
-
if (error instanceof
|
|
11617
|
+
if (error instanceof chunk3AQNLQPM_cjs.ArkError && error.code === 0 && error.message.includes("duplicated input")) {
|
|
10921
11618
|
const deleteIntent = await this.makeDeleteIntentSignature(inputs);
|
|
10922
11619
|
await this.arkProvider.deleteIntent(deleteIntent);
|
|
10923
11620
|
return this.arkProvider.registerIntent(intent);
|
|
@@ -10933,7 +11630,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10933
11630
|
expire_at: 0,
|
|
10934
11631
|
cosigners_public_keys: cosignerPubKeys
|
|
10935
11632
|
};
|
|
10936
|
-
const proof =
|
|
11633
|
+
const proof = chunk3AQNLQPM_cjs.Intent.create(message, coins, outputs);
|
|
10937
11634
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
10938
11635
|
return {
|
|
10939
11636
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -10945,7 +11642,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10945
11642
|
type: "delete",
|
|
10946
11643
|
expire_at: 0
|
|
10947
11644
|
};
|
|
10948
|
-
const proof =
|
|
11645
|
+
const proof = chunk3AQNLQPM_cjs.Intent.create(message, coins, []);
|
|
10949
11646
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
10950
11647
|
return {
|
|
10951
11648
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -10957,7 +11654,7 @@ var Wallet2 = class _Wallet extends ReadonlyWallet {
|
|
|
10957
11654
|
type: "get-pending-tx",
|
|
10958
11655
|
expire_at: 0
|
|
10959
11656
|
};
|
|
10960
|
-
const proof =
|
|
11657
|
+
const proof = chunk3AQNLQPM_cjs.Intent.create(message, coins, []);
|
|
10961
11658
|
const signedProof = await this._signerRouter.sign(proof, intentProofJobs(coins));
|
|
10962
11659
|
return {
|
|
10963
11660
|
proof: base.base64.encode(signedProof.toPSBT()),
|
|
@@ -11915,7 +12612,7 @@ var MessageBus = class {
|
|
|
11915
12612
|
this.initialized = true;
|
|
11916
12613
|
}
|
|
11917
12614
|
async buildServices(config) {
|
|
11918
|
-
const arkProvider = new
|
|
12615
|
+
const arkProvider = new chunk3AQNLQPM_cjs.RestArkProvider(config.arkServer.url);
|
|
11919
12616
|
const storage = {
|
|
11920
12617
|
walletRepository: this.walletRepository,
|
|
11921
12618
|
contractRepository: this.contractRepository
|
|
@@ -13072,7 +13769,7 @@ var WalletMessageHandler = class {
|
|
|
13072
13769
|
// Wallet methods
|
|
13073
13770
|
async handleInitWallet({ payload }) {
|
|
13074
13771
|
const { arkServerUrl } = payload;
|
|
13075
|
-
this.indexerProvider = new
|
|
13772
|
+
this.indexerProvider = new chunk3AQNLQPM_cjs.RestIndexerProvider(arkServerUrl);
|
|
13076
13773
|
await this.onWalletInitialized();
|
|
13077
13774
|
}
|
|
13078
13775
|
async handleGetBalance() {
|
|
@@ -14879,7 +15576,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
14879
15576
|
if (!inputs) {
|
|
14880
15577
|
throw new Error("Fee estimation failed");
|
|
14881
15578
|
}
|
|
14882
|
-
let tx = new
|
|
15579
|
+
let tx = new chunk3AQNLQPM_cjs.Transaction();
|
|
14883
15580
|
for (const input of inputs) {
|
|
14884
15581
|
tx.addInput({
|
|
14885
15582
|
txid: input.txid,
|
|
@@ -14910,7 +15607,7 @@ var OnchainWallet = class _OnchainWallet {
|
|
|
14910
15607
|
*/
|
|
14911
15608
|
async bumpP2A(parent) {
|
|
14912
15609
|
const parentVsize = parent.vsize;
|
|
14913
|
-
let child = new
|
|
15610
|
+
let child = new chunk3AQNLQPM_cjs.Transaction({
|
|
14914
15611
|
version: 3,
|
|
14915
15612
|
allowLegacyWitnessUtxo: true
|
|
14916
15613
|
});
|
|
@@ -15676,7 +16373,7 @@ exports.BIP322 = void 0;
|
|
|
15676
16373
|
async function sign2(message, identity, network) {
|
|
15677
16374
|
const xOnlyPubKey = await identity.xOnlyPublicKey();
|
|
15678
16375
|
const payment = btcSigner.p2tr(xOnlyPubKey, void 0, network);
|
|
15679
|
-
const toSpend =
|
|
16376
|
+
const toSpend = chunk3AQNLQPM_cjs.craftToSpendTx(message, payment.script, TAG_BIP322);
|
|
15680
16377
|
const toSign = craftBIP322ToSignP2TR(toSpend, payment.script, xOnlyPubKey);
|
|
15681
16378
|
const signed = await identity.sign(toSign, [0]);
|
|
15682
16379
|
signed.finalizeIdx(0);
|
|
@@ -15734,7 +16431,7 @@ function verifyP2TR(message, witnessItems, pkScript, pubkey) {
|
|
|
15734
16431
|
if (sighashType !== btcSigner.SigHash.DEFAULT && sighashType !== btcSigner.SigHash.ALL) {
|
|
15735
16432
|
return false;
|
|
15736
16433
|
}
|
|
15737
|
-
const toSpend =
|
|
16434
|
+
const toSpend = chunk3AQNLQPM_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
|
|
15738
16435
|
const toSign = craftBIP322ToSignP2TR(toSpend, pkScript, pubkey);
|
|
15739
16436
|
const sighash = toSign.preimageWitnessV1(0, [pkScript], sighashType, [0n]);
|
|
15740
16437
|
const rawSig = sig.length === 65 ? sig.subarray(0, 64) : sig;
|
|
@@ -15755,7 +16452,7 @@ function verifyP2WPKH(message, witnessItems, pkScript, addressHash) {
|
|
|
15755
16452
|
}
|
|
15756
16453
|
const sighashType = sigWithHash[sigWithHash.length - 1];
|
|
15757
16454
|
const derSig = sigWithHash.subarray(0, sigWithHash.length - 1);
|
|
15758
|
-
const toSpend =
|
|
16455
|
+
const toSpend = chunk3AQNLQPM_cjs.craftToSpendTx(message, pkScript, TAG_BIP322);
|
|
15759
16456
|
const toSign = craftBIP322ToSignSimple(toSpend, pkScript);
|
|
15760
16457
|
const scriptCode = btcSigner.OutScript.encode({ type: "pkh", hash: addressHash });
|
|
15761
16458
|
const sighash = toSign.preimageWitnessV0(0, scriptCode, sighashType, 0n);
|
|
@@ -15808,7 +16505,7 @@ function encodeCompactSize(n) {
|
|
|
15808
16505
|
return buf;
|
|
15809
16506
|
}
|
|
15810
16507
|
function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
|
|
15811
|
-
const tx = new
|
|
16508
|
+
const tx = new chunk3AQNLQPM_cjs.Transaction({ version: 0 });
|
|
15812
16509
|
tx.addInput({
|
|
15813
16510
|
txid: toSpend.id,
|
|
15814
16511
|
index: 0,
|
|
@@ -15822,12 +16519,12 @@ function craftBIP322ToSignP2TR(toSpend, pkScript, tapInternalKey) {
|
|
|
15822
16519
|
});
|
|
15823
16520
|
tx.addOutput({
|
|
15824
16521
|
amount: 0n,
|
|
15825
|
-
script:
|
|
16522
|
+
script: chunk3AQNLQPM_cjs.OP_RETURN_EMPTY_PKSCRIPT
|
|
15826
16523
|
});
|
|
15827
16524
|
return tx;
|
|
15828
16525
|
}
|
|
15829
16526
|
function craftBIP322ToSignSimple(toSpend, pkScript) {
|
|
15830
|
-
const tx = new
|
|
16527
|
+
const tx = new chunk3AQNLQPM_cjs.Transaction({ version: 0 });
|
|
15831
16528
|
tx.addInput({
|
|
15832
16529
|
txid: toSpend.id,
|
|
15833
16530
|
index: 0,
|
|
@@ -15839,10 +16536,24 @@ function craftBIP322ToSignSimple(toSpend, pkScript) {
|
|
|
15839
16536
|
});
|
|
15840
16537
|
tx.addOutput({
|
|
15841
16538
|
amount: 0n,
|
|
15842
|
-
script:
|
|
16539
|
+
script: chunk3AQNLQPM_cjs.OP_RETURN_EMPTY_PKSCRIPT
|
|
15843
16540
|
});
|
|
15844
16541
|
return tx;
|
|
15845
16542
|
}
|
|
16543
|
+
function chainTxTypeToChainedExit(t) {
|
|
16544
|
+
switch (t) {
|
|
16545
|
+
case "INDEXER_CHAINED_TX_TYPE_COMMITMENT" /* COMMITMENT */:
|
|
16546
|
+
return 1 /* Commitment */;
|
|
16547
|
+
case "INDEXER_CHAINED_TX_TYPE_ARK" /* ARK */:
|
|
16548
|
+
return 2 /* Ark */;
|
|
16549
|
+
case "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */:
|
|
16550
|
+
return 3 /* Tree */;
|
|
16551
|
+
case "INDEXER_CHAINED_TX_TYPE_CHECKPOINT" /* CHECKPOINT */:
|
|
16552
|
+
return 4 /* Checkpoint */;
|
|
16553
|
+
default:
|
|
16554
|
+
return 0 /* Unspecified */;
|
|
16555
|
+
}
|
|
16556
|
+
}
|
|
15846
16557
|
exports.Unroll = void 0;
|
|
15847
16558
|
((Unroll2) => {
|
|
15848
16559
|
((StepType2) => {
|
|
@@ -15852,16 +16563,54 @@ exports.Unroll = void 0;
|
|
|
15852
16563
|
})(Unroll2.StepType || (Unroll2.StepType = {}));
|
|
15853
16564
|
class Session2 {
|
|
15854
16565
|
/** Create an unroll session from a virtual output outpoint and its dependency chain. */
|
|
15855
|
-
constructor(toUnroll, bumper, explorer, indexer) {
|
|
16566
|
+
constructor(toUnroll, bumper, explorer, indexer, virtualTxRepository) {
|
|
15856
16567
|
this.toUnroll = toUnroll;
|
|
15857
16568
|
this.bumper = bumper;
|
|
15858
16569
|
this.explorer = explorer;
|
|
15859
16570
|
this.indexer = indexer;
|
|
16571
|
+
this.virtualTxRepository = virtualTxRepository;
|
|
15860
16572
|
}
|
|
15861
16573
|
/** Create an unroll session by loading the virtual output chain from the indexer. */
|
|
15862
|
-
static async create(toUnroll, bumper, explorer, indexer) {
|
|
16574
|
+
static async create(toUnroll, bumper, explorer, indexer, virtualTxRepository) {
|
|
15863
16575
|
const { chain } = await indexer.getVtxoChain(toUnroll);
|
|
15864
|
-
return new Session2(
|
|
16576
|
+
return new Session2(
|
|
16577
|
+
{ ...toUnroll, chain },
|
|
16578
|
+
bumper,
|
|
16579
|
+
explorer,
|
|
16580
|
+
indexer,
|
|
16581
|
+
virtualTxRepository
|
|
16582
|
+
);
|
|
16583
|
+
}
|
|
16584
|
+
/**
|
|
16585
|
+
* Resolve a chain tx's raw PSBT (base64). Repo first when configured;
|
|
16586
|
+
* indexer on a miss, then best-effort cached so a later exit doesn't
|
|
16587
|
+
* re-fetch. Never throws from the cache
|
|
16588
|
+
* write — exit correctness must not depend on persistence.
|
|
16589
|
+
*/
|
|
16590
|
+
async resolveVirtualTxBase64(next) {
|
|
16591
|
+
const repo = this.virtualTxRepository;
|
|
16592
|
+
if (repo) {
|
|
16593
|
+
try {
|
|
16594
|
+
const stored = await repo.getVirtualTx(next.txid);
|
|
16595
|
+
if (stored?.psbt) return stored.psbt;
|
|
16596
|
+
} catch {
|
|
16597
|
+
}
|
|
16598
|
+
}
|
|
16599
|
+
const fetched = await this.indexer.getVirtualTxs([next.txid]);
|
|
16600
|
+
const psbt = fetched.txs[0];
|
|
16601
|
+
if (psbt && repo) {
|
|
16602
|
+
const cached = {
|
|
16603
|
+
txid: next.txid,
|
|
16604
|
+
psbt,
|
|
16605
|
+
expiresAt: null,
|
|
16606
|
+
type: chainTxTypeToChainedExit(next.type)
|
|
16607
|
+
};
|
|
16608
|
+
try {
|
|
16609
|
+
await repo.upsertVirtualTxs([cached]);
|
|
16610
|
+
} catch {
|
|
16611
|
+
}
|
|
16612
|
+
}
|
|
16613
|
+
return psbt;
|
|
15865
16614
|
}
|
|
15866
16615
|
/**
|
|
15867
16616
|
* Get the next step to be executed
|
|
@@ -15896,11 +16645,11 @@ exports.Unroll = void 0;
|
|
|
15896
16645
|
do: () => Promise.resolve()
|
|
15897
16646
|
};
|
|
15898
16647
|
}
|
|
15899
|
-
const
|
|
15900
|
-
if (
|
|
16648
|
+
const virtualTxBase64 = await this.resolveVirtualTxBase64(nextTxToBroadcast);
|
|
16649
|
+
if (!virtualTxBase64) {
|
|
15901
16650
|
throw new Error(`Tx ${nextTxToBroadcast.txid} not found`);
|
|
15902
16651
|
}
|
|
15903
|
-
const tx =
|
|
16652
|
+
const tx = chunk3AQNLQPM_cjs.Transaction.fromPSBT(base.base64.decode(virtualTxBase64));
|
|
15904
16653
|
if (nextTxToBroadcast.type === "INDEXER_CHAINED_TX_TYPE_TREE" /* TREE */) {
|
|
15905
16654
|
const input = tx.getInput(0);
|
|
15906
16655
|
if (!input) {
|
|
@@ -16000,7 +16749,7 @@ async function prepareUnrollTransaction(wallet, vtxoTxIds, outputAddress) {
|
|
|
16000
16749
|
btcSigner.TaprootControlBlock.encode(spendingLeaf[0]).length
|
|
16001
16750
|
);
|
|
16002
16751
|
}
|
|
16003
|
-
const tx = new
|
|
16752
|
+
const tx = new chunk3AQNLQPM_cjs.Transaction({ version: 2 });
|
|
16004
16753
|
for (const input of inputs) {
|
|
16005
16754
|
tx.addInput(input);
|
|
16006
16755
|
}
|
|
@@ -16123,6 +16872,7 @@ function isArkContract(str) {
|
|
|
16123
16872
|
exports.ActivityRegistry = ActivityRegistry;
|
|
16124
16873
|
exports.ArkNote = ArkNote;
|
|
16125
16874
|
exports.AssetManager = AssetManager;
|
|
16875
|
+
exports.ChainedTxType = ChainedTxType;
|
|
16126
16876
|
exports.ContractManager = ContractManager;
|
|
16127
16877
|
exports.ContractRepositoryImpl = ContractRepositoryImpl;
|
|
16128
16878
|
exports.ContractWatcher = ContractWatcher;
|
|
@@ -16141,9 +16891,14 @@ exports.ElectrumOnchainProvider = ElectrumOnchainProvider;
|
|
|
16141
16891
|
exports.EsploraProvider = EsploraProvider;
|
|
16142
16892
|
exports.Estimator = Estimator;
|
|
16143
16893
|
exports.HDDescriptorProvider = HDDescriptorProvider;
|
|
16894
|
+
exports.INTENT_TERMINAL_STATES = INTENT_TERMINAL_STATES;
|
|
16144
16895
|
exports.InMemoryContractRepository = InMemoryContractRepository;
|
|
16896
|
+
exports.InMemoryIntentRepository = InMemoryIntentRepository;
|
|
16897
|
+
exports.InMemoryVirtualTxRepository = InMemoryVirtualTxRepository;
|
|
16145
16898
|
exports.InMemoryWalletRepository = InMemoryWalletRepository;
|
|
16146
16899
|
exports.IndexedDBContractRepository = IndexedDBContractRepository;
|
|
16900
|
+
exports.IndexedDBIntentRepository = IndexedDBIntentRepository;
|
|
16901
|
+
exports.IndexedDBVirtualTxRepository = IndexedDBVirtualTxRepository;
|
|
16147
16902
|
exports.IndexedDBWalletRepository = IndexedDBWalletRepository;
|
|
16148
16903
|
exports.MESSAGE_BUS_INITIALIZING = MESSAGE_BUS_INITIALIZING;
|
|
16149
16904
|
exports.MESSAGE_BUS_NOT_INITIALIZED = MESSAGE_BUS_NOT_INITIALIZED;
|
|
@@ -16177,6 +16932,7 @@ exports.WalletMessageHandler = WalletMessageHandler;
|
|
|
16177
16932
|
exports.WalletNotInitializedError = WalletNotInitializedError;
|
|
16178
16933
|
exports.WalletRepositoryImpl = WalletRepositoryImpl;
|
|
16179
16934
|
exports.WsElectrumChainSource = WsElectrumChainSource;
|
|
16935
|
+
exports.assertIntentIdUnique = assertIntentIdUnique;
|
|
16180
16936
|
exports.boardingResolver = boardingResolver;
|
|
16181
16937
|
exports.buildForfeitTx = buildForfeitTx;
|
|
16182
16938
|
exports.buildOffchainTx = buildOffchainTx;
|
|
@@ -16196,6 +16952,8 @@ exports.extendVirtualCoinForContract = extendVirtualCoinForContract;
|
|
|
16196
16952
|
exports.getMigrationStatus = getMigrationStatus;
|
|
16197
16953
|
exports.getRandomId = getRandomId;
|
|
16198
16954
|
exports.hasBoardingTxExpired = hasBoardingTxExpired;
|
|
16955
|
+
exports.intentMatchesFilter = intentMatchesFilter;
|
|
16956
|
+
exports.intentPageBounds = intentPageBounds;
|
|
16199
16957
|
exports.isArkContract = isArkContract;
|
|
16200
16958
|
exports.isBatchSignable = isBatchSignable;
|
|
16201
16959
|
exports.isCooperativelyMigratable = isCooperativelyMigratable;
|
|
@@ -16204,9 +16962,11 @@ exports.isExpired = isExpired;
|
|
|
16204
16962
|
exports.isRecoverable = isRecoverable;
|
|
16205
16963
|
exports.isSpendable = isSpendable;
|
|
16206
16964
|
exports.isSubdust = isSubdust;
|
|
16965
|
+
exports.isTerminalIntentState = isTerminalIntentState;
|
|
16207
16966
|
exports.isValidArkAddress = isValidArkAddress;
|
|
16208
16967
|
exports.isVtxoExpiringSoon = isVtxoExpiringSoon;
|
|
16209
16968
|
exports.isVtxoForScript = isVtxoForScript;
|
|
16969
|
+
exports.mergeChainedTxType = mergeChainedTxType;
|
|
16210
16970
|
exports.migrateWalletRepository = migrateWalletRepository;
|
|
16211
16971
|
exports.openDatabase = openDatabase;
|
|
16212
16972
|
exports.requiresMigration = requiresMigration;
|
|
@@ -16224,5 +16984,5 @@ exports.validateVtxoTxGraph = validateVtxoTxGraph;
|
|
|
16224
16984
|
exports.verifyTapscriptSignatures = verifyTapscriptSignatures;
|
|
16225
16985
|
exports.waitForIncomingFunds = waitForIncomingFunds;
|
|
16226
16986
|
exports.warnAndFilterVtxosForScript = warnAndFilterVtxosForScript;
|
|
16227
|
-
//# sourceMappingURL=chunk-
|
|
16228
|
-
//# sourceMappingURL=chunk-
|
|
16987
|
+
//# sourceMappingURL=chunk-QGNTDGMN.cjs.map
|
|
16988
|
+
//# sourceMappingURL=chunk-QGNTDGMN.cjs.map
|