@btc-vision/transaction 1.5.3 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/abi/ABICoder.d.ts +1 -0
  3. package/browser/buffer/BinaryWriter.d.ts +1 -1
  4. package/browser/epoch/ChallengeSolution.d.ts +45 -0
  5. package/browser/epoch/interfaces/IChallengeSolution.d.ts +50 -0
  6. package/browser/epoch/validator/EpochValidator.d.ts +19 -0
  7. package/browser/generators/Features.d.ts +6 -1
  8. package/browser/generators/Generator.d.ts +1 -0
  9. package/browser/generators/builders/CalldataGenerator.d.ts +2 -1
  10. package/browser/generators/builders/DeploymentGenerator.d.ts +3 -1
  11. package/browser/index.js +1 -1
  12. package/browser/keypair/Address.d.ts +2 -0
  13. package/browser/opnet.d.ts +4 -3
  14. package/browser/transaction/TransactionFactory.d.ts +4 -15
  15. package/browser/transaction/browser/Web3Provider.d.ts +3 -3
  16. package/browser/transaction/browser/types/Unisat.d.ts +1 -1
  17. package/browser/transaction/builders/ChallengeSolutionTransaction.d.ts +1 -18
  18. package/browser/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  19. package/browser/transaction/builders/DeploymentTransaction.d.ts +6 -4
  20. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +5 -4
  21. package/browser/transaction/builders/TransactionBuilder.d.ts +2 -0
  22. package/browser/transaction/interfaces/ITransactionParameters.d.ts +4 -6
  23. package/browser/transaction/mineable/TimelockGenerator.d.ts +9 -0
  24. package/browser/utils/StringToBuffer.d.ts +1 -0
  25. package/browser/verification/TapscriptVerificator.d.ts +4 -1
  26. package/build/_version.d.ts +1 -1
  27. package/build/_version.js +1 -1
  28. package/build/abi/ABICoder.d.ts +1 -0
  29. package/build/abi/ABICoder.js +4 -0
  30. package/build/buffer/BinaryWriter.d.ts +1 -1
  31. package/build/buffer/BinaryWriter.js +11 -9
  32. package/build/epoch/ChallengeSolution.d.ts +45 -0
  33. package/build/epoch/ChallengeSolution.js +105 -0
  34. package/build/epoch/interfaces/IChallengeSolution.d.ts +50 -0
  35. package/build/epoch/interfaces/IChallengeSolution.js +1 -0
  36. package/build/epoch/validator/EpochValidator.d.ts +19 -0
  37. package/build/epoch/validator/EpochValidator.js +99 -0
  38. package/build/generators/Features.d.ts +6 -1
  39. package/build/generators/Features.js +1 -0
  40. package/build/generators/Generator.d.ts +1 -0
  41. package/build/generators/Generator.js +17 -1
  42. package/build/generators/builders/CalldataGenerator.d.ts +2 -1
  43. package/build/generators/builders/CalldataGenerator.js +4 -2
  44. package/build/generators/builders/DeploymentGenerator.d.ts +3 -1
  45. package/build/generators/builders/DeploymentGenerator.js +5 -3
  46. package/build/keypair/Address.d.ts +2 -0
  47. package/build/keypair/Address.js +12 -0
  48. package/build/keypair/EcKeyPair.js +10 -7
  49. package/build/opnet.d.ts +4 -3
  50. package/build/opnet.js +4 -3
  51. package/build/transaction/TransactionFactory.d.ts +4 -15
  52. package/build/transaction/TransactionFactory.js +4 -32
  53. package/build/transaction/browser/Web3Provider.d.ts +3 -3
  54. package/build/transaction/browser/types/Unisat.d.ts +1 -1
  55. package/build/transaction/builders/ChallengeSolutionTransaction.d.ts +0 -18
  56. package/build/transaction/builders/ChallengeSolutionTransaction.js +1 -51
  57. package/build/transaction/builders/CustomScriptTransaction.d.ts +1 -1
  58. package/build/transaction/builders/DeploymentTransaction.d.ts +6 -4
  59. package/build/transaction/builders/DeploymentTransaction.js +19 -7
  60. package/build/transaction/builders/InteractionTransaction.js +8 -1
  61. package/build/transaction/builders/SharedInteractionTransaction.d.ts +5 -4
  62. package/build/transaction/builders/SharedInteractionTransaction.js +7 -7
  63. package/build/transaction/builders/TransactionBuilder.d.ts +2 -0
  64. package/build/transaction/builders/TransactionBuilder.js +31 -3
  65. package/build/transaction/interfaces/ITransactionParameters.d.ts +4 -6
  66. package/build/transaction/mineable/TimelockGenerator.d.ts +9 -0
  67. package/build/transaction/mineable/TimelockGenerator.js +24 -0
  68. package/build/utils/StringToBuffer.d.ts +1 -0
  69. package/build/utils/StringToBuffer.js +3 -0
  70. package/build/verification/TapscriptVerificator.d.ts +4 -1
  71. package/build/verification/TapscriptVerificator.js +2 -2
  72. package/package.json +16 -16
  73. package/src/_version.ts +1 -1
  74. package/src/abi/ABICoder.ts +4 -0
  75. package/src/buffer/BinaryWriter.ts +13 -11
  76. package/src/epoch/ChallengeSolution.ts +196 -0
  77. package/src/epoch/interfaces/IChallengeSolution.ts +56 -0
  78. package/src/epoch/validator/EpochValidator.ts +180 -0
  79. package/src/generators/Features.ts +6 -0
  80. package/src/generators/Generator.ts +24 -2
  81. package/src/generators/builders/CalldataGenerator.ts +7 -3
  82. package/src/generators/builders/DeploymentGenerator.ts +18 -6
  83. package/src/keypair/Address.ts +34 -0
  84. package/src/keypair/EcKeyPair.ts +13 -8
  85. package/src/opnet.ts +6 -3
  86. package/src/transaction/TransactionFactory.ts +7 -62
  87. package/src/transaction/browser/Web3Provider.ts +3 -3
  88. package/src/transaction/browser/types/Unisat.ts +1 -1
  89. package/src/transaction/builders/ChallengeSolutionTransaction.ts +3 -4
  90. package/src/transaction/builders/CustomScriptTransaction.ts +2 -1
  91. package/src/transaction/builders/DeploymentTransaction.ts +27 -9
  92. package/src/transaction/builders/InteractionTransaction.ts +10 -2
  93. package/src/transaction/builders/SharedInteractionTransaction.ts +12 -28
  94. package/src/transaction/builders/TransactionBuilder.ts +40 -2
  95. package/src/transaction/interfaces/ITransactionParameters.ts +5 -8
  96. package/src/transaction/mineable/TimelockGenerator.ts +42 -0
  97. package/src/utils/StringToBuffer.ts +3 -0
  98. package/src/verification/TapscriptVerificator.ts +8 -4
  99. package/browser/generators/builders/MineableReward.d.ts +0 -7
  100. package/browser/transaction/mineable/ChallengeGenerator.d.ts +0 -9
  101. package/build/generators/builders/MineableReward.d.ts +0 -7
  102. package/build/generators/builders/MineableReward.js +0 -48
  103. package/build/transaction/mineable/ChallengeGenerator.d.ts +0 -9
  104. package/build/transaction/mineable/ChallengeGenerator.js +0 -28
  105. package/src/generators/builders/MineableReward.ts +0 -66
  106. package/src/transaction/mineable/ChallengeGenerator.ts +0 -39
