@btc-vision/transaction 1.2.6 → 1.2.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 (49) hide show
  1. package/README.md +4 -19
  2. package/browser/_version.d.ts +1 -1
  3. package/browser/generators/Generator.d.ts +1 -0
  4. package/browser/generators/builders/CalldataGenerator.d.ts +1 -1
  5. package/browser/generators/builders/DeploymentGenerator.d.ts +1 -1
  6. package/browser/generators/builders/LegacyCalldataGenerator.d.ts +1 -1
  7. package/browser/index.js +1 -1
  8. package/browser/transaction/builders/MultiSignTransaction.d.ts +1 -1
  9. package/browser/transaction/builders/TransactionBuilder.d.ts +1 -0
  10. package/browser/transaction/interfaces/ITransactionParameters.d.ts +1 -0
  11. package/browser/verification/TapscriptVerificator.d.ts +1 -0
  12. package/build/_version.d.ts +1 -1
  13. package/build/_version.js +1 -1
  14. package/build/generators/Generator.d.ts +1 -0
  15. package/build/generators/Generator.js +7 -0
  16. package/build/generators/builders/CalldataGenerator.d.ts +1 -1
  17. package/build/generators/builders/CalldataGenerator.js +2 -2
  18. package/build/generators/builders/DeploymentGenerator.d.ts +1 -1
  19. package/build/generators/builders/DeploymentGenerator.js +4 -4
  20. package/build/generators/builders/LegacyCalldataGenerator.d.ts +1 -1
  21. package/build/generators/builders/LegacyCalldataGenerator.js +5 -23
  22. package/build/transaction/TransactionFactory.js +3 -2
  23. package/build/transaction/builders/DeploymentTransaction.js +1 -1
  24. package/build/transaction/builders/InteractionTransaction.js +1 -1
  25. package/build/transaction/builders/MultiSignTransaction.d.ts +1 -1
  26. package/build/transaction/builders/MultiSignTransaction.js +1 -0
  27. package/build/transaction/builders/SharedInteractionTransaction.js +3 -0
  28. package/build/transaction/builders/TransactionBuilder.d.ts +1 -0
  29. package/build/transaction/builders/TransactionBuilder.js +5 -2
  30. package/build/transaction/interfaces/ITransactionParameters.d.ts +1 -0
  31. package/build/utxo/OPNetLimitedProvider.js +2 -1
  32. package/build/verification/TapscriptVerificator.d.ts +1 -0
  33. package/build/verification/TapscriptVerificator.js +2 -2
  34. package/package.json +3 -3
  35. package/src/_version.ts +1 -1
  36. package/src/generators/Generator.ts +9 -0
  37. package/src/generators/builders/CalldataGenerator.ts +4 -1
  38. package/src/generators/builders/DeploymentGenerator.ts +6 -3
  39. package/src/generators/builders/LegacyCalldataGenerator.ts +11 -40
  40. package/src/transaction/TransactionFactory.ts +3 -2
  41. package/src/transaction/browser/extensions/UnisatSigner.ts +1 -1
  42. package/src/transaction/builders/DeploymentTransaction.ts +1 -0
  43. package/src/transaction/builders/InteractionTransaction.ts +1 -0
  44. package/src/transaction/builders/MultiSignTransaction.ts +2 -1
  45. package/src/transaction/builders/SharedInteractionTransaction.ts +4 -0
  46. package/src/transaction/builders/TransactionBuilder.ts +6 -2
  47. package/src/transaction/interfaces/ITransactionParameters.ts +1 -0
  48. package/src/utxo/OPNetLimitedProvider.ts +2 -1
  49. package/src/verification/TapscriptVerificator.ts +3 -0
@@ -3,7 +3,7 @@ import { TransactionBuilder } from './TransactionBuilder.js';
3
3
  import { TransactionType } from '../enums/TransactionType.js';
4
4
  import { ITransactionParameters } from '../interfaces/ITransactionParameters.js';
5
5
  import { ECPairInterface } from 'ecpair';
