@btc-vision/transaction 1.0.6 → 1.0.8

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.
Files changed (179) hide show
  1. package/Deploy.md +186 -0
  2. package/README.md +5 -0
  3. package/Wrap.md +192 -0
  4. package/browser/_version.d.ts +1 -1
  5. package/browser/index.js +1 -1
  6. package/browser/index.js.LICENSE.txt +9 -0
  7. package/browser/opnet.d.ts +6 -1
  8. package/browser/tests/deploy.d.ts +1 -0
  9. package/browser/tests/wrap.d.ts +1 -0
  10. package/browser/tests/wrapTest.d.ts +1 -0
  11. package/browser/transaction/TransactionFactory.d.ts +15 -1
  12. package/browser/transaction/builders/DeploymentTransaction.d.ts +40 -0
  13. package/browser/transaction/builders/InteractionTransaction.d.ts +2 -35
  14. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +46 -0
  15. package/browser/transaction/builders/TransactionBuilder.d.ts +8 -1
  16. package/browser/transaction/builders/WrapTransaction.d.ts +27 -0
  17. package/browser/transaction/interfaces/ITransactionParameters.d.ts +16 -12
  18. package/browser/utils/BitcoinUtils.d.ts +1 -0
  19. package/browser/utxo/OPNetLimitedProvider.d.ts +10 -0
  20. package/browser/wbtc/Generate.d.ts +13 -0
  21. package/browser/wbtc/WrappedGenerationParameters.d.ts +11 -0
  22. package/build/_version.d.ts +1 -1
  23. package/build/_version.js +1 -1
  24. package/build/bytecode/Compressor.js +4 -3
  25. package/build/generators/AddressGenerator.js +1 -1
  26. package/build/keypair/EcKeyPair.js +1 -1
  27. package/build/opnet.d.ts +6 -1
  28. package/build/opnet.js +6 -1
  29. package/build/signer/TweakedSigner.js +1 -1
  30. package/build/tests/deploy.d.ts +1 -0
  31. package/build/tests/deploy.js +60 -0
  32. package/build/tests/test.js +3 -3
  33. package/build/tests/transfer.js +2 -2
  34. package/build/tests/wrap.d.ts +1 -0
  35. package/build/tests/wrap.js +64 -0
  36. package/build/tests/wrapTest.d.ts +1 -0
  37. package/build/tests/wrapTest.js +64 -0
  38. package/build/tests/wrapTestg.d.ts +1 -0
  39. package/build/tests/wrapTestg.js +66 -0
  40. package/build/transaction/TransactionFactory.d.ts +15 -1
  41. package/build/transaction/TransactionFactory.js +68 -0
  42. package/build/transaction/builders/DeploymentTransaction.d.ts +40 -0
  43. package/build/transaction/builders/DeploymentTransaction.js +216 -0
  44. package/build/transaction/builders/FundingTransaction.js +4 -1
  45. package/build/transaction/builders/InteractionTransaction.d.ts +2 -35
  46. package/build/transaction/builders/InteractionTransaction.js +4 -207
  47. package/build/transaction/builders/SharedInteractionTransaction.d.ts +46 -0
  48. package/build/transaction/builders/SharedInteractionTransaction.js +213 -0
  49. package/build/transaction/builders/TransactionBuilder.d.ts +8 -1
  50. package/build/transaction/builders/TransactionBuilder.js +20 -12
  51. package/build/transaction/builders/WrapTransaction.d.ts +27 -0
  52. package/build/transaction/builders/WrapTransaction.js +132 -0
  53. package/build/transaction/interfaces/ITransactionParameters.d.ts +16 -12
  54. package/build/utils/BitcoinUtils.d.ts +1 -0
  55. package/build/utils/BitcoinUtils.js +7 -0
  56. package/build/utxo/OPNetLimitedProvider.d.ts +10 -0
  57. package/build/utxo/OPNetLimitedProvider.js +85 -0
  58. package/build/utxo/OPNetUtils.d.ts +7 -0
  59. package/build/utxo/OPNetUtils.js +47 -0
  60. package/build/verification/TapscriptVerificator.js +3 -3
  61. package/build/wbtc/Generate.d.ts +13 -0
  62. package/build/wbtc/Generate.js +1 -0
  63. package/build/wbtc/WrappedGenerationParameters.d.ts +11 -0
  64. package/build/wbtc/WrappedGenerationParameters.js +16 -0
  65. package/bytecode/contract.wasm +0 -0
  66. package/cjs/_version.d.ts +1 -1
  67. package/cjs/_version.js +1 -1
  68. package/cjs/bytecode/Compressor.js +1 -1
  69. package/cjs/generators/AddressGenerator.d.ts +7 -0
  70. package/cjs/generators/AddressGenerator.js +48 -0
  71. package/cjs/generators/Generator.d.ts +1 -2
  72. package/cjs/generators/Generator.js +1 -3
  73. package/cjs/generators/builders/DeploymentGenerator.d.ts +1 -0
  74. package/cjs/generators/builders/DeploymentGenerator.js +10 -7
  75. package/cjs/keypair/Wallet.d.ts +1 -0
  76. package/cjs/keypair/Wallet.js +6 -0
  77. package/cjs/opnet.d.ts +23 -0
  78. package/cjs/opnet.js +37 -0
  79. package/cjs/tests/Regtest.d.ts +3 -0
  80. package/cjs/tests/Regtest.js +32 -0
  81. package/cjs/tests/gen.d.ts +1 -0
  82. package/cjs/tests/gen.js +17 -0
  83. package/cjs/tests/test.d.ts +1 -0
  84. package/cjs/tests/test.js +53 -0
  85. package/cjs/tests/transfer.d.ts +1 -0
  86. package/cjs/tests/transfer.js +76 -0
  87. package/cjs/transaction/TransactionFactory.js +7 -4
  88. package/cjs/transaction/builders/FundingTransaction.js +1 -1
  89. package/cjs/transaction/builders/InteractionTransaction.d.ts +2 -0
  90. package/cjs/transaction/builders/InteractionTransaction.js +11 -2
  91. package/cjs/transaction/builders/TransactionBuilder.d.ts +3 -2
  92. package/cjs/transaction/builders/TransactionBuilder.js +22 -7
  93. package/cjs/transaction/interfaces/ITransactionParameters.d.ts +1 -0
  94. package/cjs/verification/TapscriptVerificator.d.ts +17 -0
  95. package/cjs/verification/TapscriptVerificator.js +70 -0
  96. package/docs/assets/navigation.js +1 -1
  97. package/docs/assets/search.js +1 -1
  98. package/docs/classes/AddressGenerator.html +2 -2
  99. package/docs/classes/BitcoinUtils.html +7 -3
  100. package/docs/classes/CalldataGenerator.html +10 -10
  101. package/docs/classes/Compressor.html +4 -4
  102. package/docs/classes/ContractBaseMetadata.html +4 -4
  103. package/docs/classes/DeploymentGenerator.html +9 -9
  104. package/docs/classes/DeploymentTransaction.html +368 -0
  105. package/docs/classes/EcKeyPair.html +16 -16
  106. package/docs/classes/FundingTransaction.html +50 -47
  107. package/docs/classes/Generator.html +9 -9
  108. package/docs/classes/InteractionTransaction.html +89 -109
  109. package/docs/classes/OPNetLimitedProvider.html +197 -0
  110. package/docs/classes/SharedInteractionTransaction.html +392 -0
  111. package/docs/classes/TapscriptVerificator.html +2 -2
  112. package/docs/classes/TransactionBuilder.html +53 -50
  113. package/docs/classes/TransactionFactory.html +11 -4
  114. package/docs/classes/TweakedSigner.html +2 -2
  115. package/docs/classes/Wallet.html +10 -10
  116. package/docs/classes/WrapTransaction.html +404 -0
  117. package/docs/classes/WrappedGeneration.html +187 -0
  118. package/docs/classes/wBTC.html +7 -7
  119. package/docs/enums/TransactionSequence.html +177 -0
  120. package/docs/enums/TransactionType.html +2 -2
  121. package/docs/hierarchy.html +1 -1
  122. package/docs/index.html +3 -1
  123. package/docs/interfaces/ContractAddressVerificationParams.html +2 -2
  124. package/docs/interfaces/DeploymentResult.html +177 -0
  125. package/docs/interfaces/FetchUTXOParams.html +2 -2
  126. package/docs/interfaces/GenerationConstraints.html +182 -0
  127. package/docs/interfaces/IDeploymentParameters.html +183 -0
  128. package/docs/interfaces/IFundingTransactionParameters.html +3 -3
  129. package/docs/interfaces/IInteractionParameters.html +4 -6
  130. package/docs/interfaces/ITransactionParameters.html +3 -3
  131. package/docs/interfaces/IWallet.html +4 -4
  132. package/docs/interfaces/IWrapParameters.html +186 -0
  133. package/docs/interfaces/NetworkInformation.html +2 -2
  134. package/docs/interfaces/PsbtInputExtended.html +1 -1
  135. package/docs/interfaces/PsbtOutputExtendedAddress.html +2 -2
  136. package/docs/interfaces/PsbtOutputExtendedScript.html +2 -2
  137. package/docs/interfaces/RawUTXOResponse.html +2 -2
  138. package/docs/interfaces/SharedInteractionParameters.html +183 -0
  139. package/docs/interfaces/TapLeafScript.html +2 -2
  140. package/docs/interfaces/TweakSettings.html +3 -3
  141. package/docs/interfaces/UTXO.html +2 -2
  142. package/docs/interfaces/UpdateInput.html +2 -2
  143. package/docs/interfaces/WrapResult.html +178 -0
  144. package/docs/interfaces/WrappedGenerationParameters.html +184 -0
  145. package/docs/modules.html +14 -4
  146. package/docs/types/PsbtOutputExtended.html +1 -1
  147. package/docs/variables/version.html +1 -1
  148. package/package.json +4 -5
  149. package/src/_version.ts +1 -1
  150. package/src/bytecode/Compressor.ts +27 -26
  151. package/src/generators/AddressGenerator.ts +1 -1
  152. package/src/keypair/EcKeyPair.ts +1 -1
  153. package/src/opnet.ts +8 -1
  154. package/src/signer/TweakedSigner.ts +1 -1
  155. package/src/tests/deploy.ts +81 -0
  156. package/src/tests/test.ts +3 -3
  157. package/src/tests/transfer.ts +2 -2
  158. package/src/tests/wrap.ts +89 -0
  159. package/src/tests/wrapTest.ts +88 -0
  160. package/src/transaction/TransactionFactory.ts +119 -1
  161. package/src/transaction/builders/DeploymentTransaction.ts +418 -0
  162. package/src/transaction/builders/FundingTransaction.ts +5 -1
  163. package/src/transaction/builders/InteractionTransaction.ts +5 -404
  164. package/src/transaction/builders/SharedInteractionTransaction.ts +432 -0
  165. package/src/transaction/builders/TransactionBuilder.ts +41 -16
  166. package/src/transaction/builders/WrapTransaction.ts +286 -0
  167. package/src/transaction/interfaces/ITransactionParameters.ts +20 -13
  168. package/src/utils/BitcoinUtils.ts +16 -0
  169. package/src/utxo/{UTXOManager.ts → OPNetLimitedProvider.ts} +53 -2
  170. package/src/verification/TapscriptVerificator.ts +3 -3
  171. package/src/wbtc/Generate.ts +30 -0
  172. package/src/wbtc/WrappedGenerationParameters.ts +33 -0
  173. package/tests/TransactionBuilder.test.ts +58 -58
  174. package/tsconfig.webpack.json +7 -1
  175. package/webpack.config.js +3 -1
  176. package/browser/873e754d6c7c6e9361f1.module.wasm +0 -0
  177. package/docs/classes/UTXOManager.html +0 -187
  178. package/docs/interfaces/ITransactionDataContractDeployment.html +0 -184
  179. package/docs/interfaces/ITransactionDataContractInteractionWrap.html +0 -186
