@arkade-os/sdk 0.3.0-alpha.8 → 0.3.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -14
- package/dist/cjs/arknote/index.js +3 -3
- package/dist/cjs/forfeit.js +5 -2
- package/dist/cjs/identity/singleKey.js +5 -4
- package/dist/cjs/index.js +6 -3
- package/dist/cjs/{bip322 → intent}/index.js +37 -55
- package/dist/cjs/providers/ark.js +62 -23
- package/dist/cjs/providers/expoArk.js +15 -170
- package/dist/cjs/providers/expoIndexer.js +22 -111
- package/dist/cjs/providers/expoUtils.js +124 -0
- package/dist/cjs/script/base.js +1 -2
- package/dist/cjs/script/tapscript.js +20 -21
- package/dist/cjs/script/vhtlc.js +2 -2
- package/dist/cjs/tree/signingSession.js +7 -8
- package/dist/cjs/tree/txTree.js +3 -4
- package/dist/cjs/tree/validation.js +2 -3
- package/dist/cjs/utils/arkTransaction.js +104 -12
- package/dist/cjs/utils/unknownFields.js +5 -5
- package/dist/cjs/wallet/onchain.js +4 -5
- package/dist/cjs/wallet/serviceWorker/utils.js +2 -0
- package/dist/cjs/wallet/serviceWorker/wallet.js +4 -8
- package/dist/cjs/wallet/serviceWorker/worker.js +23 -18
- package/dist/cjs/wallet/unroll.js +6 -7
- package/dist/cjs/wallet/vtxo-manager.js +381 -0
- package/dist/cjs/wallet/wallet.js +63 -94
- package/dist/esm/arknote/index.js +2 -2
- package/dist/esm/forfeit.js +4 -1
- package/dist/esm/identity/singleKey.js +7 -6
- package/dist/esm/index.js +7 -6
- package/dist/esm/{bip322 → intent}/index.js +31 -48
- package/dist/esm/providers/ark.js +62 -23
- package/dist/esm/providers/expoArk.js +15 -137
- package/dist/esm/providers/expoIndexer.js +22 -78
- package/dist/esm/providers/expoUtils.js +87 -0
- package/dist/esm/script/base.js +1 -2
- package/dist/esm/script/tapscript.js +1 -2
- package/dist/esm/script/vhtlc.js +1 -1
- package/dist/esm/tree/signingSession.js +8 -9
- package/dist/esm/tree/txTree.js +3 -4
- package/dist/esm/tree/validation.js +2 -3
- package/dist/esm/utils/arkTransaction.js +95 -4
- package/dist/esm/utils/unknownFields.js +1 -1
- package/dist/esm/wallet/onchain.js +1 -2
- package/dist/esm/wallet/serviceWorker/utils.js +1 -0
- package/dist/esm/wallet/serviceWorker/wallet.js +5 -9
- package/dist/esm/wallet/serviceWorker/worker.js +23 -18
- package/dist/esm/wallet/unroll.js +2 -3
- package/dist/esm/wallet/vtxo-manager.js +372 -0
- package/dist/esm/wallet/wallet.js +56 -87
- package/dist/types/arknote/index.d.ts +1 -1
- package/dist/types/forfeit.d.ts +2 -2
- package/dist/types/identity/index.d.ts +1 -1
- package/dist/types/identity/singleKey.d.ts +1 -1
- package/dist/types/index.d.ts +6 -5
- package/dist/types/intent/index.d.ts +41 -0
- package/dist/types/providers/ark.d.ts +55 -21
- package/dist/types/providers/expoIndexer.d.ts +2 -10
- package/dist/types/providers/expoUtils.d.ts +18 -0
- package/dist/types/providers/indexer.d.ts +1 -9
- package/dist/types/script/base.d.ts +3 -2
- package/dist/types/tree/signingSession.d.ts +10 -10
- package/dist/types/utils/anchor.d.ts +2 -2
- package/dist/types/utils/arkTransaction.d.ts +13 -3
- package/dist/types/utils/unknownFields.d.ts +2 -2
- package/dist/types/wallet/index.d.ts +6 -4
- package/dist/types/wallet/onchain.d.ts +1 -1
- package/dist/types/wallet/serviceWorker/utils.d.ts +1 -0
- package/dist/types/wallet/serviceWorker/wallet.d.ts +2 -2
- package/dist/types/wallet/serviceWorker/worker.d.ts +3 -1
- package/dist/types/wallet/unroll.d.ts +1 -1
- package/dist/types/wallet/vtxo-manager.d.ts +207 -0
- package/dist/types/wallet/wallet.d.ts +7 -3
- package/package.json +1 -2
- package/dist/cjs/bip322/errors.js +0 -13
- package/dist/esm/bip322/errors.js +0 -9
- package/dist/types/bip322/errors.d.ts +0 -6
- package/dist/types/bip322/index.d.ts +0 -57
package/dist/esm/tree/txTree.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Transaction } from "@scure/btc-signer/transaction.js";
|
|
2
2
|
import { base64 } from "@scure/base";
|
|
3
3
|
import { hex } from "@scure/base";
|
|
4
|
-
import { sha256x2 } from "@scure/btc-signer/utils.js";
|
|
5
4
|
/**
|
|
6
5
|
* TxTree is a graph of bitcoin transactions.
|
|
7
6
|
* It is used to represent batch tree created during settlement session
|
|
@@ -19,7 +18,7 @@ export class TxTree {
|
|
|
19
18
|
const chunksByTxid = new Map();
|
|
20
19
|
for (const chunk of chunks) {
|
|
21
20
|
const decodedChunk = decodeNode(chunk);
|
|
22
|
-
const txid =
|
|
21
|
+
const txid = decodedChunk.tx.id;
|
|
23
22
|
chunksByTxid.set(txid, decodedChunk);
|
|
24
23
|
}
|
|
25
24
|
// Find the root chunks (the ones that aren't referenced as a child)
|
|
@@ -88,7 +87,7 @@ export class TxTree {
|
|
|
88
87
|
}
|
|
89
88
|
child.validate();
|
|
90
89
|
const childInput = child.root.getInput(0);
|
|
91
|
-
const parentTxid =
|
|
90
|
+
const parentTxid = this.root.id;
|
|
92
91
|
// verify the input of the child is the output of the parent
|
|
93
92
|
if (!childInput.txid ||
|
|
94
93
|
hex.encode(childInput.txid) !== parentTxid ||
|
|
@@ -123,7 +122,7 @@ export class TxTree {
|
|
|
123
122
|
return leaves;
|
|
124
123
|
}
|
|
125
124
|
get txid() {
|
|
126
|
-
return
|
|
125
|
+
return this.root.id;
|
|
127
126
|
}
|
|
128
127
|
find(txid) {
|
|
129
128
|
if (txid === this.txid) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { hex } from "@scure/base";
|
|
2
2
|
import { Transaction } from "@scure/btc-signer/transaction.js";
|
|
3
3
|
import { base64 } from "@scure/base";
|
|
4
|
-
import { sha256x2 } from "@scure/btc-signer/utils.js";
|
|
5
4
|
import { aggregateKeys } from '../musig2/index.js';
|
|
6
5
|
import { CosignerPublicKey, getArkPsbtFields } from '../utils/unknownFields.js';
|
|
7
6
|
export const ErrInvalidSettlementTx = (tx) => new Error(`invalid settlement transaction: ${tx}`);
|
|
@@ -25,7 +24,7 @@ export function validateConnectorsTxGraph(settlementTxB64, connectorsGraph) {
|
|
|
25
24
|
const settlementTx = Transaction.fromPSBT(base64.decode(settlementTxB64));
|
|
26
25
|
if (settlementTx.outputsLength <= BATCH_OUTPUT_CONNECTORS_INDEX)
|
|
27
26
|
throw ErrInvalidSettlementTxOutputs;
|
|
28
|
-
const expectedRootTxid =
|
|
27
|
+
const expectedRootTxid = settlementTx.id;
|
|
29
28
|
if (!rootInput.txid)
|
|
30
29
|
throw ErrWrongSettlementTxid;
|
|
31
30
|
if (hex.encode(rootInput.txid) !== expectedRootTxid)
|
|
@@ -52,7 +51,7 @@ export function validateVtxoTxGraph(graph, roundTransaction, sweepTapTreeRoot) {
|
|
|
52
51
|
throw ErrEmptyTree;
|
|
53
52
|
}
|
|
54
53
|
const rootInput = graph.root.getInput(0);
|
|
55
|
-
const commitmentTxid =
|
|
54
|
+
const commitmentTxid = roundTransaction.id;
|
|
56
55
|
if (!rootInput.txid ||
|
|
57
56
|
hex.encode(rootInput.txid) !== commitmentTxid ||
|
|
58
57
|
rootInput.index !== BATCH_OUTPUT_VTXO_INDEX) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { schnorr } from "@noble/curves/secp256k1.js";
|
|
2
|
+
import { hex } from "@scure/base";
|
|
3
|
+
import { DEFAULT_SEQUENCE, Transaction, SigHash } from "@scure/btc-signer";
|
|
4
|
+
import { tapLeafHash } from "@scure/btc-signer/payment.js";
|
|
2
5
|
import { CLTVMultisigTapscript, decodeTapscript, } from '../script/tapscript.js';
|
|
3
6
|
import { scriptFromTapLeafScript, VtxoScript, } from '../script/base.js';
|
|
4
7
|
import { P2A } from './anchor.js';
|
|
5
|
-
import { hex } from "@scure/base";
|
|
6
|
-
import { sha256x2 } from "@scure/btc-signer/utils.js";
|
|
7
8
|
import { setArkPsbtField, VtxoTaprootTree } from './unknownFields.js';
|
|
8
9
|
/**
|
|
9
10
|
* Builds an offchain transaction with checkpoint transactions.
|
|
@@ -88,7 +89,7 @@ function buildCheckpointTx(vtxo, serverUnrollScript) {
|
|
|
88
89
|
const collaborativeLeafProof = checkpointVtxoScript.findLeaf(hex.encode(collaborativeClosure.script));
|
|
89
90
|
// create the checkpoint input that will be used as input of the virtual tx
|
|
90
91
|
const checkpointInput = {
|
|
91
|
-
txid:
|
|
92
|
+
txid: checkpointTx.id,
|
|
92
93
|
vout: 0,
|
|
93
94
|
value: vtxo.value,
|
|
94
95
|
tapLeafScript: collaborativeLeafProof,
|
|
@@ -115,3 +116,93 @@ export function hasBoardingTxExpired(coin, boardingTimelock) {
|
|
|
115
116
|
const blockTime = BigInt(Math.floor(coin.status.block_time));
|
|
116
117
|
return blockTime + boardingTimelock.value <= now;
|
|
117
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Formats a sighash type as a hex string (e.g., 0x01)
|
|
121
|
+
*/
|
|
122
|
+
function formatSighash(type) {
|
|
123
|
+
return `0x${type.toString(16).padStart(2, "0")}`;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Verify tapscript signatures on a transaction input
|
|
127
|
+
* @param tx Transaction to verify
|
|
128
|
+
* @param inputIndex Index of the input to verify
|
|
129
|
+
* @param requiredSigners List of required signer pubkeys (hex encoded)
|
|
130
|
+
* @param excludePubkeys List of pubkeys to exclude from verification (hex encoded, e.g., server key not yet signed)
|
|
131
|
+
* @param allowedSighashTypes List of allowed sighash types (defaults to [SigHash.DEFAULT])
|
|
132
|
+
* @throws Error if verification fails
|
|
133
|
+
*/
|
|
134
|
+
export function verifyTapscriptSignatures(tx, inputIndex, requiredSigners, excludePubkeys = [], allowedSighashTypes = [SigHash.DEFAULT]) {
|
|
135
|
+
const input = tx.getInput(inputIndex);
|
|
136
|
+
// Collect prevout scripts and amounts for ALL inputs (required for preimageWitnessV1)
|
|
137
|
+
const prevoutScripts = [];
|
|
138
|
+
const prevoutAmounts = [];
|
|
139
|
+
for (let i = 0; i < tx.inputsLength; i++) {
|
|
140
|
+
const inp = tx.getInput(i);
|
|
141
|
+
if (!inp.witnessUtxo) {
|
|
142
|
+
throw new Error(`Input ${i} is missing witnessUtxo`);
|
|
143
|
+
}
|
|
144
|
+
prevoutScripts.push(inp.witnessUtxo.script);
|
|
145
|
+
prevoutAmounts.push(inp.witnessUtxo.amount);
|
|
146
|
+
}
|
|
147
|
+
// Verify tapScriptSig signatures
|
|
148
|
+
if (!input.tapScriptSig || input.tapScriptSig.length === 0) {
|
|
149
|
+
throw new Error(`Input ${inputIndex} is missing tapScriptSig`);
|
|
150
|
+
}
|
|
151
|
+
// Verify each signature in tapScriptSig
|
|
152
|
+
for (const [tapScriptSigData, signature] of input.tapScriptSig) {
|
|
153
|
+
const pubKey = tapScriptSigData.pubKey;
|
|
154
|
+
const pubKeyHex = hex.encode(pubKey);
|
|
155
|
+
// Skip verification for excluded pubkeys
|
|
156
|
+
if (excludePubkeys.includes(pubKeyHex)) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
// Extract sighash type from signature
|
|
160
|
+
// Schnorr signatures are 64 bytes, with optional 1-byte sighash appended
|
|
161
|
+
const sighashType = signature.length === 65 ? signature[64] : SigHash.DEFAULT;
|
|
162
|
+
const sig = signature.subarray(0, 64);
|
|
163
|
+
// Verify sighash type is allowed
|
|
164
|
+
if (!allowedSighashTypes.includes(sighashType)) {
|
|
165
|
+
const sighashName = formatSighash(sighashType);
|
|
166
|
+
throw new Error(`Unallowed sighash type ${sighashName} for input ${inputIndex}, pubkey ${pubKeyHex}.`);
|
|
167
|
+
}
|
|
168
|
+
// Find the tapLeafScript that matches this signature's leafHash
|
|
169
|
+
if (!input.tapLeafScript || input.tapLeafScript.length === 0) {
|
|
170
|
+
throw new Error();
|
|
171
|
+
}
|
|
172
|
+
// Search for the leaf that matches the leafHash in tapScriptSigData
|
|
173
|
+
const leafHash = tapScriptSigData.leafHash;
|
|
174
|
+
const leafHashHex = hex.encode(leafHash);
|
|
175
|
+
let matchingScript;
|
|
176
|
+
let matchingVersion;
|
|
177
|
+
for (const [_, scriptWithVersion] of input.tapLeafScript) {
|
|
178
|
+
const script = scriptWithVersion.subarray(0, -1);
|
|
179
|
+
const version = scriptWithVersion[scriptWithVersion.length - 1];
|
|
180
|
+
// Compute the leaf hash for this script and compare as hex strings
|
|
181
|
+
const computedLeafHash = tapLeafHash(script, version);
|
|
182
|
+
const computedHex = hex.encode(computedLeafHash);
|
|
183
|
+
if (computedHex === leafHashHex) {
|
|
184
|
+
matchingScript = script;
|
|
185
|
+
matchingVersion = version;
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (!matchingScript || matchingVersion === undefined) {
|
|
190
|
+
throw new Error(`Input ${inputIndex}: No tapLeafScript found matching leafHash ${hex.encode(leafHash)}`);
|
|
191
|
+
}
|
|
192
|
+
// Reconstruct the message that was signed
|
|
193
|
+
// Note: preimageWitnessV1 requires ALL input prevout scripts and amounts
|
|
194
|
+
const message = tx.preimageWitnessV1(inputIndex, prevoutScripts, sighashType, prevoutAmounts, undefined, matchingScript, matchingVersion);
|
|
195
|
+
// Verify the schnorr signature
|
|
196
|
+
const isValid = schnorr.verify(sig, message, pubKey);
|
|
197
|
+
if (!isValid) {
|
|
198
|
+
throw new Error(`Invalid signature for input ${inputIndex}, pubkey ${pubKeyHex}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// Verify we have signatures from all required signers (excluding those we're skipping)
|
|
202
|
+
const signedPubkeys = input.tapScriptSig.map(([data]) => hex.encode(data.pubKey));
|
|
203
|
+
const requiredNotExcluded = requiredSigners.filter((pk) => !excludePubkeys.includes(pk));
|
|
204
|
+
const missingSigners = requiredNotExcluded.filter((pk) => !signedPubkeys.includes(pk));
|
|
205
|
+
if (missingSigners.length > 0) {
|
|
206
|
+
throw new Error(`Missing signatures from: ${missingSigners.map((pk) => pk.slice(0, 16)).join(", ")}...`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { p2tr } from "@scure/btc-signer
|
|
1
|
+
import { Transaction, p2tr } from "@scure/btc-signer";
|
|
2
2
|
import { getNetwork } from '../networks.js';
|
|
3
3
|
import { ESPLORA_URL, EsploraProvider, } from '../providers/onchain.js';
|
|
4
|
-
import { Transaction } from "@scure/btc-signer/transaction.js";
|
|
5
4
|
import { findP2AOutput, P2A } from '../utils/anchor.js';
|
|
6
5
|
import { TxWeightEstimator } from '../utils/txSizeEstimator.js';
|
|
7
6
|
/**
|
|
@@ -3,7 +3,7 @@ import { hex } from "@scure/base";
|
|
|
3
3
|
import { IndexedDBStorageAdapter } from '../../storage/indexedDB.js';
|
|
4
4
|
import { WalletRepositoryImpl } from '../../repositories/walletRepository.js';
|
|
5
5
|
import { ContractRepositoryImpl } from '../../repositories/contractRepository.js';
|
|
6
|
-
import { setupServiceWorker } from './utils.js';
|
|
6
|
+
import { DEFAULT_DB_NAME, setupServiceWorker } from './utils.js';
|
|
7
7
|
const isPrivateKeyIdentity = (identity) => {
|
|
8
8
|
return typeof identity.toHex === "function";
|
|
9
9
|
};
|
|
@@ -22,7 +22,7 @@ export class ServiceWorkerWallet {
|
|
|
22
22
|
}
|
|
23
23
|
static async create(options) {
|
|
24
24
|
// Default to IndexedDB for service worker context
|
|
25
|
-
const storage = options.
|
|
25
|
+
const storage = new IndexedDBStorageAdapter(options.dbName || DEFAULT_DB_NAME, options.dbVersion);
|
|
26
26
|
// Create repositories
|
|
27
27
|
const walletRepo = new WalletRepositoryImpl(storage);
|
|
28
28
|
const contractRepo = new ContractRepositoryImpl(storage);
|
|
@@ -31,7 +31,7 @@ export class ServiceWorkerWallet {
|
|
|
31
31
|
? options.identity
|
|
32
32
|
: null;
|
|
33
33
|
if (!identity) {
|
|
34
|
-
throw new Error("ServiceWorkerWallet.create() requires a Identity that can expose
|
|
34
|
+
throw new Error("ServiceWorkerWallet.create() requires a Identity that can expose a single private key");
|
|
35
35
|
}
|
|
36
36
|
// Extract private key for service worker initialization
|
|
37
37
|
const privateKey = identity.toHex();
|
|
@@ -74,13 +74,9 @@ export class ServiceWorkerWallet {
|
|
|
74
74
|
// Register and setup the service worker
|
|
75
75
|
const serviceWorker = await setupServiceWorker(options.serviceWorkerPath);
|
|
76
76
|
// Use the existing create method
|
|
77
|
-
return
|
|
78
|
-
|
|
79
|
-
arkServerUrl: options.arkServerUrl,
|
|
80
|
-
esploraUrl: options.esploraUrl,
|
|
81
|
-
identity: options.identity,
|
|
77
|
+
return ServiceWorkerWallet.create({
|
|
78
|
+
...options,
|
|
82
79
|
serviceWorker,
|
|
83
|
-
storage: options.storage,
|
|
84
80
|
});
|
|
85
81
|
}
|
|
86
82
|
// send a message and wait for a response
|
|
@@ -11,14 +11,17 @@ import { hex } from "@scure/base";
|
|
|
11
11
|
import { IndexedDBStorageAdapter } from '../../storage/indexedDB.js';
|
|
12
12
|
import { WalletRepositoryImpl, } from '../../repositories/walletRepository.js';
|
|
13
13
|
import { extendVirtualCoin } from '../utils.js';
|
|
14
|
+
import { DEFAULT_DB_NAME } from './utils.js';
|
|
14
15
|
/**
|
|
15
16
|
* Worker is a class letting to interact with ServiceWorkerWallet from the client
|
|
16
17
|
* it aims to be run in a service worker context
|
|
17
18
|
*/
|
|
18
19
|
export class Worker {
|
|
19
|
-
constructor(messageCallback = () => { }) {
|
|
20
|
+
constructor(dbName = DEFAULT_DB_NAME, dbVersion = 1, messageCallback = () => { }) {
|
|
21
|
+
this.dbName = dbName;
|
|
22
|
+
this.dbVersion = dbVersion;
|
|
20
23
|
this.messageCallback = messageCallback;
|
|
21
|
-
this.storage = new IndexedDBStorageAdapter(
|
|
24
|
+
this.storage = new IndexedDBStorageAdapter(dbName, dbVersion);
|
|
22
25
|
this.walletRepository = new WalletRepositoryImpl(this.storage);
|
|
23
26
|
}
|
|
24
27
|
/**
|
|
@@ -104,6 +107,9 @@ export class Worker {
|
|
|
104
107
|
const txs = await this.wallet.getTransactionHistory();
|
|
105
108
|
if (txs)
|
|
106
109
|
await this.walletRepository.saveTransactions(address, txs);
|
|
110
|
+
// unsubscribe previous subscription if any
|
|
111
|
+
if (this.incomingFundsSubscription)
|
|
112
|
+
this.incomingFundsSubscription();
|
|
107
113
|
// subscribe for incoming funds and notify all clients when new funds arrive
|
|
108
114
|
this.incomingFundsSubscription = await this.wallet.notifyIncomingFunds(async (funds) => {
|
|
109
115
|
if (funds.type === "vtxo") {
|
|
@@ -350,22 +356,21 @@ export class Worker {
|
|
|
350
356
|
return;
|
|
351
357
|
}
|
|
352
358
|
try {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
event.source?.postMessage(Response.vtxos(message.id, vtxos));
|
|
359
|
+
const vtxos = await this.getSpendableVtxos();
|
|
360
|
+
const dustAmount = this.wallet.dustAmount;
|
|
361
|
+
const includeRecoverable = message.filter?.withRecoverable ?? false;
|
|
362
|
+
const filteredVtxos = includeRecoverable
|
|
363
|
+
? vtxos
|
|
364
|
+
: vtxos.filter((v) => {
|
|
365
|
+
if (dustAmount != null && isSubdust(v, dustAmount)) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
if (isRecoverable(v)) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
return true;
|
|
372
|
+
});
|
|
373
|
+
event.source?.postMessage(Response.vtxos(message.id, filteredVtxos));
|
|
369
374
|
}
|
|
370
375
|
catch (error) {
|
|
371
376
|
console.error("Error getting vtxos:", error);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { SigHash, Transaction } from "@scure/btc-signer/transaction.js";
|
|
2
|
-
import { ChainTxType } from '../providers/indexer.js';
|
|
3
1
|
import { base64, hex } from "@scure/base";
|
|
2
|
+
import { SigHash, Transaction, TaprootControlBlock } from "@scure/btc-signer";
|
|
3
|
+
import { ChainTxType } from '../providers/indexer.js';
|
|
4
4
|
import { VtxoScript } from '../script/base.js';
|
|
5
|
-
import { TaprootControlBlock, } from "@scure/btc-signer/psbt.js";
|
|
6
5
|
import { TxWeightEstimator } from '../utils/txSizeEstimator.js';
|
|
7
6
|
import { Wallet } from './wallet.js';
|
|
8
7
|
export var Unroll;
|