6
- export interface MultiSignParameters extends Omit<ITransactionParameters, 'priorityFee' | 'signer'> {
6
+ export interface MultiSignParameters extends Omit<ITransactionParameters, 'gasSatFee' | 'priorityFee' | 'signer'> {
7
7
  readonly pubkeys: Buffer[];
8
8
  readonly minimumSignatures: number;
9
9
  readonly from?: undefined;
@@ -26,6 +26,7 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
26
26
  protected readonly network: Network;
27
27
  protected readonly feeRate: number;
28
28
  protected priorityFee: bigint;
29
+ protected gasSatFee: bigint;
29
30
  protected utxos: UTXO[];
30
31
  protected to: string | undefined;
31
32
  protected from: string;
@@ -12,6 +12,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
12
12
  chainId?: ChainId;
13
13
  readonly feeRate: number;
14
14
  readonly priorityFee: bigint;
15
+ readonly gasSatFee: bigint;
15
16
  }
16
17
  export interface IFundingTransactionParameters extends ITransactionParameters {
17
18
  amount: bigint;
@@ -5,6 +5,7 @@ export interface ContractAddressVerificationParams {
5
5
  readonly originalSalt: Buffer;
6
6
  readonly bytecode: Buffer;
7
7
  readonly preimage: Buffer;
8
+ readonly priorityFee: bigint;
8
9
  readonly calldata?: Buffer;
9
10
  readonly network?: Network;
10
11
  }
@@ -1 +1 @@
1
- export declare const version = "1.2.6";
1
+ export declare const version = "1.2.7";
package/build/_version.js CHANGED
@@ -1 +1 @@
1
- export const version = '1.2.6';
1
+ export const version = '1.2.7';
@@ -8,6 +8,7 @@ export declare abstract class Generator {
8
8
  protected readonly network: Network;
9
9
  protected constructor(senderPubKey: Buffer, contractSaltPubKey?: Buffer, network?: Network);
10
10
  get senderFirstByte(): Buffer;
11
+ getHeader(maxPriority: bigint): Buffer;
11
12
  abstract compile(...args: unknown[]): Buffer;
12
13
  protected splitBufferIntoChunks(buffer: Buffer, chunkSize?: number): Array<Buffer[]>;
13
14
  }
@@ -1,4 +1,5 @@
1
1
  import { networks, toXOnly } from '@btc-vision/bitcoin';
2
+ import { BinaryWriter } from '../buffer/BinaryWriter.js';
2
3
  export class Generator {
3
4
  constructor(senderPubKey, contractSaltPubKey, network = networks.bitcoin) {
4
5
  this.network = networks.bitcoin;
@@ -10,6 +11,12 @@ export class Generator {
10
11
  get senderFirstByte() {
11
12
  return Buffer.from([this.senderPubKey[0], 0, 0, 0]);
12
13
  }
14
+ getHeader(maxPriority) {
15
+ const writer = new BinaryWriter(8 + 4);
16
+ writer.writeBytes(this.senderFirstByte);
17
+ writer.writeU64(maxPriority);
18
+ return Buffer.from(writer.getBuffer());
19
+ }
13
20
  splitBufferIntoChunks(buffer, chunkSize = Generator.DATA_CHUNK_SIZE) {
14
21
  const chunks = [];
15
22
  for (let i = 0; i < buffer.length; i += chunkSize) {
@@ -4,5 +4,5 @@ import { Generator } from '../Generator.js';
4
4
  export declare class CalldataGenerator extends Generator {
5
5
  constructor(senderPubKey: Buffer, contractSaltPubKey: Buffer, network?: Network);
6
6
  static getPubKeyAsBuffer(witnessKeys: Buffer[], network: Network): Buffer;
7
- compile(calldata: Buffer, contractSecret: Buffer, preimage: Buffer, features?: Features[]): Buffer;
7
+ compile(calldata: Buffer, contractSecret: Buffer, preimage: Buffer, maxPriority: bigint, features?: Features[]): Buffer;
8
8
  }
@@ -25,14 +25,14 @@ export class CalldataGenerator extends Generator {
25
25
  }
26
26
  return compressed;
27
27
  }
28
- compile(calldata, contractSecret, preimage, features = []) {
28
+ compile(calldata, contractSecret, preimage, maxPriority, features = []) {
29
29
  if (!this.contractSaltPubKey)
30
30
  throw new Error('Contract salt public key not set');
31
31
  const dataChunks = this.splitBufferIntoChunks(calldata);
32
32
  if (!dataChunks.length)
33
33
  throw new Error('No data chunks found');
34
34
  let compiledData = [
35
- this.senderFirstByte,
35
+ this.getHeader(maxPriority),
36
36
  opcodes.OP_TOALTSTACK,
37
37
  preimage,
38
38
  opcodes.OP_TOALTSTACK,
@@ -2,6 +2,6 @@ import { Network } from '@btc-vision/bitcoin';
2
2
  import { Generator } from '../Generator.js';
3
3
  export declare class DeploymentGenerator extends Generator {
4
4
  constructor(senderPubKey: Buffer, contractSaltPubKey: Buffer, network?: Network);
5
- compile(contractBytecode: Buffer, contractSalt: Buffer, preimage: Buffer, calldata?: Buffer): Buffer;
5
+ compile(contractBytecode: Buffer, contractSalt: Buffer, preimage: Buffer, maxPriority: bigint, calldata?: Buffer): Buffer;
6
6
  private getAsm;
7
7
  }
@@ -4,8 +4,8 @@ export class DeploymentGenerator extends Generator {
4
4
  constructor(senderPubKey, contractSaltPubKey, network = networks.bitcoin) {
5
5
  super(senderPubKey, contractSaltPubKey, network);
6
6
  }
7
- compile(contractBytecode, contractSalt, preimage, calldata) {
8
- const asm = this.getAsm(contractBytecode, contractSalt, preimage, calldata);
7
+ compile(contractBytecode, contractSalt, preimage, maxPriority, calldata) {
8
+ const asm = this.getAsm(contractBytecode, contractSalt, preimage, maxPriority, calldata);
9
9
  const compiled = script.compile(asm);
10
10
  const decompiled = script.decompile(compiled);
11
11
  if (!decompiled) {
@@ -13,13 +13,13 @@ export class DeploymentGenerator extends Generator {
13
13
  }
14
14
  return compiled;
15
15
  }
16
- getAsm(contractBytecode, contractSalt, preimage, calldata) {
16
+ getAsm(contractBytecode, contractSalt, preimage, maxPriority, calldata) {
17
17
  if (!this.contractSaltPubKey)
18
18
  throw new Error('Contract salt public key not set');
19
19
  const dataChunks = this.splitBufferIntoChunks(contractBytecode);
20
20
  const calldataChunks = calldata ? this.splitBufferIntoChunks(calldata) : [];
21
21
  const compiledData = [
22
- this.senderFirstByte,
22
+ this.getHeader(maxPriority),
23
23
  opcodes.OP_TOALTSTACK,
24
24
  preimage,
25
25
  opcodes.OP_TOALTSTACK,
@@ -4,5 +4,5 @@ import { Generator } from '../Generator.js';
4
4
  export declare class LegacyCalldataGenerator extends Generator {
5
5
  constructor(senderPubKey: Buffer, network?: Network);
6
6
  static getPubKeyAsBuffer(witnessKeys: Buffer[], network: Network): Buffer;
7
- compile(calldata: Buffer, contractSecret: Buffer, features?: Features[], vaultPublicKeys?: Buffer[], minimumSignatures?: number): Buffer;
7
+ compile(calldata: Buffer, contractSecret: Buffer, preimage: Buffer, maxPriority: bigint, features?: Features[]): Buffer;
8
8
  }
@@ -25,11 +25,15 @@ export class LegacyCalldataGenerator extends Generator {
25
25
  }
26
26
  return compressed;
27
27
  }
28
- compile(calldata, contractSecret, features = [], vaultPublicKeys = [], minimumSignatures = 0) {
28
+ compile(calldata, contractSecret, preimage, maxPriority, features = []) {
29
29
  const dataChunks = this.splitBufferIntoChunks(calldata);
30
30
  if (!dataChunks.length)
31
31
  throw new Error('No data chunks found');
32
32
  let compiledData = [
33
+ this.getHeader(maxPriority),
34
+ opcodes.OP_TOALTSTACK,
35
+ preimage,
36
+ opcodes.OP_TOALTSTACK,
33
37
  this.senderPubKey,
34
38
  opcodes.OP_DUP,
35
39
  opcodes.OP_HASH256,
@@ -44,28 +48,6 @@ export class LegacyCalldataGenerator extends Generator {
44
48
  opcodes.OP_IF,
45
49
  Generator.MAGIC,
46
50
  ];
47
- if (vaultPublicKeys.length > 0) {
48
- const pubKeyBuffer = LegacyCalldataGenerator.getPubKeyAsBuffer(vaultPublicKeys, this.network);
49
- const pubKeyDataChunks = this.splitBufferIntoChunks(pubKeyBuffer);
50
- compiledData = compiledData.concat(...[
51
- opcodes.OP_0,
52
- ...pubKeyDataChunks,
53
- ]);
54
- if (minimumSignatures) {
55
- if (minimumSignatures > 255) {
56
- throw new Error('Minimum signatures cannot exceed 255');
57
- }
58
- const minSigBuffer = Buffer.alloc(2);
59
- minSigBuffer.writeUint16LE(minimumSignatures, 0);
60
- compiledData = compiledData.concat(...[
61
- opcodes.OP_1,
62
- minSigBuffer,
63
- ]);
64
- }
65
- else {
66
- throw new Error('Minimum signatures must be provided');
67
- }
68
- }
69
51
  const featureOpcodes = features.map((feature) => FeatureOpCodes[feature]);
70
52
  compiledData = compiledData.concat(...featureOpcodes, ...[opcodes.OP_1NEGATE, ...dataChunks, opcodes.OP_ELSE, opcodes.OP_1, opcodes.OP_ENDIF]);
71
53
  const asm = compiledData.flat();
@@ -255,10 +255,11 @@ export class TransactionFactory {
255
255
  return Buffer.concat([header, buf]).toString('hex');
256
256
  }
257
257
  getPriorityFee(params) {
258
- if (params.priorityFee < TransactionBuilder.MINIMUM_DUST) {
258
+ const totalFee = params.priorityFee + params.gasSatFee;
259
+ if (totalFee < TransactionBuilder.MINIMUM_DUST) {
259
260
  return TransactionBuilder.MINIMUM_DUST;
260
261
  }
261
- return params.priorityFee;
262
+ return totalFee;
262
263
  }
263
264
  getUTXOAsTransaction(tx, to, index) {
264
265
  if (!tx.outs[index])
@@ -47,7 +47,7 @@ export class DeploymentTransaction extends TransactionBuilder {
47
47
  this.contractSeed = this.getContractSeed();
48
48
  this.contractSigner = EcKeyPair.fromSeedKeyPair(this.contractSeed, this.network);
49
49
  this.deploymentGenerator = new DeploymentGenerator(Buffer.from(this.signer.publicKey), this.contractSignerXOnlyPubKey(), this.network);
50
- this.compiledTargetScript = this.deploymentGenerator.compile(this.bytecode, this.randomBytes, this.preimage, this.calldata);
50
+ this.compiledTargetScript = this.deploymentGenerator.compile(this.bytecode, this.randomBytes, this.preimage, this.priorityFee, this.calldata);
51
51
  this.scriptTree = this.getScriptTree();
52
52
  this.internalInit();
53
53
  this._contractPubKey = '0x' + this.contractSeed.toString('hex');
@@ -6,7 +6,7 @@ export class InteractionTransaction extends SharedInteractionTransaction {
6
6
  this.type = TransactionType.INTERACTION;
7
7
  this.tapLeafScript = null;
8
8
  this.contractSecret = this.generateSecret();
9
- this.compiledTargetScript = this.calldataGenerator.compile(this.calldata, this.contractSecret, this.preimage);
9
+ this.compiledTargetScript = this.calldataGenerator.compile(this.calldata, this.contractSecret, this.preimage, this.priorityFee);
10
10
  this.scriptTree = this.getScriptTree();
11
11
  this.internalInit();
12
12
  }
@@ -3,7 +3,7 @@ import { TransactionBuilder } from './TransactionBuilder.js';
3
3
  import { TransactionType } from '../enums/TransactionType.js';
4
4
  import { ITransactionParameters } from '../interfaces/ITransactionParameters.js';
5
5
  import { ECPairInterface } from 'ecpair';
6
- export interface MultiSignParameters extends Omit<ITransactionParameters, 'priorityFee' | 'signer'> {
6
+ export interface MultiSignParameters extends Omit<ITransactionParameters, 'gasSatFee' | 'priorityFee' | 'signer'> {
7
7
  readonly pubkeys: Buffer[];
8
8
  readonly minimumSignatures: number;
9
9
  readonly from?: undefined;
@@ -18,6 +18,7 @@ export class MultiSignTransaction extends TransactionBuilder {
18
18
  ...parameters,
19
19
  signer: EcKeyPair.fromPrivateKey(bitcoinCrypto.sha256(Buffer.from('aaaaaaaa', 'utf-8'))),
20
20
  priorityFee: 0n,
21
+ gasSatFee: 0n,
21
22
  });
22
23
  this.type = TransactionType.MULTI_SIG;
23
24
  this.targetScriptRedeem = null;
@@ -48,6 +48,9 @@ export class SharedInteractionTransaction extends TransactionBuilder {
48
48
  generateSecret() {
49
49
  if (!this.to)
50
50
  throw new Error('To address is required');
51
+ if (this.to.startsWith('0x')) {
52
+ throw new Error(`Legacy not support at this time. Reserved for future use.`);
53
+ }
51
54
  return address.fromBech32(this.to).data;
52
55
  }
53
56
  scriptSignerXOnlyPubKey() {
@@ -26,6 +26,7 @@ export declare abstract class TransactionBuilder<T extends TransactionType> exte
26
26
  protected readonly network: Network;
27
27
  protected readonly feeRate: number;
28
28
  protected priorityFee: bigint;
29
+ protected gasSatFee: bigint;
29
30
  protected utxos: UTXO[];
30
31
  protected to: string | undefined;
31
32
  protected from: string;
@@ -24,6 +24,7 @@ export class TransactionBuilder extends TweakedTransaction {
24
24
  this.network = parameters.network;
25
25
  this.feeRate = parameters.feeRate;
26
26
  this.priorityFee = parameters.priorityFee ?? 0n;
27
+ this.gasSatFee = parameters.gasSatFee ?? 0n;
27
28
  this.utxos = parameters.utxos;
28
29
  this.to = parameters.to || undefined;
29
30
  this.isPubKeyDestination = this.to
@@ -76,6 +77,7 @@ export class TransactionBuilder extends TweakedTransaction {
76
77
  network: this.network,
77
78
  feeRate: this.feeRate,
78
79
  priorityFee: this.priorityFee ?? 0n,
80
+ gasSatFee: this.gasSatFee ?? 0n,
79
81
  from: this.from,
80
82
  amount: this.estimatedFees,
81
83
  optionalOutputs: this.optionalOutputs,
@@ -241,8 +243,9 @@ export class TransactionBuilder extends TweakedTransaction {
241
243
  throw new Error('Output not found');
242
244
  }
243
245
  getTransactionOPNetFee() {
244
- if (this.priorityFee > TransactionBuilder.MINIMUM_DUST) {
245
- return this.priorityFee;
246
+ const totalFee = this.priorityFee + this.gasSatFee;
247
+ if (totalFee > TransactionBuilder.MINIMUM_DUST) {
248
+ return totalFee;
246
249
  }
247
250
  return TransactionBuilder.MINIMUM_DUST;
248
251
  }
@@ -12,6 +12,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
12
12
  chainId?: ChainId;
13
13
  readonly feeRate: number;
14
14
  readonly priorityFee: bigint;
15
+ readonly gasSatFee: bigint;
15
16
  }
16
17
  export interface IFundingTransactionParameters extends ITransactionParameters {
17
18
  amount: bigint;
@@ -122,7 +122,8 @@ export class OPNetLimitedProvider {
122
122
  network,
123
123
  to: wallet.p2tr,
124
124
  splitInputsInto,
125
- priorityFee: 330n,
125
+ priorityFee: 0n,
126
+ gasSatFee: 330n,
126
127
  };
127
128
  const transactionFactory = new TransactionFactory();
128
129
  const fundingTx = await transactionFactory.createBTCTransfer(fundingTransactionParameters);
@@ -5,6 +5,7 @@ export interface ContractAddressVerificationParams {
5
5
  readonly originalSalt: Buffer;
6
6
  readonly bytecode: Buffer;
7
7
  readonly preimage: Buffer;
8
+ readonly priorityFee: bigint;
8
9
  readonly calldata?: Buffer;
9
10
  readonly network?: Network;
10
11
  }
@@ -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.calldata);
8
+ const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt, params.preimage, params.priorityFee, params.calldata);
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.calldata);
24
+ const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt, params.preimage, params.priorityFee, params.calldata);
25
25
  const scriptTree = [
26
26
  {
27
27
  output: compiledTargetScript,
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@btc-vision/transaction",
3
3
  "type": "module",
4
- "version": "1.2.6",
4
+ "version": "1.2.8",
5
5
  "author": "BlobMaster41",
6
6
  "description": "OPNet transaction library allows you to create and sign transactions for the OPNet network.",
7
7
  "engines": {
8
- "node": ">=16.0.0"
8
+ "node": ">=20.0.0"
9
9
  },
10
10
  "exports": {
11
11
  ".": {
@@ -89,7 +89,7 @@
89
89
  "dependencies": {
90
90
  "@babel/plugin-proposal-object-rest-spread": "^7.20.7",
91
91
  "@bitcoinerlab/secp256k1": "^1.1.1",
92
- "@btc-vision/bitcoin": "^6.3.3",
92
+ "@btc-vision/bitcoin": "^6.3.4",
93
93
  "@btc-vision/bitcoin-rpc": "^1.0.0",
94
94
  "@btc-vision/logger": "^1.0.6",
95
95
  "@eslint/js": "^9.14.0",
package/src/_version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '1.2.6';
1
+ export const version = '1.2.7';
@@ -1,4 +1,5 @@
1
1
  import { Network, networks, toXOnly } from '@btc-vision/bitcoin';
2
+ import { BinaryWriter } from '../buffer/BinaryWriter.js';
2
3
 
3
4
  /** Bitcoin Script Generator */
4
5
  export abstract class Generator {
@@ -51,6 +52,14 @@ export abstract class Generator {
51
52
  return Buffer.from([this.senderPubKey[0], 0, 0, 0]);
52
53
  }
53
54
 
55
+ public getHeader(maxPriority: bigint): Buffer {
56
+ const writer = new BinaryWriter(8 + 4);
57
+ writer.writeBytes(this.senderFirstByte);
58
+ writer.writeU64(maxPriority);
59
+
60
+ return Buffer.from(writer.getBuffer());
61
+ }
62
+
54
63
  /**
55
64
  * Compile the script
56
65
  * @param args - The arguments to use when compiling the script
@@ -4,6 +4,7 @@ import { Compressor } from '../../bytecode/Compressor.js';
4
4
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
5
5
  import { FeatureOpCodes, Features } from '../Features.js';
6
6
  import { Generator } from '../Generator.js';
7
+ import { BinaryWriter } from '../../buffer/BinaryWriter.js';
7
8
 
8
9
  /**
9
10
  * Class to generate bitcoin script for interaction transactions
@@ -57,6 +58,7 @@ export class CalldataGenerator extends Generator {
57
58
  * @param {Buffer} calldata - The calldata to use
58
59
  * @param {Buffer} contractSecret - The contract secret
59
60
  * @param preimage
61
+ * @param maxPriority - Amount of satoshis to spend max on priority fee
60
62
  * @param {number[]} [features=[]] - The features to use (optional)
61
63
  * @returns {Buffer} - The compiled script
62
64
  * @throws {Error} - If something goes wrong
@@ -65,6 +67,7 @@ export class CalldataGenerator extends Generator {
65
67
  calldata: Buffer,
66
68
  contractSecret: Buffer,
67
69
  preimage: Buffer,
70
+ maxPriority: bigint,
68
71
  features: Features[] = [],
69
72
  ): Buffer {
70
73
  if (!this.contractSaltPubKey) throw new Error('Contract salt public key not set');
@@ -73,7 +76,7 @@ export class CalldataGenerator extends Generator {
73
76
  if (!dataChunks.length) throw new Error('No data chunks found');
74
77
 
75
78
  let compiledData = [
76
- this.senderFirstByte,
79
+ this.getHeader(maxPriority),
77
80
  opcodes.OP_TOALTSTACK,
78
81
 
79
82
  // CHALLENGE PREIMAGE FOR REWARD,
@@ -15,6 +15,7 @@ export class DeploymentGenerator extends Generator {
15
15
  * @param {Buffer} contractBytecode - The contract bytecode
16
16
  * @param {Buffer} contractSalt - The contract salt
17
17
  * @param {Buffer} preimage - The preimage for reward
18
+ * @param {bigint} maxPriority - The maximum priority for the contract
18
19
  * @param {Buffer} [calldata] - The calldata to be passed to the contract
19
20
  * @returns {Buffer} - The compiled script
20
21
  */
@@ -22,9 +23,10 @@ export class DeploymentGenerator extends Generator {
22
23
  contractBytecode: Buffer,
23
24
  contractSalt: Buffer,
24
25
  preimage: Buffer,
26
+ maxPriority: bigint,
25
27
  calldata?: Buffer,
26
28
  ): Buffer {
27
- const asm = this.getAsm(contractBytecode, contractSalt, preimage, calldata);
29
+ const asm = this.getAsm(contractBytecode, contractSalt, preimage, maxPriority, calldata);
28
30
  const compiled = script.compile(asm);
29
31
 
30
32
  /**
@@ -42,15 +44,16 @@ export class DeploymentGenerator extends Generator {
42
44
  contractBytecode: Buffer,
43
45
  contractSalt: Buffer,
44
46
  preimage: Buffer,
47
+ maxPriority: bigint,
45
48
  calldata?: Buffer,
46
49
  ): (number | Buffer)[] {
47
50
  if (!this.contractSaltPubKey) throw new Error('Contract salt public key not set');
48
51
 
49
52
  const dataChunks: Buffer[][] = this.splitBufferIntoChunks(contractBytecode);
50
53
  const calldataChunks: Buffer[][] = calldata ? this.splitBufferIntoChunks(calldata) : [];
51
-
54
+
52
55
  const compiledData = [
53
- this.senderFirstByte,
56
+ this.getHeader(maxPriority),
54
57
  opcodes.OP_TOALTSTACK,
55
58
 
56
59
  // CHALLENGE PREIMAGE FOR REWARD,
@@ -52,23 +52,30 @@ export class LegacyCalldataGenerator extends Generator {
52
52
  * Compile an interaction bitcoin script
53
53
  * @param {Buffer} calldata - The calldata to use
54
54
  * @param {Buffer} contractSecret - The contract secret
55
+ * @param {Buffer} preimage - The preimage to use
56
+ * @param {bigint} maxPriority - The maximum priority
55
57
  * @param {number[]} [features=[]] - The features to use (optional)
56
- * @param {Buffer[]} [vaultPublicKeys=[]] - The public keys of the vault (optional)
57
- * @param {number} [minimumSignatures=0] - The minimum number of signatures (optional)
58
58
  * @returns {Buffer} - The compiled script
59
59
  * @throws {Error} - If something goes wrong
60
60
  */
61
61
  public compile(
62
62
  calldata: Buffer,
63
63
  contractSecret: Buffer,
64
+ preimage: Buffer,
65
+ maxPriority: bigint,
64
66
  features: Features[] = [],
65
- vaultPublicKeys: Buffer[] = [],
66
- minimumSignatures: number = 0,
67
67
  ): Buffer {
68
68
  const dataChunks: Buffer[][] = this.splitBufferIntoChunks(calldata);
69
69
  if (!dataChunks.length) throw new Error('No data chunks found');
70
70
 
71
71
  let compiledData = [
72
+ this.getHeader(maxPriority),
73
+ opcodes.OP_TOALTSTACK,
74
+
75
+ // CHALLENGE PREIMAGE FOR REWARD,
76
+ preimage,
77
+ opcodes.OP_TOALTSTACK,
78
+
72
79
  this.senderPubKey,
73
80
  opcodes.OP_DUP,
74
81
  opcodes.OP_HASH256,
@@ -87,42 +94,6 @@ export class LegacyCalldataGenerator extends Generator {
87
94
  Generator.MAGIC,
88
95
  ];
89
96
 
90
- // write pub keys, when requested.
91
- if (vaultPublicKeys.length > 0) {
92
- const pubKeyBuffer = LegacyCalldataGenerator.getPubKeyAsBuffer(
93
- vaultPublicKeys,
94
- this.network,
95
- );
96
- const pubKeyDataChunks: Buffer[][] = this.splitBufferIntoChunks(pubKeyBuffer);
97
-
98
- compiledData = compiledData.concat(
99
- ...[
100
- opcodes.OP_0, // provide opnet public keys
101
- ...pubKeyDataChunks,
102
- ],
103
- );
104
-
105
- if (minimumSignatures) {
106
- // verify that the minimum is not greater than 255
107
- if (minimumSignatures > 255) {
108
- throw new Error('Minimum signatures cannot exceed 255');
109
- }
110
-
111
- // we use a 2 bytes buffer even if we limit to 255 so it does not use an opcode for the number
112
- const minSigBuffer = Buffer.alloc(2);
113
- minSigBuffer.writeUint16LE(minimumSignatures, 0);
114
-
115
- compiledData = compiledData.concat(
116
- ...[
117
- opcodes.OP_1, // provide minimum signatures
118
- minSigBuffer,
119
- ],
120
- );
121
- } else {
122
- throw new Error('Minimum signatures must be provided');
123
- }
124
- }
125
-
126
97
  const featureOpcodes = features.map((feature) => FeatureOpCodes[feature]); // Get the opcodes for the features
127
98
 
128
99
  // Write calldata
@@ -462,11 +462,12 @@ export class TransactionFactory {
462
462
  }
463
463
 
464
464
  private getPriorityFee(params: ITransactionParameters): bigint {
465
- if (params.priorityFee < TransactionBuilder.MINIMUM_DUST) {
465
+ const totalFee = params.priorityFee + params.gasSatFee;
466
+ if (totalFee < TransactionBuilder.MINIMUM_DUST) {
466
467
  return TransactionBuilder.MINIMUM_DUST;
467
468
  }
468
469
 
469
- return params.priorityFee;
470
+ return totalFee;
470
471
  }
471
472
 
472
473
  private getUTXOAsTransaction(tx: Transaction, to: string, index: number): UTXO[] {
@@ -102,7 +102,7 @@ export class UnisatSigner extends CustomKeypair {
102
102
  if (this.isInitialized) {
103
103
  return;
104
104
  }
105
-
105
+
106
106
  const network = await this.unisat.getNetwork();
107
107
  switch (network) {
108
108
  case UnisatNetwork.mainnet:
@@ -139,6 +139,7 @@ export class DeploymentTransaction extends TransactionBuilder<TransactionType.DE
139
139
  this.bytecode,
140
140
  this.randomBytes,
141
141
  this.preimage,
142
+ this.priorityFee,
142
143
  this.calldata,
143
144
  );
144
145
 
@@ -31,6 +31,7 @@ export class InteractionTransaction extends SharedInteractionTransaction<Transac
31
31
  this.calldata,
32
32
  this.contractSecret,
33
33
  this.preimage,
34
+ this.priorityFee,
34
35
  );
35
36
 
36
37
  this.scriptTree = this.getScriptTree();
@@ -21,7 +21,7 @@ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
21
21
  import { ECPairInterface } from 'ecpair';
22
22
 
23
23
  export interface MultiSignParameters
24
- extends Omit<ITransactionParameters, 'priorityFee' | 'signer'> {
24
+ extends Omit<ITransactionParameters, 'gasSatFee' | 'priorityFee' | 'signer'> {
25
25
  readonly pubkeys: Buffer[];
26
26
  readonly minimumSignatures: number;
27
27
  readonly from?: undefined;
@@ -97,6 +97,7 @@ export class MultiSignTransaction extends TransactionBuilder<TransactionType.MUL
97
97
  bitcoinCrypto.sha256(Buffer.from('aaaaaaaa', 'utf-8')),
98
98
  ),
99
99
  priorityFee: 0n,
100
+ gasSatFee: 0n,
100
101
  });
101
102
 
102
103
  if (!parameters.pubkeys) {
@@ -119,6 +119,10 @@ export abstract class SharedInteractionTransaction<
119
119
  protected generateSecret(): Buffer {
120
120
  if (!this.to) throw new Error('To address is required');
121
121
 
122
+ if (this.to.startsWith('0x')) {
123
+ throw new Error(`Legacy not support at this time. Reserved for future use.`);
124
+ }
125
+
122
126
  return address.fromBech32(this.to).data;
123
127
  }
124
128