@@ -0,0 +1,64 @@
1
+ import { Wallet } from '../keypair/Wallet.js';
2
+ import { Testnet } from './Regtest.js';
3
+ import { OPNetLimitedProvider } from '../utxo/OPNetLimitedProvider.js';
4
+ import { networks } from 'bitcoinjs-lib';
5
+ import { TransactionFactory } from '../transaction/TransactionFactory.js';
6
+ import { BitcoinRPC } from '@btc-vision/bsi-bitcoin-rpc';
7
+ const network = networks.testnet;
8
+ const rpc = new BitcoinRPC();
9
+ const wallet = new Wallet(Testnet.wallet, network);
10
+ const opnet = new OPNetLimitedProvider('https://testnet.opnet.org');
11
+ const factory = new TransactionFactory();
12
+ const shouldMineBlock = true;
13
+ async function mineBlock() {
14
+ const ok = await rpc.generateToAddress(1, wallet.p2wpkh, 'default');
15
+ if (!ok) {
16
+ throw new Error('Could not mine block');
17
+ }
18
+ console.log(`Mined block`, ok);
19
+ return !!ok.length;
20
+ }
21
+ await rpc.init(Testnet.config);
22
+ const wrapAmount = 100000000n;
23
+ const utxoSetting = {
24
+ address: wallet.p2wpkh,
25
+ minAmount: 10000n,
26
+ requestedAmount: wrapAmount,
27
+ };
28
+ const utxos = await opnet.fetchUTXO(utxoSetting);
29
+ if (!utxos) {
30
+ throw new Error('No UTXOs found');
31
+ }
32
+ const generationParameters = await opnet.fetchWrapParameters(wrapAmount);
33
+ if (!generationParameters) {
34
+ throw new Error('No generation parameters found');
35
+ }
36
+ const wrapParameters = {
37
+ from: wallet.p2wpkh,
38
+ utxos: utxos,
39
+ signer: wallet.keypair,
40
+ network: network,
41
+ feeRate: 350,
42
+ priorityFee: 50000n,
43
+ amount: wrapAmount,
44
+ generationParameters: generationParameters,
45
+ };
46
+ const finalTx = factory.wrap(wrapParameters);
47
+ console.log(`Final transaction:`, finalTx);
48
+ const firstTxBroadcast = await rpc.sendRawTransaction({
49
+ hexstring: finalTx.transaction[0],
50
+ });
51
+ console.log(`First transaction broadcasted: ${firstTxBroadcast}`);
52
+ if (!firstTxBroadcast) {
53
+ throw new Error('Could not broadcast first transaction');
54
+ }
55
+ const secondTxBroadcast = await rpc.sendRawTransaction({
56
+ hexstring: finalTx.transaction[1],
57
+ });
58
+ console.log(`Second transaction broadcasted: ${secondTxBroadcast}`);
59
+ if (!secondTxBroadcast) {
60
+ throw new Error('Could not broadcast second transaction');
61
+ }
62
+ if (shouldMineBlock) {
63
+ await mineBlock();
64
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ import { Wallet } from '../keypair/Wallet.js';
2
+ import { Regtest } from './Regtest.js';
3
+ import { OPNetLimitedProvider } from '../utxo/OPNetLimitedProvider.js';
4
+ import { networks } from 'bitcoinjs-lib';
5
+ import { TransactionFactory } from '../transaction/TransactionFactory.js';
6
+ import { BitcoinRPC } from '@btc-vision/bsi-bitcoin-rpc';
7
+ import { wBTC } from '../metadata/contracts/wBTC.js';
8
+ const network = networks.regtest;
9
+ const rpc = new BitcoinRPC();
10
+ const wallet = new Wallet(Regtest.wallet, network);
11
+ const opnet = new OPNetLimitedProvider('http://localhost:9001');
12
+ const factory = new TransactionFactory();
13
+ const wBtc = new wBTC(network);
14
+ const shouldMineBlock = true;
15
+ async function mineBlock() {
16
+ const ok = await rpc.generateToAddress(1, wallet.p2wpkh, 'default');
17
+ if (!ok) {
18
+ throw new Error('Could not mine block');
19
+ }
20
+ console.log(`Mined block`, ok);
21
+ return !!ok.length;
22
+ }
23
+ await rpc.init(Regtest.config);
24
+ const wrapAmount = 1000000n;
25
+ const utxoSetting = {
26
+ address: wallet.p2wpkh,
27
+ minAmount: 10000n,
28
+ requestedAmount: wrapAmount,
29
+ };
30
+ const utxos = await opnet.fetchUTXO(utxoSetting);
31
+ if (!utxos) {
32
+ throw new Error('No UTXOs found');
33
+ }
34
+ const generationParameters = await opnet.fetchWrapParameters(wrapAmount);
35
+ if (!generationParameters) {
36
+ throw new Error('No generation parameters found');
37
+ }
38
+ const wrapParameters = {
39
+ from: wallet.p2wpkh,
40
+ utxos: utxos,
41
+ signer: wallet.keypair,
42
+ network: network,
43
+ feeRate: 150,
44
+ priorityFee: 50000n,
45
+ amount: wrapAmount,
46
+ generationParameters: generationParameters,
47
+ };
48
+ const finalTx = factory.wrap(wrapParameters);
49
+ console.log(`Final transaction:`, finalTx);
50
+ const firstTxBroadcast = await rpc.sendRawTransaction({
51
+ hexstring: finalTx.transaction[0],
52
+ });
53
+ console.log(`First transaction broadcasted: ${firstTxBroadcast}`);
54
+ if (!firstTxBroadcast) {
55
+ throw new Error('Could not broadcast first transaction');
56
+ }
57
+ const secondTxBroadcast = await rpc.sendRawTransaction({
58
+ hexstring: finalTx.transaction[1],
59
+ });
60
+ console.log(`Second transaction broadcasted: ${secondTxBroadcast}`);
61
+ if (!secondTxBroadcast) {
62
+ throw new Error('Could not broadcast second transaction');
63
+ }
64
+ if (shouldMineBlock) {
65
+ await mineBlock();
66
+ }
@@ -1,4 +1,18 @@
1
- import { IInteractionParameters } from './interfaces/ITransactionParameters.js';
1
+ import { IDeploymentParameters, IInteractionParameters, IWrapParameters } from './interfaces/ITransactionParameters.js';
2
+ import { Address } from '@btc-vision/bsi-binary';
3
+ export interface DeploymentResult {
4
+ readonly transaction: [string, string];
5
+ readonly contractAddress: Address;
6
+ readonly p2trAddress: Address;
7
+ }
8
+ export interface WrapResult {
9
+ readonly transaction: [string, string];
10
+ readonly vaultAddress: Address;
11
+ readonly amount: bigint;
12
+ readonly receiverAddress: Address;
13
+ }
2
14
  export declare class TransactionFactory {
3
15
  signInteraction(interactionParameters: IInteractionParameters): [string, string];
16
+ signDeployment(deploymentParameters: IDeploymentParameters): DeploymentResult;
17
+ wrap(warpParameters: IWrapParameters): WrapResult;
4
18
  }
@@ -1,5 +1,7 @@
1
1
  import { FundingTransaction } from './builders/FundingTransaction.js';
2
2
  import { InteractionTransaction } from './builders/InteractionTransaction.js';
3
+ import { DeploymentTransaction } from './builders/DeploymentTransaction.js';
4
+ import { WrapTransaction } from './builders/WrapTransaction.js';
3
5
  export class TransactionFactory {
4
6
  signInteraction(interactionParameters) {
5
7
  const preTransaction = new InteractionTransaction(interactionParameters);
@@ -29,4 +31,70 @@ export class TransactionFactory {
29
31
  const outTx = finalTransaction.signTransaction();
30
32
  return [signedTransaction.toHex(), outTx.toHex()];
31
33
  }
34
+ signDeployment(deploymentParameters) {
35
+ const preTransaction = new DeploymentTransaction(deploymentParameters);
36
+ preTransaction.signTransaction();
37
+ const parameters = preTransaction.getFundingTransactionParameters();
38
+ const fundingTransaction = new FundingTransaction(parameters);
39
+ const signedTransaction = fundingTransaction.signTransaction();
40
+ if (!signedTransaction) {
41
+ throw new Error('Could not sign funding transaction.');
42
+ }
43
+ const out = signedTransaction.outs[0];
44
+ const newUtxo = {
45
+ transactionId: signedTransaction.getId(),
46
+ outputIndex: 0,
47
+ scriptPubKey: {
48
+ hex: out.script.toString('hex'),
49
+ address: preTransaction.getScriptAddress(),
50
+ },
51
+ value: BigInt(out.value),
52
+ };
53
+ const newParams = {
54
+ ...deploymentParameters,
55
+ utxos: [newUtxo],
56
+ randomBytes: preTransaction.getRndBytes(),
57
+ };
58
+ const finalTransaction = new DeploymentTransaction(newParams);
59
+ const outTx = finalTransaction.signTransaction();
60
+ return {
61
+ transaction: [signedTransaction.toHex(), outTx.toHex()],
62
+ contractAddress: finalTransaction.contractAddress,
63
+ p2trAddress: finalTransaction.p2trAddress,
64
+ };
65
+ }
66
+ wrap(warpParameters) {
67
+ const preTransaction = new WrapTransaction(warpParameters);
68
+ preTransaction.signTransaction();
69
+ const parameters = preTransaction.getFundingTransactionParameters();
70
+ parameters.childTransactionRequiredValue += warpParameters.amount;
71
+ const fundingTransaction = new FundingTransaction(parameters);
72
+ const signedTransaction = fundingTransaction.signTransaction();
73
+ if (!signedTransaction) {
74
+ throw new Error('Could not sign funding transaction.');
75
+ }
76
+ const out = signedTransaction.outs[0];
77
+ const newUtxo = {
78
+ transactionId: signedTransaction.getId(),
79
+ outputIndex: 0,
80
+ scriptPubKey: {
81
+ hex: out.script.toString('hex'),
82
+ address: preTransaction.getScriptAddress(),
83
+ },
84
+ value: BigInt(out.value),
85
+ };
86
+ const newParams = {
87
+ ...warpParameters,
88
+ utxos: [newUtxo],
89
+ randomBytes: preTransaction.getRndBytes(),
90
+ };
91
+ const finalTransaction = new WrapTransaction(newParams);
92
+ const outTx = finalTransaction.signTransaction();
93
+ return {
94
+ transaction: [signedTransaction.toHex(), outTx.toHex()],
95
+ vaultAddress: finalTransaction.vault,
96
+ amount: finalTransaction.amount,
97
+ receiverAddress: finalTransaction.receiver,
98
+ };
99
+ }
32
100
  }
@@ -0,0 +1,40 @@
1
+ /// <reference types="node" />
2
+ import { TransactionType } from '../enums/TransactionType.js';
3
+ import { IDeploymentParameters } from '../interfaces/ITransactionParameters.js';
4
+ import { Payment, Psbt, Signer } from 'bitcoinjs-lib';
5
+ import { TransactionBuilder } from './TransactionBuilder.js';
6
+ import { Address } from '@btc-vision/bsi-binary';
7
+ export declare class DeploymentTransaction extends TransactionBuilder<TransactionType.DEPLOYMENT> {
8
+ type: TransactionType.DEPLOYMENT;
9
+ protected readonly _contractAddress: Address;
10
+ private targetScriptRedeem;
11
+ private leftOverFundsScriptRedeem;
12
+ private readonly compiledTargetScript;
13
+ private readonly scriptTree;
14
+ private readonly tweakedSigner;
15
+ private tapLeafScript;
16
+ private deploymentGenerator;
17
+ private readonly contractSeed;
18
+ private readonly bytecode;
19
+ private readonly contractSigner;
20
+ private readonly randomBytes;
21
+ constructor(parameters: IDeploymentParameters);
22
+ get contractAddress(): Address;
23
+ get p2trAddress(): Address;
24
+ getRndBytes(): Buffer;
25
+ protected contractSignerXOnlyPubKey(): Buffer;
26
+ protected addInputsFromUTXO(): void;
27
+ protected buildTransaction(): void;
28
+ protected signInputs(transaction: Psbt): void;
29
+ protected getSignerKey(): Signer;
30
+ protected generateScriptAddress(): Payment;
31
+ protected generateTapData(): Payment;
32
+ private getContractSeed;
33
+ private customFinalizer;
34
+ private getTweakerHash;
35
+ private getTweakedSigner;
36
+ private getPubKeys;
37
+ private generateRedeemScripts;
38
+ private getLeafScript;
39
+ private getScriptTree;
40
+ }
@@ -0,0 +1,216 @@
1
+ import { TransactionType } from '../enums/TransactionType.js';
2
+ import { crypto as bitCrypto } from 'bitcoinjs-lib';
3
+ import { TransactionBuilder } from './TransactionBuilder.js';
4
+ import { DeploymentGenerator } from '../../generators/builders/DeploymentGenerator.js';
5
+ import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
6
+ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
7
+ import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
8
+ import { TweakedSigner } from '../../signer/TweakedSigner.js';
9
+ import { Compressor } from '../../bytecode/Compressor.js';
10
+ import { AddressGenerator } from '../../generators/AddressGenerator.js';
11
+ export class DeploymentTransaction extends TransactionBuilder {
12
+ type = TransactionType.DEPLOYMENT;
13
+ _contractAddress;
14
+ targetScriptRedeem = null;
15
+ leftOverFundsScriptRedeem = null;
16
+ compiledTargetScript;
17
+ scriptTree;
18
+ tweakedSigner;
19
+ tapLeafScript = null;
20
+ deploymentGenerator;
21
+ contractSeed;
22
+ bytecode;
23
+ contractSigner;
24
+ randomBytes;
25
+ constructor(parameters) {
26
+ super(parameters);
27
+ this.bytecode = Compressor.compress(parameters.bytecode);
28
+ if (!this.bytecode)
29
+ throw new Error('Bytecode is required');
30
+ this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
31
+ this.contractSeed = this.getContractSeed();
32
+ this.contractSigner = EcKeyPair.fromSeedKeyPair(this.contractSeed, this.network);
33
+ this.deploymentGenerator = new DeploymentGenerator(this.internalPubKeyToXOnly(), this.contractSignerXOnlyPubKey(), this.network);
34
+ this.compiledTargetScript = this.deploymentGenerator.compile(this.bytecode, this.randomBytes);
35
+ this.scriptTree = this.getScriptTree();
36
+ this.internalInit();
37
+ this._contractAddress = AddressGenerator.generatePKSH(this.contractSeed, this.network);
38
+ }
39
+ get contractAddress() {
40
+ return this._contractAddress;
41
+ }
42
+ get p2trAddress() {
43
+ return this.to || this.getScriptAddress();
44
+ }
45
+ getRndBytes() {
46
+ return this.randomBytes;
47
+ }
48
+ contractSignerXOnlyPubKey() {
49
+ return toXOnly(this.contractSigner.publicKey);
50
+ }
51
+ addInputsFromUTXO() {
52
+ if (!this.tapLeafScript)
53
+ throw new Error('Tap leaf script is required');
54
+ for (let utxo of this.utxos) {
55
+ const input = {
56
+ hash: utxo.transactionId,
57
+ index: utxo.outputIndex,
58
+ witnessUtxo: {
59
+ value: Number(utxo.value),
60
+ script: this.getTapOutput() || utxo.scriptPubKey.hex,
61
+ },
62
+ tapLeafScript: [this.tapLeafScript],
63
+ sequence: this.sequence,
64
+ };
65
+ this.addInput(input);
66
+ }
67
+ }
68
+ buildTransaction() {
69
+ if (!this.to) {
70
+ this.to = this.getScriptAddress();
71
+ }
72
+ const selectedRedeem = !!this.contractSigner
73
+ ? this.targetScriptRedeem
74
+ : this.leftOverFundsScriptRedeem;
75
+ if (!selectedRedeem) {
76
+ throw new Error('Left over funds script redeem is required');
77
+ }
78
+ if (!selectedRedeem.redeemVersion) {
79
+ throw new Error('Left over funds script redeem version is required');
80
+ }
81
+ if (!selectedRedeem.output) {
82
+ throw new Error('Left over funds script redeem output is required');
83
+ }
84
+ this.tapLeafScript = {
85
+ leafVersion: selectedRedeem.redeemVersion,
86
+ script: selectedRedeem.output,
87
+ controlBlock: this.getWitness(),
88
+ };
89
+ this.addInputsFromUTXO();
90
+ const amountSpent = this.getTransactionOPNetFee();
91
+ this.addOutput({
92
+ value: Number(amountSpent),
93
+ address: this.to,
94
+ });
95
+ this.addRefundOutput(amountSpent);
96
+ }
97
+ signInputs(transaction) {
98
+ if (!this.contractSigner) {
99
+ super.signInputs(transaction);
100
+ return;
101
+ }
102
+ transaction.signInput(0, this.contractSigner);
103
+ transaction.signInput(0, this.getSignerKey());
104
+ transaction.finalizeInput(0, this.customFinalizer);
105
+ }
106
+ getSignerKey() {
107
+ if (this.tweakedSigner) {
108
+ return this.tweakedSigner;
109
+ }
110
+ return this.signer;
111
+ }
112
+ generateScriptAddress() {
113
+ return {
114
+ internalPubkey: this.internalPubKeyToXOnly(),
115
+ network: this.network,
116
+ scriptTree: this.scriptTree,
117
+ };
118
+ }
119
+ generateTapData() {
120
+ const selectedRedeem = !!this.contractSigner
121
+ ? this.targetScriptRedeem
122
+ : this.leftOverFundsScriptRedeem;
123
+ if (!selectedRedeem) {
124
+ throw new Error('Left over funds script redeem is required');
125
+ }
126
+ if (!this.scriptTree) {
127
+ throw new Error('Script tree is required');
128
+ }
129
+ return {
130
+ internalPubkey: this.internalPubKeyToXOnly(),
131
+ network: this.network,
132
+ scriptTree: this.scriptTree,
133
+ redeem: selectedRedeem,
134
+ };
135
+ }
136
+ getContractSeed() {
137
+ if (!this.bytecode) {
138
+ throw new Error('Bytecode is required');
139
+ }
140
+ const deployerPubKey = this.internalPubKeyToXOnly();
141
+ const salt = bitCrypto.hash256(this.randomBytes);
142
+ const sha256OfBytecode = bitCrypto.hash256(this.bytecode);
143
+ const buf = Buffer.concat([deployerPubKey, salt, sha256OfBytecode]);
144
+ return bitCrypto.hash256(buf);
145
+ }
146
+ customFinalizer = (_inputIndex, input) => {
147
+ if (!this.tapLeafScript) {
148
+ throw new Error('Tap leaf script is required');
149
+ }
150
+ if (!input.tapScriptSig) {
151
+ throw new Error('Tap script signature is required');
152
+ }
153
+ const scriptSolution = [
154
+ this.randomBytes,
155
+ this.internalPubKeyToXOnly(),
156
+ input.tapScriptSig[0].signature,
157
+ input.tapScriptSig[1].signature,
158
+ ];
159
+ const witness = scriptSolution
160
+ .concat(this.tapLeafScript.script)
161
+ .concat(this.tapLeafScript.controlBlock);
162
+ return {
163
+ finalScriptWitness: this.witnessStackToScriptWitness(witness),
164
+ };
165
+ };
166
+ getTweakerHash() {
167
+ return this.tapData?.hash;
168
+ }
169
+ getTweakedSigner(useTweakedHash = false) {
170
+ const settings = {
171
+ network: this.network,
172
+ };
173
+ if (useTweakedHash) {
174
+ settings.tweakHash = this.getTweakerHash();
175
+ }
176
+ return TweakedSigner.tweakSigner(this.signer, settings);
177
+ }
178
+ getPubKeys() {
179
+ const pubkeys = [this.signer.publicKey];
180
+ if (this.contractSigner) {
181
+ pubkeys.push(this.contractSigner.publicKey);
182
+ }
183
+ return pubkeys;
184
+ }
185
+ generateRedeemScripts() {
186
+ this.targetScriptRedeem = {
187
+ pubkeys: this.getPubKeys(),
188
+ output: this.compiledTargetScript,
189
+ redeemVersion: 192,
190
+ };
191
+ this.leftOverFundsScriptRedeem = {
192
+ pubkeys: this.getPubKeys(),
193
+ output: this.getLeafScript(),
194
+ redeemVersion: 192,
195
+ };
196
+ }
197
+ getLeafScript() {
198
+ return TransactionBuilder.LOCK_LEAF_SCRIPT;
199
+ }
200
+ getScriptTree() {
201
+ if (!this.bytecode) {
202
+ throw new Error('Contract bytecode is required');
203
+ }
204
+ this.generateRedeemScripts();
205
+ return [
206
+ {
207
+ output: this.compiledTargetScript,
208
+ version: 192,
209
+ },
210
+ {
211
+ output: this.getLeafScript(),
212
+ version: 192,
213
+ },
214
+ ];
215
+ }
216
+ }
@@ -5,10 +5,13 @@ export class FundingTransaction extends TransactionBuilder {
5
5
  childTransactionRequiredFees;
6
6
  constructor(parameters) {
7
7
  super(parameters);
8
- this.childTransactionRequiredFees = parameters.childTransactionRequiredFees;
8
+ this.childTransactionRequiredFees = parameters.childTransactionRequiredValue;
9
9
  this.internalInit();
10
10
  }
11
11
  buildTransaction() {
12
+ if (!this.to) {
13
+ throw new Error('Recipient address is required');
14
+ }
12
15
  this.addInputsFromUTXO();
13
16
  const amountSpent = this.getTransactionOPNetFee() + this.childTransactionRequiredFees;
14
17
  this.addOutput({
@@ -1,47 +1,14 @@
1
1
  /// <reference types="node" />
2
- import { PsbtInput } from 'bip174/src/lib/interfaces.js';
3
- import { Payment, Psbt, Signer } from 'bitcoinjs-lib';
4
2
  import { Taptree } from 'bitcoinjs-lib/src/types.js';
5
- import { ECPairInterface } from 'ecpair';
6
- import { TransactionBuilder } from './TransactionBuilder.js';
7
3
  import { TransactionType } from '../enums/TransactionType.js';
8
4
  import { TapLeafScript } from '../interfaces/Tap.js';
9
- import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
10
5
  import { IInteractionParameters } from '../interfaces/ITransactionParameters.js';
11
- export declare class InteractionTransaction extends TransactionBuilder<TransactionType.INTERACTION> {
6
+ import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
7
+ export declare class InteractionTransaction extends SharedInteractionTransaction<TransactionType.INTERACTION> {
12
8
  type: TransactionType.INTERACTION;
13
- readonly randomBytes: Buffer;
14
- protected targetScriptRedeem: Payment | null;
15
- protected leftOverFundsScriptRedeem: Payment | null;
16
9
  protected readonly compiledTargetScript: Buffer;
17
10
  protected readonly scriptTree: Taptree;
18
11
  protected tapLeafScript: TapLeafScript | null;
19
- protected calldataGenerator: CalldataGenerator;
20
- protected readonly calldata: Buffer;
21
12
  protected readonly contractSecret: Buffer;
22
- protected tweakedSigner?: Signer;
23
- protected readonly scriptSigner: Signer;
24
- protected readonly interactionPubKeys: Buffer[];
25
- protected readonly minimumSignatures: number;
26
13
  constructor(parameters: IInteractionParameters);
27
- getContractSecret(): Buffer;
28
- getRndBytes(): Buffer;
29
- protected generateSecret(): Buffer;
30
- protected tweakSigner(): void;
31
- protected scriptSignerXOnlyPubKey(): Buffer;
32
- protected generateKeyPairFromSeed(): ECPairInterface;
33
- protected addInputsFromUTXO(): void;
34
- protected buildTransaction(): void;
35
- protected signInputs(transaction: Psbt): void;
36
- protected getSignerKey(): Signer;
37
- protected generateScriptAddress(): Payment;
38
- protected generateTapData(): Payment;
39
- protected getScriptSolution(input: PsbtInput): Buffer[];
40
- private getPubKeys;
41
- private customFinalizer;
42
- private getTweakerHash;
43
- private getTweakedSigner;
44
- private generateRedeemScripts;
45
- private getLeafScript;
46
- private getScriptTree;
47
14
  }