@btc-vision/transaction 1.0.85 → 1.0.86
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/.gitattributes +2 -2
- package/browser/_version.d.ts +1 -1
- package/browser/index.js +1 -1
- package/browser/keypair/Wallet.d.ts +3 -0
- package/browser/transaction/builders/TapUnwarpTransaction.d.ts +40 -40
- package/browser/transaction/builders/UnwarpTransaction.d.ts +34 -34
- package/browser/utxo/UTXOManager.d.ts +7 -7
- package/build/Utils.d.ts +0 -0
- package/build/Utils.js +1 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/consensus/metadata/RoswsellConsensus.d.ts +2 -0
- package/build/consensus/metadata/RoswsellConsensus.js +4 -0
- package/build/contracts/ContractMetadataManager.d.ts +0 -0
- package/build/contracts/ContractMetadataManager.js +1 -0
- package/build/generators/OPNetAddressGenerator.d.ts +0 -0
- package/build/generators/OPNetAddressGenerator.js +1 -0
- package/build/generators/builders/UnwrapGenerator.d.ts +8 -0
- package/build/generators/builders/UnwrapGenerator.js +79 -0
- package/build/keypair/Wallet.d.ts +3 -0
- package/build/keypair/Wallet.js +8 -0
- package/build/keypair/interfaces/GeneratedWallet.d.ts +5 -0
- package/build/keypair/interfaces/GeneratedWallet.js +1 -0
- package/build/metadata/CommonContracts.d.ts +6 -0
- package/build/metadata/CommonContracts.js +5 -0
- package/build/metadata/ContractMetadataManager.d.ts +1 -0
- package/build/metadata/ContractMetadataManager.js +9 -0
- package/build/metadata/contracts/ContractBase.d.ts +9 -0
- package/build/metadata/contracts/ContractBase.js +13 -0
- package/build/metadata/contracts/ContractBaseMetadata.d.ts +9 -0
- package/build/metadata/contracts/ContractBaseMetadata.js +13 -0
- package/build/metadata/contracts/ContractMetadataManager.d.ts +0 -0
- package/build/metadata/contracts/ContractMetadataManager.js +1 -0
- package/build/network/NetworkConverter.d.ts +0 -0
- package/build/network/NetworkConverter.js +14 -0
- package/build/scripts/Regtest.d.ts +2 -0
- package/build/scripts/Regtest.js +15 -0
- package/build/scripts/test.d.ts +1 -0
- package/build/scripts/test.js +74 -0
- package/build/signer/Regtest.d.ts +2 -0
- package/build/signer/Regtest.js +15 -0
- package/build/tests/Regtest.d.ts +3 -0
- package/build/tests/Regtest.js +29 -0
- package/build/tests/adaptPSBT.d.ts +1 -0
- package/build/tests/adaptPSBT.js +44 -0
- package/build/tests/btc/send.d.ts +1 -0
- package/build/tests/btc/send.js +35 -0
- package/build/tests/btc/transfer.d.ts +1 -0
- package/build/tests/btc/transfer.js +35 -0
- package/build/tests/createPairReg.d.ts +1 -0
- package/build/tests/createPairReg.js +73 -0
- package/build/tests/deploy/deployMoto.d.ts +4 -0
- package/build/tests/deploy/deployMoto.js +89 -0
- package/build/tests/deploy/deployPool.d.ts +1 -0
- package/build/tests/deploy/deployPool.js +5 -0
- package/build/tests/deploy/deployStep1.d.ts +1 -0
- package/build/tests/deploy/deployStep1.js +5 -0
- package/build/tests/deploy/deployStep2.d.ts +1 -0
- package/build/tests/deploy/deployStep2.js +5 -0
- package/build/tests/deploy/deployStep3.d.ts +1 -0
- package/build/tests/deploy/deployStep3.js +5 -0
- package/build/tests/deploy.d.ts +1 -0
- package/build/tests/deploy.js +41 -0
- package/build/tests/deployMotoRegStep1.d.ts +1 -0
- package/build/tests/deployMotoRegStep1.js +85 -0
- package/build/tests/deployReg.d.ts +1 -0
- package/build/tests/deployReg.js +85 -0
- package/build/tests/factory/createPairReg.d.ts +1 -0
- package/build/tests/factory/createPairReg.js +13 -0
- package/build/tests/gen.d.ts +1 -0
- package/build/tests/gen.js +19 -0
- package/build/tests/interaction.d.ts +5 -0
- package/build/tests/interaction.js +62 -0
- package/build/tests/massWrapReg.d.ts +1 -0
- package/build/tests/massWrapReg.js +105 -0
- package/build/tests/mineReg.d.ts +1 -0
- package/build/tests/mineReg.js +19 -0
- package/build/tests/moto/airdropToken.d.ts +1 -0
- package/build/tests/moto/airdropToken.js +21 -0
- package/build/tests/moto/airdropTokens.d.ts +1 -0
- package/build/tests/moto/airdropTokens.js +60 -0
- package/build/tests/moto/allowance.d.ts +1 -0
- package/build/tests/moto/allowance.js +6 -0
- package/build/tests/moto/approve.d.ts +1 -0
- package/build/tests/moto/approve.js +10 -0
- package/build/tests/moto/approveWBTC.d.ts +1 -0
- package/build/tests/moto/approveWBTC.js +12 -0
- package/build/tests/moto/balanceOf.d.ts +1 -0
- package/build/tests/moto/balanceOf.js +12 -0
- package/build/tests/moto/transfer.d.ts +1 -0
- package/build/tests/moto/transfer.js +16 -0
- package/build/tests/motoswap/airdropToken.d.ts +11 -0
- package/build/tests/motoswap/airdropToken.js +36 -0
- package/build/tests/motoswap/deployMoto.d.ts +4 -0
- package/build/tests/motoswap/deployMoto.js +89 -0
- package/build/tests/motoswap/deployMotoRegStep1.d.ts +1 -0
- package/build/tests/motoswap/deployMotoRegStep1.js +91 -0
- package/build/tests/motoswap/deployMotoRegStep2.d.ts +1 -0
- package/build/tests/motoswap/deployMotoRegStep2.js +91 -0
- package/build/tests/motoswap/deployPool.d.ts +1 -0
- package/build/tests/motoswap/deployPool.js +5 -0
- package/build/tests/motoswap/deployStep1.d.ts +1 -0
- package/build/tests/motoswap/deployStep1.js +5 -0
- package/build/tests/motoswap/deployStep2.d.ts +1 -0
- package/build/tests/motoswap/deployStep2.js +5 -0
- package/build/tests/motoswap/deployStep3.d.ts +1 -0
- package/build/tests/motoswap/deployStep3.js +5 -0
- package/build/tests/motoswap/interaction.d.ts +3 -0
- package/build/tests/motoswap/interaction.js +63 -0
- package/build/tests/motoswap/routerAddLiquidity.d.ts +11 -0
- package/build/tests/motoswap/routerAddLiquidity.js +35 -0
- package/build/tests/motoswap-router/addLiquidity.d.ts +11 -0
- package/build/tests/motoswap-router/addLiquidity.js +36 -0
- package/build/tests/motoswap-router/deployMoto.d.ts +4 -0
- package/build/tests/motoswap-router/deployMoto.js +89 -0
- package/build/tests/motoswap-router/deployPool.d.ts +1 -0
- package/build/tests/motoswap-router/deployPool.js +5 -0
- package/build/tests/motoswap-router/deployStep1.d.ts +1 -0
- package/build/tests/motoswap-router/deployStep1.js +5 -0
- package/build/tests/motoswap-router/deployStep2.d.ts +1 -0
- package/build/tests/motoswap-router/deployStep2.js +5 -0
- package/build/tests/motoswap-router/deployStep3.d.ts +1 -0
- package/build/tests/motoswap-router/deployStep3.js +5 -0
- package/build/tests/motoswap-router/getAmountsOut.d.ts +5 -0
- package/build/tests/motoswap-router/getAmountsOut.js +34 -0
- package/build/tests/motoswap-router/routerAddLiquidity.d.ts +11 -0
- package/build/tests/motoswap-router/routerAddLiquidity.js +35 -0
- package/build/tests/motoswap-router/swap.d.ts +8 -0
- package/build/tests/motoswap-router/swap.js +24 -0
- package/build/tests/multisign.d.ts +1 -0
- package/build/tests/multisign.js +47 -0
- package/build/tests/multisign2.d.ts +1 -0
- package/build/tests/multisign2.js +27 -0
- package/build/tests/pool/DecodePoolAddress.d.ts +6 -0
- package/build/tests/pool/DecodePoolAddress.js +12 -0
- package/build/tests/pool/decodeReserves.d.ts +5 -0
- package/build/tests/pool/decodeReserves.js +13 -0
- package/build/tests/pool/reserves.d.ts +1 -0
- package/build/tests/pool/reserves.js +18 -0
- package/build/tests/shared/Utils.d.ts +2 -0
- package/build/tests/shared/Utils.js +14 -0
- package/build/tests/shared/interaction.d.ts +7 -0
- package/build/tests/shared/interaction.js +85 -0
- package/build/tests/shared/tokens.d.ts +6 -0
- package/build/tests/shared/tokens.js +5 -0
- package/build/tests/stakeReg.d.ts +1 -0
- package/build/tests/stakeReg.js +73 -0
- package/build/tests/stakedReg.d.ts +1 -0
- package/build/tests/stakedReg.js +28 -0
- package/build/tests/test.d.ts +1 -0
- package/build/tests/test.js +51 -0
- package/build/tests/test2.d.ts +1 -0
- package/build/tests/test2.js +73 -0
- package/build/tests/testReg.d.ts +1 -0
- package/build/tests/testReg.js +91 -0
- package/build/tests/tokens.d.ts +6 -0
- package/build/tests/tokens.js +5 -0
- package/build/tests/totalRewardReg.d.ts +1 -0
- package/build/tests/totalRewardReg.js +28 -0
- package/build/tests/transfer.d.ts +1 -0
- package/build/tests/transfer.js +74 -0
- package/build/tests/transferReg.d.ts +1 -0
- package/build/tests/transferReg.js +74 -0
- package/build/tests/unStakeReg.d.ts +1 -0
- package/build/tests/unStakeReg.js +72 -0
- package/build/tests/unwrapReg.d.ts +1 -0
- package/build/tests/unwrapReg.js +61 -0
- package/build/tests/unwrapReg2.d.ts +1 -0
- package/build/tests/unwrapReg2.js +56 -0
- package/build/tests/unwrapRegSegwit.d.ts +1 -0
- package/build/tests/unwrapRegSegwit.js +83 -0
- package/build/tests/wbtc/approve.d.ts +1 -0
- package/build/tests/wbtc/approve.js +6 -0
- package/build/tests/wbtc/approveWBTC.d.ts +1 -0
- package/build/tests/wbtc/approveWBTC.js +12 -0
- package/build/tests/wbtc/massWrapReg.d.ts +1 -0
- package/build/tests/wbtc/massWrapReg.js +105 -0
- package/build/tests/wbtc/transfer.d.ts +1 -0
- package/build/tests/wbtc/transfer.js +16 -0
- package/build/tests/wbtc/transferReg.d.ts +1 -0
- package/build/tests/wbtc/transferReg.js +16 -0
- package/build/tests/wbtc/unStakeReg.d.ts +1 -0
- package/build/tests/wbtc/unStakeReg.js +72 -0
- package/build/tests/wbtc/unwrapReg.d.ts +1 -0
- package/build/tests/wbtc/unwrapReg.js +60 -0
- package/build/tests/wbtc/unwrapRegSegwit.d.ts +1 -0
- package/build/tests/wbtc/unwrapRegSegwit.js +83 -0
- package/build/tests/wbtc/withdrawalRequestReg.d.ts +1 -0
- package/build/tests/wbtc/withdrawalRequestReg.js +71 -0
- package/build/tests/wbtc/wrapReg.d.ts +1 -0
- package/build/tests/wbtc/wrapReg.js +65 -0
- package/build/tests/wbtc/wrapTest.d.ts +1 -0
- package/build/tests/wbtc/wrapTest.js +66 -0
- package/build/tests/withdrawalRequestReg.d.ts +1 -0
- package/build/tests/withdrawalRequestReg.js +71 -0
- package/build/tests/wrap.d.ts +1 -0
- package/build/tests/wrap.js +65 -0
- package/build/tests/wrapReg.d.ts +1 -0
- package/build/tests/wrapReg.js +68 -0
- package/build/tests/wrapTest.d.ts +1 -0
- package/build/tests/wrapTest.js +66 -0
- package/build/tests/wrapTestg.d.ts +1 -0
- package/build/tests/wrapTestg.js +66 -0
- package/build/tests/writers/allowance.d.ts +3 -0
- package/build/tests/writers/allowance.js +10 -0
- package/build/tests/writers/approve.d.ts +4 -0
- package/build/tests/writers/approve.js +11 -0
- package/build/transaction/TransactionBuilder.d.ts +60 -0
- package/build/transaction/TransactionBuilder.js +244 -0
- package/build/transaction/browser/BrowserSigner.d.ts +11 -0
- package/build/transaction/browser/BrowserSigner.js +10 -0
- package/build/transaction/browser/extensions/Unisat.d.ts +54 -0
- package/build/transaction/browser/extensions/Unisat.js +11 -0
- package/build/transaction/builders/GenericTransaction.d.ts +11 -0
- package/build/transaction/builders/GenericTransaction.js +23 -0
- package/build/transaction/builders/TapUnwarpTransaction.d.ts +37 -0
- package/build/transaction/builders/TapUnwarpTransaction.js +201 -0
- package/build/transaction/builders/UnwarpSegwitTransaction.d.ts +34 -0
- package/build/transaction/builders/UnwarpSegwitTransaction.js +184 -0
- package/build/transaction/builders/UnwarpTransaction.d.ts +35 -0
- package/build/transaction/builders/UnwarpTransaction.js +199 -0
- package/build/transaction/interfaces/ITransactions.d.ts +32 -0
- package/build/transaction/interfaces/ITransactions.js +1 -0
- package/build/utxo/IUTXO.d.ts +0 -0
- package/build/utxo/IUTXO.js +1 -0
- package/build/utxo/OPNetUtils.d.ts +7 -0
- package/build/utxo/OPNetUtils.js +47 -0
- package/build/utxo/UTXOManager.d.ts +7 -0
- package/build/utxo/UTXOManager.js +47 -0
- package/build/wbtc/BroadcastResponse.d.ts +0 -0
- package/build/wbtc/BroadcastResponse.js +1 -0
- package/gulpfile.js +152 -152
- package/package.json +109 -109
- package/src/_version.ts +1 -1
- package/src/consensus/Consensus.ts +36 -36
- package/src/consensus/ConsensusConfig.ts +39 -39
- package/src/crypto/crypto-browser.js +75 -75
- package/src/generators/AddressGenerator.ts +24 -24
- package/src/generators/Features.ts +5 -5
- package/src/generators/Generator.ts +75 -75
- package/src/generators/builders/CalldataGenerator.ts +148 -148
- package/src/generators/builders/DeploymentGenerator.ts +66 -66
- package/src/index.ts +4 -4
- package/src/keypair/AddressVerificator.ts +40 -40
- package/src/keypair/EcKeyPair.ts +282 -282
- package/src/keypair/Wallet.ts +120 -97
- package/src/keypair/interfaces/IWallet.ts +19 -19
- package/src/metadata/ContractBaseMetadata.ts +23 -23
- package/src/metadata/contracts/wBTC.ts +60 -60
- package/src/metadata/tokens.ts +135 -135
- package/src/network/NetworkInformation.ts +7 -7
- package/src/transaction/TransactionFactory.ts +496 -496
- package/src/transaction/browser/BrowserSignerBase.ts +37 -37
- package/src/transaction/browser/Web3Provider.ts +46 -46
- package/src/transaction/browser/extensions/UnisatSigner.ts +218 -218
- package/src/transaction/browser/types/Unisat.ts +97 -97
- package/src/transaction/builders/FundingTransaction.ts +40 -40
- package/src/transaction/builders/InteractionTransaction.ts +38 -38
- package/src/transaction/builders/SharedInteractionTransaction.ts +368 -368
- package/src/transaction/builders/TransactionBuilder.ts +665 -665
- package/src/transaction/builders/UnwrapSegwitTransaction.ts +365 -365
- package/src/transaction/builders/UnwrapTransaction.ts +507 -507
- package/src/transaction/builders/WrapTransaction.ts +346 -346
- package/src/transaction/interfaces/ITransactionParameters.ts +59 -59
- package/src/transaction/interfaces/Tap.ts +26 -26
- package/src/transaction/psbt/PSBTTypes.ts +3 -3
- package/src/transaction/shared/TweakedTransaction.ts +539 -539
- package/src/utxo/OPNetLimitedProvider.ts +244 -244
- package/src/utxo/interfaces/BroadcastResponse.ts +10 -10
- package/src/utxo/interfaces/IUTXO.ts +29 -29
- package/src/verification/TapscriptVerificator.ts +89 -89
- package/src/wbtc/Generate.ts +40 -40
- package/src/wbtc/UnwrapGeneration.ts +13 -13
- package/src/wbtc/WrappedGenerationParameters.ts +33 -33
- package/webpack.config.js +78 -78
- /package/build/generators/builders/{MultiSignGenerator.d.ts → MultisignGenerator.d.ts} +0 -0
- /package/build/generators/builders/{MultiSignGenerator.js → MultisignGenerator.js} +0 -0
- /package/build/generators/{Features.d.ts → features.d.ts} +0 -0
- /package/build/generators/{Features.js → features.js} +0 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ABICoder, BinaryWriter } from '@btc-vision/bsi-binary';
|
|
2
|
+
const abiCoder = new ABICoder();
|
|
3
|
+
const approveSelector = Number(`0x` + abiCoder.encodeSelector('approve'));
|
|
4
|
+
export const MAX_UINT256 = 2n ** 256n - 1n;
|
|
5
|
+
export function approve(spender, amount = MAX_UINT256) {
|
|
6
|
+
const calldata = new BinaryWriter();
|
|
7
|
+
calldata.writeSelector(approveSelector);
|
|
8
|
+
calldata.writeAddress(spender);
|
|
9
|
+
calldata.writeU256(amount);
|
|
10
|
+
return Buffer.from(calldata.getBuffer());
|
|
11
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Logger } from '@btc-vision/bsi-common';
|
|
3
|
+
import { Network, Payment, Psbt, Signer, Transaction } from 'bitcoinjs-lib';
|
|
4
|
+
import { PsbtInputExtended, PsbtOutputExtended, UpdateInput } from './interfaces/Tap.js';
|
|
5
|
+
import { TransactionType } from './enums/TransactionType.js';
|
|
6
|
+
import { ITransactionParameters } from './interfaces/ITransactionParameters.js';
|
|
7
|
+
import { Address } from '@btc-vision/bsi-binary';
|
|
8
|
+
import { UTXO } from '../utxo/interfaces/IUTXO.js';
|
|
9
|
+
export declare abstract class TransactionBuilder<T extends TransactionType> extends Logger {
|
|
10
|
+
protected static readonly LOCK_LEAF_SCRIPT: Buffer;
|
|
11
|
+
protected static readonly MINIMUM_DUST: bigint;
|
|
12
|
+
abstract readonly type: T;
|
|
13
|
+
readonly logColor: string;
|
|
14
|
+
transactionFee: bigint;
|
|
15
|
+
protected readonly transaction: Psbt;
|
|
16
|
+
protected readonly inputs: PsbtInputExtended[];
|
|
17
|
+
protected readonly updateInputs: UpdateInput[];
|
|
18
|
+
protected readonly outputs: PsbtOutputExtended[];
|
|
19
|
+
protected feeOutput: PsbtOutputExtended | null;
|
|
20
|
+
protected signed: boolean;
|
|
21
|
+
protected tapData: Payment | null;
|
|
22
|
+
protected scriptData: Payment | null;
|
|
23
|
+
protected totalInputAmount: bigint;
|
|
24
|
+
protected readonly signer: Signer;
|
|
25
|
+
protected readonly network: Network;
|
|
26
|
+
protected readonly feeRate: number;
|
|
27
|
+
protected readonly priorityFee: bigint;
|
|
28
|
+
protected readonly utxos: UTXO[];
|
|
29
|
+
protected to: Address | null;
|
|
30
|
+
private _maximumFeeRate;
|
|
31
|
+
protected constructor(parameters: ITransactionParameters);
|
|
32
|
+
setDestinationAddress(address: Address): void;
|
|
33
|
+
setMaximumFeeRate(feeRate: number): void;
|
|
34
|
+
signTransaction(): string | null;
|
|
35
|
+
getTransaction(): Transaction;
|
|
36
|
+
getScriptAddress(): string;
|
|
37
|
+
getTapAddress(): string;
|
|
38
|
+
addInput(input: PsbtInputExtended): void;
|
|
39
|
+
addOutput(output: PsbtOutputExtended): void;
|
|
40
|
+
protected calculateTotalUTXOAmount(): bigint;
|
|
41
|
+
protected calculateTotalVOutAmount(): bigint;
|
|
42
|
+
protected addInputsFromUTXO(): void;
|
|
43
|
+
protected witnessStackToScriptWitness(witness: Buffer[]): Buffer;
|
|
44
|
+
protected internalInit(): void;
|
|
45
|
+
protected abstract buildTransaction(to?: Address): void;
|
|
46
|
+
protected generateScriptAddress(): Payment;
|
|
47
|
+
protected generateTapData(): Payment;
|
|
48
|
+
protected updateInput(input: UpdateInput): void;
|
|
49
|
+
protected getWitness(): Buffer;
|
|
50
|
+
protected getTapOutput(): Buffer;
|
|
51
|
+
protected getInputs(): PsbtInputExtended[];
|
|
52
|
+
protected getOutputs(): PsbtOutputExtended[];
|
|
53
|
+
protected verifyUTXOValidity(): void;
|
|
54
|
+
protected setFeeOutput(output: PsbtOutputExtended): void;
|
|
55
|
+
protected abstract getSignerKey(): Signer;
|
|
56
|
+
protected internalPubKeyToXOnly(): Buffer;
|
|
57
|
+
protected signInputs(transaction: Psbt): void;
|
|
58
|
+
private internalBuildTransaction;
|
|
59
|
+
private estimateTransactionFees;
|
|
60
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { Logger } from '@btc-vision/bsi-common';
|
|
2
|
+
import { initEccLib, opcodes, payments, Psbt, script, } from 'bitcoinjs-lib';
|
|
3
|
+
import { varuint } from 'bitcoinjs-lib/src/bufferutils.js';
|
|
4
|
+
import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
|
|
5
|
+
import * as ecc from 'tiny-secp256k1';
|
|
6
|
+
import { EcKeyPair } from '../keypair/EcKeyPair.js';
|
|
7
|
+
initEccLib(ecc);
|
|
8
|
+
export class TransactionBuilder extends Logger {
|
|
9
|
+
static LOCK_LEAF_SCRIPT = script.compile([opcodes.OP_0]);
|
|
10
|
+
static MINIMUM_DUST = 330n;
|
|
11
|
+
logColor = '#785def';
|
|
12
|
+
transactionFee = 0n;
|
|
13
|
+
transaction;
|
|
14
|
+
inputs = [];
|
|
15
|
+
updateInputs = [];
|
|
16
|
+
outputs = [];
|
|
17
|
+
feeOutput = null;
|
|
18
|
+
signed = false;
|
|
19
|
+
tapData = null;
|
|
20
|
+
scriptData = null;
|
|
21
|
+
totalInputAmount;
|
|
22
|
+
signer;
|
|
23
|
+
network;
|
|
24
|
+
feeRate;
|
|
25
|
+
priorityFee;
|
|
26
|
+
utxos;
|
|
27
|
+
to = null;
|
|
28
|
+
_maximumFeeRate = 1000000;
|
|
29
|
+
constructor(parameters) {
|
|
30
|
+
super();
|
|
31
|
+
this.signer = parameters.signer;
|
|
32
|
+
this.network = parameters.network;
|
|
33
|
+
this.feeRate = parameters.feeRate;
|
|
34
|
+
this.priorityFee = parameters.priorityFee;
|
|
35
|
+
this.utxos = parameters.utxos;
|
|
36
|
+
this.to = parameters.to;
|
|
37
|
+
this.totalInputAmount = this.calculateTotalUTXOAmount();
|
|
38
|
+
const totalVOut = this.calculateTotalVOutAmount();
|
|
39
|
+
if (totalVOut < this.totalInputAmount) {
|
|
40
|
+
throw new Error(`Vout value is less than the value to send`);
|
|
41
|
+
}
|
|
42
|
+
if (this.totalInputAmount < TransactionBuilder.MINIMUM_DUST) {
|
|
43
|
+
throw new Error(`Value is less than the minimum dust`);
|
|
44
|
+
}
|
|
45
|
+
this.transaction = new Psbt({
|
|
46
|
+
network: this.network,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
setDestinationAddress(address) {
|
|
50
|
+
this.to = address;
|
|
51
|
+
}
|
|
52
|
+
setMaximumFeeRate(feeRate) {
|
|
53
|
+
this._maximumFeeRate = feeRate;
|
|
54
|
+
}
|
|
55
|
+
signTransaction() {
|
|
56
|
+
if (!this.to)
|
|
57
|
+
throw new Error('Transaction must have a recipient');
|
|
58
|
+
if (!EcKeyPair.verifyContractAddress(this.to, this.network)) {
|
|
59
|
+
throw new Error('Invalid contract address. The contract address must be a taproot address.');
|
|
60
|
+
}
|
|
61
|
+
if (this.signed)
|
|
62
|
+
throw new Error('Transaction is already signed');
|
|
63
|
+
this.signed = true;
|
|
64
|
+
this.buildTransaction(this.to);
|
|
65
|
+
const builtTx = this.internalBuildTransaction(this.transaction);
|
|
66
|
+
if (builtTx) {
|
|
67
|
+
return this.transaction.extractTransaction(false).toHex();
|
|
68
|
+
}
|
|
69
|
+
throw new Error('Could not sign transaction');
|
|
70
|
+
}
|
|
71
|
+
getTransaction() {
|
|
72
|
+
return this.transaction.extractTransaction(false);
|
|
73
|
+
}
|
|
74
|
+
getScriptAddress() {
|
|
75
|
+
if (!this.scriptData || !this.scriptData.address) {
|
|
76
|
+
throw new Error('Tap data is required');
|
|
77
|
+
}
|
|
78
|
+
return this.scriptData.address;
|
|
79
|
+
}
|
|
80
|
+
getTapAddress() {
|
|
81
|
+
if (!this.tapData || !this.tapData.address) {
|
|
82
|
+
throw new Error('Tap data is required');
|
|
83
|
+
}
|
|
84
|
+
return this.tapData.address;
|
|
85
|
+
}
|
|
86
|
+
addInput(input) {
|
|
87
|
+
this.inputs.push(input);
|
|
88
|
+
}
|
|
89
|
+
addOutput(output) {
|
|
90
|
+
this.outputs.push(output);
|
|
91
|
+
}
|
|
92
|
+
calculateTotalUTXOAmount() {
|
|
93
|
+
let total = 0n;
|
|
94
|
+
for (let utxo of this.utxos) {
|
|
95
|
+
total += utxo.value;
|
|
96
|
+
}
|
|
97
|
+
return total;
|
|
98
|
+
}
|
|
99
|
+
calculateTotalVOutAmount() {
|
|
100
|
+
let total = 0n;
|
|
101
|
+
for (let utxo of this.utxos) {
|
|
102
|
+
total += utxo.value;
|
|
103
|
+
}
|
|
104
|
+
return total;
|
|
105
|
+
}
|
|
106
|
+
addInputsFromUTXO() {
|
|
107
|
+
for (let utxo of this.utxos) {
|
|
108
|
+
const input = {
|
|
109
|
+
hash: utxo.transactionId,
|
|
110
|
+
index: utxo.outputIndex,
|
|
111
|
+
witnessUtxo: {
|
|
112
|
+
value: Number(utxo.value),
|
|
113
|
+
script: Buffer.from(utxo.scriptPubKey.hex, 'hex'),
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
this.addInput(input);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
witnessStackToScriptWitness(witness) {
|
|
120
|
+
let buffer = Buffer.allocUnsafe(0);
|
|
121
|
+
function writeSlice(slice) {
|
|
122
|
+
buffer = Buffer.concat([buffer, Buffer.from(slice)]);
|
|
123
|
+
}
|
|
124
|
+
function writeVarInt(i) {
|
|
125
|
+
const currentLen = buffer.length;
|
|
126
|
+
const varintLen = varuint.encodingLength(i);
|
|
127
|
+
buffer = Buffer.concat([buffer, Buffer.allocUnsafe(varintLen)]);
|
|
128
|
+
varuint.encode(i, buffer, currentLen);
|
|
129
|
+
}
|
|
130
|
+
function writeVarSlice(slice) {
|
|
131
|
+
writeVarInt(slice.length);
|
|
132
|
+
writeSlice(slice);
|
|
133
|
+
}
|
|
134
|
+
function writeVector(vector) {
|
|
135
|
+
writeVarInt(vector.length);
|
|
136
|
+
vector.forEach(writeVarSlice);
|
|
137
|
+
}
|
|
138
|
+
writeVector(witness);
|
|
139
|
+
return buffer;
|
|
140
|
+
}
|
|
141
|
+
internalInit() {
|
|
142
|
+
this.verifyUTXOValidity();
|
|
143
|
+
this.scriptData = payments.p2tr(this.generateScriptAddress());
|
|
144
|
+
this.tapData = payments.p2tr(this.generateTapData());
|
|
145
|
+
}
|
|
146
|
+
generateScriptAddress() {
|
|
147
|
+
return {
|
|
148
|
+
internalPubkey: this.internalPubKeyToXOnly(),
|
|
149
|
+
network: this.network,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
generateTapData() {
|
|
153
|
+
return {
|
|
154
|
+
internalPubkey: this.internalPubKeyToXOnly(),
|
|
155
|
+
network: this.network,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
updateInput(input) {
|
|
159
|
+
this.updateInputs.push(input);
|
|
160
|
+
}
|
|
161
|
+
getWitness() {
|
|
162
|
+
if (!this.tapData || !this.tapData.witness) {
|
|
163
|
+
throw new Error('Witness is required');
|
|
164
|
+
}
|
|
165
|
+
if (this.tapData.witness.length === 0) {
|
|
166
|
+
throw new Error('Witness is empty');
|
|
167
|
+
}
|
|
168
|
+
return this.tapData.witness[this.tapData.witness.length - 1];
|
|
169
|
+
}
|
|
170
|
+
getTapOutput() {
|
|
171
|
+
if (!this.tapData || !this.tapData.output) {
|
|
172
|
+
throw new Error('Tap data is required');
|
|
173
|
+
}
|
|
174
|
+
return this.tapData.output;
|
|
175
|
+
}
|
|
176
|
+
getInputs() {
|
|
177
|
+
return this.inputs;
|
|
178
|
+
}
|
|
179
|
+
getOutputs() {
|
|
180
|
+
if (!this.feeOutput)
|
|
181
|
+
throw new Error('Fee output is required');
|
|
182
|
+
const outputs = [...this.outputs];
|
|
183
|
+
outputs.push(this.feeOutput);
|
|
184
|
+
return outputs;
|
|
185
|
+
}
|
|
186
|
+
verifyUTXOValidity() {
|
|
187
|
+
for (let utxo of this.utxos) {
|
|
188
|
+
if (!utxo.scriptPubKey) {
|
|
189
|
+
throw new Error('Address is required');
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
setFeeOutput(output) {
|
|
194
|
+
this.feeOutput = output;
|
|
195
|
+
const fee = this.estimateTransactionFees();
|
|
196
|
+
if (fee > BigInt(output.value)) {
|
|
197
|
+
throw new Error('Insufficient funds');
|
|
198
|
+
}
|
|
199
|
+
this.feeOutput.value = this.feeOutput.value - Number(fee);
|
|
200
|
+
}
|
|
201
|
+
internalPubKeyToXOnly() {
|
|
202
|
+
return toXOnly(this.signer.publicKey);
|
|
203
|
+
}
|
|
204
|
+
signInputs(transaction) {
|
|
205
|
+
transaction.signAllInputs(this.getSignerKey());
|
|
206
|
+
transaction.finalizeAllInputs();
|
|
207
|
+
}
|
|
208
|
+
internalBuildTransaction(transaction) {
|
|
209
|
+
const inputs = this.getInputs();
|
|
210
|
+
const outputs = this.getOutputs();
|
|
211
|
+
transaction.setMaximumFeeRate(this._maximumFeeRate);
|
|
212
|
+
transaction.addInputs(inputs);
|
|
213
|
+
for (let i = 0; i < this.updateInputs.length; i++) {
|
|
214
|
+
transaction.updateInput(i, this.updateInputs[i]);
|
|
215
|
+
}
|
|
216
|
+
transaction.addOutputs(outputs);
|
|
217
|
+
try {
|
|
218
|
+
this.signInputs(transaction);
|
|
219
|
+
this.transactionFee = BigInt(transaction.getFee());
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
222
|
+
catch (e) {
|
|
223
|
+
const err = e;
|
|
224
|
+
this.error(`[internalBuildTransaction] Something went wrong while getting building the transaction: ${err.stack}`);
|
|
225
|
+
}
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
estimateTransactionFees() {
|
|
229
|
+
const fakeTx = new Psbt({
|
|
230
|
+
network: this.network,
|
|
231
|
+
});
|
|
232
|
+
const builtTx = this.internalBuildTransaction(fakeTx);
|
|
233
|
+
if (builtTx) {
|
|
234
|
+
const tx = fakeTx.extractTransaction(false);
|
|
235
|
+
const size = tx.virtualSize();
|
|
236
|
+
const fee = this.feeRate * size + 1;
|
|
237
|
+
this.log(`Transaction fee estimated to: ${fee} - ${fakeTx.getFeeRate()}`);
|
|
238
|
+
return BigInt(Math.ceil(fee));
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
throw new Error(`Could not build transaction to estimate fee. Something went wrong while building the transaction.`);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Psbt, Transaction } from 'bitcoinjs-lib';
|
|
2
|
+
import { Unisat } from './types/Unisat.js';
|
|
3
|
+
declare global {
|
|
4
|
+
interface Window {
|
|
5
|
+
unisat?: Unisat;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export declare abstract class BrowserSigner {
|
|
9
|
+
signTransaction(transaction: Psbt): Promise<Transaction>;
|
|
10
|
+
generateSigner(): Promise<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Address } from '@btc-vision/bsi-binary';
|
|
2
|
+
export declare enum UnisatNetwork {
|
|
3
|
+
testnet = "testnet",
|
|
4
|
+
mainnet = "livenet",
|
|
5
|
+
regtest = "regtest"
|
|
6
|
+
}
|
|
7
|
+
export interface Balance {
|
|
8
|
+
readonly confirmed: number;
|
|
9
|
+
readonly unconfirmed: number;
|
|
10
|
+
readonly total: number;
|
|
11
|
+
}
|
|
12
|
+
export declare enum MessageType {
|
|
13
|
+
ecdsa = "ecdsa",
|
|
14
|
+
bip322 = "bip322-simple"
|
|
15
|
+
}
|
|
16
|
+
interface ToSignInputBase {
|
|
17
|
+
readonly index: number;
|
|
18
|
+
readonly sighashTypes?: number[];
|
|
19
|
+
readonly disableTweakSigner?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export interface ToSignInputPublicKey extends ToSignInputBase {
|
|
22
|
+
readonly publicKey: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ToSignInputAddress extends ToSignInputBase {
|
|
25
|
+
readonly address: Address;
|
|
26
|
+
}
|
|
27
|
+
export type ToSignInput = ToSignInputPublicKey | ToSignInputAddress;
|
|
28
|
+
export interface PsbtSignatureOptions {
|
|
29
|
+
readonly autoFinalized?: boolean;
|
|
30
|
+
readonly toSignInputs?: ToSignInput[];
|
|
31
|
+
}
|
|
32
|
+
export interface Unisat {
|
|
33
|
+
sendBitcoin(toAddress: Address, satoshis: number, options: {
|
|
34
|
+
feeRate: number;
|
|
35
|
+
}): Promise<string>;
|
|
36
|
+
requestAccounts(): Promise<string[]>;
|
|
37
|
+
getNetwork(): Promise<UnisatNetwork>;
|
|
38
|
+
getAccounts(): Promise<string[]>;
|
|
39
|
+
switchNetwork(network: UnisatNetwork): Promise<void>;
|
|
40
|
+
getPublicKey(): Promise<string>;
|
|
41
|
+
getBalance(): Promise<Balance>;
|
|
42
|
+
signMessage(message: string, type?: MessageType): Promise<string>;
|
|
43
|
+
pushTx(options: {
|
|
44
|
+
rawtx: string;
|
|
45
|
+
}): Promise<string>;
|
|
46
|
+
signPsbt(psbtHex: string, psbtOptions: PsbtSignatureOptions): Promise<string>;
|
|
47
|
+
signPsbts(psbtHex: string[], psbtOptions: PsbtSignatureOptions): Promise<string[]>;
|
|
48
|
+
pushPsbt(psbtHex: string): Promise<string>;
|
|
49
|
+
on(event: 'accountsChanged', listener: (accounts: string[]) => void): void;
|
|
50
|
+
on(event: 'networkChanged', listener: (network: UnisatNetwork) => void): void;
|
|
51
|
+
removeListener(event: 'accountsChanged', listener: (accounts: string[]) => void): void;
|
|
52
|
+
removeListener(event: 'networkChanged', listener: (network: UnisatNetwork) => void): void;
|
|
53
|
+
}
|
|
54
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export var UnisatNetwork;
|
|
2
|
+
(function (UnisatNetwork) {
|
|
3
|
+
UnisatNetwork["testnet"] = "testnet";
|
|
4
|
+
UnisatNetwork["mainnet"] = "livenet";
|
|
5
|
+
UnisatNetwork["regtest"] = "regtest";
|
|
6
|
+
})(UnisatNetwork || (UnisatNetwork = {}));
|
|
7
|
+
export var MessageType;
|
|
8
|
+
(function (MessageType) {
|
|
9
|
+
MessageType["ecdsa"] = "ecdsa";
|
|
10
|
+
MessageType["bip322"] = "bip322-simple";
|
|
11
|
+
})(MessageType || (MessageType = {}));
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
2
|
+
import { TransactionType } from '../enums/TransactionType.js';
|
|
3
|
+
import { IFundingTransactionParameters } from '../interfaces/ITransactionParameters.js';
|
|
4
|
+
import { Signer } from 'bitcoinjs-lib';
|
|
5
|
+
export declare class FundingTransaction extends TransactionBuilder<TransactionType.FUNDING> {
|
|
6
|
+
readonly type: TransactionType.FUNDING;
|
|
7
|
+
protected childTransactionRequiredFees: bigint;
|
|
8
|
+
constructor(parameters: IFundingTransactionParameters);
|
|
9
|
+
protected buildTransaction(): void;
|
|
10
|
+
protected getSignerKey(): Signer;
|
|
11
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
2
|
+
import { TransactionType } from '../enums/TransactionType.js';
|
|
3
|
+
export class FundingTransaction extends TransactionBuilder {
|
|
4
|
+
type = TransactionType.FUNDING;
|
|
5
|
+
childTransactionRequiredFees;
|
|
6
|
+
constructor(parameters) {
|
|
7
|
+
super(parameters);
|
|
8
|
+
this.childTransactionRequiredFees = parameters.childTransactionRequiredFees;
|
|
9
|
+
this.internalInit();
|
|
10
|
+
}
|
|
11
|
+
buildTransaction() {
|
|
12
|
+
this.addInputsFromUTXO();
|
|
13
|
+
const amountSpent = this.getTransactionOPNetFee() + this.childTransactionRequiredFees;
|
|
14
|
+
this.setFeeOutput({
|
|
15
|
+
value: Number(amountSpent),
|
|
16
|
+
address: this.to,
|
|
17
|
+
});
|
|
18
|
+
this.addRefundOutput(amountSpent);
|
|
19
|
+
}
|
|
20
|
+
getSignerKey() {
|
|
21
|
+
return this.signer;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Taptree } from 'bitcoinjs-lib/src/types.js';
|
|
3
|
+
import { TransactionType } from '../enums/TransactionType.js';
|
|
4
|
+
import { IUnwrapParameters } from '../interfaces/ITransactionParameters.js';
|
|
5
|
+
import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
|
|
6
|
+
import bitcoin, { Payment, Psbt } from 'bitcoinjs-lib';
|
|
7
|
+
import { VaultUTXOs } from '../processor/PsbtTransaction.js';
|
|
8
|
+
import { PsbtInput } from 'bip174/src/lib/interfaces.js';
|
|
9
|
+
export declare class TapUnwrapTransaction extends SharedInteractionTransaction<TransactionType.WBTC_UNWRAP> {
|
|
10
|
+
private static readonly UNWRAP_SELECTOR;
|
|
11
|
+
type: TransactionType.WBTC_UNWRAP;
|
|
12
|
+
readonly amount: bigint;
|
|
13
|
+
protected readonly compiledTargetScript: Buffer;
|
|
14
|
+
protected readonly scriptTree: Taptree;
|
|
15
|
+
protected sighashTypes: number[];
|
|
16
|
+
protected readonly contractSecret: Buffer;
|
|
17
|
+
protected readonly vaultUTXOs: VaultUTXOs[];
|
|
18
|
+
private readonly wbtc;
|
|
19
|
+
private readonly calculatedSignHash;
|
|
20
|
+
constructor(parameters: IUnwrapParameters);
|
|
21
|
+
static generateBurnCalldata(amount: bigint): Buffer;
|
|
22
|
+
signPSBT(): Psbt;
|
|
23
|
+
mergeVaults(input: VaultUTXOs[]): void;
|
|
24
|
+
protected internalPubKeyToXOnly(): Buffer;
|
|
25
|
+
protected generateTapDataForInput(pubkeys: Buffer[], minimumSignatures: number): {
|
|
26
|
+
internalPubkey: Buffer;
|
|
27
|
+
network: bitcoin.Network;
|
|
28
|
+
scriptTree: Taptree;
|
|
29
|
+
redeem: Payment;
|
|
30
|
+
};
|
|
31
|
+
protected getScriptSolution(input: PsbtInput): Buffer[];
|
|
32
|
+
protected internalBuildTransaction(transaction: Psbt): boolean;
|
|
33
|
+
private addVaultUTXO;
|
|
34
|
+
private addVaultInputs;
|
|
35
|
+
private calculateOutputLeftAmountFromVaults;
|
|
36
|
+
private getVaultTotalOutputAmount;
|
|
37
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { TransactionType } from '../enums/TransactionType.js';
|
|
2
|
+
import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
|
|
3
|
+
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
4
|
+
import { ABICoder, BinaryWriter } from '@btc-vision/bsi-binary';
|
|
5
|
+
import { wBTC } from '../../metadata/contracts/wBTC.js';
|
|
6
|
+
import { payments } from 'bitcoinjs-lib';
|
|
7
|
+
import { EcKeyPair } from '../../keypair/EcKeyPair.js';
|
|
8
|
+
import { PsbtTransaction } from '../processor/PsbtTransaction.js';
|
|
9
|
+
import { MultiSignGenerator } from '../../generators/builders/MultiSignGenerator.js';
|
|
10
|
+
import { MultiSignTransaction } from './MultiSignTransaction.js';
|
|
11
|
+
import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
|
|
12
|
+
import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
|
|
13
|
+
const abiCoder = new ABICoder();
|
|
14
|
+
const numsPoint = Buffer.from('50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0', 'hex');
|
|
15
|
+
export class TapUnwrapTransaction extends SharedInteractionTransaction {
|
|
16
|
+
static UNWRAP_SELECTOR = Number('0x' + abiCoder.encodeSelector('burn'));
|
|
17
|
+
type = TransactionType.WBTC_UNWRAP;
|
|
18
|
+
amount;
|
|
19
|
+
compiledTargetScript;
|
|
20
|
+
scriptTree;
|
|
21
|
+
sighashTypes = [];
|
|
22
|
+
contractSecret;
|
|
23
|
+
vaultUTXOs;
|
|
24
|
+
wbtc;
|
|
25
|
+
calculatedSignHash = PsbtTransaction.calculateSignHash(this.sighashTypes);
|
|
26
|
+
constructor(parameters) {
|
|
27
|
+
if (parameters.amount < TransactionBuilder.MINIMUM_DUST) {
|
|
28
|
+
throw new Error('Amount is below dust limit');
|
|
29
|
+
}
|
|
30
|
+
parameters.disableAutoRefund = true;
|
|
31
|
+
parameters.calldata = TapUnwrapTransaction.generateBurnCalldata(parameters.amount);
|
|
32
|
+
super(parameters);
|
|
33
|
+
this.wbtc = new wBTC(parameters.network);
|
|
34
|
+
this.to = this.wbtc.getAddress();
|
|
35
|
+
this.vaultUTXOs = parameters.unwrapUTXOs;
|
|
36
|
+
this.amount = parameters.amount;
|
|
37
|
+
this.contractSecret = this.generateSecret();
|
|
38
|
+
this.calldataGenerator = new CalldataGenerator(toXOnly(this.signer.publicKey), this.scriptSignerXOnlyPubKey(), this.network);
|
|
39
|
+
this.compiledTargetScript = this.calldataGenerator.compile(this.calldata, this.contractSecret);
|
|
40
|
+
this.scriptTree = this.getScriptTree();
|
|
41
|
+
this.internalInit();
|
|
42
|
+
}
|
|
43
|
+
static generateBurnCalldata(amount) {
|
|
44
|
+
if (!amount)
|
|
45
|
+
throw new Error('Amount is required');
|
|
46
|
+
const bufWriter = new BinaryWriter();
|
|
47
|
+
bufWriter.writeSelector(TapUnwrapTransaction.UNWRAP_SELECTOR);
|
|
48
|
+
bufWriter.writeU256(amount);
|
|
49
|
+
return Buffer.from(bufWriter.getBuffer());
|
|
50
|
+
}
|
|
51
|
+
signPSBT() {
|
|
52
|
+
if (this.to && !EcKeyPair.verifyContractAddress(this.to, this.network)) {
|
|
53
|
+
throw new Error('Invalid contract address. The contract address must be a taproot address.');
|
|
54
|
+
}
|
|
55
|
+
if (!this.vaultUTXOs.length) {
|
|
56
|
+
throw new Error('No vault UTXOs provided');
|
|
57
|
+
}
|
|
58
|
+
this.buildTransaction();
|
|
59
|
+
this.ignoreSignatureError();
|
|
60
|
+
this.mergeVaults(this.vaultUTXOs);
|
|
61
|
+
const builtTx = this.internalBuildTransaction(this.transaction);
|
|
62
|
+
if (builtTx) {
|
|
63
|
+
return this.transaction;
|
|
64
|
+
}
|
|
65
|
+
throw new Error('Could not sign transaction');
|
|
66
|
+
}
|
|
67
|
+
mergeVaults(input) {
|
|
68
|
+
const firstVault = input[0];
|
|
69
|
+
if (!firstVault) {
|
|
70
|
+
throw new Error('No vaults provided');
|
|
71
|
+
}
|
|
72
|
+
const outputLeftAmount = this.calculateOutputLeftAmountFromVaults(input);
|
|
73
|
+
if (outputLeftAmount < 0) {
|
|
74
|
+
throw new Error(`Output left amount is negative ${outputLeftAmount} for vault ${firstVault.vault}`);
|
|
75
|
+
}
|
|
76
|
+
this.addOutput({
|
|
77
|
+
address: firstVault.vault,
|
|
78
|
+
value: Number(outputLeftAmount),
|
|
79
|
+
});
|
|
80
|
+
this.addOutput({
|
|
81
|
+
address: this.from,
|
|
82
|
+
value: Number(this.amount),
|
|
83
|
+
});
|
|
84
|
+
for (const vault of input) {
|
|
85
|
+
this.addVaultInputs(vault);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
internalPubKeyToXOnly() {
|
|
89
|
+
return toXOnly(numsPoint);
|
|
90
|
+
}
|
|
91
|
+
generateTapDataForInput(pubkeys, minimumSignatures) {
|
|
92
|
+
const compiledTargetScript = MultiSignGenerator.compile(pubkeys, minimumSignatures);
|
|
93
|
+
const scriptTree = [
|
|
94
|
+
{
|
|
95
|
+
output: compiledTargetScript,
|
|
96
|
+
version: 192,
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
output: MultiSignTransaction.LOCK_LEAF_SCRIPT,
|
|
100
|
+
version: 192,
|
|
101
|
+
},
|
|
102
|
+
];
|
|
103
|
+
const redeem = {
|
|
104
|
+
output: compiledTargetScript,
|
|
105
|
+
redeemVersion: 192,
|
|
106
|
+
};
|
|
107
|
+
return {
|
|
108
|
+
internalPubkey: this.internalPubKeyToXOnly(),
|
|
109
|
+
network: this.network,
|
|
110
|
+
scriptTree: scriptTree,
|
|
111
|
+
redeem: redeem,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
getScriptSolution(input) {
|
|
115
|
+
if (!input.tapScriptSig) {
|
|
116
|
+
throw new Error('Tap script signature is required');
|
|
117
|
+
}
|
|
118
|
+
return [
|
|
119
|
+
this.contractSecret,
|
|
120
|
+
toXOnly(this.signer.publicKey),
|
|
121
|
+
input.tapScriptSig[0].signature,
|
|
122
|
+
input.tapScriptSig[1].signature,
|
|
123
|
+
];
|
|
124
|
+
}
|
|
125
|
+
internalBuildTransaction(transaction) {
|
|
126
|
+
if (transaction.data.inputs.length === 0) {
|
|
127
|
+
const inputs = this.getInputs();
|
|
128
|
+
const outputs = this.getOutputs();
|
|
129
|
+
transaction.setMaximumFeeRate(this._maximumFeeRate);
|
|
130
|
+
transaction.addInputs(inputs);
|
|
131
|
+
for (let i = 0; i < this.updateInputs.length; i++) {
|
|
132
|
+
transaction.updateInput(i, this.updateInputs[i]);
|
|
133
|
+
}
|
|
134
|
+
transaction.addOutputs(outputs);
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
this.signInput(transaction, transaction.data.inputs[0], 0, this.scriptSigner);
|
|
138
|
+
this.signInput(transaction, transaction.data.inputs[0], 0);
|
|
139
|
+
try {
|
|
140
|
+
transaction.finalizeInput(0, this.customFinalizer);
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
console.log(e);
|
|
144
|
+
}
|
|
145
|
+
if (this.finalized) {
|
|
146
|
+
this.transactionFee = BigInt(transaction.getFee());
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
catch (e) {
|
|
151
|
+
const err = e;
|
|
152
|
+
this.error(`[internalBuildTransaction] Something went wrong while getting building the transaction: ${err.stack}`);
|
|
153
|
+
}
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
addVaultUTXO(utxo, pubkeys, minimumSignatures) {
|
|
157
|
+
const tapInput = this.generateTapDataForInput(pubkeys, minimumSignatures);
|
|
158
|
+
const tap = payments.p2tr(tapInput);
|
|
159
|
+
if (!tap.witness)
|
|
160
|
+
throw new Error('Failed to generate taproot witness');
|
|
161
|
+
this.disableRBF();
|
|
162
|
+
const controlBlock = tap.witness[tap.witness.length - 1];
|
|
163
|
+
const input = {
|
|
164
|
+
hash: utxo.hash,
|
|
165
|
+
index: utxo.outputIndex,
|
|
166
|
+
witnessUtxo: {
|
|
167
|
+
script: Buffer.from(utxo.output, 'base64'),
|
|
168
|
+
value: Number(utxo.value),
|
|
169
|
+
},
|
|
170
|
+
tapInternalKey: tapInput.internalPubkey,
|
|
171
|
+
sequence: this.sequence,
|
|
172
|
+
tapLeafScript: [
|
|
173
|
+
{
|
|
174
|
+
leafVersion: tapInput.redeem.redeemVersion,
|
|
175
|
+
script: tapInput.redeem.output,
|
|
176
|
+
controlBlock: controlBlock,
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
};
|
|
180
|
+
this.addInput(input);
|
|
181
|
+
}
|
|
182
|
+
addVaultInputs(vault) {
|
|
183
|
+
const pubKeys = vault.publicKeys.map((key) => Buffer.from(key, 'base64'));
|
|
184
|
+
for (const utxo of vault.utxos) {
|
|
185
|
+
this.addVaultUTXO(utxo, pubKeys, vault.minimum);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
calculateOutputLeftAmountFromVaults(vaults) {
|
|
189
|
+
const total = this.getVaultTotalOutputAmount(vaults);
|
|
190
|
+
return total - this.amount;
|
|
191
|
+
}
|
|
192
|
+
getVaultTotalOutputAmount(vaults) {
|
|
193
|
+
let total = BigInt(0);
|
|
194
|
+
for (const vault of vaults) {
|
|
195
|
+
for (const utxo of vault.utxos) {
|
|
196
|
+
total += BigInt(utxo.value);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return total;
|
|
200
|
+
}
|
|
201
|
+
}
|