@btc-vision/transaction 1.2.1 → 1.2.3

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 (84) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/crypto/crypto-browser.d.ts +1 -1
  3. package/browser/generators/builders/CalldataGenerator.d.ts +1 -1
  4. package/browser/generators/builders/DeploymentGenerator.d.ts +1 -1
  5. package/browser/generators/builders/MineableReward.d.ts +7 -0
  6. package/browser/index.js +1 -1
  7. package/browser/opnet.d.ts +4 -0
  8. package/browser/transaction/ContractAddress.d.ts +1 -0
  9. package/browser/transaction/TransactionFactory.d.ts +19 -4
  10. package/browser/transaction/browser/WalletConnection.d.ts +18 -0
  11. package/browser/transaction/browser/types/Xverse.d.ts +24 -10
  12. package/browser/transaction/builders/ChallengeSolutionTransaction.d.ts +18 -0
  13. package/browser/transaction/builders/DeploymentTransaction.d.ts +4 -0
  14. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +5 -0
  15. package/browser/transaction/builders/TransactionBuilder.d.ts +2 -0
  16. package/browser/transaction/enums/TransactionType.d.ts +3 -4
  17. package/browser/transaction/interfaces/ITransactionParameters.d.ts +6 -0
  18. package/browser/transaction/mineable/ChallengeGenerator.d.ts +9 -0
  19. package/browser/utxo/interfaces/IUTXO.d.ts +1 -1
  20. package/browser/verification/TapscriptVerificator.d.ts +1 -1
  21. package/build/_version.d.ts +1 -1
  22. package/build/_version.js +1 -1
  23. package/build/generators/Generator.js +1 -1
  24. package/build/generators/builders/CalldataGenerator.d.ts +1 -1
  25. package/build/generators/builders/CalldataGenerator.js +7 -26
  26. package/build/generators/builders/DeploymentGenerator.d.ts +1 -1
  27. package/build/generators/builders/DeploymentGenerator.js +9 -6
  28. package/build/generators/builders/LegacyCalldataGenerator.js +5 -1
  29. package/build/generators/builders/MineableReward.d.ts +7 -0
  30. package/build/generators/builders/MineableReward.js +47 -0
  31. package/build/opnet.d.ts +4 -0
  32. package/build/opnet.js +4 -0
  33. package/build/transaction/ContractAddress.d.ts +1 -0
  34. package/build/transaction/ContractAddress.js +4 -1
  35. package/build/transaction/TransactionFactory.d.ts +19 -4
  36. package/build/transaction/TransactionFactory.js +32 -0
  37. package/build/transaction/browser/WalletConnection.d.ts +18 -0
  38. package/build/transaction/browser/WalletConnection.js +95 -0
  39. package/build/transaction/browser/extensions/UnisatSigner.js +5 -2
  40. package/build/transaction/browser/extensions/XverseSigner.js +15 -9
  41. package/build/transaction/browser/types/Xverse.d.ts +24 -10
  42. package/build/transaction/builders/ChallengeSolutionTransaction.d.ts +18 -0
  43. package/build/transaction/builders/ChallengeSolutionTransaction.js +51 -0
  44. package/build/transaction/builders/DeploymentTransaction.d.ts +4 -0
  45. package/build/transaction/builders/DeploymentTransaction.js +23 -4
  46. package/build/transaction/builders/InteractionTransaction.js +1 -1
  47. package/build/transaction/builders/SharedInteractionTransaction.d.ts +5 -0
  48. package/build/transaction/builders/SharedInteractionTransaction.js +35 -13
  49. package/build/transaction/builders/TransactionBuilder.d.ts +2 -0
  50. package/build/transaction/builders/TransactionBuilder.js +2 -0
  51. package/build/transaction/enums/TransactionType.d.ts +3 -4
  52. package/build/transaction/enums/TransactionType.js +3 -4
  53. package/build/transaction/interfaces/ITransactionParameters.d.ts +6 -0
  54. package/build/transaction/mineable/ChallengeGenerator.d.ts +9 -0
  55. package/build/transaction/mineable/ChallengeGenerator.js +28 -0
  56. package/build/transaction/shared/TweakedTransaction.js +1 -1
  57. package/build/utxo/interfaces/IUTXO.d.ts +1 -1
  58. package/build/verification/TapscriptVerificator.d.ts +1 -1
  59. package/build/verification/TapscriptVerificator.js +2 -8
  60. package/package.json +3 -3
  61. package/src/_version.ts +1 -1
  62. package/src/generators/Generator.ts +1 -1
  63. package/src/generators/builders/CalldataGenerator.ts +10 -41
  64. package/src/generators/builders/DeploymentGenerator.ts +18 -7
  65. package/src/generators/builders/LegacyCalldataGenerator.ts +5 -1
  66. package/src/generators/builders/MineableReward.ts +63 -0
  67. package/src/opnet.ts +5 -0
  68. package/src/transaction/ContractAddress.ts +5 -1
  69. package/src/transaction/TransactionFactory.ts +66 -3
  70. package/src/transaction/browser/WalletConnection.ts +110 -0
  71. package/src/transaction/browser/extensions/UnisatSigner.ts +7 -3
  72. package/src/transaction/browser/extensions/XverseSigner.ts +24 -23
  73. package/src/transaction/browser/types/Xverse.ts +50 -36
  74. package/src/transaction/builders/ChallengeSolutionTransaction.ts +88 -0
  75. package/src/transaction/builders/DeploymentTransaction.ts +46 -3
  76. package/src/transaction/builders/InteractionTransaction.ts +1 -0
  77. package/src/transaction/builders/SharedInteractionTransaction.ts +54 -14
  78. package/src/transaction/builders/TransactionBuilder.ts +3 -0
  79. package/src/transaction/enums/TransactionType.ts +3 -4
  80. package/src/transaction/interfaces/ITransactionParameters.ts +8 -15
  81. package/src/transaction/mineable/ChallengeGenerator.ts +39 -0
  82. package/src/transaction/shared/TweakedTransaction.ts +1 -1
  83. package/src/utxo/interfaces/IUTXO.ts +1 -1
  84. package/src/verification/TapscriptVerificator.ts +3 -18
