@btc-vision/transaction 1.1.16 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser/_version.d.ts +1 -1
- package/browser/crypto/crypto-browser.d.ts +2 -2
- package/browser/index.js +1 -1
- package/browser/index.js.LICENSE.txt +2 -0
- package/browser/keypair/Address.d.ts +10 -0
- package/browser/keypair/Secp256k1PointDeriver.d.ts +16 -0
- package/browser/opnet.d.ts +2 -0
- package/browser/signer/SignerUtils.d.ts +5 -0
- package/browser/transaction/ContractAddress.d.ts +6 -0
- package/browser/transaction/builders/CustomScriptTransaction.d.ts +1 -1
- package/browser/transaction/builders/InteractionTransaction.d.ts +1 -1
- package/browser/transaction/builders/MultiSignTransaction.d.ts +3 -4
- package/browser/transaction/builders/SharedInteractionTransaction.d.ts +2 -3
- package/browser/transaction/shared/TweakedTransaction.d.ts +5 -6
- package/browser/utxo/interfaces/IUTXO.d.ts +1 -0
- package/browser/verification/TapscriptVerificator.d.ts +1 -2
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/buffer/BinaryReader.js +2 -2
- package/build/buffer/BinaryWriter.js +1 -1
- package/build/generators/AddressGenerator.js +1 -2
- package/build/generators/Generator.js +1 -2
- package/build/generators/builders/CalldataGenerator.js +1 -1
- package/build/generators/builders/LegacyCalldataGenerator.js +1 -1
- package/build/generators/builders/MultiSignGenerator.js +1 -2
- package/build/keypair/Address.d.ts +10 -0
- package/build/keypair/Address.js +76 -7
- package/build/keypair/AddressVerificator.js +5 -2
- package/build/keypair/EcKeyPair.js +3 -4
- package/build/keypair/MessageSigner.js +1 -2
- package/build/keypair/Secp256k1PointDeriver.d.ts +16 -0
- package/build/keypair/Secp256k1PointDeriver.js +80 -0
- package/build/keypair/Wallet.js +1 -2
- package/build/opnet.d.ts +2 -0
- package/build/opnet.js +2 -0
- package/build/signer/SignerUtils.d.ts +5 -0
- package/build/signer/SignerUtils.js +40 -0
- package/build/signer/TweakedSigner.js +1 -3
- package/build/transaction/ContractAddress.d.ts +6 -0
- package/build/transaction/ContractAddress.js +12 -0
- package/build/transaction/browser/extensions/UnisatSigner.js +5 -33
- package/build/transaction/browser/extensions/XverseSigner.js +5 -49
- package/build/transaction/builders/CustomScriptTransaction.d.ts +1 -1
- package/build/transaction/builders/CustomScriptTransaction.js +1 -2
- package/build/transaction/builders/DeploymentTransaction.js +2 -2
- package/build/transaction/builders/FundingTransaction.js +6 -1
- package/build/transaction/builders/InteractionTransaction.d.ts +1 -1
- package/build/transaction/builders/MultiSignTransaction.d.ts +3 -4
- package/build/transaction/builders/MultiSignTransaction.js +1 -2
- package/build/transaction/builders/SharedInteractionTransaction.d.ts +2 -3
- package/build/transaction/builders/SharedInteractionTransaction.js +1 -2
- package/build/transaction/builders/TransactionBuilder.js +14 -3
- package/build/transaction/shared/TweakedTransaction.d.ts +5 -6
- package/build/transaction/shared/TweakedTransaction.js +121 -94
- package/build/utils/BitcoinUtils.js +4 -4
- package/build/utils/BufferHelper.js +1 -1
- package/build/utxo/OPNetLimitedProvider.js +1 -0
- package/build/utxo/interfaces/IUTXO.d.ts +1 -0
- package/build/verification/TapscriptVerificator.d.ts +1 -2
- package/build/verification/TapscriptVerificator.js +1 -2
- package/package.json +9 -12
- package/src/_version.ts +1 -1
- package/src/buffer/BinaryReader.ts +2 -2
- package/src/buffer/BinaryWriter.ts +1 -1
- package/src/generators/AddressGenerator.ts +1 -2
- package/src/generators/Generator.ts +1 -2
- package/src/generators/builders/CalldataGenerator.ts +5 -1
- package/src/generators/builders/LegacyCalldataGenerator.ts +5 -1
- package/src/generators/builders/MultiSignGenerator.ts +1 -2
- package/src/keypair/Address.ts +106 -10
- package/src/keypair/AddressVerificator.ts +6 -2
- package/src/keypair/EcKeyPair.ts +14 -5
- package/src/keypair/MessageSigner.ts +1 -2
- package/src/keypair/Secp256k1PointDeriver.ts +170 -0
- package/src/keypair/Wallet.ts +1 -2
- package/src/opnet.ts +2 -0
- package/src/signer/SignerUtils.ts +66 -0
- package/src/signer/TweakedSigner.ts +1 -3
- package/src/transaction/ContractAddress.ts +13 -0
- package/src/transaction/TransactionFactory.ts +4 -258
- package/src/transaction/browser/extensions/UnisatSigner.ts +5 -41
- package/src/transaction/browser/extensions/XverseSigner.ts +9 -69
- package/src/transaction/builders/CustomScriptTransaction.ts +10 -3
- package/src/transaction/builders/DeploymentTransaction.ts +13 -3
- package/src/transaction/builders/FundingTransaction.ts +7 -2
- package/src/transaction/builders/InteractionTransaction.ts +1 -1
- package/src/transaction/builders/MultiSignTransaction.ts +2 -2
- package/src/transaction/builders/SharedInteractionTransaction.ts +1 -3
- package/src/transaction/builders/TransactionBuilder.ts +14 -2
- package/src/transaction/shared/TweakedTransaction.ts +186 -123
- package/src/utils/BitcoinUtils.ts +4 -4
- package/src/utils/BufferHelper.ts +1 -1
- package/src/utxo/OPNetLimitedProvider.ts +1 -0
- package/src/utxo/interfaces/IUTXO.ts +2 -0
- package/src/verification/TapscriptVerificator.ts +9 -3
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Transaction } from '@btc-vision/bitcoin';
|
|
2
|
-
import { Output } from '@btc-vision/bitcoin/src/transaction.js';
|
|
1
|
+
import { Transaction, TxOutput } from '@btc-vision/bitcoin';
|
|
3
2
|
import { currentConsensus } from '../consensus/ConsensusConfig.js';
|
|
4
3
|
import { UTXO } from '../utxo/interfaces/IUTXO.js';
|
|
5
4
|
import {
|
|
@@ -51,15 +50,6 @@ export interface BitcoinTransferResponse {
|
|
|
51
50
|
readonly nextUTXOs: UTXO[];
|
|
52
51
|
}
|
|
53
52
|
|
|
54
|
-
/*export interface UnwrapResult {
|
|
55
|
-
readonly fundingTransaction: string;
|
|
56
|
-
readonly psbt: string;
|
|
57
|
-
|
|
58
|
-
readonly feeRefundOrLoss: bigint;
|
|
59
|
-
|
|
60
|
-
readonly utxos: UTXO[];
|
|
61
|
-
}*/
|
|
62
|
-
|
|
63
53
|
export class TransactionFactory {
|
|
64
54
|
/**
|
|
65
55
|
* @description Generate a transaction with a custom script.
|
|
@@ -239,7 +229,7 @@ export class TransactionFactory {
|
|
|
239
229
|
throw new Error('Could not sign funding transaction.');
|
|
240
230
|
}
|
|
241
231
|
|
|
242
|
-
const out:
|
|
232
|
+
const out: TxOutput = signedTransaction.outs[0];
|
|
243
233
|
const newUtxo: UTXO = {
|
|
244
234
|
transactionId: signedTransaction.getId(),
|
|
245
235
|
outputIndex: 0, // always 0
|
|
@@ -263,7 +253,7 @@ export class TransactionFactory {
|
|
|
263
253
|
// We have to regenerate using the new utxo
|
|
264
254
|
const outTx: Transaction = await finalTransaction.signTransaction();
|
|
265
255
|
|
|
266
|
-
const out2:
|
|
256
|
+
const out2: TxOutput = signedTransaction.outs[1];
|
|
267
257
|
const refundUTXO: UTXO = {
|
|
268
258
|
transactionId: signedTransaction.getId(),
|
|
269
259
|
outputIndex: 1, // always 1
|
|
@@ -283,220 +273,6 @@ export class TransactionFactory {
|
|
|
283
273
|
};
|
|
284
274
|
}
|
|
285
275
|
|
|
286
|
-
/**
|
|
287
|
-
* Basically it's fun to manage UTXOs.
|
|
288
|
-
* @param {IWrapParameters} wrapParameters - The wrap parameters
|
|
289
|
-
* @returns {Promise<WrapResult>} - The signed transaction
|
|
290
|
-
* @throws {Error} - If the transaction could not be signed
|
|
291
|
-
*/
|
|
292
|
-
/*public async wrap(wrapParameters: Omit<IWrapParameters, 'calldata'>): Promise<WrapResult> {
|
|
293
|
-
if (wrapParameters.amount < currentConsensusConfig.VAULT_MINIMUM_AMOUNT) {
|
|
294
|
-
throw new Error(
|
|
295
|
-
`Amount is too low. Minimum consolidation is ${currentConsensusConfig.VAULT_MINIMUM_AMOUNT} sat. Received ${wrapParameters.amount} sat. Make sure that you cover the unwrap consolidation fees of ${currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT}sat.`,
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const childTransactionRequiredValue: bigint =
|
|
300
|
-
wrapParameters.amount +
|
|
301
|
-
currentConsensusConfig.UNWRAP_CONSOLIDATION_PREPAID_FEES_SAT +
|
|
302
|
-
this.getPriorityFee(wrapParameters);
|
|
303
|
-
|
|
304
|
-
const wbtc: wBTC = new wBTC(wrapParameters.network, wrapParameters.chainId);
|
|
305
|
-
const to = wbtc.getAddress();
|
|
306
|
-
const fundingParameters: IFundingTransactionParameters = {
|
|
307
|
-
...wrapParameters,
|
|
308
|
-
amount: childTransactionRequiredValue,
|
|
309
|
-
to: wrapParameters.to ?? to,
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
const preFundingTransaction = await this.createFundTransaction(fundingParameters);
|
|
313
|
-
wrapParameters.utxos = this.getUTXOAsTransaction(preFundingTransaction.tx, to, 0);
|
|
314
|
-
|
|
315
|
-
const preTransaction: WrapTransaction = new WrapTransaction(wrapParameters);
|
|
316
|
-
|
|
317
|
-
// Initial generation
|
|
318
|
-
await preTransaction.signTransaction();
|
|
319
|
-
|
|
320
|
-
const parameters: IFundingTransactionParameters =
|
|
321
|
-
await preTransaction.getFundingTransactionParameters();
|
|
322
|
-
|
|
323
|
-
// We add the amount
|
|
324
|
-
parameters.amount += childTransactionRequiredValue;
|
|
325
|
-
parameters.utxos = fundingParameters.utxos;
|
|
326
|
-
|
|
327
|
-
const signedTransaction = await this.createFundTransaction(parameters);
|
|
328
|
-
if (!signedTransaction) {
|
|
329
|
-
throw new Error('Could not sign funding transaction.');
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
const newParams: IWrapParameters = {
|
|
333
|
-
...wrapParameters,
|
|
334
|
-
utxos: this.getUTXOAsTransaction(signedTransaction.tx, to, 0), // always 0
|
|
335
|
-
randomBytes: preTransaction.getRndBytes(),
|
|
336
|
-
nonWitnessUtxo: signedTransaction.tx.toBuffer(),
|
|
337
|
-
};
|
|
338
|
-
|
|
339
|
-
const finalTransaction: WrapTransaction = new WrapTransaction(newParams);
|
|
340
|
-
|
|
341
|
-
// We have to regenerate using the new utxo
|
|
342
|
-
const outTx: Transaction = await finalTransaction.signTransaction();
|
|
343
|
-
return {
|
|
344
|
-
transaction: [signedTransaction.tx.toHex(), outTx.toHex()],
|
|
345
|
-
vaultAddress: finalTransaction.vault,
|
|
346
|
-
amount: finalTransaction.amount,
|
|
347
|
-
receiverAddress: finalTransaction.receiver.p2tr(wrapParameters.network),
|
|
348
|
-
utxos: this.getUTXOAsTransaction(signedTransaction.tx, wrapParameters.from, 1),
|
|
349
|
-
};
|
|
350
|
-
}*/
|
|
351
|
-
|
|
352
|
-
/**
|
|
353
|
-
* Unwrap bitcoin.
|
|
354
|
-
* @param {IUnwrapParameters} unwrapParameters - The unwrap parameters
|
|
355
|
-
* @returns {Promise<UnwrapResult>} - The signed transaction
|
|
356
|
-
* @throws {Error} - If the transaction could not be signed
|
|
357
|
-
* @deprecated
|
|
358
|
-
*/
|
|
359
|
-
/*public async unwrapSegwit(unwrapParameters: IUnwrapParameters): Promise<UnwrapResult> {
|
|
360
|
-
console.error('The "unwrap" method is deprecated. Use unwrapTap instead.');
|
|
361
|
-
|
|
362
|
-
const transaction: UnwrapSegwitTransaction = new UnwrapSegwitTransaction(unwrapParameters);
|
|
363
|
-
await transaction.signTransaction();
|
|
364
|
-
|
|
365
|
-
const to = transaction.toAddress();
|
|
366
|
-
if (!to) throw new Error('To address is required');
|
|
367
|
-
|
|
368
|
-
// Initial generation
|
|
369
|
-
const estimatedGas = await transaction.estimateTransactionFees();
|
|
370
|
-
const estimatedFees = transaction.preEstimateTransactionFees(
|
|
371
|
-
BigInt(unwrapParameters.feeRate),
|
|
372
|
-
this.calculateNumInputs(unwrapParameters.unwrapUTXOs),
|
|
373
|
-
2n,
|
|
374
|
-
this.calculateNumSignatures(unwrapParameters.unwrapUTXOs),
|
|
375
|
-
this.maxPubKeySize(unwrapParameters.unwrapUTXOs),
|
|
376
|
-
);
|
|
377
|
-
|
|
378
|
-
const fundingParameters: IFundingTransactionParameters = {
|
|
379
|
-
...unwrapParameters,
|
|
380
|
-
amount: estimatedGas + estimatedFees,
|
|
381
|
-
to: to,
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
const preFundingTransaction = await this.createFundTransaction(fundingParameters);
|
|
385
|
-
unwrapParameters.utxos = this.getUTXOAsTransaction(preFundingTransaction.tx, to, 0);
|
|
386
|
-
|
|
387
|
-
const preTransaction: UnwrapSegwitTransaction = new UnwrapSegwitTransaction({
|
|
388
|
-
...unwrapParameters,
|
|
389
|
-
randomBytes: transaction.getRndBytes(),
|
|
390
|
-
});
|
|
391
|
-
|
|
392
|
-
// Initial generation
|
|
393
|
-
await preTransaction.signTransaction();
|
|
394
|
-
|
|
395
|
-
const parameters: IFundingTransactionParameters =
|
|
396
|
-
await preTransaction.getFundingTransactionParameters();
|
|
397
|
-
|
|
398
|
-
parameters.utxos = fundingParameters.utxos;
|
|
399
|
-
parameters.amount = (await preTransaction.estimateTransactionFees()) + estimatedFees;
|
|
400
|
-
|
|
401
|
-
const signedTransaction = await this.createFundTransaction(parameters);
|
|
402
|
-
if (!signedTransaction) {
|
|
403
|
-
throw new Error('Could not sign funding transaction.');
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
const newParams: IUnwrapParameters = {
|
|
407
|
-
...unwrapParameters,
|
|
408
|
-
utxos: this.getUTXOAsTransaction(signedTransaction.tx, to, 0), // always 0
|
|
409
|
-
randomBytes: preTransaction.getRndBytes(),
|
|
410
|
-
nonWitnessUtxo: signedTransaction.tx.toBuffer(),
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
const finalTransaction: UnwrapSegwitTransaction = new UnwrapSegwitTransaction(newParams);
|
|
414
|
-
|
|
415
|
-
// We have to regenerate using the new utxo
|
|
416
|
-
const outTx: Psbt = await finalTransaction.signPSBT();
|
|
417
|
-
const asBase64 = outTx.toBase64();
|
|
418
|
-
const psbt = this.writePSBTHeader(PSBTTypes.UNWRAP, asBase64);
|
|
419
|
-
|
|
420
|
-
return {
|
|
421
|
-
fundingTransaction: signedTransaction.tx.toHex(),
|
|
422
|
-
psbt: psbt,
|
|
423
|
-
feeRefundOrLoss: estimatedFees,
|
|
424
|
-
utxos: [],
|
|
425
|
-
};
|
|
426
|
-
}*/
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Unwrap bitcoin via taproot.
|
|
430
|
-
* @param {IUnwrapParameters} unwrapParameters - The unwrap parameters
|
|
431
|
-
* @returns {Promise<UnwrapResult>} - The signed transaction
|
|
432
|
-
* @throws {Error} - If the transaction could not be signed
|
|
433
|
-
*/
|
|
434
|
-
|
|
435
|
-
/*public async unwrap(unwrapParameters: IUnwrapParameters): Promise<UnwrapResult> {
|
|
436
|
-
if (!unwrapParameters.from) {
|
|
437
|
-
throw new Error('Field "from" not provided.');
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
const transaction: UnwrapTransaction = new UnwrapTransaction(unwrapParameters);
|
|
441
|
-
await transaction.signTransaction();
|
|
442
|
-
|
|
443
|
-
const to = transaction.toAddress();
|
|
444
|
-
if (!to) throw new Error('To address is required');
|
|
445
|
-
|
|
446
|
-
// Initial generation
|
|
447
|
-
const estimatedGas = await transaction.estimateTransactionFees();
|
|
448
|
-
const fundingParameters: IFundingTransactionParameters = {
|
|
449
|
-
...unwrapParameters,
|
|
450
|
-
amount: estimatedGas,
|
|
451
|
-
to: to,
|
|
452
|
-
};
|
|
453
|
-
|
|
454
|
-
const preFundingTransaction = await this.createFundTransaction(fundingParameters);
|
|
455
|
-
unwrapParameters.utxos = this.getUTXOAsTransaction(preFundingTransaction.tx, to, 0);
|
|
456
|
-
|
|
457
|
-
const preTransaction: UnwrapTransaction = new UnwrapTransaction({
|
|
458
|
-
...unwrapParameters,
|
|
459
|
-
randomBytes: transaction.getRndBytes(),
|
|
460
|
-
});
|
|
461
|
-
|
|
462
|
-
// Initial generation
|
|
463
|
-
await preTransaction.signTransaction();
|
|
464
|
-
|
|
465
|
-
const parameters: IFundingTransactionParameters =
|
|
466
|
-
await preTransaction.getFundingTransactionParameters();
|
|
467
|
-
|
|
468
|
-
parameters.utxos = fundingParameters.utxos;
|
|
469
|
-
parameters.amount =
|
|
470
|
-
(await preTransaction.estimateTransactionFees()) +
|
|
471
|
-
this.getPriorityFee(unwrapParameters);
|
|
472
|
-
|
|
473
|
-
const signedTransaction = await this.createFundTransaction(parameters);
|
|
474
|
-
if (!signedTransaction) {
|
|
475
|
-
throw new Error('Could not sign funding transaction.');
|
|
476
|
-
}
|
|
477
|
-
|
|
478
|
-
const newParams: IUnwrapParameters = {
|
|
479
|
-
...unwrapParameters,
|
|
480
|
-
utxos: this.getUTXOAsTransaction(signedTransaction.tx, to, 0), // always 0
|
|
481
|
-
randomBytes: preTransaction.getRndBytes(),
|
|
482
|
-
nonWitnessUtxo: signedTransaction.tx.toBuffer(),
|
|
483
|
-
};
|
|
484
|
-
|
|
485
|
-
const finalTransaction: UnwrapTransaction = new UnwrapTransaction(newParams);
|
|
486
|
-
|
|
487
|
-
// We have to regenerate using the new utxo
|
|
488
|
-
const outTx: Psbt = await finalTransaction.signPSBT();
|
|
489
|
-
const asBase64 = outTx.toBase64();
|
|
490
|
-
const psbt = this.writePSBTHeader(PSBTTypes.UNWRAP, asBase64);
|
|
491
|
-
|
|
492
|
-
return {
|
|
493
|
-
fundingTransaction: signedTransaction.tx.toHex(),
|
|
494
|
-
psbt: psbt,
|
|
495
|
-
feeRefundOrLoss: finalTransaction.getFeeLossOrRefund(),
|
|
496
|
-
utxos: this.getUTXOAsTransaction(signedTransaction.tx, unwrapParameters.from, 1),
|
|
497
|
-
};
|
|
498
|
-
}*/
|
|
499
|
-
|
|
500
276
|
/**
|
|
501
277
|
* @description Creates a funding transaction.
|
|
502
278
|
* @param {IFundingTransactionParameters} parameters - The funding transaction parameters
|
|
@@ -566,36 +342,6 @@ export class TransactionFactory {
|
|
|
566
342
|
};
|
|
567
343
|
}
|
|
568
344
|
|
|
569
|
-
/*private calculateNumSignatures(vault: VaultUTXOs[]): bigint {
|
|
570
|
-
let numSignatures = 0n;
|
|
571
|
-
|
|
572
|
-
for (const v of vault) {
|
|
573
|
-
numSignatures += BigInt(v.minimum * v.utxos.length);
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
return numSignatures;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
private calculateNumInputs(vault: VaultUTXOs[]): bigint {
|
|
580
|
-
let numSignatures = 0n;
|
|
581
|
-
|
|
582
|
-
for (const v of vault) {
|
|
583
|
-
numSignatures += BigInt(v.utxos.length);
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
return numSignatures;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
private maxPubKeySize(vault: VaultUTXOs[]): bigint {
|
|
590
|
-
let size = 0;
|
|
591
|
-
|
|
592
|
-
for (const v of vault) {
|
|
593
|
-
size = Math.max(size, v.publicKeys.length);
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
return BigInt(size);
|
|
597
|
-
}*/
|
|
598
|
-
|
|
599
345
|
private writePSBTHeader(type: PSBTTypes, psbt: string): string {
|
|
600
346
|
const buf = Buffer.from(psbt, 'base64');
|
|
601
347
|
|
|
@@ -617,7 +363,7 @@ export class TransactionFactory {
|
|
|
617
363
|
private getUTXOAsTransaction(tx: Transaction, to: string, index: number): UTXO[] {
|
|
618
364
|
if (!tx.outs[index]) return [];
|
|
619
365
|
|
|
620
|
-
const out:
|
|
366
|
+
const out: TxOutput = tx.outs[index];
|
|
621
367
|
const newUtxo: UTXO = {
|
|
622
368
|
transactionId: tx.getId(),
|
|
623
369
|
outputIndex: index,
|
|
@@ -2,18 +2,17 @@ import {
|
|
|
2
2
|
crypto as bitCrypto,
|
|
3
3
|
Network,
|
|
4
4
|
networks,
|
|
5
|
-
opcodes,
|
|
6
5
|
Psbt,
|
|
7
|
-
PsbtInput,
|
|
8
6
|
script as bitScript,
|
|
9
7
|
TapScriptSig,
|
|
8
|
+
toXOnly,
|
|
10
9
|
} from '@btc-vision/bitcoin';
|
|
11
10
|
import { ECPairInterface } from 'ecpair';
|
|
12
11
|
import { EcKeyPair } from '../../../keypair/EcKeyPair.js';
|
|
13
12
|
import { CustomKeypair } from '../BrowserSignerBase.js';
|
|
14
13
|
import { PsbtSignatureOptions, Unisat, UnisatNetwork } from '../types/Unisat.js';
|
|
15
14
|
import { PartialSig } from 'bip174/src/lib/interfaces.js';
|
|
16
|
-
import {
|
|
15
|
+
import { canSignNonTaprootInput, isTaprootInput } from '../../../signer/SignerUtils.js';
|
|
17
16
|
|
|
18
17
|
declare global {
|
|
19
18
|
interface Window {
|
|
@@ -219,14 +218,10 @@ export class UnisatSigner extends CustomKeypair {
|
|
|
219
218
|
viaTaproot = true;
|
|
220
219
|
}
|
|
221
220
|
}
|
|
222
|
-
} else {
|
|
221
|
+
} else if (canSignNonTaprootInput(input, this.publicKey)) {
|
|
223
222
|
// Non-Taproot input
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (script && pubkeyInScript(this.publicKey, script)) {
|
|
227
|
-
needsToSign = true;
|
|
228
|
-
viaTaproot = false;
|
|
229
|
-
}
|
|
223
|
+
needsToSign = true;
|
|
224
|
+
viaTaproot = false;
|
|
230
225
|
}
|
|
231
226
|
|
|
232
227
|
if (needsToSign) {
|
|
@@ -357,37 +352,6 @@ export class UnisatSigner extends CustomKeypair {
|
|
|
357
352
|
}
|
|
358
353
|
}
|
|
359
354
|
|
|
360
|
-
// Helper functions
|
|
361
|
-
function isTaprootInput(input: PsbtInput): boolean {
|
|
362
|
-
if (input.tapInternalKey || input.tapKeySig || input.tapScriptSig || input.tapLeafScript) {
|
|
363
|
-
return true;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
if (input.witnessUtxo) {
|
|
367
|
-
const script = input.witnessUtxo.script;
|
|
368
|
-
return script.length === 34 && script[0] === opcodes.OP_1 && script[1] === 0x20;
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
return false;
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
function getInputRelevantScript(input: PsbtInput): Buffer | null {
|
|
375
|
-
if (input.redeemScript) {
|
|
376
|
-
return input.redeemScript;
|
|
377
|
-
}
|
|
378
|
-
if (input.witnessScript) {
|
|
379
|
-
return input.witnessScript;
|
|
380
|
-
}
|
|
381
|
-
if (input.witnessUtxo) {
|
|
382
|
-
return input.witnessUtxo.script;
|
|
383
|
-
}
|
|
384
|
-
if (input.nonWitnessUtxo) {
|
|
385
|
-
// Additional logic can be added here if needed
|
|
386
|
-
return null;
|
|
387
|
-
}
|
|
388
|
-
return null;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
355
|
function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean {
|
|
392
356
|
return pubkeyPositionInScript(pubkey, script) !== -1;
|
|
393
357
|
}
|
|
@@ -1,20 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
crypto as bitCrypto,
|
|
3
|
-
script as bitScript,
|
|
4
|
-
Network,
|
|
5
|
-
networks,
|
|
6
|
-
opcodes,
|
|
7
|
-
Psbt,
|
|
8
|
-
PsbtInput,
|
|
9
|
-
TapScriptSig,
|
|
10
|
-
} from '@btc-vision/bitcoin';
|
|
11
|
-
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
1
|
+
import { Network, networks, Psbt, TapScriptSig, toXOnly } from '@btc-vision/bitcoin';
|
|
12
2
|
import { PartialSig } from 'bip174/src/lib/interfaces.js';
|
|
13
3
|
import { ECPairInterface } from 'ecpair';
|
|
14
4
|
import { EcKeyPair } from '../../../keypair/EcKeyPair.js';
|
|
15
5
|
import { CustomKeypair } from '../BrowserSignerBase.js';
|
|
16
6
|
import { PsbtSignatureOptions } from '../types/Unisat.js';
|
|
17
7
|
import { Xverse, XverseRPCGetAccountResponse, XverseRPCSignPsbtResponse } from '../types/Xverse.js';
|
|
8
|
+
import {
|
|
9
|
+
canSignNonTaprootInput,
|
|
10
|
+
isTaprootInput,
|
|
11
|
+
pubkeyInScript,
|
|
12
|
+
} from '../../../signer/SignerUtils.js';
|
|
18
13
|
|
|
19
14
|
declare global {
|
|
20
15
|
interface Window {
|
|
@@ -226,14 +221,10 @@ export class XverseSigner extends CustomKeypair {
|
|
|
226
221
|
viaTaproot = true;
|
|
227
222
|
}
|
|
228
223
|
}
|
|
229
|
-
} else {
|
|
224
|
+
} else if (canSignNonTaprootInput(input, this.publicKey)) {
|
|
230
225
|
// Non-Taproot input
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (script && pubkeyInScript(this.publicKey, script)) {
|
|
234
|
-
needsToSign = true;
|
|
235
|
-
viaTaproot = false;
|
|
236
|
-
}
|
|
226
|
+
needsToSign = true;
|
|
227
|
+
viaTaproot = false;
|
|
237
228
|
}
|
|
238
229
|
|
|
239
230
|
if (needsToSign) {
|
|
@@ -376,54 +367,3 @@ export class XverseSigner extends CustomKeypair {
|
|
|
376
367
|
return nonDuplicate;
|
|
377
368
|
}
|
|
378
369
|
}
|
|
379
|
-
|
|
380
|
-
// Helper functions
|
|
381
|
-
function isTaprootInput(input: PsbtInput): boolean {
|
|
382
|
-
if (input.tapInternalKey || input.tapKeySig || input.tapScriptSig || input.tapLeafScript) {
|
|
383
|
-
return true;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
if (input.witnessUtxo) {
|
|
387
|
-
const script = input.witnessUtxo.script;
|
|
388
|
-
return script.length === 34 && script[0] === opcodes.OP_1 && script[1] === 0x20;
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
return false;
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
function getInputRelevantScript(input: PsbtInput): Buffer | null {
|
|
395
|
-
if (input.redeemScript) {
|
|
396
|
-
return input.redeemScript;
|
|
397
|
-
}
|
|
398
|
-
if (input.witnessScript) {
|
|
399
|
-
return input.witnessScript;
|
|
400
|
-
}
|
|
401
|
-
if (input.witnessUtxo) {
|
|
402
|
-
return input.witnessUtxo.script;
|
|
403
|
-
}
|
|
404
|
-
if (input.nonWitnessUtxo) {
|
|
405
|
-
// Additional logic can be added here if needed
|
|
406
|
-
return null;
|
|
407
|
-
}
|
|
408
|
-
return null;
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
function pubkeyInScript(pubkey: Buffer, script: Buffer): boolean {
|
|
412
|
-
return pubkeyPositionInScript(pubkey, script) !== -1;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
function pubkeyPositionInScript(pubkey: Buffer, script: Buffer): number {
|
|
416
|
-
const pubkeyHash = bitCrypto.hash160(pubkey);
|
|
417
|
-
const pubkeyXOnly = toXOnly(pubkey);
|
|
418
|
-
|
|
419
|
-
const decompiled = bitScript.decompile(script);
|
|
420
|
-
if (decompiled === null) throw new Error('Unknown script error');
|
|
421
|
-
|
|
422
|
-
return decompiled.findIndex((element) => {
|
|
423
|
-
if (typeof element === 'number') return false;
|
|
424
|
-
return (
|
|
425
|
-
Buffer.isBuffer(element) &&
|
|
426
|
-
(element.equals(pubkey) || element.equals(pubkeyHash) || element.equals(pubkeyXOnly))
|
|
427
|
-
);
|
|
428
|
-
});
|
|
429
|
-
}
|
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
crypto as bitCrypto,
|
|
3
|
+
Payment,
|
|
4
|
+
Psbt,
|
|
5
|
+
PsbtInput,
|
|
6
|
+
Signer,
|
|
7
|
+
Stack,
|
|
8
|
+
Taptree,
|
|
9
|
+
toXOnly,
|
|
10
|
+
} from '@btc-vision/bitcoin';
|
|
2
11
|
import { TransactionType } from '../enums/TransactionType.js';
|
|
3
12
|
import { TapLeafScript } from '../interfaces/Tap.js';
|
|
4
13
|
import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
|
|
5
|
-
import { crypto as bitCrypto, Payment, Psbt, PsbtInput, Signer, Stack } from '@btc-vision/bitcoin';
|
|
6
14
|
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
7
15
|
import { CustomGenerator } from '../../generators/builders/CustomGenerator.js';
|
|
8
16
|
import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
|
|
9
17
|
import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
10
18
|
import { AddressGenerator } from '../../generators/AddressGenerator.js';
|
|
11
|
-
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
12
19
|
import { ECPairInterface } from 'ecpair';
|
|
13
20
|
|
|
14
21
|
export interface ICustomTransactionParameters extends SharedInteractionParameters {
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import { TransactionType } from '../enums/TransactionType.js';
|
|
2
2
|
import { IDeploymentParameters } from '../interfaces/ITransactionParameters.js';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
crypto as bitCrypto,
|
|
5
|
+
Payment,
|
|
6
|
+
Psbt,
|
|
7
|
+
PsbtInput,
|
|
8
|
+
Signer,
|
|
9
|
+
Taptree,
|
|
10
|
+
toXOnly,
|
|
11
|
+
} from '@btc-vision/bitcoin';
|
|
4
12
|
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
5
|
-
import { Taptree } from '@btc-vision/bitcoin/src/types.js';
|
|
6
13
|
import { TapLeafScript } from '../interfaces/Tap.js';
|
|
7
14
|
import { DeploymentGenerator } from '../../generators/builders/DeploymentGenerator.js';
|
|
8
|
-
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
9
15
|
import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
10
16
|
import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
|
|
11
17
|
import { Compressor } from '../../bytecode/Compressor.js';
|
|
@@ -14,6 +20,8 @@ import { ECPairInterface } from 'ecpair';
|
|
|
14
20
|
import { Address } from '../../keypair/Address.js';
|
|
15
21
|
import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
|
|
16
22
|
|
|
23
|
+
const p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
|
|
24
|
+
|
|
17
25
|
export class DeploymentTransaction extends TransactionBuilder<TransactionType.DEPLOYMENT> {
|
|
18
26
|
public static readonly MAXIMUM_CONTRACT_SIZE = 128 * 1024;
|
|
19
27
|
public type: TransactionType.DEPLOYMENT = TransactionType.DEPLOYMENT;
|
|
@@ -90,6 +98,7 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
|
|
|
90
98
|
private readonly randomBytes: Buffer;
|
|
91
99
|
|
|
92
100
|
public constructor(parameters: IDeploymentParameters) {
|
|
101
|
+
// TODO: Add legacy deployment, this is only p2tr.
|
|
93
102
|
super(parameters);
|
|
94
103
|
|
|
95
104
|
this.bytecode = Compressor.compress(parameters.bytecode);
|
|
@@ -317,6 +326,7 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
|
|
|
317
326
|
throw new Error('Bytecode is required');
|
|
318
327
|
}
|
|
319
328
|
|
|
329
|
+
// Concatenate deployer pubkey, salt, and sha256(bytecode)
|
|
320
330
|
const deployerPubKey: Buffer = this.internalPubKeyToXOnly();
|
|
321
331
|
const salt: Buffer = bitCrypto.hash256(this.randomBytes);
|
|
322
332
|
const sha256OfBytecode: Buffer = bitCrypto.hash256(this.bytecode);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TransactionType } from '../enums/TransactionType.js';
|
|
2
2
|
import { IFundingTransactionParameters } from '../interfaces/ITransactionParameters.js';
|
|
3
|
-
import { Signer } from '@btc-vision/bitcoin';
|
|
3
|
+
import { opcodes, script, Signer } from '@btc-vision/bitcoin';
|
|
4
4
|
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
5
5
|
import { ECPairInterface } from 'ecpair';
|
|
6
6
|
|
|
@@ -29,9 +29,14 @@ export class FundingTransaction extends TransactionBuilder<TransactionType.FUNDI
|
|
|
29
29
|
if (this.splitInputsInto > 1) {
|
|
30
30
|
this.splitInputs(this.amount);
|
|
31
31
|
} else if (this.isPubKeyDestination) {
|
|
32
|
+
const pubKeyScript = script.compile([
|
|
33
|
+
Buffer.from(this.to.replace('0x', ''), 'hex'),
|
|
34
|
+
opcodes.OP_CHECKSIG,
|
|
35
|
+
]);
|
|
36
|
+
|
|
32
37
|
this.addOutput({
|
|
33
38
|
value: Number(this.amount),
|
|
34
|
-
script:
|
|
39
|
+
script: pubKeyScript,
|
|
35
40
|
});
|
|
36
41
|
} else {
|
|
37
42
|
this.addOutput({
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Taptree } from '@btc-vision/bitcoin
|
|
1
|
+
import { Taptree } from '@btc-vision/bitcoin';
|
|
2
2
|
import { TransactionType } from '../enums/TransactionType.js';
|
|
3
3
|
import { TapLeafScript } from '../interfaces/Tap.js';
|
|
4
4
|
import { IInteractionParameters } from '../interfaces/ITransactionParameters.js';
|
|
@@ -9,14 +9,14 @@ import {
|
|
|
9
9
|
script,
|
|
10
10
|
Signer,
|
|
11
11
|
TapScriptSig,
|
|
12
|
+
Taptree,
|
|
13
|
+
toXOnly,
|
|
12
14
|
} from '@btc-vision/bitcoin';
|
|
13
|
-
import { Taptree } from '@btc-vision/bitcoin/src/types.js';
|
|
14
15
|
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
15
16
|
import { TransactionType } from '../enums/TransactionType.js';
|
|
16
17
|
import { ITransactionParameters } from '../interfaces/ITransactionParameters.js';
|
|
17
18
|
import { MultiSignGenerator } from '../../generators/builders/MultiSignGenerator.js';
|
|
18
19
|
import { UTXO } from '../../utxo/interfaces/IUTXO.js';
|
|
19
|
-
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
20
20
|
import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
21
21
|
import { ECPairInterface } from 'ecpair';
|
|
22
22
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { address, Payment, Psbt, PsbtInput, Signer } from '@btc-vision/bitcoin';
|
|
2
|
-
import { Taptree } from '@btc-vision/bitcoin/src/types.js';
|
|
1
|
+
import { address, Payment, Psbt, PsbtInput, Signer, Taptree, toXOnly } from '@btc-vision/bitcoin';
|
|
3
2
|
import { ECPairInterface } from 'ecpair';
|
|
4
3
|
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
5
4
|
import { TransactionType } from '../enums/TransactionType.js';
|
|
@@ -8,7 +7,6 @@ import { SharedInteractionParameters } from '../interfaces/ITransactionParameter
|
|
|
8
7
|
import { Compressor } from '../../bytecode/Compressor.js';
|
|
9
8
|
import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
10
9
|
import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
|
|
11
|
-
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
12
10
|
import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
|
|
13
11
|
|
|
14
12
|
/**
|
|
@@ -8,8 +8,8 @@ import {
|
|
|
8
8
|
script,
|
|
9
9
|
Signer,
|
|
10
10
|
Transaction,
|
|
11
|
+
varuint,
|
|
11
12
|
} from '@btc-vision/bitcoin';
|
|
12
|
-
import { varuint } from '@btc-vision/bitcoin/src/bufferutils.js';
|
|
13
13
|
import * as ecc from '@bitcoinerlab/secp256k1';
|
|
14
14
|
import { UpdateInput } from '../interfaces/Tap.js';
|
|
15
15
|
import { TransactionType } from '../enums/TransactionType.js';
|
|
@@ -151,7 +151,9 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
|
|
|
151
151
|
this.utxos = parameters.utxos;
|
|
152
152
|
this.to = parameters.to || undefined;
|
|
153
153
|
|
|
154
|
-
this.isPubKeyDestination = this.to
|
|
154
|
+
this.isPubKeyDestination = this.to
|
|
155
|
+
? AddressVerificator.isValidPublicKey(this.to, this.network)
|
|
156
|
+
: false;
|
|
155
157
|
|
|
156
158
|
this.optionalOutputs = parameters.optionalOutputs;
|
|
157
159
|
|
|
@@ -471,6 +473,16 @@ export abstract class TransactionBuilder<T extends TransactionType> extends Twea
|
|
|
471
473
|
address: this.from,
|
|
472
474
|
tapInternalKey: this.internalPubKeyToXOnly(),
|
|
473
475
|
});
|
|
476
|
+
} else if (AddressVerificator.isValidPublicKey(this.from, this.network)) {
|
|
477
|
+
const pubKeyScript = script.compile([
|
|
478
|
+
Buffer.from(this.from.replace('0x', ''), 'hex'),
|
|
479
|
+
opcodes.OP_CHECKSIG,
|
|
480
|
+
]);
|
|
481
|
+
|
|
482
|
+
await this.setFeeOutput({
|
|
483
|
+
value: Number(sendBackAmount),
|
|
484
|
+
script: pubKeyScript,
|
|
485
|
+
});
|
|
474
486
|
} else {
|
|
475
487
|
await this.setFeeOutput({
|
|
476
488
|
value: Number(sendBackAmount),
|