@@ -4,12 +4,13 @@ import { P2TRPayment, Psbt } from '@btc-vision/bitcoin';
4
4
  import { TransactionBuilder } from './TransactionBuilder.js';
5
5
  import { TapLeafScript } from '../interfaces/Tap.js';
6
6
  import { Address } from '../../keypair/Address.js';
7
- import { IMineableReward } from '../mineable/ChallengeGenerator.js';
7
+ import { ITimeLockOutput } from '../mineable/TimelockGenerator.js';
8
+ import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
8
9
  export declare class DeploymentTransaction extends TransactionBuilder<TransactionType.DEPLOYMENT> {
9
10
  static readonly MAXIMUM_CONTRACT_SIZE: number;
10
11
  type: TransactionType.DEPLOYMENT;
11
- protected readonly preimage: Buffer;
12
- protected readonly rewardChallenge: IMineableReward;
12
+ protected readonly preimage: ChallengeSolution;
13
+ protected readonly epochChallenge: ITimeLockOutput;
13
14
  protected readonly _contractAddress: Address;
14
15
  protected tapLeafScript: TapLeafScript | null;
15
16
  private readonly deploymentVersion;
@@ -30,7 +31,7 @@ export declare class DeploymentTransaction extends TransactionBuilder<Transactio
30
31
  get contractAddress(): Address;
31
32
  get p2trAddress(): string;
32
33
  getRndBytes(): Buffer;
33
- getPreimage(): Buffer;
34
+ getPreimage(): ChallengeSolution;
34
35
  getContractAddress(): string;
35
36
  protected contractSignerXOnlyPubKey(): Buffer;
36
37
  protected buildTransaction(): Promise<void>;
@@ -38,6 +39,7 @@ export declare class DeploymentTransaction extends TransactionBuilder<Transactio
38
39
  protected signInputs(transaction: Psbt): Promise<void>;
39
40
  protected generateScriptAddress(): P2TRPayment;
40
41
  protected generateTapData(): P2TRPayment;
42
+ private generateFeatures;
41
43
  private verifyCalldata;
42
44
  private verifyBytecode;
43
45
  private getContractSeed;
@@ -7,7 +7,8 @@ import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
7
7
  import { Compressor } from '../../bytecode/Compressor.js';
8
8
  import { SharedInteractionTransaction } from './SharedInteractionTransaction.js';
9
9
  import { Address } from '../../keypair/Address.js';
10
- import { ChallengeGenerator } from '../mineable/ChallengeGenerator.js';
10
+ import { TimeLockGenerator } from '../mineable/TimelockGenerator.js';
11
+ import { Features } from '../../generators/Features.js';
11
12
  export class DeploymentTransaction extends TransactionBuilder {
12
13
  constructor(parameters) {
13
14
  super(parameters);
@@ -41,15 +42,15 @@ export class DeploymentTransaction extends TransactionBuilder {
41
42
  this.calldata = parameters.calldata;
42
43
  this.verifyCalldata();
43
44
  }
44
- if (!parameters.preimage)
45
- throw new Error('Preimage is required');
45
+ if (!parameters.challenge)
46
+ throw new Error('Challenge solution is required');
46
47
  this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
47
- this.preimage = parameters.preimage;
48
- this.rewardChallenge = ChallengeGenerator.generateMineableReward(this.preimage, this.network);
48
+ this.preimage = parameters.challenge;
49
+ this.epochChallenge = TimeLockGenerator.generateTimeLockAddress(this.preimage.publicKey.originalPublicKeyBuffer(), this.network);
49
50
  this.contractSeed = this.getContractSeed();
50
51
  this.contractSigner = EcKeyPair.fromSeedKeyPair(this.contractSeed, this.network);
51
52
  this.deploymentGenerator = new DeploymentGenerator(Buffer.from(this.signer.publicKey), this.contractSignerXOnlyPubKey(), this.network);
52
- this.compiledTargetScript = this.deploymentGenerator.compile(this.bytecode, this.randomBytes, this.preimage, this.priorityFee, this.calldata);
53
+ this.compiledTargetScript = this.deploymentGenerator.compile(this.bytecode, this.randomBytes, this.preimage, this.priorityFee, this.calldata, this.generateFeatures(parameters));
53
54
  this.scriptTree = this.getScriptTree();
54
55
  this.internalInit();
55
56
  this._contractPubKey = '0x' + this.contractSeed.toString('hex');
@@ -118,7 +119,7 @@ export class DeploymentTransaction extends TransactionBuilder {
118
119
  amountSpent - MINIMUM_AMOUNT_CA > MINIMUM_AMOUNT_REWARD) {
119
120
  this.addOutput({
120
121
  value: Number(amountSpent - amountToCA),
121
- address: this.rewardChallenge.address,
122
+ address: this.epochChallenge.address,
122
123
  });
123
124
  }
124
125
  await this.addRefundOutput(amountSpent + this.addOptionalOutputsAndGetAmount());
@@ -193,6 +194,17 @@ export class DeploymentTransaction extends TransactionBuilder {
193
194
  redeem: selectedRedeem,
194
195
  };
195
196
  }
197
+ generateFeatures(parameters) {
198
+ const features = [];
199
+ const submission = parameters.challenge.getSubmission();
200
+ if (submission) {
201
+ features.push({
202
+ opcode: Features.EPOCH_SUBMISSION,
203
+ data: submission,
204
+ });
205
+ }
206
+ return features;
207
+ }
196
208
  verifyCalldata() {
197
209
  if (this.calldata &&
198
210
  this.calldata.length > SharedInteractionTransaction.MAXIMUM_CALLDATA_SIZE) {
@@ -13,7 +13,7 @@ export class InteractionTransaction extends SharedInteractionTransaction {
13
13
  if (this.contractSecret.length !== 32) {
14
14
  throw new Error('Invalid contract secret length. Expected 32 bytes.');
15
15
  }
16
- this.compiledTargetScript = this.calldataGenerator.compile(this.calldata, this.contractSecret, this.preimage, this.priorityFee, this.generateFeatures(parameters));
16
+ this.compiledTargetScript = this.calldataGenerator.compile(this.calldata, this.contractSecret, this.challenge, this.priorityFee, this.generateFeatures(parameters));
17
17
  this.scriptTree = this.getScriptTree();
18
18
  this.internalInit();
19
19
  }
@@ -25,6 +25,13 @@ export class InteractionTransaction extends SharedInteractionTransaction {
25
25
  data: parameters.loadedStorage,
26
26
  });
27
27
  }
28
+ const submission = parameters.challenge.getSubmission();
29
+ if (submission) {
30
+ features.push({
31
+ opcode: Features.EPOCH_SUBMISSION,
32
+ data: submission,
33
+ });
34
+ }
28
35
  return features;
29
36
  }
30
37
  }
