@btc-vision/transaction 1.2.2 → 1.2.4

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 (80) 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/TransactionFactory.d.ts +19 -4
  9. package/browser/transaction/browser/WalletConnection.d.ts +18 -0
  10. package/browser/transaction/browser/types/Xverse.d.ts +24 -10
  11. package/browser/transaction/builders/ChallengeSolutionTransaction.d.ts +18 -0
  12. package/browser/transaction/builders/DeploymentTransaction.d.ts +4 -0
  13. package/browser/transaction/builders/SharedInteractionTransaction.d.ts +5 -0
  14. package/browser/transaction/builders/TransactionBuilder.d.ts +2 -0
  15. package/browser/transaction/enums/TransactionType.d.ts +3 -4
  16. package/browser/transaction/interfaces/ITransactionParameters.d.ts +6 -0
  17. package/browser/transaction/mineable/ChallengeGenerator.d.ts +9 -0
  18. package/browser/utxo/interfaces/IUTXO.d.ts +1 -1
  19. package/browser/verification/TapscriptVerificator.d.ts +1 -1
  20. package/build/_version.d.ts +1 -1
  21. package/build/_version.js +1 -1
  22. package/build/generators/Generator.js +1 -1
  23. package/build/generators/builders/CalldataGenerator.d.ts +1 -1
  24. package/build/generators/builders/CalldataGenerator.js +7 -26
  25. package/build/generators/builders/DeploymentGenerator.d.ts +1 -1
  26. package/build/generators/builders/DeploymentGenerator.js +9 -6
  27. package/build/generators/builders/LegacyCalldataGenerator.js +5 -1
  28. package/build/generators/builders/MineableReward.d.ts +7 -0
  29. package/build/generators/builders/MineableReward.js +48 -0
  30. package/build/opnet.d.ts +4 -0
  31. package/build/opnet.js +4 -0
  32. package/build/transaction/TransactionFactory.d.ts +19 -4
  33. package/build/transaction/TransactionFactory.js +32 -0
  34. package/build/transaction/browser/WalletConnection.d.ts +18 -0
  35. package/build/transaction/browser/WalletConnection.js +95 -0
  36. package/build/transaction/browser/extensions/UnisatSigner.js +5 -2
  37. package/build/transaction/browser/extensions/XverseSigner.js +15 -9
  38. package/build/transaction/browser/types/Xverse.d.ts +24 -10
  39. package/build/transaction/builders/ChallengeSolutionTransaction.d.ts +18 -0
  40. package/build/transaction/builders/ChallengeSolutionTransaction.js +51 -0
  41. package/build/transaction/builders/DeploymentTransaction.d.ts +4 -0
  42. package/build/transaction/builders/DeploymentTransaction.js +23 -4
  43. package/build/transaction/builders/InteractionTransaction.js +1 -1
  44. package/build/transaction/builders/SharedInteractionTransaction.d.ts +5 -0
  45. package/build/transaction/builders/SharedInteractionTransaction.js +35 -13
  46. package/build/transaction/builders/TransactionBuilder.d.ts +2 -0
  47. package/build/transaction/builders/TransactionBuilder.js +2 -0
  48. package/build/transaction/enums/TransactionType.d.ts +3 -4
  49. package/build/transaction/enums/TransactionType.js +3 -4
  50. package/build/transaction/interfaces/ITransactionParameters.d.ts +6 -0
  51. package/build/transaction/mineable/ChallengeGenerator.d.ts +9 -0
  52. package/build/transaction/mineable/ChallengeGenerator.js +28 -0
  53. package/build/transaction/shared/TweakedTransaction.js +1 -1
  54. package/build/utxo/interfaces/IUTXO.d.ts +1 -1
  55. package/build/verification/TapscriptVerificator.d.ts +1 -1
  56. package/build/verification/TapscriptVerificator.js +2 -8
  57. package/package.json +3 -3
  58. package/src/_version.ts +1 -1
  59. package/src/generators/Generator.ts +1 -1
  60. package/src/generators/builders/CalldataGenerator.ts +10 -41
  61. package/src/generators/builders/DeploymentGenerator.ts +18 -7
  62. package/src/generators/builders/LegacyCalldataGenerator.ts +5 -1
  63. package/src/generators/builders/MineableReward.ts +66 -0
  64. package/src/opnet.ts +5 -0
  65. package/src/transaction/TransactionFactory.ts +66 -3
  66. package/src/transaction/browser/WalletConnection.ts +110 -0
  67. package/src/transaction/browser/extensions/UnisatSigner.ts +7 -3
  68. package/src/transaction/browser/extensions/XverseSigner.ts +24 -23
  69. package/src/transaction/browser/types/Xverse.ts +50 -36
  70. package/src/transaction/builders/ChallengeSolutionTransaction.ts +88 -0
  71. package/src/transaction/builders/DeploymentTransaction.ts +46 -3
  72. package/src/transaction/builders/InteractionTransaction.ts +1 -0
  73. package/src/transaction/builders/SharedInteractionTransaction.ts +54 -14
  74. package/src/transaction/builders/TransactionBuilder.ts +3 -0
  75. package/src/transaction/enums/TransactionType.ts +3 -4
  76. package/src/transaction/interfaces/ITransactionParameters.ts +8 -15
  77. package/src/transaction/mineable/ChallengeGenerator.ts +39 -0
  78. package/src/transaction/shared/TweakedTransaction.ts +1 -1
  79. package/src/utxo/interfaces/IUTXO.ts +1 -1
  80. package/src/verification/TapscriptVerificator.ts +3 -18
