@btc-vision/transaction 1.0.99 → 1.0.101

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 (163) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/generators/Generator.d.ts +2 -2
  3. package/browser/generators/builders/CustomGenerator.d.ts +6 -0
  4. package/browser/index.js +1 -1
  5. package/browser/opnet.d.ts +5 -3
  6. package/browser/transaction/TransactionFactory.d.ts +2 -0
  7. package/browser/transaction/builders/CustomScriptTransaction.d.ts +40 -0
  8. package/browser/transaction/enums/TransactionType.d.ts +2 -1
  9. package/build/_version.d.ts +1 -1
  10. package/build/_version.js +1 -1
  11. package/build/generators/Generator.d.ts +2 -2
  12. package/build/generators/builders/CalldataGenerator.js +2 -0
  13. package/build/generators/builders/CustomGenerator.d.ts +6 -0
  14. package/build/generators/builders/CustomGenerator.js +16 -0
  15. package/build/generators/builders/DeploymentGenerator.js +2 -0
  16. package/build/metadata/tokens.js +5 -5
  17. package/build/opnet.d.ts +5 -3
  18. package/build/opnet.js +5 -3
  19. package/build/transaction/TransactionFactory.d.ts +2 -0
  20. package/build/transaction/TransactionFactory.js +42 -3
  21. package/build/transaction/builders/CustomScriptTransaction.d.ts +40 -0
  22. package/build/transaction/builders/CustomScriptTransaction.js +165 -0
  23. package/build/transaction/enums/TransactionType.d.ts +2 -1
  24. package/build/transaction/enums/TransactionType.js +1 -0
  25. package/eslint.config.js +30 -0
  26. package/package.json +10 -9
  27. package/src/_version.ts +1 -1
  28. package/src/generators/Generator.ts +2 -2
  29. package/src/generators/builders/CalldataGenerator.ts +2 -0
  30. package/src/generators/builders/CustomGenerator.ts +30 -0
  31. package/src/generators/builders/DeploymentGenerator.ts +2 -0
  32. package/src/metadata/tokens.ts +5 -5
  33. package/src/opnet.ts +5 -5
  34. package/src/transaction/TransactionFactory.ts +72 -14
  35. package/src/transaction/builders/CustomScriptTransaction.ts +337 -0
  36. package/src/transaction/enums/TransactionType.ts +1 -0
  37. package/docs/.nojekyll +0 -1
  38. package/docs/assets/highlight.css +0 -43
  39. package/docs/assets/icons.js +0 -15
  40. package/docs/assets/icons.svg +0 -1
  41. package/docs/assets/main.js +0 -59
  42. package/docs/assets/material-style.css +0 -247
  43. package/docs/assets/navigation.js +0 -1
  44. package/docs/assets/search.js +0 -1
  45. package/docs/assets/style.css +0 -1412
  46. package/docs/classes/AddressGenerator.html +0 -177
  47. package/docs/classes/AddressVerificator.html +0 -177
  48. package/docs/classes/BitcoinUtils.html +0 -196
  49. package/docs/classes/CalldataGenerator.html +0 -213
  50. package/docs/classes/Compressor.html +0 -185
  51. package/docs/classes/ContractBaseMetadata.html +0 -182
  52. package/docs/classes/CustomKeypair.html +0 -189
  53. package/docs/classes/DeploymentGenerator.html +0 -201
  54. package/docs/classes/DeploymentTransaction.html +0 -465
  55. package/docs/classes/EcKeyPair.html +0 -280
  56. package/docs/classes/FundingTransaction.html +0 -425
  57. package/docs/classes/Generator.html +0 -199
  58. package/docs/classes/InteractionTransaction.html +0 -467
  59. package/docs/classes/MultiSignGenerator.html +0 -178
  60. package/docs/classes/MultiSignTransaction.html +0 -490
  61. package/docs/classes/OPNetLimitedProvider.html +0 -225
  62. package/docs/classes/OPNetTokenAddressManager.html +0 -182
  63. package/docs/classes/P2TR_MS.html +0 -186
  64. package/docs/classes/PsbtTransaction.html +0 -320
  65. package/docs/classes/SharedInteractionTransaction.html +0 -477
  66. package/docs/classes/TapscriptVerificator.html +0 -180
  67. package/docs/classes/TransactionBuilder.html +0 -423
  68. package/docs/classes/TransactionFactory.html +0 -230
  69. package/docs/classes/TweakedSigner.html +0 -181
  70. package/docs/classes/TweakedTransaction.html +0 -301
  71. package/docs/classes/UnisatSigner.html +0 -199
  72. package/docs/classes/UnwrapGeneration.html +0 -177
  73. package/docs/classes/UnwrapTransaction.html +0 -518
  74. package/docs/classes/Wallet.html +0 -204
  75. package/docs/classes/WrapTransaction.html +0 -509
  76. package/docs/classes/WrappedGeneration.html +0 -187
  77. package/docs/classes/wBTC.html +0 -190
  78. package/docs/enums/ChainId.html +0 -176
  79. package/docs/enums/Consensus.html +0 -204
  80. package/docs/enums/Features.html +0 -175
  81. package/docs/enums/MessageType.html +0 -176
  82. package/docs/enums/OPNetNetwork.html +0 -177
  83. package/docs/enums/PSBTTypes.html +0 -175
  84. package/docs/enums/TransactionSequence.html +0 -177
  85. package/docs/enums/TransactionType.html +0 -181
  86. package/docs/enums/UnisatChainType.html +0 -181
  87. package/docs/enums/UnisatNetwork.html +0 -177
  88. package/docs/hierarchy.html +0 -174
  89. package/docs/index.html +0 -215
  90. package/docs/interfaces/Balance.html +0 -177
  91. package/docs/interfaces/BitcoinTransferResponse.html +0 -178
  92. package/docs/interfaces/BroadcastResponse.html +0 -181
  93. package/docs/interfaces/BroadcastTransactionOptions.html +0 -176
  94. package/docs/interfaces/BroadcastedTransaction.html +0 -184
  95. package/docs/interfaces/ConsensusConfig.html +0 -182
  96. package/docs/interfaces/ContractAddressVerificationParams.html +0 -179
  97. package/docs/interfaces/DeploymentResult.html +0 -178
  98. package/docs/interfaces/FetchUTXOParams.html +0 -178
  99. package/docs/interfaces/FetchUTXOParamsMultiAddress.html +0 -178
  100. package/docs/interfaces/FundingTransactionResponse.html +0 -178
  101. package/docs/interfaces/GenerationConstraints.html +0 -182
  102. package/docs/interfaces/IDeploymentParameters.html +0 -186
  103. package/docs/interfaces/IFundingTransactionParameters.html +0 -186
  104. package/docs/interfaces/IInteractionParameters.html +0 -187
  105. package/docs/interfaces/ITransactionParameters.html +0 -184
  106. package/docs/interfaces/ITweakedTransactionData.html +0 -178
  107. package/docs/interfaces/IUnwrapParameters.html +0 -189
  108. package/docs/interfaces/IWBTCUTXODocument.html +0 -180
  109. package/docs/interfaces/IWallet.html +0 -181
  110. package/docs/interfaces/IWrapParameters.html +0 -190
  111. package/docs/interfaces/MultiSignFromBase64Params.html +0 -188
  112. package/docs/interfaces/MultiSignParameters.html +0 -188
  113. package/docs/interfaces/OPNetTokenMetadata.html +0 -179
  114. package/docs/interfaces/PsbtInputExtended.html +0 -194
  115. package/docs/interfaces/PsbtOutputExtendedAddress.html +0 -183
  116. package/docs/interfaces/PsbtOutputExtendedScript.html +0 -183
  117. package/docs/interfaces/PsbtSignatureOptions.html +0 -176
  118. package/docs/interfaces/PsbtTransactionData.html +0 -179
  119. package/docs/interfaces/RawUTXOResponse.html +0 -178
  120. package/docs/interfaces/SharedInteractionParameters.html +0 -187
  121. package/docs/interfaces/TapLeafScript.html +0 -177
  122. package/docs/interfaces/ToSignInputAddress.html +0 -178
  123. package/docs/interfaces/ToSignInputPublicKey.html +0 -178
  124. package/docs/interfaces/TweakSettings.html +0 -179
  125. package/docs/interfaces/UTXO.html +0 -178
  126. package/docs/interfaces/Unisat.html +0 -190
  127. package/docs/interfaces/UnisatChainInfo.html +0 -177
  128. package/docs/interfaces/UnwrapResult.html +0 -181
  129. package/docs/interfaces/UnwrappedGenerationParameters.html +0 -178
  130. package/docs/interfaces/UpdateInput.html +0 -175
  131. package/docs/interfaces/VaultUTXOs.html +0 -178
  132. package/docs/interfaces/Web3Provider.html +0 -180
  133. package/docs/interfaces/WrapResult.html +0 -179
  134. package/docs/interfaces/WrappedGenerationParameters.html +0 -184
  135. package/docs/modules.html +0 -289
  136. package/docs/types/FromBase64Params.html +0 -174
  137. package/docs/types/IDeploymentParametersWithoutSigner.html +0 -174
  138. package/docs/types/IUnwrapParametersWithoutSigner.html +0 -174
  139. package/docs/types/IWrapParametersWithoutSigner.html +0 -174
  140. package/docs/types/InteractionParametersWithoutSigner.html +0 -174
  141. package/docs/types/PsbtOutputExtended.html +0 -174
  142. package/docs/types/ToSignInput.html +0 -174
  143. package/docs/variables/FACTORY_ADDRESS_FRACTAL.html +0 -174
  144. package/docs/variables/FACTORY_ADDRESS_REGTEST.html +0 -174
  145. package/docs/variables/FACTORY_ADDRESS_TESTNET.html +0 -174
  146. package/docs/variables/MOTO_ADDRESS_FRACTAL.html +0 -174
  147. package/docs/variables/MOTO_ADDRESS_REGTEST.html +0 -174
  148. package/docs/variables/MOTO_ADDRESS_TESTNET.html +0 -174
  149. package/docs/variables/OPNetConsensusConfig.html +0 -174
  150. package/docs/variables/OPNetMetadata.html +0 -174
  151. package/docs/variables/POOL_ADDRESS_FRACTAL.html +0 -174
  152. package/docs/variables/POOL_ADDRESS_REGTEST.html +0 -174
  153. package/docs/variables/POOL_ADDRESS_TESTNET.html +0 -174
  154. package/docs/variables/ROUTER_ADDRESS_FRACTAL.html +0 -174
  155. package/docs/variables/ROUTER_ADDRESS_REGTEST.html +0 -174
  156. package/docs/variables/ROUTER_ADDRESS_TESTNET.html +0 -174
  157. package/docs/variables/RoswellConsensus.html +0 -174
  158. package/docs/variables/WBTC_ADDRESS_FRACTAL.html +0 -174
  159. package/docs/variables/WBTC_ADDRESS_REGTEST.html +0 -174
  160. package/docs/variables/WBTC_ADDRESS_TESTNET.html +0 -174
  161. package/docs/variables/currentConsensus.html +0 -174
  162. package/docs/variables/currentConsensusConfig.html +0 -174
  163. package/docs/variables/version.html +0 -174