@@ -4,7 +4,8 @@ import { TransactionBuilder } from './TransactionBuilder.js';
4
4
  import { TransactionType } from '../enums/TransactionType.js';
5
5
  import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
6
6
  import { SharedInteractionParameters } from '../interfaces/ITransactionParameters.js';
7
- import { IMineableReward } from '../mineable/ChallengeGenerator.js';
7
+ import { ITimeLockOutput } from '../mineable/TimelockGenerator.js';
8
+ import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
8
9
  export declare abstract class SharedInteractionTransaction<T extends TransactionType> extends TransactionBuilder<T> {
9
10
  static readonly MAXIMUM_CALLDATA_SIZE: number;
10
11
  readonly randomBytes: Buffer;
@@ -12,8 +13,8 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
12
13
  protected leftOverFundsScriptRedeem: P2TRPayment | null;
13
14
  protected abstract readonly compiledTargetScript: Buffer;
14
15
  protected abstract readonly scriptTree: Taptree;
15
- protected readonly preimage: Buffer;
16
- protected readonly rewardChallenge: IMineableReward;
16
+ protected readonly challenge: ChallengeSolution;
17
+ protected readonly epochChallenge: ITimeLockOutput;
17
18
  protected calldataGenerator: CalldataGenerator;
18
19
  protected readonly calldata: Buffer;
19
20
  protected abstract readonly contractSecret: Buffer;
@@ -22,7 +23,7 @@ export declare abstract class SharedInteractionTransaction<T extends Transaction
22
23
  protected constructor(parameters: SharedInteractionParameters);
23
24
  getContractSecret(): Buffer;
24
25
  getRndBytes(): Buffer;
25
- getPreimage(): Buffer;
26
+ getPreimage(): ChallengeSolution;
26
27
  protected scriptSignerXOnlyPubKey(): Buffer;
27
28
  protected generateKeyPairFromSeed(): ECPairInterface;
28
29
  protected buildTransaction(): Promise<void>;
@@ -4,7 +4,7 @@ import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.j
4
4
  import { Compressor } from '../../bytecode/Compressor.js';
5
5
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
6
6
  import { BitcoinUtils } from '../../utils/BitcoinUtils.js';
7
- import { ChallengeGenerator } from '../mineable/ChallengeGenerator.js';
7
+ import { TimeLockGenerator } from '../mineable/TimelockGenerator.js';
8
8
  export class SharedInteractionTransaction extends TransactionBuilder {
9
9
  constructor(parameters) {
10
10
  super(parameters);
@@ -28,12 +28,12 @@ export class SharedInteractionTransaction extends TransactionBuilder {
28
28
  if (!parameters.calldata) {
29
29
  throw new Error('Calldata is required');
30
30
  }
31
- if (!parameters.preimage) {
32
- throw new Error('Preimage is required');
31
+ if (!parameters.challenge) {
32
+ throw new Error('Challenge solution is required');
33
33
  }
34
- this.preimage = parameters.preimage;
34
+ this.challenge = parameters.challenge;
35
35
  this.disableAutoRefund = parameters.disableAutoRefund || false;
36
- this.rewardChallenge = ChallengeGenerator.generateMineableReward(this.preimage, this.network);
36
+ this.epochChallenge = TimeLockGenerator.generateTimeLockAddress(this.challenge.publicKey.originalPublicKeyBuffer(), this.network);
37
37
  this.calldata = Compressor.compress(parameters.calldata);
38
38
  this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
39
39
  this.scriptSigner = this.generateKeyPairFromSeed();
@@ -46,7 +46,7 @@ export class SharedInteractionTransaction extends TransactionBuilder {
46
46
  return this.randomBytes;
47
47
  }
48
48
  getPreimage() {
49
- return this.preimage;
49
+ return this.challenge;
50
50
  }
51
51
  scriptSignerXOnlyPubKey() {
52
52
  return toXOnly(Buffer.from(this.scriptSigner.publicKey));
@@ -196,7 +196,7 @@ export class SharedInteractionTransaction extends TransactionBuilder {
196
196
  amountSpent - MINIMUM_AMOUNT_CA > MINIMUM_AMOUNT_REWARD) {
197
197
  this.addOutput({
198
198
  value: Number(amountSpent - amountToCA),
199
- address: this.rewardChallenge.address,
199
+ address: this.epochChallenge.address,
200
200
  });
201
201
  }
202
202
  const amount = this.addOptionalOutputsAndGetAmount();
@@ -33,9 +33,11 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
33
33
  protected from: string;
34
34
  protected _maximumFeeRate: number;
35
35
  protected isPubKeyDestination: boolean;
36
+ protected note?: Buffer;
36
37
  protected constructor(parameters: ITransactionParameters);
37
38
  static getFrom(from: string | undefined, keypair: ECPairInterface | Signer, network: Network): string;
38
39
  static witnessStackToScriptWitness(witness: Buffer[]): Buffer;
40
+ addOPReturn(buffer: Buffer): void;
39
41
  getFundingTransactionParameters(): Promise<IFundingTransactionParameters>;
40
42
  setDestinationAddress(address: string): void;
41
43
  setMaximumFeeRate(feeRate: number): void;
@@ -28,6 +28,14 @@ export class TransactionBuilder extends TweakedTransaction {
28
28
  this.utxos = parameters.utxos;
29
29
  this.optionalInputs = parameters.optionalInputs || [];
30
30
  this.to = parameters.to || undefined;
31
+ if (parameters.note) {
32
+ if (typeof parameters.note === 'string') {
33
+ this.note = Buffer.from(parameters.note, 'utf8');
34
+ }
35
+ else {
36
+ this.note = parameters.note;
37
+ }
38
+ }
31
39
  this.isPubKeyDestination = this.to
32
40
  ? AddressVerificator.isValidPublicKey(this.to, this.network)
33
41
  : false;
@@ -67,6 +75,13 @@ export class TransactionBuilder extends TweakedTransaction {
67
75
  writeVector(witness);
68
76
  return buffer;
69
77
  }
78
+ addOPReturn(buffer) {
79
+ const compileScript = script.compile([opcodes.OP_RETURN, buffer]);
80
+ this.addOutput({
81
+ value: 0,
82
+ script: compileScript,
83
+ });
84
+ }
70
85
  async getFundingTransactionParameters() {
71
86
  if (!this.estimatedFees) {
72
87
  this.estimatedFees = await this.estimateTransactionFees();
@@ -141,9 +156,19 @@ export class TransactionBuilder extends TweakedTransaction {
141
156
  this.inputs.push(input);
142
157
  }
143
158
  addOutput(output) {
144
- if (output.value === 0)
145
- return;
146
- if (output.value < TransactionBuilder.MINIMUM_DUST) {
159
+ if (output.value === 0) {
160
+ const script = output;
161
+ if (!script.script || script.script.length === 0) {
162
+ throw new Error('Output value is 0 and no script provided');
163
+ }
164
+ if (script.script.length < 2) {
165
+ throw new Error('Output script is too short');
166
+ }
167
+ if (script.script[0] !== opcodes.OP_RETURN) {
168
+ throw new Error('Output script must start with OP_RETURN when value is 0');
169
+ }
170
+ }
171
+ else if (output.value < TransactionBuilder.MINIMUM_DUST) {
147
172
  throw new Error(`Output value is less than the minimum dust ${output.value} < ${TransactionBuilder.MINIMUM_DUST}`);
148
173
  }
149
174
  this.outputs.push(output);
@@ -203,6 +228,9 @@ export class TransactionBuilder extends TweakedTransaction {
203
228
  return total;
204
229
  }
205
230
  async addRefundOutput(amountSpent) {
231
+ if (this.note) {
232
+ this.addOPReturn(this.note);
233
+ }
206
234
  const sendBackAmount = this.totalInputAmount - amountSpent;
207
235
  if (sendBackAmount >= TransactionBuilder.MINIMUM_DUST) {
208
236
  if (AddressVerificator.isValidP2TRAddress(this.from, this.network)) {
@@ -2,6 +2,7 @@ import { UTXO } from '../../utxo/interfaces/IUTXO.js';
2
2
  import { ITweakedTransactionData } from '../shared/TweakedTransaction.js';
3
3
  import { ChainId } from '../../network/ChainId.js';
4
4
  import { PsbtOutputExtended } from '@btc-vision/bitcoin';
5
+ import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
5
6
  export interface LoadedStorage {
6
7
  [key: string]: string[];
7
8
  }
@@ -15,6 +16,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
15
16
  optionalOutputs?: PsbtOutputExtended[];
16
17
  chainId?: ChainId;
17
18
  noSignatures?: boolean;
19
+ readonly note?: string | Buffer;
18
20
  readonly feeRate: number;
19
21
  readonly priorityFee: bigint;
20
22
  readonly gasSatFee: bigint;
@@ -23,14 +25,10 @@ export interface IFundingTransactionParameters extends ITransactionParameters {
23
25
  amount: bigint;
24
26
  splitInputsInto?: number;
25
27
  }
26
- export interface IChallengeSolutionTransactionParameters extends ITransactionParameters {
27
- amount: bigint;
28
- readonly challengeSolution: Buffer;
29
- }
30
28
  export interface SharedInteractionParameters extends ITransactionParameters {
31
29
  calldata?: Buffer;
32
30
  disableAutoRefund?: boolean;
33
- readonly preimage: Buffer;
31
+ readonly challenge: ChallengeSolution;
34
32
  readonly randomBytes?: Buffer;
35
33
  readonly loadedStorage?: LoadedStorage;
36
34
  }
@@ -43,5 +41,5 @@ export interface IDeploymentParameters extends Omit<ITransactionParameters, 'to'
43
41
  readonly bytecode: Buffer;
44
42
  readonly calldata?: Buffer;
45
43
  readonly randomBytes?: Buffer;
46
- readonly preimage: Buffer;
44
+ readonly challenge: ChallengeSolution;
47
45
  }
@@ -0,0 +1,9 @@
1
+ import { Network } from '@btc-vision/bitcoin';
2
+ export interface ITimeLockOutput {
3
+ address: string;
4
+ witnessScript: Buffer;
5
+ }
6
+ export declare class TimeLockGenerator {
7
+ private static readonly CSV_BLOCKS;
8
+ static generateTimeLockAddress(publicKey: Buffer, network?: Network, csvBlocks?: number): ITimeLockOutput;
9
+ }
@@ -0,0 +1,24 @@
1
+ import bitcoin, { networks, opcodes, script } from '@btc-vision/bitcoin';
2
+ export class TimeLockGenerator {
3
+ static generateTimeLockAddress(publicKey, network = networks.bitcoin, csvBlocks = TimeLockGenerator.CSV_BLOCKS) {
4
+ const witnessScript = script.compile([
5
+ script.number.encode(csvBlocks),
6
+ opcodes.OP_CHECKSEQUENCEVERIFY,
7
+ opcodes.OP_DROP,
8
+ publicKey,
9
+ opcodes.OP_CHECKSIG,
10
+ ]);
11
+ const p2wsh = bitcoin.payments.p2wsh({
12
+ redeem: { output: witnessScript },
13
+ network,
14
+ });
15
+ if (!p2wsh.address) {
16
+ throw new Error('Failed to generate P2WSH address');
17
+ }
18
+ return {
19
+ address: p2wsh.address,
20
+ witnessScript: witnessScript,
21
+ };
22
+ }
23
+ }
24
+ TimeLockGenerator.CSV_BLOCKS = 75;
@@ -0,0 +1 @@
1
+ export declare function stringToBuffer(str: string): Buffer;
@@ -0,0 +1,3 @@
1
+ export function stringToBuffer(str) {
2
+ return Buffer.from(str.replace('0x', ''), 'hex');
3
+ }
@@ -1,11 +1,14 @@
1
1
  import { Network, Taptree } from '@btc-vision/bitcoin';
2
+ import { ChallengeSolution } from '../epoch/ChallengeSolution.js';
3
+ import { Feature, Features } from '../generators/Features.js';
2
4
  export interface ContractAddressVerificationParams {
3
5
  readonly deployerPubKey: Buffer;
4
6
  readonly contractSaltPubKey: Buffer;
5
7
  readonly originalSalt: Buffer;
6
8
  readonly bytecode: Buffer;
7
- readonly preimage: Buffer;
9
+ readonly challenge: ChallengeSolution;
8
10
  readonly priorityFee: bigint;
11
+ readonly features: Feature<Features>[];
9
12
  readonly calldata?: Buffer;
10
13
  readonly network?: Network;
11
14
  }
@@ -5,7 +5,7 @@ export class TapscriptVerificator {
5
5
  static getContractAddress(params) {
6
6
  const network = params.network || networks.bitcoin;
7
7
  const scriptBuilder = new DeploymentGenerator(params.deployerPubKey, toXOnly(params.contractSaltPubKey), network);
8
- const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt, params.preimage, params.priorityFee, params.calldata);
8
+ const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt, params.challenge, params.priorityFee, params.calldata, params.features);
9
9
  const scriptTree = [
10
10
  {
11
11
  output: compiledTargetScript,
@@ -21,7 +21,7 @@ export class TapscriptVerificator {
21
21
  static verifyControlBlock(params, controlBlock) {
22
22
  const network = params.network || networks.bitcoin;
23
23
  const scriptBuilder = new DeploymentGenerator(params.deployerPubKey, toXOnly(params.contractSaltPubKey), network);
24
- const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt, params.preimage, params.priorityFee, params.calldata);
24
+ const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt, params.challenge, params.priorityFee, params.calldata, params.features);
25
25
  const scriptTree = [
26
26
  {
27
27
  output: compiledTargetScript,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@btc-vision/transaction",
3
3
  "type": "module",
4
- "version": "1.5.3",
4
+ "version": "1.6.0",
5
5
  "author": "BlobMaster41",
6
6
  "description": "OPNet transaction library allows you to create and sign transactions for the OPNet network.",
7
7
  "engines": {
@@ -64,39 +64,39 @@
64
64
  "docs": "typedoc --out docs --exclude 'src/tests/*.ts' --tsconfig tsconfig.json --readme README.md --name OPNet --plugin typedoc-material-theme --themeColor '#cb9820' --exclude src/tests/test.ts --exclude src/index.ts src"
65
65
  },
66
66
  "devDependencies": {
67
- "@babel/core": "^7.27.4",
67
+ "@babel/core": "^7.28.0",
68
68
  "@babel/plugin-proposal-class-properties": "^7.18.6",
69
- "@babel/plugin-transform-runtime": "^7.27.4",
70
- "@babel/preset-env": "^7.27.2",
69
+ "@babel/plugin-transform-runtime": "^7.28.0",
70
+ "@babel/preset-env": "^7.28.0",
71
71
  "@babel/preset-flow": "^7.27.1",
72
72
  "@babel/preset-react": "^7.27.1",
73
73
  "@babel/preset-typescript": "^7.27.1",
74
- "@types/node": "^22.15.29",
74
+ "@types/node": "^24.1.0",
75
75
  "@types/sha.js": "^2.4.4",
76
- "eslint": "^9.28.0",
76
+ "eslint": "^9.32.0",
77
77
  "gulp": "^5.0.1",
78
78
  "gulp-cached": "^1.1.1",
79
79
  "gulp-typescript": "^6.0.0-alpha.1",
80
80
  "https-browserify": "^1.0.0",
81
81
  "os-browserify": "^0.3.0",
82
- "prettier": "^3.5.3",
82
+ "prettier": "^3.6.2",
83
83
  "stream-browserify": "^3.0.0",
84
84
  "stream-http": "^3.2.0",
85
- "typedoc": "^0.28.5",
86
- "typescript-eslint": "^8.33.0",
85
+ "typedoc": "^0.28.7",
86
+ "typescript-eslint": "^8.38.0",
87
87
  "webpack-cli": "^6.0.1"
88
88
  },
89
89
  "dependencies": {
90
- "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
90
+ "@babel/plugin-proposal-object-rest-spread": "^7.21.4-esm",
91
91
  "@bitcoinerlab/secp256k1": "^1.2.0",
92
92
  "@btc-vision/bitcoin": "^6.4.6",
93
- "@btc-vision/bitcoin-rpc": "^1.0.1",
93
+ "@btc-vision/bitcoin-rpc": "^1.0.2",
94
94
  "@btc-vision/logger": "^1.0.6",
95
- "@eslint/js": "^9.28.0",
96
- "@noble/secp256k1": "^2.2.3",
95
+ "@eslint/js": "^9.32.0",
96
+ "@noble/secp256k1": "^2.3.0",
97
97
  "assert": "^2.1.0",
98
98
  "babel-loader": "^10.0.0",
99
- "babel-plugin-transform-import-meta": "^2.3.2",
99
+ "babel-plugin-transform-import-meta": "^2.3.3",
100
100
  "babel-preset-react": "^6.24.1",
101
101
  "babelify": "^10.0.0",
102
102
  "bech32": "^2.0.0",
@@ -109,10 +109,10 @@
109
109
  "gulp-eslint-new": "^2.4.0",
110
110
  "gulp-logger-new": "^1.0.1",
111
111
  "process": "^0.11.10",
112
- "sha.js": "^2.4.11",
112
+ "sha.js": "^2.4.12",
113
113
  "ts-loader": "^9.5.2",
114
114
  "ts-node": "^10.9.2",
115
115
  "typescript": "^5.8.3",
116
- "webpack": "^5.99.9"
116
+ "webpack": "^5.100.2"
117
117
  }
118
118
  }
package/src/_version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '1.5.3';
1
+ export const version = '1.6.0';
@@ -14,6 +14,7 @@ export enum ABIDataTypes {
14
14
  BOOL = 'BOOL',
15
15
  ADDRESS = 'ADDRESS',
16
16
  STRING = 'STRING',
17
+ BYTES4 = 'BYTES4',
17
18
  BYTES32 = 'BYTES32',
18
19
  BYTES = 'BYTES',
19
20
  ADDRESS_UINT256_TUPLE = 'ADDRESS_UINT256_TUPLE',
@@ -45,6 +46,9 @@ export class ABICoder {
45
46
  case ABIDataTypes.UINT32:
46
47
  result.push(byteReader.readU32());
47
48
  break;
49
+ case ABIDataTypes.BYTES4:
50
+ result.push(byteReader.readBytes(4));
51
+ break;
48
52
  case ABIDataTypes.BYTES32:
49
53
  result.push(byteReader.readBytes(32));
50
54
  break;
@@ -146,24 +146,26 @@ export class BinaryWriter {
146
146
  }
147
147
 
148
148
  public writeString(value: string): void {
149
- this.allocSafe(value.length);
149
+ const encoder = new TextEncoder();
150
+ const bytes = encoder.encode(value);
150
151
 
151
- for (let i: i32 = 0; i < value.length; i++) {
152
- this.writeU8(value.charCodeAt(i));
153
- }
152
+ this.allocSafe(bytes.length);
153
+ this.writeBytes(bytes);
154
154
  }
155
155
 
156
- public writeAddress(value: Address): void {
157
- this.verifyAddress(value);
156
+ public writeStringWithLength(value: string): void {
157
+ const encoder = new TextEncoder();
158
+ const bytes = encoder.encode(value);
158
159
 
159
- this.writeBytes(value);
160
+ this.allocSafe(U32_BYTE_LENGTH + bytes.length);
161
+ this.writeU32(bytes.length);
162
+ this.writeBytes(bytes);
160
163
  }
161
164
 
162
- public writeStringWithLength(value: string): void {
163
- this.allocSafe(U32_BYTE_LENGTH + value.length);
165
+ public writeAddress(value: Address): void {
166
+ this.verifyAddress(value);
164
167
 
165
- this.writeU32(value.length);
166
- this.writeString(value);
168
+ this.writeBytes(value);
167
169
  }
168
170
 
169
171
  public getBuffer(clear: boolean = true): Uint8Array {