@@ -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.2",
4
+ "version": "1.2.4",
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.2';
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,66 @@
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 (
62
+ this.network.bech32 === networks.testnet.bech32 ||
63
+ this.network.bech32 === networks.regtest.bech32
64
+ );
65
+ }
66
+ }
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';
@@ -11,12 +11,14 @@ import { InteractionTransaction } from './builders/InteractionTransaction.js';
11
11
  import { TransactionBuilder } from './builders/TransactionBuilder.js';
12
12
  import { TransactionType } from './enums/TransactionType.js';
13
13
  import {
14
+ IChallengeSolutionTransactionParameters,
14
15
  IDeploymentParameters,
15
16
  IFundingTransactionParameters,
16
17
  IInteractionParameters,
17
18
  ITransactionParameters,
18
19
  } from './interfaces/ITransactionParameters.js';
19
20
  import { PSBTTypes } from './psbt/PSBTTypes.js';
21
+ import { ChallengeSolutionTransaction } from './builders/ChallengeSolutionTransaction.js';
20
22
 
21
23
  export interface DeploymentResult {
22
24
  readonly transaction: [string, string];
@@ -25,6 +27,8 @@ export interface DeploymentResult {
25
27
  readonly contractPubKey: string;
26
28
  readonly p2trAddress: string;
27
29
 
30
+ readonly preimage: string;
31
+
28
32
  readonly utxos: UTXO[];
29
33
  }
30
34
 
@@ -43,13 +47,27 @@ export interface FundingTransactionResponse {
43
47
  readonly nextUTXOs: UTXO[];
44
48
  }
45
49
 
46
- export interface BitcoinTransferResponse {
50
+ export interface ChallengeSolutionResponse {
51
+ readonly tx: Transaction;
52
+ readonly original: ChallengeSolutionTransaction;
53
+ readonly estimatedFees: bigint;
54
+ readonly nextUTXOs: UTXO[];
55
+ }
56
+
57
+ export interface BitcoinTransferBase {
47
58
  readonly tx: string;
48
- readonly original: FundingTransaction;
49
59
  readonly estimatedFees: bigint;
50
60
  readonly nextUTXOs: UTXO[];
51
61
  }
52
62
 
63
+ export interface ChallengeSolution extends BitcoinTransferBase {
64
+ readonly original: ChallengeSolutionTransaction;
65
+ }
66
+
67
+ export interface BitcoinTransferResponse extends BitcoinTransferBase {
68
+ readonly original: FundingTransaction;
69
+ }
70
+
53
71
  export class TransactionFactory {
54
72
  /**
55
73
  * @description Generate a transaction with a custom script.
@@ -127,7 +145,7 @@ export class TransactionFactory {
127
145
  */
128
146
  public async signInteraction(
129
147
  interactionParameters: IInteractionParameters,
130
- ): Promise<[string, string, UTXO[]]> {
148
+ ): Promise<[string, string, UTXO[], string]> {
131
149
  if (!interactionParameters.to) {
132
150
  throw new Error('Field "to" not provided.');
133
151
  }
@@ -185,6 +203,7 @@ export class TransactionFactory {
185
203
  ...interactionParameters,
186
204
  utxos: this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.to, 0), // always 0
187
205
  randomBytes: preTransaction.getRndBytes(),
206
+ preimage: preTransaction.getPreimage(),
188
207
  nonWitnessUtxo: signedTransaction.tx.toBuffer(),
189
208
  estimatedFees: preTransaction.estimatedFees,
190
209
  };
@@ -197,6 +216,7 @@ export class TransactionFactory {
197
216
  signedTransaction.tx.toHex(),
198
217
  outTx.toHex(),
199
218
  this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.from, 1), // always 1
219
+ preTransaction.getPreimage().toString('hex'),
200
220
  ];
201
221
  }
202
222
 
@@ -244,6 +264,7 @@ export class TransactionFactory {
244
264
  ...deploymentParameters,
245
265
  utxos: [newUtxo],
246
266
  randomBytes: preTransaction.getRndBytes(),
267
+ preimage: preTransaction.getPreimage(),
247
268
  nonWitnessUtxo: signedTransaction.toBuffer(),
248
269
  optionalOutputs: [],
249
270
  };
@@ -270,6 +291,7 @@ export class TransactionFactory {
270
291
  contractPubKey: finalTransaction.contractPubKey,
271
292
  p2trAddress: finalTransaction.p2trAddress,
272
293
  utxos: [refundUTXO],
294
+ preimage: preTransaction.getPreimage().toString('hex'),
273
295
  };
274
296
  }