@@ -22,7 +22,7 @@ export abstract class Generator {
22
22
  * The public key of the contract salt
23
23
  * @protected
24
24
  */
25
- protected readonly contractSaltPubKey: Buffer;
25
+ protected readonly contractSaltPubKey?: Buffer;
26
26
 
27
27
  /**
28
28
  * The network to use
@@ -32,7 +32,7 @@ export abstract class Generator {
32
32
 
33
33
  protected constructor(
34
34
  senderPubKey: Buffer,
35
- contractSaltPubKey: Buffer,
35
+ contractSaltPubKey?: Buffer,
36
36
  network: Network = networks.bitcoin,
37
37
  ) {
38
38
  this.senderPubKey = senderPubKey;
@@ -69,6 +69,8 @@ export class CalldataGenerator extends Generator {
69
69
  vaultPublicKeys: Buffer[] = [],
70
70
  minimumSignatures: number = 0,
71
71
  ): Buffer {
72
+ if (!this.contractSaltPubKey) throw new Error('Contract salt public key not set');
73
+
72
74
  const dataChunks: Buffer[][] = this.splitBufferIntoChunks(calldata);
73
75
  if (!dataChunks.length) throw new Error('No data chunks found');
74
76
 
@@ -0,0 +1,30 @@
1
+ import { Network, networks, script, Stack } from 'bitcoinjs-lib';
2
+ import { Generator } from '../Generator.js';
3
+
4
+ /**
5
+ * Class to generate bitcoin script for interaction transactions
6
+ */
7
+ export class CustomGenerator extends Generator {
8
+ constructor(senderPubKey: Buffer, network: Network = networks.bitcoin) {
9
+ super(senderPubKey, undefined, network);
10
+ }
11
+
12
+ /**
13
+ * Compile an interaction bitcoin script
14
+ * @param compiledData - The compiled data
15
+ * @returns {Buffer} - The compiled script
16
+ * @throws {Error} - If something goes wrong
17
+ */
18
+ public compile(compiledData: (Buffer | Stack)[]): Buffer {
19
+ const asm = compiledData.flat();
20
+ const compiled = script.compile(asm);
21
+
22
+ /** Verify the validity of the script */
23
+ const decompiled = script.decompile(compiled);
24
+ if (!decompiled) {
25
+ throw new Error('Failed to decompile script??');
26
+ }
27
+
28
+ return compiled;
29
+ }
30
+ }
@@ -32,6 +32,8 @@ export class DeploymentGenerator extends Generator {
32
32
  }
33
33
 
34
34
  private getAsm(contractBytecode: Buffer, contractSalt: Buffer): (number | Buffer)[] {
35
+ if (!this.contractSaltPubKey) throw new Error('Contract salt public key not set');
36
+
35
37
  const dataChunks = this.splitBufferIntoChunks(contractBytecode);
36
38
 
37
39
  return [
@@ -2,11 +2,11 @@ import { Address } from '@btc-vision/bsi-binary';
2
2
  import { ChainId } from '../network/ChainId.js';
3
3
 
4
4
  // Addresses Regtest
5
- export const FACTORY_ADDRESS_REGTEST: Address = 'bcrt1qxtpreq8zg7pp9wm550kjrhaa2r5kj6lhph9he5';
6
- export const POOL_ADDRESS_REGTEST: Address = 'bcrt1qqg2a8076rwuruzetdyquj8fh5jxtc22pmh9vep';
7
- export const WBTC_ADDRESS_REGTEST: Address = 'bcrt1qdr7sjgtnudda8zrfklw8l5cnrxum5hns7e46hf';
8
- export const MOTO_ADDRESS_REGTEST: Address = 'bcrt1q8reuxx9naek4mqesrfsgdpjv3q7a5g2llkh6ua';
9
- export const ROUTER_ADDRESS_REGTEST: Address = 'bcrt1qplnz54sca73t8a03nh494jatr9ffjg6ecarrj8';
5
+ export const FACTORY_ADDRESS_REGTEST: Address = 'bcrt1q9pf9fnpch9z2qrp5e3dgr2avzu3mypq3km2k40';
6
+ export const POOL_ADDRESS_REGTEST: Address = 'bcrt1qg87nx9v9ln3qyadcn0llekzjn0hx8js46ztwky';
7
+ export const WBTC_ADDRESS_REGTEST: Address = 'bcrt1qy44f5630m4ap4mvmgqc44qh4vndaees9y30t0m';
8
+ export const MOTO_ADDRESS_REGTEST: Address = 'bcrt1q5txqpm5sy0s2xsprvce4ddj0088nlq8lazkd6n';
9
+ export const ROUTER_ADDRESS_REGTEST: Address = 'bcrt1q9yd6mk324k0q4krmlxjky0pk65ul6hkf4u35e6';
10
10
 
11
11
  // Addresses Testnet
12
12
  export const FACTORY_ADDRESS_TESTNET: Address = 'tb1qgev5kldhp5zvg6j8t9vl6x4phkrwn8nk9felxh';
package/src/opnet.ts CHANGED
@@ -7,6 +7,8 @@ export * from './bytecode/Compressor.js';
7
7
  export * from './generators/Generator.js';
8
8
  export * from './generators/builders/CalldataGenerator.js';
9
9
  export * from './generators/builders/DeploymentGenerator.js';
10
+ export * from './generators/builders/CustomGenerator.js';
11
+ export * from './generators/builders/MultiSignGenerator.js';
10
12
  export * from './generators/Features.js';
11
13
 
12
14
  /** Address */
@@ -39,6 +41,9 @@ export * from './transaction/builders/TransactionBuilder.js';
39
41
  export * from './transaction/builders/WrapTransaction.js';
40
42
  export * from './transaction/builders/SharedInteractionTransaction.js';
41
43
  export * from './transaction/builders/DeploymentTransaction.js';
44
+ export * from './transaction/builders/UnwrapTransaction.js';
45
+ export * from './transaction/builders/CustomScriptTransaction.js';
46
+ export * from './transaction/builders/MultiSignTransaction.js';
42
47
 
43
48
  /** wBTC */
44
49
  export * from './wbtc/WrappedGenerationParameters.js';
@@ -60,12 +65,7 @@ export * from './transaction/shared/TweakedTransaction.js';
60
65
  export * from './utxo/interfaces/BroadcastResponse.js';
61
66
  export * from './transaction/psbt/PSBTTypes.js';
62
67
 
63
- export * from './transaction/builders/MultiSignTransaction.js';
64
- export * from './generators/builders/MultiSignGenerator.js';
65
-
66
68
  export * from './transaction/shared/P2TR_MS.js';
67
- export * from './transaction/builders/UnwrapTransaction.js';
68
-
69
69
  export * from './wbtc/UnwrapGeneration.js';
70
70
 
71
71
  /** Consensus */
@@ -21,6 +21,10 @@ import { UnwrapTransaction } from './builders/UnwrapTransaction.js';
21
21
  import { currentConsensus, currentConsensusConfig } from '../consensus/ConsensusConfig.js';
22
22
  import { TransactionBuilder } from './builders/TransactionBuilder.js';
23
23
  import { TransactionType } from './enums/TransactionType.js';
24
+ import {
25
+ CustomScriptTransaction,
26
+ ICustomTransactionParameters,
27
+ } from './builders/CustomScriptTransaction.js';
24
28
 
25
29
  export interface DeploymentResult {
26
30
  readonly transaction: [string, string];
@@ -71,6 +75,74 @@ export interface UnwrapResult {
71
75
  export class TransactionFactory {
72
76
  constructor() {}
73
77
 
78
+ /**
79
+ * @description Generate a transaction with a custom script.
80
+ * @returns {Promise<[string, string]>} - The signed transaction
81
+ */
82
+ public async createCustomScriptTransaction(
83
+ interactionParameters: ICustomTransactionParameters,
84
+ ): Promise<[string, string, UTXO[]]> {
85
+ if (!interactionParameters.to) {
86
+ throw new Error('Field "to" not provided.');
87
+ }
88
+
89
+ if (!interactionParameters.from) {
90
+ throw new Error('Field "from" not provided.');
91
+ }
92
+
93
+ const preTransaction: CustomScriptTransaction = new CustomScriptTransaction({
94
+ ...interactionParameters,
95
+ utxos: [interactionParameters.utxos[0]], // we simulate one input here.
96
+ });
97
+
98
+ // we don't sign that transaction, we just need the parameters.
99
+
100
+ await preTransaction.generateTransactionMinimalSignatures();
101
+
102
+ const parameters: IFundingTransactionParameters =
103
+ await preTransaction.getFundingTransactionParameters();
104
+
105
+ parameters.utxos = interactionParameters.utxos;
106
+ parameters.amount =
107
+ (await preTransaction.estimateTransactionFees()) + interactionParameters.priorityFee;
108
+
109
+ const feeEstimationFundingTransaction = await this.createFundTransaction({ ...parameters });
110
+ if (!feeEstimationFundingTransaction) {
111
+ throw new Error('Could not sign funding transaction.');
112
+ }
113
+
114
+ parameters.estimatedFees = feeEstimationFundingTransaction.estimatedFees;
115
+
116
+ const signedTransaction = await this.createFundTransaction(parameters);
117
+ if (!signedTransaction) {
118
+ throw new Error('Could not sign funding transaction.');
119
+ }
120
+
121
+ interactionParameters.utxos = this.getUTXOAsTransaction(
122
+ signedTransaction.tx,
123
+ interactionParameters.to,
124
+ 0,
125
+ );
126
+
127
+ const newParams: ICustomTransactionParameters = {
128
+ ...interactionParameters,
129
+ utxos: this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.to, 0), // always 0
130
+ randomBytes: preTransaction.getRndBytes(),
131
+ nonWitnessUtxo: signedTransaction.tx.toBuffer(),
132
+ estimatedFees: preTransaction.estimatedFees,
133
+ };
134
+
135
+ const finalTransaction: CustomScriptTransaction = new CustomScriptTransaction(newParams);
136
+
137
+ // We have to regenerate using the new utxo
138
+ const outTx: Transaction = await finalTransaction.signTransaction();
139
+ return [
140
+ signedTransaction.tx.toHex(),
141
+ outTx.toHex(),
142
+ this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.from, 1), // always 1
143
+ ];
144
+ }
145
+
74
146
  /**
75
147
  * @description Generates the required transactions.
76
148
  * @returns {Promise<[string, string]>} - The signed transaction
@@ -132,7 +204,6 @@ export class TransactionFactory {
132
204
 
133
205
  // We have to regenerate using the new utxo
134
206
  const outTx: Transaction = await finalTransaction.signTransaction();
135
-
136
207
  return [
137
208
  signedTransaction.tx.toHex(),
138
209
  outTx.toHex(),
@@ -243,8 +314,6 @@ export class TransactionFactory {
243
314
  const parameters: IFundingTransactionParameters =
244
315
  await preTransaction.getFundingTransactionParameters();
245
316
 
246
- console.log('wrap parameters', parameters);
247
-
248
317
  // We add the amount
249
318
  parameters.amount += childTransactionRequiredValue;
250
319
  parameters.utxos = fundingParameters.utxos;
@@ -300,15 +369,6 @@ export class TransactionFactory {
300
369
  this.maxPubKeySize(unwrapParameters.unwrapUTXOs),
301
370
  );
302
371
 
303
- console.log(
304
- 'estimatedFees',
305
- estimatedFees,
306
- 'estimatedGas',
307
- estimatedGas,
308
- 'priority',
309
- unwrapParameters.priorityFee,
310
- );
311
-
312
372
  const fundingParameters: IFundingTransactionParameters = {
313
373
  ...unwrapParameters,
314
374
  amount: estimatedGas + estimatedFees,
@@ -402,8 +462,6 @@ export class TransactionFactory {
402
462
  parameters.amount =
403
463
  (await preTransaction.estimateTransactionFees()) + unwrapParameters.priorityFee;
404
464
 
405
- console.log('parameters', parameters);
406
-
407
465
  const signedTransaction = await this.createFundTransaction(parameters);
408
466
  if (!signedTransaction) {
409
467
  throw new Error('Could not sign funding transaction.');
@@ -0,0 +1,337 @@
1
+ import { Taptree } from 'bitcoinjs-lib/src/types.js';
2
+ import { TransactionType } from '../enums/TransactionType.js';
3
+ import { TapLeafScript } from '../interfaces/Tap.js';
4
+ import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
5
+ import { Address } from '@btc-vision/bsi-binary';
6
+ import { crypto as bitCrypto, Payment, Psbt, Signer, Stack } from 'bitcoinjs-lib';
7
+ import { TransactionBuilder } from './TransactionBuilder.js';
8
+ import { CustomGenerator } from '../../generators/builders/CustomGenerator.js';
9
+ import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
10
+ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
11
+ import { AddressGenerator } from '../../generators/AddressGenerator.js';
12
+ import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
13
+ import { PsbtInput } from 'bip174/src/lib/interfaces.js';
14
+
15
+ export interface ICustomTransactionParameters extends SharedInteractionParameters {
16
+ readonly script: (Buffer | Stack)[];
17
+ readonly witnesses: Buffer[];
18
+
19
+ readonly to: Address;
20
+ }
21
+
22
+ /**
23
+ * Class for interaction transactions
24
+ * @class CustomScriptTransaction
25
+ */
26
+ export class CustomScriptTransaction extends TransactionBuilder<TransactionType.CUSTOM_CODE> {
27
+ public type: TransactionType.CUSTOM_CODE = TransactionType.CUSTOM_CODE;
28
+
29
+ /**
30
+ * The contract address
31
+ * @protected
32
+ */
33
+ protected readonly _scriptAddress: Address;
34
+ /**
35
+ * The tap leaf script
36
+ * @private
37
+ */
38
+ protected tapLeafScript: TapLeafScript | null = null;
39
+ /**
40
+ * The target script redeem
41
+ * @private
42
+ */
43
+ private targetScriptRedeem: Payment | null = null;
44
+ /**
45
+ * The left over funds script redeem
46
+ * @private
47
+ */
48
+ private leftOverFundsScriptRedeem: Payment | null = null;
49
+ /**
50
+ * The compiled target script
51
+ * @private
52
+ */
53
+ private readonly compiledTargetScript: Buffer;
54
+ /**
55
+ * The script tree
56
+ * @private
57
+ */
58
+ private readonly scriptTree: Taptree;
59
+ /**
60
+ * The deployment bitcoin generator
61
+ * @private
62
+ */
63
+ private generator: CustomGenerator;
64
+
65
+ /**
66
+ * The contract seed
67
+ * @private
68
+ */
69
+ private readonly scriptSeed: Buffer;
70
+
71
+ /**
72
+ * The contract signer
73
+ * @private
74
+ */
75
+ private readonly contractSigner: Signer;
76
+
77
+ /**
78
+ * The contract salt random bytes
79
+ * @private
80
+ */
81
+ private readonly randomBytes: Buffer;
82
+
83
+ /**
84
+ * The witnesses
85
+ * @private
86
+ */
87
+ private readonly witnesses: Buffer[];
88
+
89
+ public constructor(parameters: ICustomTransactionParameters) {
90
+ super(parameters);
91
+
92
+ if (!parameters.script) throw new Error('Bitcoin script is required');
93
+ if (!parameters.witnesses) throw new Error('Witness(es) are required');
94
+
95
+ this.witnesses = parameters.witnesses;
96
+ this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
97
+
98
+ this.scriptSeed = this.getContractSeed();
99
+ this.contractSigner = EcKeyPair.fromSeedKeyPair(this.scriptSeed, this.network);
100
+
101
+ this.generator = new CustomGenerator(this.internalPubKeyToXOnly(), this.network);
102
+
103
+ this.compiledTargetScript = this.generator.compile(parameters.script);
104
+
105
+ this.scriptTree = this.getScriptTree();
106
+
107
+ this.internalInit();
108
+
109
+ this._scriptAddress = AddressGenerator.generatePKSH(this.scriptSeed, this.network);
110
+ }
111
+
112
+ /**
113
+ * @description Get the contract address (PKSH)
114
+ */
115
+ public get scriptAddress(): Address {
116
+ return this._scriptAddress;
117
+ }
118
+
119
+ /**
120
+ * @description Get the P2TR address
121
+ */
122
+ public get p2trAddress(): Address {
123
+ return this.to || this.getScriptAddress();
124
+ }
125
+
126
+ /**
127
+ * Get the random bytes used for the interaction
128
+ * @returns {Buffer} The random bytes
129
+ */
130
+ public getRndBytes(): Buffer {
131
+ return this.randomBytes;
132
+ }
133
+
134
+ /**
135
+ * Get the contract signer public key
136
+ * @protected
137
+ */
138
+ protected contractSignerXOnlyPubKey(): Buffer {
139
+ return toXOnly(this.contractSigner.publicKey);
140
+ }
141
+
142
+ /**
143
+ * Build the transaction
144
+ * @protected
145
+ */
146
+ protected override async buildTransaction(): Promise<void> {
147
+ if (!this.to) {
148
+ this.to = this.getScriptAddress();
149
+ }
150
+
151
+ const selectedRedeem = !!this.contractSigner
152
+ ? this.targetScriptRedeem
153
+ : this.leftOverFundsScriptRedeem;
154
+
155
+ if (!selectedRedeem) {
156
+ throw new Error('Left over funds script redeem is required');
157
+ }
158
+
159
+ if (!selectedRedeem.redeemVersion) {
160
+ throw new Error('Left over funds script redeem version is required');
161
+ }
162
+
163
+ if (!selectedRedeem.output) {
164
+ throw new Error('Left over funds script redeem output is required');
165
+ }
166
+
167
+ this.tapLeafScript = {
168
+ leafVersion: selectedRedeem.redeemVersion,
169
+ script: selectedRedeem.output,
170
+ controlBlock: this.getWitness(),
171
+ };
172
+
173
+ this.addInputsFromUTXO();
174
+
175
+ const amountSpent: bigint = this.getTransactionOPNetFee();
176
+ this.addOutput({
177
+ value: Number(amountSpent),
178
+ address: this.to,
179
+ });
180
+
181
+ await this.addRefundOutput(amountSpent);
182
+ }
183
+
184
+ /**
185
+ * Sign the inputs
186
+ * @param {Psbt} transaction The transaction to sign
187
+ * @protected
188
+ */
189
+ protected async signInputs(transaction: Psbt): Promise<void> {
190
+ if (!this.contractSigner) {
191
+ await super.signInputs(transaction);
192
+
193
+ return;
194
+ }
195
+
196
+ for (let i = 0; i < transaction.data.inputs.length; i++) {
197
+ if (i === 0) {
198
+ // multi sig input
199
+ transaction.signInput(0, this.contractSigner);
200
+ transaction.signInput(0, this.getSignerKey());
201
+
202
+ transaction.finalizeInput(0, this.customFinalizer);
203
+ } else {
204
+ transaction.signInput(i, this.getSignerKey());
205
+ transaction.finalizeInput(i);
206
+ }
207
+ }
208
+ }
209
+
210
+ /**
211
+ * Get the tap output
212
+ * @protected
213
+ */
214
+ protected override generateScriptAddress(): Payment {
215
+ return {
216
+ internalPubkey: this.internalPubKeyToXOnly(),
217
+ network: this.network,
218
+ scriptTree: this.scriptTree,
219
+ };
220
+ }
221
+
222
+ /**
223
+ * Generate the tap data
224
+ * @protected
225
+ */
226
+ protected override generateTapData(): Payment {
227
+ const selectedRedeem = !!this.contractSigner
228
+ ? this.targetScriptRedeem
229
+ : this.leftOverFundsScriptRedeem;
230
+
231
+ if (!selectedRedeem) {
232
+ throw new Error('Left over funds script redeem is required');
233
+ }
234
+
235
+ if (!this.scriptTree) {
236
+ throw new Error('Script tree is required');
237
+ }
238
+
239
+ return {
240
+ internalPubkey: this.internalPubKeyToXOnly(),
241
+ network: this.network,
242
+ scriptTree: this.scriptTree,
243
+ redeem: selectedRedeem,
244
+ };
245
+ }
246
+
247
+ /**
248
+ * Generate the contract seed for the deployment
249
+ * @private
250
+ */
251
+ private getContractSeed(): Buffer {
252
+ return bitCrypto.hash256(this.randomBytes);
253
+ }
254
+
255
+ /**
256
+ * Finalize the transaction
257
+ * @param _inputIndex
258
+ * @param input
259
+ */
260
+ private customFinalizer = (_inputIndex: number, input: PsbtInput) => {
261
+ if (!this.tapLeafScript) {
262
+ throw new Error('Tap leaf script is required');
263
+ }
264
+
265
+ if (!input.tapScriptSig) {
266
+ throw new Error('Tap script signature is required');
267
+ }
268
+
269
+ const scriptSolution = this.witnesses;
270
+ const witness = scriptSolution
271
+ .concat(this.tapLeafScript.script)
272
+ .concat(this.tapLeafScript.controlBlock);
273
+
274
+ return {
275
+ finalScriptWitness: TransactionBuilder.witnessStackToScriptWitness(witness),
276
+ };
277
+ };
278
+
279
+ /**
280
+ * Get the public keys for the redeem scripts
281
+ * @private
282
+ */
283
+ private getPubKeys(): Buffer[] {
284
+ const pubkeys = [this.signer.publicKey];
285
+
286
+ if (this.contractSigner) {
287
+ pubkeys.push(this.contractSigner.publicKey);
288
+ }
289
+
290
+ return pubkeys;
291
+ }
292
+
293
+ /**
294
+ * Generate the redeem scripts
295
+ * @private
296
+ */
297
+ private generateRedeemScripts(): void {
298
+ this.targetScriptRedeem = {
299
+ pubkeys: this.getPubKeys(),
300
+ output: this.compiledTargetScript,
301
+ redeemVersion: 192,
302
+ };
303
+
304
+ this.leftOverFundsScriptRedeem = {
305
+ pubkeys: this.getPubKeys(),
306
+ output: this.getLeafScript(),
307
+ redeemVersion: 192,
308
+ };
309
+ }
310
+
311
+ /**
312
+ * Get the second leaf script
313
+ * @private
314
+ */
315
+ private getLeafScript(): Buffer {
316
+ return TransactionBuilder.LOCK_LEAF_SCRIPT;
317
+ }
318
+
319
+ /**
320
+ * Get the script tree
321
+ * @private
322
+ */
323
+ private getScriptTree(): Taptree {
324
+ this.generateRedeemScripts();
325
+
326
+ return [
327
+ {
328
+ output: this.compiledTargetScript,
329
+ version: 192,
330
+ },
331
+ {
332
+ output: this.getLeafScript(),
333
+ version: 192,
334
+ },
335
+ ];
336
+ }
337
+ }
@@ -6,4 +6,5 @@ export enum TransactionType {
6
6
  WBTC_WRAP = 4,
7
7
  WBTC_UNWRAP = 5,
8
8
  MULTI_SIG = 6,
9
+ CUSTOM_CODE = 7,
9
10
  }
package/docs/.nojekyll DELETED
@@ -1 +0,0 @@
1
- TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false.
@@ -1,43 +0,0 @@
1
- :root {
2
- --light-hl-0: #795E26;
3
- --dark-hl-0: #DCDCAA;
4
- --light-hl-1: #000000;
5
- --dark-hl-1: #D4D4D4;
6
- --light-hl-2: #A31515;
7
- --dark-hl-2: #CE9178;
8
- --light-code-background: #FFFFFF;
9
- --dark-code-background: #1E1E1E;
10
- }
11
-
12
- @media (prefers-color-scheme: light) { :root {
13
- --hl-0: var(--light-hl-0);
14
- --hl-1: var(--light-hl-1);
15
- --hl-2: var(--light-hl-2);
16
- --code-background: var(--light-code-background);
17
- } }
18
-
19
- @media (prefers-color-scheme: dark) { :root {
20
- --hl-0: var(--dark-hl-0);
21
- --hl-1: var(--dark-hl-1);
22
- --hl-2: var(--dark-hl-2);
23
- --code-background: var(--dark-code-background);
24
- } }
25
-
26
- :root[data-theme='light'] {
27
- --hl-0: var(--light-hl-0);
28
- --hl-1: var(--light-hl-1);
29
- --hl-2: var(--light-hl-2);
30
- --code-background: var(--light-code-background);
31
- }
32
-
33
- :root[data-theme='dark'] {
34
- --hl-0: var(--dark-hl-0);
35
- --hl-1: var(--dark-hl-1);
36
- --hl-2: var(--dark-hl-2);
37
- --code-background: var(--dark-code-background);
38
- }
39
-
40
- .hl-0 { color: var(--hl-0); }
41
- .hl-1 { color: var(--hl-1); }
42
- .hl-2 { color: var(--hl-2); }
43
- pre, code { background: var(--code-background); }