@@ -1,9 +1,10 @@
1
1
  import { address, toXOnly } from '@btc-vision/bitcoin';
2
- import { TransactionBuilder } from './TransactionBuilder.js';
2
+ import { MINIMUM_AMOUNT_CA, MINIMUM_AMOUNT_REWARD, TransactionBuilder } from './TransactionBuilder.js';
3
3
  import { CalldataGenerator } from '../../generators/builders/CalldataGenerator.js';
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
8
  export class SharedInteractionTransaction extends TransactionBuilder {
8
9
  constructor(parameters) {
9
10
  super(parameters);
@@ -27,7 +28,9 @@ export class SharedInteractionTransaction extends TransactionBuilder {
27
28
  if (!parameters.calldata) {
28
29
  throw new Error('Calldata is required');
29
30
  }
31
+ this.preimage = parameters.preimage || BitcoinUtils.getSafeRandomValues(128);
30
32
  this.disableAutoRefund = parameters.disableAutoRefund || false;
33
+ this.rewardChallenge = ChallengeGenerator.generateMineableReward(this.preimage, this.network);
31
34
  this.calldata = Compressor.compress(parameters.calldata);
32
35
  this.randomBytes = parameters.randomBytes || BitcoinUtils.rndBytes();
33
36
  this.scriptSigner = this.generateKeyPairFromSeed();
@@ -39,6 +42,9 @@ export class SharedInteractionTransaction extends TransactionBuilder {
39
42
  getRndBytes() {
40
43
  return this.randomBytes;
41
44
  }
45
+ getPreimage() {
46
+ return this.preimage;
47
+ }
42
48
  generateSecret() {
43
49
  if (!this.to)
44
50
  throw new Error('To address is required');
@@ -51,8 +57,6 @@ export class SharedInteractionTransaction extends TransactionBuilder {
51
57
  return EcKeyPair.fromSeedKeyPair(this.randomBytes, this.network);
52
58
  }
53
59
  async buildTransaction() {
54
- if (!this.to)
55
- throw new Error('To address is required');
56
60
  const selectedRedeem = this.scriptSigner
57
61
  ? this.targetScriptRedeem
58
62
  : this.leftOverFundsScriptRedeem;
@@ -73,15 +77,7 @@ export class SharedInteractionTransaction extends TransactionBuilder {
73
77
  if (!this.regenerated) {
74
78
  this.addInputsFromUTXO();
75
79
  }
76
- const amountSpent = this.getTransactionOPNetFee();
77
- this.addOutput({
78
- value: Number(amountSpent),
79
- address: this.to,
80
- });
81
- const amount = this.addOptionalOutputsAndGetAmount();
82
- if (!this.disableAutoRefund) {
83
- await this.addRefundOutput(amountSpent + amount);
84
- }
80
+ await this.createMineableRewardOutputs();
85
81
  }
86
82
  async signInputs(transaction) {
87
83
  if (!this.scriptSigner) {
@@ -125,7 +121,6 @@ export class SharedInteractionTransaction extends TransactionBuilder {
125
121
  }
126
122
  return [
127
123
  this.contractSecret,
128
- this.internalPubKeyToXOnly(),
129
124
  input.tapScriptSig[0].signature,
130
125
  input.tapScriptSig[1].signature,
131
126
  ];
@@ -159,6 +154,33 @@ export class SharedInteractionTransaction extends TransactionBuilder {
159
154
  }
160
155
  }
161
156
  }
157
+ async createMineableRewardOutputs() {
158
+ if (!this.to)
159
+ throw new Error('To address is required');
160
+ const amountSpent = this.getTransactionOPNetFee();
161
+ let amountToCA;
162
+ if (amountSpent > MINIMUM_AMOUNT_REWARD + MINIMUM_AMOUNT_CA) {
163
+ amountToCA = MINIMUM_AMOUNT_CA;
164
+ }
165
+ else {
166
+ amountToCA = amountSpent;
167
+ }
168
+ this.addOutput({
169
+ value: Number(amountToCA),
170
+ address: this.to,
171
+ });
172
+ if (amountToCA === MINIMUM_AMOUNT_CA &&
173
+ amountSpent - MINIMUM_AMOUNT_CA > MINIMUM_AMOUNT_REWARD) {
174
+ this.addOutput({
175
+ value: Number(amountSpent - amountToCA),
176
+ address: this.rewardChallenge.address,
177
+ });
178
+ }
179
+ const amount = this.addOptionalOutputsAndGetAmount();
180
+ if (!this.disableAutoRefund) {
181
+ await this.addRefundOutput(amountSpent + amount);
182
+ }
183
+ }
162
184
  async signInputsNonWalletBased(transaction) {
163
185
  for (let i = 0; i < transaction.data.inputs.length; i++) {
164
186
  if (i === 0) {
@@ -6,6 +6,8 @@ import { UTXO } from '../../utxo/interfaces/IUTXO.js';
6
6
  import { ECPairInterface } from 'ecpair';
7
7
  import { TweakedTransaction } from '../shared/TweakedTransaction.js';
8
8
  import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
9
+ export declare const MINIMUM_AMOUNT_REWARD: bigint;
10
+ export declare const MINIMUM_AMOUNT_CA: bigint;
9
11
  export declare abstract class TransactionBuilder<T extends TransactionType> extends TweakedTransaction {
10
12
  static readonly LOCK_LEAF_SCRIPT: Buffer;
11
13
  static readonly MINIMUM_DUST: bigint;
@@ -4,6 +4,8 @@ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
4
4
  import { AddressVerificator } from '../../keypair/AddressVerificator.js';
5
5
  import { TweakedTransaction } from '../shared/TweakedTransaction.js';
6
6
  initEccLib(ecc);
7
+ export const MINIMUM_AMOUNT_REWARD = 540n;
8
+ export const MINIMUM_AMOUNT_CA = 330n;
7
9
  export class TransactionBuilder extends TweakedTransaction {
8
10
  constructor(parameters) {
9
11
  super(parameters);
@@ -3,8 +3,7 @@ export declare enum TransactionType {
3
3
  FUNDING = 1,
4
4
  DEPLOYMENT = 2,
5
5
  INTERACTION = 3,
6
- WBTC_WRAP = 4,
7
- WBTC_UNWRAP = 5,
8
- MULTI_SIG = 6,
9
- CUSTOM_CODE = 7
6
+ MULTI_SIG = 4,
7
+ CUSTOM_CODE = 5,
8
+ CHALLENGE_SOLUTION = 6
10
9
  }
@@ -4,8 +4,7 @@ export var TransactionType;
4
4
  TransactionType[TransactionType["FUNDING"] = 1] = "FUNDING";
5
5
  TransactionType[TransactionType["DEPLOYMENT"] = 2] = "DEPLOYMENT";
6
6
  TransactionType[TransactionType["INTERACTION"] = 3] = "INTERACTION";
7
- TransactionType[TransactionType["WBTC_WRAP"] = 4] = "WBTC_WRAP";
8
- TransactionType[TransactionType["WBTC_UNWRAP"] = 5] = "WBTC_UNWRAP";
9
- TransactionType[TransactionType["MULTI_SIG"] = 6] = "MULTI_SIG";
10
- TransactionType[TransactionType["CUSTOM_CODE"] = 7] = "CUSTOM_CODE";
7
+ TransactionType[TransactionType["MULTI_SIG"] = 4] = "MULTI_SIG";
8
+ TransactionType[TransactionType["CUSTOM_CODE"] = 5] = "CUSTOM_CODE";
9
+ TransactionType[TransactionType["CHALLENGE_SOLUTION"] = 6] = "CHALLENGE_SOLUTION";
11
10
  })(TransactionType || (TransactionType = {}));
@@ -17,9 +17,14 @@ export interface IFundingTransactionParameters extends ITransactionParameters {
17
17
  amount: bigint;
18
18
  splitInputsInto?: number;
19
19
  }
20
+ export interface IChallengeSolutionTransactionParameters extends ITransactionParameters {
21
+ amount: bigint;
22
+ readonly challengeSolution: Buffer;
23
+ }
20
24
  export interface SharedInteractionParameters extends ITransactionParameters {
21
25
  calldata?: Buffer;
22
26
  disableAutoRefund?: boolean;
27
+ readonly preimage?: Buffer;
23
28
  readonly randomBytes?: Buffer;
24
29
  }
25
30
  export interface IInteractionParameters extends SharedInteractionParameters {
@@ -30,4 +35,5 @@ export interface IDeploymentParameters extends Omit<ITransactionParameters, 'to'
30
35
  readonly bytecode: Buffer;
31
36
  readonly calldata?: Buffer;
32
37
  readonly randomBytes?: Buffer;
38
+ readonly preimage?: Buffer;
33
39
  }
@@ -0,0 +1,9 @@
1
+ import { Network } from '@btc-vision/bitcoin';
2
+ export interface IMineableReward {
3
+ address: string;
4
+ p2shOutputScript: Buffer;
5
+ redeemScript: Buffer;
6
+ }
7
+ export declare class ChallengeGenerator {
8
+ static generateMineableReward(preimage1: Buffer, network: Network): IMineableReward;
9
+ }
@@ -0,0 +1,28 @@
1
+ import bitcoin from '@btc-vision/bitcoin';
2
+ import { MineableReward } from '../../generators/builders/MineableReward.js';
3
+ export class ChallengeGenerator {
4
+ static generateMineableReward(preimage1, network) {
5
+ const mineableReward = new MineableReward(Buffer.alloc(0), network);
6
+ const redeemScript = mineableReward.compile(preimage1);
7
+ const p2sh = bitcoin.payments.p2sh({
8
+ redeem: { output: redeemScript },
9
+ network,
10
+ });
11
+ const outputRedeem = p2sh.redeem?.output;
12
+ if (!outputRedeem) {
13
+ throw new Error('Output redeem is required');
14
+ }
15
+ if (!p2sh.address) {
16
+ throw new Error('P2SH address is required');
17
+ }
18
+ const p2shOutputScript = p2sh?.redeem?.output;
19
+ if (!p2shOutputScript) {
20
+ throw new Error('No redeem output');
21
+ }
22
+ return {
23
+ address: p2sh.address,
24
+ p2shOutputScript,
25
+ redeemScript: redeemScript,
26
+ };
27
+ }
28
+ }
@@ -24,7 +24,7 @@ export class TweakedTransaction extends Logger {
24
24
  this.customFinalizerP2SH = (inputIndex, input, scriptA, isSegwit, isP2SH, isP2WSH) => {
25
25
  const inputDecoded = this.inputs[inputIndex];
26
26
  if (isP2SH && input.partialSig && inputDecoded && inputDecoded.redeemScript) {
27
- const signatures = input.partialSig.map((sig) => sig.signature);
27
+ const signatures = input.partialSig.map((sig) => sig.signature) || [];
28
28
  const scriptSig = script.compile([...signatures, inputDecoded.redeemScript]);
29
29
  return {
30
30
  finalScriptSig: scriptSig,
@@ -1,4 +1,4 @@
1
- import { ScriptPubKey } from '@btc-vision/bsi-bitcoin-rpc';
1
+ import { ScriptPubKey } from '@btc-vision/bitcoin-rpc';
2
2
  export interface UTXO {
3
3
  readonly transactionId: string;
4
4
  readonly outputIndex: number;
@@ -4,6 +4,7 @@ export interface ContractAddressVerificationParams {
4
4
  readonly contractSaltPubKey: Buffer;
5
5
  readonly originalSalt: Buffer;
6
6
  readonly bytecode: Buffer;
7
+ readonly preimage: Buffer;
7
8
  readonly calldata?: Buffer;
8
9
  readonly network?: Network;
9
10
  }
@@ -12,6 +13,5 @@ export declare class TapscriptVerificator {
12
13
  static getContractAddress(params: ContractAddressVerificationParams): string | undefined;
13
14
  static verifyControlBlock(params: ContractAddressVerificationParams, controlBlock: Buffer): boolean;
14
15
  static getContractSeed(deployerPubKey: Buffer, bytecode: Buffer, saltHash: Buffer): Buffer;
15
- static generateContractVirtualAddress(deployerPubKey: Buffer, bytecode: Buffer, saltHash: Buffer, network?: Network): string;
16
16
  static generateAddressFromScript(params: ContractAddressVerificationParams, scriptTree: Taptree): string | undefined;
17
17
  }
@@ -1,12 +1,11 @@
1
1
  import { crypto as bitCrypto, networks, payments, toXOnly, } from '@btc-vision/bitcoin';
2
2
  import { DeploymentGenerator } from '../generators/builders/DeploymentGenerator.js';
3
3
  import { TransactionBuilder } from '../transaction/builders/TransactionBuilder.js';
4
- import { Address } from '../keypair/Address.js';
5
4
  export class TapscriptVerificator {
6
5
  static getContractAddress(params) {
7
6
  const network = params.network || networks.bitcoin;
8
7
  const scriptBuilder = new DeploymentGenerator(params.deployerPubKey, toXOnly(params.contractSaltPubKey), network);
9
- const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt, params.calldata);
8
+ const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt, params.preimage, params.calldata);
10
9
  const scriptTree = [
11
10
  {
12
11
  output: compiledTargetScript,
@@ -22,7 +21,7 @@ export class TapscriptVerificator {
22
21
  static verifyControlBlock(params, controlBlock) {
23
22
  const network = params.network || networks.bitcoin;
24
23
  const scriptBuilder = new DeploymentGenerator(params.deployerPubKey, toXOnly(params.contractSaltPubKey), network);
25
- const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt, params.calldata);
24
+ const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt, params.preimage, params.calldata);
26
25
  const scriptTree = [
27
26
  {
28
27
  output: compiledTargetScript,
@@ -55,11 +54,6 @@ export class TapscriptVerificator {
55
54
  const buf = Buffer.concat([deployerPubKey, saltHash, sha256OfBytecode]);
56
55
  return bitCrypto.hash256(buf);
57
56
  }
58
- static generateContractVirtualAddress(deployerPubKey, bytecode, saltHash, network = networks.bitcoin) {
59
- const virtualAddress = TapscriptVerificator.getContractSeed(deployerPubKey, bytecode, saltHash);
60
- const address = new Address(virtualAddress);
61
- return address.p2tr(network);
62
- }
63
57
  static generateAddressFromScript(params, scriptTree) {
64
58
  const network = params.network || networks.bitcoin;
65
59
  const transactionData = {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@btc-vision/transaction",
3
3
  "type": "module",
4
- "version": "1.2.1",
4
+ "version": "1.2.3",
5
5
  "author": "BlobMaster41",
6
6
  "description": "OPNet transaction library allows you to create and sign transactions for the OPNet network.",
7
7
  "engines": {
@@ -89,8 +89,8 @@
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.2",
93
- "@btc-vision/bsi-bitcoin-rpc": "^1.0.29",
92
+ "@btc-vision/bitcoin": "^6.3.3",
93
+ "@btc-vision/bitcoin-rpc": "^1.0.0",
94
94
  "@btc-vision/logger": "^1.0.6",
95
95
  "@eslint/js": "^9.14.0",
96
96
  "@noble/secp256k1": "^2.1.0",
package/src/_version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '1.2.1';
1
+ export const version = '1.2.3';
@@ -10,7 +10,7 @@ export abstract class Generator {
10
10
  /**
11
11
  * The magic number of OPNet
12
12
  */
13
- public static readonly MAGIC: Buffer = Buffer.from('bsi', 'utf-8');
13
+ public static readonly MAGIC: Buffer = Buffer.from('op', 'utf-8');
14
14
 
15
15
  /**
16
16
  * The public key of the sender
@@ -56,18 +56,16 @@ export class CalldataGenerator extends Generator {
56
56
  * Compile an interaction bitcoin script
57
57
  * @param {Buffer} calldata - The calldata to use
58
58
  * @param {Buffer} contractSecret - The contract secret
59
+ * @param preimage
59
60
  * @param {number[]} [features=[]] - The features to use (optional)
60
- * @param {Buffer[]} [vaultPublicKeys=[]] - The public keys of the vault (optional)
61
- * @param {number} [minimumSignatures=0] - The minimum number of signatures (optional)
62
61
  * @returns {Buffer} - The compiled script
63
62
  * @throws {Error} - If something goes wrong
64
63
  */
65
64
  public compile(
66
65
  calldata: Buffer,
67
66
  contractSecret: Buffer,
67
+ preimage: Buffer,
68
68
  features: Features[] = [],
69
- vaultPublicKeys: Buffer[] = [],
70
- minimumSignatures: number = 0,
71
69
  ): Buffer {
72
70
  if (!this.contractSaltPubKey) throw new Error('Contract salt public key not set');
73
71
 
@@ -78,16 +76,20 @@ export class CalldataGenerator extends Generator {
78
76
  this.senderFirstByte,
79
77
  opcodes.OP_TOALTSTACK,
80
78
 
79
+ // CHALLENGE PREIMAGE FOR REWARD,
80
+ preimage,
81
+ opcodes.OP_TOALTSTACK,
82
+
81
83
  this.xSenderPubKey,
84
+ opcodes.OP_DUP,
85
+ opcodes.OP_HASH256,
86
+ crypto.hash256(this.xSenderPubKey),
87
+ opcodes.OP_EQUALVERIFY,
82
88
  opcodes.OP_CHECKSIGVERIFY,
83
89
 
84
90
  this.contractSaltPubKey,
85
91
  opcodes.OP_CHECKSIGVERIFY,
86
92
 
87
- opcodes.OP_HASH160,
88
- crypto.hash160(this.xSenderPubKey),
89
- opcodes.OP_EQUALVERIFY,
90
-
91
93
  opcodes.OP_HASH160,
92
94
  crypto.hash160(contractSecret),
93
95
  opcodes.OP_EQUALVERIFY,
@@ -100,39 +102,6 @@ export class CalldataGenerator extends Generator {
100
102
  Generator.MAGIC,
101
103
  ];
102
104
 
103
- // write pub keys, when requested.
104
- if (vaultPublicKeys.length > 0) {
105
- const pubKeyBuffer = CalldataGenerator.getPubKeyAsBuffer(vaultPublicKeys, this.network);
106
- const pubKeyDataChunks: Buffer[][] = this.splitBufferIntoChunks(pubKeyBuffer);
107
-
108
- compiledData = compiledData.concat(
109
- ...[
110
- opcodes.OP_0, // provide opnet public keys
111
- ...pubKeyDataChunks,
112
- ],
113
- );
114
-
115
- if (minimumSignatures) {
116
- // verify that the minimum is not greater than 255
117
- if (minimumSignatures > 255) {
118
- throw new Error('Minimum signatures cannot exceed 255');
119
- }
120
-
121
- // we use a 2 bytes buffer even if we limit to 255 so it does not use an opcode for the number
122
- const minSigBuffer = Buffer.alloc(2);
123
- minSigBuffer.writeUint16LE(minimumSignatures, 0);
124
-
125
- compiledData = compiledData.concat(
126
- ...[
127
- opcodes.OP_1, // provide minimum signatures
128
- minSigBuffer,
129
- ],
130
- );
131
- } else {
132
- throw new Error('Minimum signatures must be provided');
133
- }
134
- }
135
-
136
105
  const featureOpcodes = features.map((feature) => FeatureOpCodes[feature]); // Get the opcodes for the features
137
106
 
138
107
  // Write calldata
@@ -14,11 +14,17 @@ export class DeploymentGenerator extends Generator {
14
14
  * Compile a bitcoin script representing a contract deployment
15
15
  * @param {Buffer} contractBytecode - The contract bytecode
16
16
  * @param {Buffer} contractSalt - The contract salt
17
+ * @param {Buffer} preimage - The preimage for reward
17
18
  * @param {Buffer} [calldata] - The calldata to be passed to the contract
18
19
  * @returns {Buffer} - The compiled script
19
20
  */
20
- public compile(contractBytecode: Buffer, contractSalt: Buffer, calldata?: Buffer): Buffer {
21
- const asm = this.getAsm(contractBytecode, contractSalt, calldata);
21
+ public compile(
22
+ contractBytecode: Buffer,
23
+ contractSalt: Buffer,
24
+ preimage: Buffer,
25
+ calldata?: Buffer,
26
+ ): Buffer {
27
+ const asm = this.getAsm(contractBytecode, contractSalt, preimage, calldata);
22
28
  const compiled = script.compile(asm);
23
29
 
24
30
  /**
@@ -35,27 +41,32 @@ export class DeploymentGenerator extends Generator {
35
41
  private getAsm(
36
42
  contractBytecode: Buffer,
37
43
  contractSalt: Buffer,
44
+ preimage: Buffer,
38
45
  calldata?: Buffer,
39
46
  ): (number | Buffer)[] {
40
47
  if (!this.contractSaltPubKey) throw new Error('Contract salt public key not set');
41
48
 
42
49
  const dataChunks: Buffer[][] = this.splitBufferIntoChunks(contractBytecode);
43
50
  const calldataChunks: Buffer[][] = calldata ? this.splitBufferIntoChunks(calldata) : [];
44
-
51
+
45
52
  const compiledData = [
46
53
  this.senderFirstByte,
47
54
  opcodes.OP_TOALTSTACK,
48
55
 
56
+ // CHALLENGE PREIMAGE FOR REWARD,
57
+ preimage,
58
+ opcodes.OP_TOALTSTACK,
59
+
49
60
  this.xSenderPubKey,
61
+ opcodes.OP_DUP,
62
+ opcodes.OP_HASH256,
63
+ crypto.hash256(this.xSenderPubKey),
64
+ opcodes.OP_EQUALVERIFY,
50
65
  opcodes.OP_CHECKSIGVERIFY,
51
66
 
52
67
  this.contractSaltPubKey,
53
68
  opcodes.OP_CHECKSIGVERIFY,
54
69
 
55
- opcodes.OP_HASH160,
56
- crypto.hash160(this.xSenderPubKey),
57
- opcodes.OP_EQUALVERIFY,
58
-
59
70
  opcodes.OP_HASH256,
60
71
  crypto.hash256(contractSalt),
61
72
  opcodes.OP_EQUALVERIFY,
@@ -1,4 +1,4 @@
1
- import { Network, networks, opcodes, script } from '@btc-vision/bitcoin';
1
+ import { crypto, Network, networks, opcodes, script } from '@btc-vision/bitcoin';
2
2
  import { ECPairInterface } from 'ecpair';
3
3
  import { Compressor } from '../../bytecode/Compressor.js';
4
4
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
@@ -70,6 +70,10 @@ export class LegacyCalldataGenerator extends Generator {
70
70
 
71
71
  let compiledData = [
72
72
  this.senderPubKey,
73
+ opcodes.OP_DUP,
74
+ opcodes.OP_HASH256,
75
+ crypto.hash256(this.senderPubKey),
76
+ opcodes.OP_EQUALVERIFY,
73
77
  opcodes.OP_CHECKSIGVERIFY,
74
78
 
75
79
  contractSecret,
@@ -0,0 +1,63 @@
1
+ import { Network, networks, opcodes, script } from '@btc-vision/bitcoin';
2
+ import { Generator } from '../Generator.js';
3
+
4
+ /**
5
+ * Class to generate bitcoin script for interaction transactions
6
+ */
7
+ export class MineableReward extends Generator {
8
+ constructor(senderPubKey: Buffer, network: Network = networks.bitcoin) {
9
+ super(senderPubKey, Buffer.alloc(0), network);
10
+ }
11
+
12
+ /**
13
+ * Compile an interaction bitcoin script
14
+ * @param {Buffer} preimage1 - Preimage 1
15
+ * @returns {Buffer} - The compiled script
16
+ * @throws {Error} - If something goes wrong
17
+ */
18
+ public compile(preimage1: Buffer): Buffer {
19
+ let compiledData: (number | Buffer)[];
20
+
21
+ if (this.isTestnet()) {
22
+ compiledData = [
23
+ preimage1,
24
+ opcodes.OP_SHA1,
25
+ opcodes.OP_SHA1,
26
+ opcodes.OP_SWAP,
27
+ opcodes.OP_SHA1,
28
+ opcodes.OP_SHA1,
29
+ opcodes.OP_EQUAL,
30
+ ];
31
+ } else {
32
+ compiledData = [
33
+ preimage1,
34
+ opcodes.OP_SWAP,
35
+ opcodes.OP_2DUP,
36
+ opcodes.OP_EQUAL,
37
+ opcodes.OP_NOT,
38
+ opcodes.OP_VERIFY,
39
+ opcodes.OP_SHA1,
40
+ opcodes.OP_SHA1,
41
+ opcodes.OP_SWAP,
42
+ opcodes.OP_SHA1,
43
+ opcodes.OP_SHA1,
44
+ opcodes.OP_EQUAL,
45
+ ];
46
+ }
47
+
48
+ const asm = compiledData.flat();
49
+ const compiled = script.compile(asm);
50
+
51
+ /** Verify the validity of the script */
52
+ const decompiled = script.decompile(compiled);
53
+ if (!decompiled) {
54
+ throw new Error('Failed to decompile script??');
55
+ }
56
+
57
+ return compiled;
58
+ }
59
+
60
+ private isTestnet(): boolean {
61
+ return this.network === networks.testnet || this.network === networks.regtest;
62
+ }
63
+ }
package/src/opnet.ts CHANGED
@@ -9,9 +9,12 @@ export * from './generators/builders/CustomGenerator.js';
9
9
  export * from './generators/builders/DeploymentGenerator.js';
10
10
  export * from './generators/builders/LegacyCalldataGenerator.js';
11
11
  export * from './generators/builders/MultiSignGenerator.js';
12
+ export * from './generators/builders/MineableReward.js';
12
13
  export * from './generators/Features.js';
13
14
  export * from './generators/Generator.js';
14
15
 
16
+ export * from './transaction/mineable/ChallengeGenerator.js';
17
+
15
18
  /** Address */
16
19
  export * from './generators/AddressGenerator.js';
17
20
  export * from './verification/TapscriptVerificator.js';
@@ -44,6 +47,7 @@ export * from './transaction/builders/InteractionTransaction.js';
44
47
  export * from './transaction/builders/MultiSignTransaction.js';
45
48
  export * from './transaction/builders/SharedInteractionTransaction.js';
46
49
  export * from './transaction/builders/TransactionBuilder.js';
50
+ export * from './transaction/builders/ChallengeSolutionTransaction.js';
47
51
 
48
52
  /** Utils */
49
53
  export * from './utils/BitcoinUtils.js';
@@ -87,6 +91,7 @@ export * from './transaction/browser/extensions/UnisatSigner.js';
87
91
  export * from './transaction/browser/extensions/XverseSigner.js';
88
92
  export * from './transaction/browser/types/Unisat.js';
89
93
  export * from './transaction/browser/types/Xverse.js';
94
+ export * from './transaction/browser/WalletConnection.js';
90
95
 
91
96
  export * from './metadata/tokens.js';
92
97
  export * from './transaction/browser/Web3Provider.js';
@@ -4,10 +4,14 @@ class ContractAddressBase {
4
4
  private readonly deriver: Secp256k1PointDeriver = new Secp256k1PointDeriver();
5
5
 
6
6
  public generateHybridKeyFromHash(input: Buffer): Buffer {
7
- const p = this.deriver.findOrDeriveValidPoint(Buffer.copyBytesFrom(input), false);
7
+ const p = this.deriver.findOrDeriveValidPoint(this.cloneBuffer(input), false);
8
8
  const y = this.deriver.getCanonicalY(p.y1, p.y2);
9
9
  return Buffer.from(this.deriver.getHybridPublicKey(p.x, y));
10
10
  }
11
+
12
+ private cloneBuffer(buffer: Buffer): Buffer {
13
+ return Buffer.from(buffer);
14
+ }
11
15
  }
12
16
 
13
17
  export const ContractAddress = new ContractAddressBase();