275
297
 
@@ -286,7 +308,27 @@ export class TransactionFactory {
286
308
  }
287
309
 
288
310
  const resp = await this.createFundTransaction(parameters);
311
+ return {
312
+ estimatedFees: resp.estimatedFees,
313
+ original: resp.original,
314
+ tx: resp.tx.toHex(),
315
+ nextUTXOs: this.getAllNewUTXOs(resp.original, resp.tx, parameters.from),
316
+ };
317
+ }
289
318
 
319
+ /**
320
+ * @description Creates a challenge solution transaction.
321
+ * @param {IChallengeSolutionTransactionParameters} parameters - The challenge solution transaction parameters
322
+ * @returns {Promise<ChallengeSolution>} - The signed transaction
323
+ */
324
+ public async createChallengeSolution(
325
+ parameters: IChallengeSolutionTransactionParameters,
326
+ ): Promise<ChallengeSolution> {
327
+ if (!parameters.from) {
328
+ throw new Error('Field "from" not provided.');
329
+ }
330
+
331
+ const resp = await this._createChallengeSolution(parameters);
290
332
  return {
291
333
  estimatedFees: resp.estimatedFees,
292
334
  original: resp.original,
@@ -323,6 +365,27 @@ export class TransactionFactory {
323
365
  return utxos;
324
366
  }
325
367
 
368
+ private async _createChallengeSolution(
369
+ parameters: IChallengeSolutionTransactionParameters,
370
+ ): Promise<ChallengeSolutionResponse> {
371
+ if (!parameters.to) throw new Error('Field "to" not provided.');
372
+
373
+ const challengeTransaction: ChallengeSolutionTransaction = new ChallengeSolutionTransaction(
374
+ parameters,
375
+ );
376
+ const signedTransaction: Transaction = await challengeTransaction.signTransaction();
377
+ if (!signedTransaction) {
378
+ throw new Error('Could not sign funding transaction.');
379
+ }
380
+
381
+ return {
382
+ tx: signedTransaction,
383
+ original: challengeTransaction,
384
+ estimatedFees: challengeTransaction.estimatedFees,
385
+ nextUTXOs: this.getUTXOAsTransaction(signedTransaction, parameters.to, 0),
386
+ };
387
+ }
388
+
326
389
  private async createFundTransaction(
327
390
  parameters: IFundingTransactionParameters,
328
391
  ): Promise<FundingTransactionResponse> {