@btc-vision/transaction 1.0.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 (270) hide show
  1. package/.babelrc +7 -0
  2. package/.gitattributes +2 -0
  3. package/.github/workflows/node.js.yml +22 -0
  4. package/.idea/codeStyles/Project.xml +56 -0
  5. package/.idea/codeStyles/codeStyleConfig.xml +5 -0
  6. package/.idea/inspectionProfiles/Project_Default.xml +6 -0
  7. package/.idea/jsLibraryMappings.xml +6 -0
  8. package/.idea/modules.xml +8 -0
  9. package/.idea/prettier.xml +6 -0
  10. package/.idea/transaction.iml +16 -0
  11. package/.idea/vcs.xml +6 -0
  12. package/.prettierrc.json +12 -0
  13. package/CONTRIBUTING.md +71 -0
  14. package/LICENSE.md +16 -0
  15. package/README.md +213 -0
  16. package/browser/873e754d6c7c6e9361f1.module.wasm +0 -0
  17. package/browser/_version.d.ts +1 -0
  18. package/browser/bytecode/Compressor.d.ts +6 -0
  19. package/browser/crypto/crypto-browser.d.ts +40 -0
  20. package/browser/crypto/crypto.d.ts +2 -0
  21. package/browser/generators/Generator.d.ts +12 -0
  22. package/browser/generators/builders/CalldataGenerator.d.ts +8 -0
  23. package/browser/generators/builders/DeploymentGenerator.d.ts +7 -0
  24. package/browser/index.d.ts +3 -0
  25. package/browser/index.js +2 -0
  26. package/browser/index.js.LICENSE.txt +23 -0
  27. package/browser/keypair/EcKeyPair.d.ts +24 -0
  28. package/browser/keypair/Wallet.d.ts +16 -0
  29. package/browser/keypair/interfaces/IWallet.d.ts +5 -0
  30. package/browser/metadata/ContractBaseMetadata.d.ts +9 -0
  31. package/browser/metadata/ContractMetadataManager.d.ts +1 -0
  32. package/browser/metadata/contracts/wBTC.d.ts +12 -0
  33. package/browser/network/NetworkInformation.d.ts +6 -0
  34. package/browser/opnet.d.ts +22 -0
  35. package/browser/scripts/Regtest.d.ts +2 -0
  36. package/browser/scripts/test.d.ts +1 -0
  37. package/browser/signer/TweakedSigner.d.ts +9 -0
  38. package/browser/transaction/TransactionBuilder.d.ts +1 -0
  39. package/browser/transaction/TransactionFactory.d.ts +4 -0
  40. package/browser/transaction/builders/FundingTransaction.d.ts +11 -0
  41. package/browser/transaction/builders/InteractionTransaction.d.ts +47 -0
  42. package/browser/transaction/builders/TransactionBuilder.d.ts +64 -0
  43. package/browser/transaction/enums/TransactionType.d.ts +7 -0
  44. package/browser/transaction/interfaces/ITransactionParameters.d.ts +33 -0
  45. package/browser/transaction/interfaces/Tap.d.ts +22 -0
  46. package/browser/utils/BitcoinUtils.d.ts +5 -0
  47. package/browser/utxo/UTXOManager.d.ts +7 -0
  48. package/browser/utxo/interfaces/IUTXO.d.ts +19 -0
  49. package/build/Utils.d.ts +0 -0
  50. package/build/Utils.js +1 -0
  51. package/build/_version.d.ts +1 -0
  52. package/build/_version.js +1 -0
  53. package/build/bytecode/Compressor.d.ts +6 -0
  54. package/build/bytecode/Compressor.js +13 -0
  55. package/build/contracts/ContractMetadataManager.d.ts +0 -0
  56. package/build/contracts/ContractMetadataManager.js +1 -0
  57. package/build/crypto/crypto.d.ts +2 -0
  58. package/build/crypto/crypto.js +1 -0
  59. package/build/generators/Generator.d.ts +12 -0
  60. package/build/generators/Generator.js +25 -0
  61. package/build/generators/builders/CalldataGenerator.d.ts +8 -0
  62. package/build/generators/builders/CalldataGenerator.js +79 -0
  63. package/build/generators/builders/DeploymentGenerator.d.ts +7 -0
  64. package/build/generators/builders/DeploymentGenerator.js +38 -0
  65. package/build/index.d.ts +3 -0
  66. package/build/index.js +3 -0
  67. package/build/keypair/EcKeyPair.d.ts +24 -0
  68. package/build/keypair/EcKeyPair.js +107 -0
  69. package/build/keypair/Wallet.d.ts +16 -0
  70. package/build/keypair/Wallet.js +30 -0
  71. package/build/keypair/interfaces/GeneratedWallet.d.ts +5 -0
  72. package/build/keypair/interfaces/GeneratedWallet.js +1 -0
  73. package/build/keypair/interfaces/IWallet.d.ts +5 -0
  74. package/build/keypair/interfaces/IWallet.js +1 -0
  75. package/build/metadata/ContractBaseMetadata.d.ts +9 -0
  76. package/build/metadata/ContractBaseMetadata.js +13 -0
  77. package/build/metadata/ContractMetadataManager.d.ts +1 -0
  78. package/build/metadata/ContractMetadataManager.js +9 -0
  79. package/build/metadata/contracts/ContractBase.d.ts +9 -0
  80. package/build/metadata/contracts/ContractBase.js +13 -0
  81. package/build/metadata/contracts/ContractBaseMetadata.d.ts +9 -0
  82. package/build/metadata/contracts/ContractBaseMetadata.js +13 -0
  83. package/build/metadata/contracts/ContractMetadataManager.d.ts +0 -0
  84. package/build/metadata/contracts/ContractMetadataManager.js +1 -0
  85. package/build/metadata/contracts/wBTC.d.ts +12 -0
  86. package/build/metadata/contracts/wBTC.js +26 -0
  87. package/build/network/NetworkConverter.d.ts +0 -0
  88. package/build/network/NetworkConverter.js +14 -0
  89. package/build/network/NetworkInformation.d.ts +6 -0
  90. package/build/network/NetworkInformation.js +1 -0
  91. package/build/opnet.d.ts +22 -0
  92. package/build/opnet.js +22 -0
  93. package/build/scripts/Regtest.d.ts +2 -0
  94. package/build/scripts/Regtest.js +15 -0
  95. package/build/scripts/test.d.ts +1 -0
  96. package/build/scripts/test.js +74 -0
  97. package/build/signer/Regtest.d.ts +2 -0
  98. package/build/signer/Regtest.js +15 -0
  99. package/build/signer/TweakedSigner.d.ts +9 -0
  100. package/build/signer/TweakedSigner.js +22 -0
  101. package/build/transaction/TransactionBuilder.d.ts +60 -0
  102. package/build/transaction/TransactionBuilder.js +244 -0
  103. package/build/transaction/TransactionFactory.d.ts +4 -0
  104. package/build/transaction/TransactionFactory.js +32 -0
  105. package/build/transaction/builders/FundingTransaction.d.ts +11 -0
  106. package/build/transaction/builders/FundingTransaction.js +23 -0
  107. package/build/transaction/builders/GenericTransaction.d.ts +11 -0
  108. package/build/transaction/builders/GenericTransaction.js +23 -0
  109. package/build/transaction/builders/InteractionTransaction.d.ts +47 -0
  110. package/build/transaction/builders/InteractionTransaction.js +219 -0
  111. package/build/transaction/builders/TransactionBuilder.d.ts +64 -0
  112. package/build/transaction/builders/TransactionBuilder.js +288 -0
  113. package/build/transaction/enums/TransactionType.d.ts +7 -0
  114. package/build/transaction/enums/TransactionType.js +8 -0
  115. package/build/transaction/interfaces/ITransactionParameters.d.ts +33 -0
  116. package/build/transaction/interfaces/ITransactionParameters.js +1 -0
  117. package/build/transaction/interfaces/ITransactions.d.ts +32 -0
  118. package/build/transaction/interfaces/ITransactions.js +1 -0
  119. package/build/transaction/interfaces/Tap.d.ts +22 -0
  120. package/build/transaction/interfaces/Tap.js +1 -0
  121. package/build/utils/BitcoinUtils.d.ts +5 -0
  122. package/build/utils/BitcoinUtils.js +9 -0
  123. package/build/utxo/IUTXO.d.ts +0 -0
  124. package/build/utxo/IUTXO.js +1 -0
  125. package/build/utxo/UTXOManager.d.ts +7 -0
  126. package/build/utxo/UTXOManager.js +47 -0
  127. package/build/utxo/interfaces/IUTXO.d.ts +19 -0
  128. package/build/utxo/interfaces/IUTXO.js +1 -0
  129. package/cjs/_version.d.ts +1 -0
  130. package/cjs/_version.js +4 -0
  131. package/cjs/bytecode/Compressor.d.ts +6 -0
  132. package/cjs/bytecode/Compressor.js +20 -0
  133. package/cjs/crypto/crypto.d.ts +2 -0
  134. package/cjs/crypto/crypto.js +8 -0
  135. package/cjs/generators/Generator.d.ts +13 -0
  136. package/cjs/generators/Generator.js +31 -0
  137. package/cjs/generators/builders/CalldataGenerator.d.ts +8 -0
  138. package/cjs/generators/builders/CalldataGenerator.js +83 -0
  139. package/cjs/generators/builders/DeploymentGenerator.d.ts +7 -0
  140. package/cjs/generators/builders/DeploymentGenerator.js +42 -0
  141. package/cjs/index.d.ts +3 -0
  142. package/cjs/index.js +32 -0
  143. package/cjs/keypair/EcKeyPair.d.ts +24 -0
  144. package/cjs/keypair/EcKeyPair.js +137 -0
  145. package/cjs/keypair/Wallet.d.ts +16 -0
  146. package/cjs/keypair/Wallet.js +34 -0
  147. package/cjs/keypair/interfaces/IWallet.d.ts +5 -0
  148. package/cjs/keypair/interfaces/IWallet.js +2 -0
  149. package/cjs/metadata/ContractBaseMetadata.d.ts +9 -0
  150. package/cjs/metadata/ContractBaseMetadata.js +17 -0
  151. package/cjs/metadata/ContractMetadataManager.d.ts +0 -0
  152. package/cjs/metadata/ContractMetadataManager.js +1 -0
  153. package/cjs/metadata/contracts/wBTC.d.ts +12 -0
  154. package/cjs/metadata/contracts/wBTC.js +30 -0
  155. package/cjs/network/NetworkInformation.d.ts +6 -0
  156. package/cjs/network/NetworkInformation.js +2 -0
  157. package/cjs/opnet.d.ts +1 -0
  158. package/cjs/opnet.js +5 -0
  159. package/cjs/scripts/Regtest.d.ts +2 -0
  160. package/cjs/scripts/Regtest.js +18 -0
  161. package/cjs/scripts/test.d.ts +1 -0
  162. package/cjs/scripts/test.js +44 -0
  163. package/cjs/signer/TweakedSigner.d.ts +9 -0
  164. package/cjs/signer/TweakedSigner.js +49 -0
  165. package/cjs/transaction/TransactionBuilder.d.ts +0 -0
  166. package/cjs/transaction/TransactionBuilder.js +1 -0
  167. package/cjs/transaction/TransactionFactory.d.ts +4 -0
  168. package/cjs/transaction/TransactionFactory.js +33 -0
  169. package/cjs/transaction/builders/FundingTransaction.d.ts +11 -0
  170. package/cjs/transaction/builders/FundingTransaction.js +27 -0
  171. package/cjs/transaction/builders/InteractionTransaction.d.ts +45 -0
  172. package/cjs/transaction/builders/InteractionTransaction.js +214 -0
  173. package/cjs/transaction/builders/TransactionBuilder.d.ts +64 -0
  174. package/cjs/transaction/builders/TransactionBuilder.js +304 -0
  175. package/cjs/transaction/enums/TransactionType.d.ts +7 -0
  176. package/cjs/transaction/enums/TransactionType.js +11 -0
  177. package/cjs/transaction/interfaces/ITransactionParameters.d.ts +32 -0
  178. package/cjs/transaction/interfaces/ITransactionParameters.js +2 -0
  179. package/cjs/transaction/interfaces/Tap.d.ts +22 -0
  180. package/cjs/transaction/interfaces/Tap.js +2 -0
  181. package/cjs/utils/BitcoinUtils.d.ts +5 -0
  182. package/cjs/utils/BitcoinUtils.js +13 -0
  183. package/cjs/utxo/UTXOManager.d.ts +7 -0
  184. package/cjs/utxo/UTXOManager.js +51 -0
  185. package/cjs/utxo/interfaces/IUTXO.d.ts +19 -0
  186. package/cjs/utxo/interfaces/IUTXO.js +2 -0
  187. package/docs/.nojekyll +1 -0
  188. package/docs/assets/highlight.css +92 -0
  189. package/docs/assets/icons.js +15 -0
  190. package/docs/assets/icons.svg +1 -0
  191. package/docs/assets/main.js +59 -0
  192. package/docs/assets/material-style.css +247 -0
  193. package/docs/assets/navigation.js +1 -0
  194. package/docs/assets/search.js +1 -0
  195. package/docs/assets/style.css +1412 -0
  196. package/docs/classes/BitcoinUtils.html +183 -0
  197. package/docs/classes/CalldataGenerator.html +211 -0
  198. package/docs/classes/Compressor.html +185 -0
  199. package/docs/classes/ContractBaseMetadata.html +182 -0
  200. package/docs/classes/DeploymentGenerator.html +200 -0
  201. package/docs/classes/EcKeyPair.html +280 -0
  202. package/docs/classes/FundingTransaction.html +293 -0
  203. package/docs/classes/Generator.html +199 -0
  204. package/docs/classes/InteractionTransaction.html +365 -0
  205. package/docs/classes/TransactionBuilder.html +303 -0
  206. package/docs/classes/TransactionFactory.html +180 -0
  207. package/docs/classes/TweakedSigner.html +181 -0
  208. package/docs/classes/UTXOManager.html +187 -0
  209. package/docs/classes/Wallet.html +191 -0
  210. package/docs/classes/wBTC.html +189 -0
  211. package/docs/enums/TransactionType.html +179 -0
  212. package/docs/hierarchy.html +174 -0
  213. package/docs/index.html +237 -0
  214. package/docs/interfaces/FetchUTXOParams.html +178 -0
  215. package/docs/interfaces/IFundingTransactionParameters.html +182 -0
  216. package/docs/interfaces/IInteractionParameters.html +185 -0
  217. package/docs/interfaces/ITransactionDataContractDeployment.html +184 -0
  218. package/docs/interfaces/ITransactionDataContractInteractionWrap.html +186 -0
  219. package/docs/interfaces/ITransactionParameters.html +181 -0
  220. package/docs/interfaces/IWallet.html +181 -0
  221. package/docs/interfaces/NetworkInformation.html +176 -0
  222. package/docs/interfaces/PsbtInputExtended.html +194 -0
  223. package/docs/interfaces/PsbtOutputExtendedAddress.html +183 -0
  224. package/docs/interfaces/PsbtOutputExtendedScript.html +183 -0
  225. package/docs/interfaces/RawUTXOResponse.html +178 -0
  226. package/docs/interfaces/TapLeafScript.html +177 -0
  227. package/docs/interfaces/TweakSettings.html +179 -0
  228. package/docs/interfaces/UTXO.html +178 -0
  229. package/docs/interfaces/UpdateInput.html +175 -0
  230. package/docs/modules.html +208 -0
  231. package/docs/types/PsbtOutputExtended.html +174 -0
  232. package/docs/variables/version.html +174 -0
  233. package/gulpfile.js +152 -0
  234. package/jest.config.ts +52 -0
  235. package/package.json +116 -0
  236. package/src/_version.ts +1 -0
  237. package/src/bytecode/Compressor.ts +27 -0
  238. package/src/crypto/crypto-browser.js +71 -0
  239. package/src/crypto/crypto.ts +1 -0
  240. package/src/generators/Generator.ts +75 -0
  241. package/src/generators/builders/CalldataGenerator.ts +143 -0
  242. package/src/generators/builders/DeploymentGenerator.ts +63 -0
  243. package/src/index.ts +4 -0
  244. package/src/keypair/EcKeyPair.ts +265 -0
  245. package/src/keypair/Wallet.ts +75 -0
  246. package/src/keypair/interfaces/IWallet.ts +19 -0
  247. package/src/metadata/ContractBaseMetadata.ts +23 -0
  248. package/src/metadata/contracts/wBTC.ts +44 -0
  249. package/src/network/NetworkInformation.ts +7 -0
  250. package/src/opnet.ts +42 -0
  251. package/src/scripts/Regtest.ts +19 -0
  252. package/src/scripts/test.ts +98 -0
  253. package/src/signer/TweakedSigner.ts +57 -0
  254. package/src/transaction/TransactionFactory.ts +57 -0
  255. package/src/transaction/builders/FundingTransaction.ts +36 -0
  256. package/src/transaction/builders/InteractionTransaction.ts +439 -0
  257. package/src/transaction/builders/TransactionBuilder.ts +603 -0
  258. package/src/transaction/enums/TransactionType.ts +7 -0
  259. package/src/transaction/interfaces/ITransactionParameters.ts +41 -0
  260. package/src/transaction/interfaces/Tap.ts +26 -0
  261. package/src/utils/BitcoinUtils.ts +24 -0
  262. package/src/utxo/UTXOManager.ts +67 -0
  263. package/src/utxo/interfaces/IUTXO.ts +22 -0
  264. package/tests/TransactionBuilder.test.ts +58 -0
  265. package/tests/contracts/wbtc.wasm +0 -0
  266. package/tsconfig.base.json +43 -0
  267. package/tsconfig.cjs.json +9 -0
  268. package/tsconfig.json +8 -0
  269. package/tsconfig.webpack.json +11 -0
  270. package/webpack.config.js +77 -0
@@ -0,0 +1,75 @@
1
+ import { Network, networks } from 'bitcoinjs-lib';
2
+
3
+ /** Bitcoin Script Generator */
4
+ export abstract class Generator {
5
+ /**
6
+ * The maximum size of a data chunk
7
+ */
8
+ public static readonly DATA_CHUNK_SIZE: number = 512;
9
+
10
+ /**
11
+ * The magic number of OPNet
12
+ */
13
+ public static readonly MAGIC: Buffer = Buffer.from('bsi', 'utf-8');
14
+
15
+ /**
16
+ * The public key of the sender
17
+ * @protected
18
+ */
19
+ protected readonly senderPubKey: Buffer;
20
+
21
+ /**
22
+ * The public key of the contract salt
23
+ * @protected
24
+ */
25
+ protected readonly contractSaltPubKey: Buffer;
26
+
27
+ /**
28
+ * The network to use
29
+ * @protected
30
+ */
31
+ protected readonly network: Network = networks.bitcoin;
32
+
33
+ protected constructor(
34
+ senderPubKey: Buffer,
35
+ contractSaltPubKey: Buffer,
36
+ network: Network = networks.bitcoin,
37
+ ) {
38
+ this.senderPubKey = senderPubKey;
39
+ this.contractSaltPubKey = contractSaltPubKey;
40
+ this.network = network;
41
+ }
42
+
43
+ /**
44
+ * Compile the script
45
+ * @param args - The arguments to use when compiling the script
46
+ * @returns {Buffer} - The compiled script
47
+ */
48
+ public abstract compile(...args: unknown[]): Buffer;
49
+
50
+ /**
51
+ * Split a buffer into chunks
52
+ * @param {Buffer} buffer - The buffer to split
53
+ * @param {number} chunkSize - The size of each chunk
54
+ * @protected
55
+ * @returns {Array<Buffer[]>} - The chunks
56
+ */
57
+ protected splitBufferIntoChunks(
58
+ buffer: Buffer,
59
+ chunkSize: number = Generator.DATA_CHUNK_SIZE,
60
+ ): Array<Buffer[]> {
61
+ const chunks: Array<Buffer[]> = [];
62
+ for (let i = 0; i < buffer.length; i += chunkSize) {
63
+ const dataLength = Math.min(chunkSize, buffer.length - i);
64
+
65
+ const buf2 = Buffer.alloc(dataLength);
66
+ for (let j = 0; j < dataLength; j++) {
67
+ buf2.writeUInt8(buffer[i + j], j);
68
+ }
69
+
70
+ chunks.push([buf2]);
71
+ }
72
+
73
+ return chunks;
74
+ }
75
+ }
@@ -0,0 +1,143 @@
1
+ import { crypto, Network, networks, opcodes, script } from 'bitcoinjs-lib';
2
+ import { ECPairInterface } from 'ecpair';
3
+ import { Compressor } from '../../bytecode/Compressor.js';
4
+ import { Generator } from '../Generator.js';
5
+ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
6
+
7
+ /**
8
+ * Class to generate bitcoin script for interaction transactions
9
+ */
10
+ export class CalldataGenerator extends Generator {
11
+ constructor(
12
+ senderPubKey: Buffer,
13
+ contractSaltPubKey: Buffer,
14
+ network: Network = networks.bitcoin,
15
+ ) {
16
+ super(senderPubKey, contractSaltPubKey, network);
17
+ }
18
+
19
+ /**
20
+ * Compile an interaction bitcoin script
21
+ * @param {Buffer} calldata - The calldata to use
22
+ * @param {Buffer} contractSecret - The contract secret
23
+ * @param {Buffer[]} [vaultPublicKeys=[]] - The public keys of the vault (optional)
24
+ * @param {number} [minimumSignatures=0] - The minimum number of signatures (optional)
25
+ * @returns {Buffer} - The compiled script
26
+ * @throws {Error} - If something goes wrong
27
+ */
28
+ public compile(
29
+ calldata: Buffer,
30
+ contractSecret: Buffer,
31
+ vaultPublicKeys: Buffer[] = [],
32
+ minimumSignatures: number = 0,
33
+ ): Buffer {
34
+ const dataChunks: Buffer[][] = this.splitBufferIntoChunks(calldata);
35
+ if (!dataChunks.length) throw new Error('No data chunks found');
36
+
37
+ let compiledData = [
38
+ this.senderPubKey,
39
+ opcodes.OP_CHECKSIGVERIFY,
40
+
41
+ this.contractSaltPubKey,
42
+ opcodes.OP_CHECKSIGVERIFY,
43
+
44
+ opcodes.OP_HASH160,
45
+ crypto.hash160(this.senderPubKey),
46
+ opcodes.OP_EQUALVERIFY,
47
+
48
+ opcodes.OP_HASH160,
49
+ crypto.hash160(contractSecret),
50
+ opcodes.OP_EQUALVERIFY,
51
+
52
+ opcodes.OP_DEPTH,
53
+ opcodes.OP_1,
54
+ opcodes.OP_NUMEQUAL,
55
+ opcodes.OP_IF,
56
+
57
+ Generator.MAGIC,
58
+ ];
59
+
60
+ // write pub keys, when requested.
61
+ if (vaultPublicKeys.length > 0) {
62
+ const pubKeyBuffer = this.getPubKeyAsBuffer(vaultPublicKeys);
63
+ const pubKeyDataChunks: Buffer[][] = this.splitBufferIntoChunks(pubKeyBuffer);
64
+
65
+ compiledData = compiledData.concat(
66
+ ...[
67
+ opcodes.OP_0, // provide opnet public keys
68
+ ...pubKeyDataChunks,
69
+ ],
70
+ );
71
+
72
+ if (minimumSignatures) {
73
+ // verify that the minimum is not greater than 255
74
+ if (minimumSignatures > 255) {
75
+ throw new Error('Minimum signatures cannot exceed 255');
76
+ }
77
+
78
+ // we use a 2 bytes buffer even if we limit to 255 so it does not use an opcode for the number
79
+ const minSigBuffer = Buffer.alloc(2);
80
+ minSigBuffer.writeUint16LE(minimumSignatures, 0);
81
+
82
+ compiledData = compiledData.concat(
83
+ ...[
84
+ opcodes.OP_1, // provide minimum signatures
85
+ minSigBuffer,
86
+ ],
87
+ );
88
+ } else {
89
+ throw new Error('Minimum signatures must be provided');
90
+ }
91
+ }
92
+
93
+ // Write calldata
94
+ compiledData = compiledData.concat(
95
+ ...[opcodes.OP_1NEGATE, ...dataChunks, opcodes.OP_ELSE, opcodes.OP_1, opcodes.OP_ENDIF],
96
+ );
97
+
98
+ const asm = compiledData.flat();
99
+ const compiled = script.compile(asm);
100
+
101
+ /** Verify the validity of the script */
102
+ const decompiled = script.decompile(compiled);
103
+ if (!decompiled) {
104
+ throw new Error('Failed to decompile script??');
105
+ }
106
+
107
+ return compiled;
108
+ }
109
+
110
+ /**
111
+ * Get the public key as a buffer
112
+ * @param {Buffer[]} witnessKeys - The public keys
113
+ * @private
114
+ * @returns {Buffer} - The public key as a buffer
115
+ */
116
+ private getPubKeyAsBuffer(witnessKeys: Buffer[]): Buffer {
117
+ let finalBuffer: Buffer = Buffer.alloc(0);
118
+
119
+ for (let pubKey of witnessKeys) {
120
+ const key: ECPairInterface = EcKeyPair.fromPublicKey(pubKey, this.network);
121
+
122
+ if (!key.compressed) {
123
+ throw new Error('Public key must be compressed');
124
+ }
125
+
126
+ if (pubKey.byteLength !== 33) {
127
+ throw new Error(`Public key must be 33 bytes, got ${pubKey.byteLength} bytes.`);
128
+ }
129
+
130
+ finalBuffer = Buffer.concat([finalBuffer, pubKey]);
131
+ }
132
+
133
+ // compress the public keys
134
+ const compressed: Buffer = Compressor.compress(finalBuffer);
135
+ if (compressed.byteLength >= finalBuffer.byteLength) {
136
+ // we ensure that the user pays the smallest amount of fees. [micro-optimization]
137
+ return finalBuffer;
138
+ }
139
+
140
+ // if compressed is smaller, return compressed.
141
+ return compressed;
142
+ }
143
+ }
@@ -0,0 +1,63 @@
1
+ import { crypto, Network, networks, opcodes, script } from 'bitcoinjs-lib';
2
+ import { Generator } from '../Generator.js';
3
+
4
+ export class DeploymentGenerator extends Generator {
5
+ constructor(
6
+ senderPubKey: Buffer,
7
+ contractSaltPubKey: Buffer,
8
+ network: Network = networks.bitcoin,
9
+ ) {
10
+ super(senderPubKey, contractSaltPubKey, network);
11
+ }
12
+
13
+ /**
14
+ * Compile a bitcoin script representing a contract deployment
15
+ * @param {Buffer} contractBytecode - The contract bytecode
16
+ * @param {Buffer} contractSalt - The contract salt
17
+ * @returns {Buffer} - The compiled script
18
+ */
19
+ public compile(contractBytecode: Buffer, contractSalt: Buffer): Buffer {
20
+ const dataChunks = this.splitBufferIntoChunks(contractBytecode);
21
+
22
+ const asm = [
23
+ this.senderPubKey,
24
+ opcodes.OP_CHECKSIGVERIFY,
25
+
26
+ this.contractSaltPubKey,
27
+ opcodes.OP_CHECKSIGVERIFY,
28
+
29
+ opcodes.OP_HASH160,
30
+ crypto.hash160(this.senderPubKey),
31
+ opcodes.OP_EQUALVERIFY,
32
+
33
+ opcodes.OP_HASH256,
34
+ crypto.hash256(contractSalt),
35
+ opcodes.OP_EQUALVERIFY,
36
+
37
+ opcodes.OP_DEPTH,
38
+ opcodes.OP_1,
39
+ opcodes.OP_NUMEQUAL,
40
+ opcodes.OP_IF,
41
+
42
+ Generator.MAGIC,
43
+ opcodes.OP_1NEGATE,
44
+ ...dataChunks,
45
+
46
+ opcodes.OP_ELSE,
47
+ opcodes.OP_1,
48
+ opcodes.OP_ENDIF,
49
+ ].flat();
50
+
51
+ const compiled = script.compile(asm);
52
+
53
+ /**
54
+ * Verify that the script can be decompiled
55
+ */
56
+ const decompiled = script.decompile(compiled);
57
+ if (!decompiled) {
58
+ throw new Error('Failed to decompile script??');
59
+ }
60
+
61
+ return compiled;
62
+ }
63
+ }
package/src/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ import * as opnet from './opnet.js';
2
+
3
+ export { opnet };
4
+ export * from './opnet.js';
@@ -0,0 +1,265 @@
1
+ import bip32, { BIP32Interface } from 'bip32';
2
+ import { address, initEccLib, Network, networks, payments } from 'bitcoinjs-lib';
3
+ import { ECPairFactory, ECPairInterface } from 'ecpair';
4
+ import * as ecc from 'tiny-secp256k1';
5
+ import { Address } from '@btc-vision/bsi-binary';
6
+ import { IWallet } from './interfaces/IWallet.js';
7
+
8
+ initEccLib(ecc);
9
+
10
+ // @ts-ignore
11
+ const BIP32Factory = typeof bip32 === 'function' ? bip32 : bip32.BIP32Factory;
12
+
13
+ /**
14
+ * Class for handling EC key pairs
15
+ * @class EcKeyPair
16
+ * @module EcKeyPair
17
+ * @typicalname EcKeyPair
18
+ * @example import { EcKeyPair } from '@btc-vision/transaction';
19
+ */
20
+ export class EcKeyPair {
21
+ // @ts-ignore
22
+ public static BIP32 = BIP32Factory(ecc);
23
+ public static ECPair = ECPairFactory(ecc);
24
+
25
+ /**
26
+ * Generate a keypair from a WIF
27
+ * @param {string} wif - The WIF to use
28
+ * @param {Network} network - The network to use
29
+ * @returns {ECPairInterface} - The generated keypair
30
+ */
31
+ public static fromWIF(wif: string, network: Network = networks.bitcoin): ECPairInterface {
32
+ return this.ECPair.fromWIF(wif, network);
33
+ }
34
+
35
+ /**
36
+ * Generate a keypair from a private key
37
+ * @param {Buffer} privateKey - The private key to use
38
+ * @param {Network} network - The network to use
39
+ * @returns {ECPairInterface} - The generated keypair
40
+ */
41
+ public static fromPrivateKey(
42
+ privateKey: Buffer,
43
+ network: Network = networks.bitcoin,
44
+ ): ECPairInterface {
45
+ return this.ECPair.fromPrivateKey(privateKey, { network });
46
+ }
47
+
48
+ /**
49
+ * Generate a keypair from a public key
50
+ * @param {Buffer} publicKey - The public key to use
51
+ * @param {Network} network - The network to use
52
+ * @returns {ECPairInterface} - The generated keypair
53
+ */
54
+ public static fromPublicKey(
55
+ publicKey: Buffer,
56
+ network: Network = networks.bitcoin,
57
+ ): ECPairInterface {
58
+ return this.ECPair.fromPublicKey(publicKey, { network });
59
+ }
60
+
61
+ /**
62
+ * Generate a multi-sig address
63
+ * @param {Buffer[]} pubKeys - The public keys to use
64
+ * @param {number} minimumSignatureRequired - The minimum number of signatures required
65
+ * @param {Network} network - The network to use
66
+ * @returns {Address} - The generated address
67
+ * @throws {Error} - If the address cannot be generated
68
+ */
69
+ public static generateMultiSigAddress(
70
+ pubKeys: Buffer[],
71
+ minimumSignatureRequired: number,
72
+ network: Network = networks.bitcoin,
73
+ ): Address {
74
+ const publicKeys: Buffer[] = this.verifyPubKeys(pubKeys, network);
75
+ const { address } = payments.p2wsh({
76
+ redeem: payments.p2ms({
77
+ m: minimumSignatureRequired,
78
+ pubkeys: publicKeys,
79
+ network: network,
80
+ }),
81
+ network: network,
82
+ });
83
+
84
+ if (!address) {
85
+ throw new Error('Failed to generate address');
86
+ }
87
+
88
+ return address;
89
+ }
90
+
91
+ /**
92
+ * Verify public keys and return the public keys
93
+ * @param {Buffer[]} pubKeys - The public keys to verify
94
+ * @param {Network} network - The network to use
95
+ * @returns {Buffer[]} - The verified public keys
96
+ * @throws {Error} - If the key cannot be regenerated
97
+ */
98
+ public static verifyPubKeys(pubKeys: Buffer[], network: Network = networks.bitcoin): Buffer[] {
99
+ return pubKeys.map((pubKey) => {
100
+ const key = EcKeyPair.fromPublicKey(pubKey, network);
101
+
102
+ if (!key) {
103
+ throw new Error('Failed to regenerate key');
104
+ }
105
+
106
+ return key.publicKey;
107
+ });
108
+ }
109
+
110
+ /**
111
+ * Get a P2WPKH address from a keypair
112
+ * @param {ECPairInterface} keyPair - The keypair to get the address for
113
+ * @param {Network} network - The network to use
114
+ * @returns {Address} - The address
115
+ */
116
+ public static getP2WPKHAddress(
117
+ keyPair: ECPairInterface,
118
+ network: Network = networks.bitcoin,
119
+ ): Address {
120
+ const res = payments.p2wpkh({ pubkey: keyPair.publicKey, network: network });
121
+
122
+ if (!res.address) {
123
+ throw new Error('Failed to generate wallet');
124
+ }
125
+
126
+ return res.address;
127
+ }
128
+
129
+ /**
130
+ * Generate a random wallet
131
+ * @param {Network} network - The network to use
132
+ * @returns {IWallet} - The generated wallet
133
+ */
134
+ public static generateWallet(network: Network = networks.bitcoin): IWallet {
135
+ const keyPair = this.ECPair.makeRandom({
136
+ network: network,
137
+ });
138
+
139
+ const wallet = this.getP2WPKHAddress(keyPair, network);
140
+
141
+ if (!wallet) {
142
+ throw new Error('Failed to generate wallet');
143
+ }
144
+
145
+ return {
146
+ address: wallet,
147
+ privateKey: keyPair.toWIF(),
148
+ publicKey: keyPair.publicKey.toString('hex'),
149
+ };
150
+ }
151
+
152
+ /**
153
+ * Verify that a contract address is a valid p2tr address
154
+ * @param {Address} contractAddress - The contract address to verify
155
+ * @param {Network} network - The network to use
156
+ * @returns {boolean} - Whether the address is valid
157
+ */
158
+ public static verifyContractAddress(
159
+ contractAddress: Address,
160
+ network: Network = networks.bitcoin,
161
+ ): boolean {
162
+ return !!address.toOutputScript(contractAddress, network);
163
+ }
164
+
165
+ /**
166
+ * Get the legacy address from a keypair
167
+ * @param {ECPairInterface} keyPair - The keypair to get the address for
168
+ * @param {Network} network - The network to use
169
+ * @returns {Address} - The legacy address
170
+ */
171
+ public static getLegacyAddress(
172
+ keyPair: ECPairInterface,
173
+ network: Network = networks.bitcoin,
174
+ ): Address {
175
+ const wallet = payments.p2pkh({ pubkey: keyPair.publicKey, network: network });
176
+
177
+ if (!wallet.address) {
178
+ throw new Error('Failed to generate wallet');
179
+ }
180
+
181
+ return wallet.address;
182
+ }
183
+
184
+ /**
185
+ * Generate a random keypair
186
+ * @param {Network} network - The network to use
187
+ * @returns {ECPairInterface} - The generated keypair
188
+ */
189
+ public static generateRandomKeyPair(network: Network = networks.bitcoin): ECPairInterface {
190
+ return this.ECPair.makeRandom({
191
+ network: network,
192
+ });
193
+ }
194
+
195
+ /**
196
+ * Generate a BIP32 keypair from a seed
197
+ * @param {Buffer} seed - The seed to generate the keypair from
198
+ * @param {Network} network - The network to use
199
+ * @returns {BIP32Interface} - The generated keypair
200
+ */
201
+ public static fromSeed(seed: Buffer, network: Network = networks.bitcoin): BIP32Interface {
202
+ return this.BIP32.fromSeed(seed, network);
203
+ }
204
+
205
+ /**
206
+ * Get taproot address from keypair
207
+ * @param {ECPairInterface} keyPair - The keypair to get the taproot address for
208
+ * @param {Network} network - The network to use
209
+ * @returns {Address} - The taproot address
210
+ */
211
+ public static getTaprootAddress(
212
+ keyPair: ECPairInterface,
213
+ network: Network = networks.bitcoin,
214
+ ): Address {
215
+ const myXOnlyPubkey = keyPair.publicKey.slice(1, 33);
216
+
217
+ const output = Buffer.concat([
218
+ // witness v1, PUSH_DATA 32 bytes
219
+ Buffer.from([0x51, 0x20]),
220
+ // x-only pubkey (remove 1 byte y parity)
221
+ myXOnlyPubkey,
222
+ ]);
223
+
224
+ return address.fromOutputScript(output, network);
225
+ }
226
+
227
+ /**
228
+ * Get taproot address from address
229
+ * @param {Address} inAddr - The address to convert to taproot
230
+ * @param {Network} network - The network to use
231
+ * @returns {Address} - The taproot address
232
+ */
233
+ public static getTaprootAddressFromAddress(
234
+ inAddr: Address,
235
+ network: Network = networks.bitcoin,
236
+ ): Address {
237
+ const { address } = payments.p2tr({
238
+ address: inAddr,
239
+ network: network,
240
+ });
241
+
242
+ if (!address) {
243
+ throw new Error(`Failed to generate sender address for transaction`);
244
+ }
245
+
246
+ return address;
247
+ }
248
+
249
+ /**
250
+ * Get a keypair from a given seed.
251
+ * @param {Buffer} seed - The seed to generate the key pair from
252
+ * @param {Network} network - The network to use
253
+ * @returns {ECPairInterface} - The generated key pair
254
+ */
255
+ public static fromSeedKeyPair(
256
+ seed: Buffer,
257
+ network: Network = networks.bitcoin,
258
+ ): ECPairInterface {
259
+ const fromSeed = this.BIP32.fromSeed(seed, network);
260
+ const privKey = fromSeed.privateKey;
261
+ if (!privKey) throw new Error('Failed to generate key pair');
262
+
263
+ return this.ECPair.fromPrivateKey(privKey, { network });
264
+ }
265
+ }
@@ -0,0 +1,75 @@
1
+ import { IWallet } from './interfaces/IWallet.js';
2
+ import { ECPairInterface } from 'ecpair';
3
+ import { EcKeyPair } from './EcKeyPair.js';
4
+ import { Network, networks } from 'bitcoinjs-lib';
5
+ import { Address } from '@btc-vision/bsi-binary';
6
+
7
+ /**
8
+ * Wallet class
9
+ */
10
+ export class Wallet {
11
+ /**
12
+ * Keypair for the wallet
13
+ * @private
14
+ */
15
+ private readonly _keypair: ECPairInterface;
16
+
17
+ /**
18
+ * P2WPKH address for the wallet
19
+ * @private
20
+ */
21
+ private readonly _p2wpkh: Address;
22
+
23
+ /**
24
+ * P2TR address for the wallet
25
+ * @private
26
+ */
27
+ private readonly _p2tr: Address;
28
+
29
+ constructor(
30
+ wallet: IWallet,
31
+ public readonly network: Network = networks.bitcoin,
32
+ ) {
33
+ this._keypair = EcKeyPair.fromWIF(wallet.privateKey, this.network);
34
+
35
+ this._p2wpkh = EcKeyPair.getP2WPKHAddress(this._keypair, this.network);
36
+ this._p2tr = EcKeyPair.getTaprootAddress(this._keypair, this.network);
37
+ }
38
+
39
+ /**
40
+ * Get the keypair for the wallet
41
+ * @returns {ECPairInterface}
42
+ */
43
+ public get keypair(): ECPairInterface {
44
+ if (!this._keypair) throw new Error('Keypair not set');
45
+
46
+ return this._keypair;
47
+ }
48
+
49
+ /**
50
+ * Get the P2WPKH address for the wallet
51
+ * @returns {Address}
52
+ */
53
+ public get p2wpkh(): Address {
54
+ return this._p2wpkh;
55
+ }
56
+
57
+ /**
58
+ * Get the P2TR address for the wallet
59
+ * @returns {Address}
60
+ */
61
+ public get p2tr(): Address {
62
+ return this._p2tr;
63
+ }
64
+
65
+ /**
66
+ * Get the public key for the wallet
67
+ * @protected
68
+ * @returns {Buffer}
69
+ */
70
+ public get publicKey(): Buffer {
71
+ if (!this.keypair) throw new Error('Keypair not set');
72
+
73
+ return this.keypair.publicKey;
74
+ }
75
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Interface for the generated wallet
3
+ */
4
+ export interface IWallet {
5
+ /**
6
+ * The address of the wallet
7
+ */
8
+ readonly address: string;
9
+
10
+ /**
11
+ * The private key of the wallet
12
+ */
13
+ readonly privateKey: string;
14
+
15
+ /**
16
+ * The public key of the wallet
17
+ */
18
+ readonly publicKey: string;
19
+ }
@@ -0,0 +1,23 @@
1
+ import { Address } from '@btc-vision/bsi-binary';
2
+ import { Network, networks } from 'bitcoinjs-lib';
3
+
4
+ export abstract class ContractBaseMetadata {
5
+ protected abstract readonly address: Address;
6
+
7
+ protected constructor(protected network: Network = networks.bitcoin) {}
8
+
9
+ /**
10
+ * @description Get the contract address
11
+ * @param {Network} network - The network to get the address for
12
+ */
13
+ public static getAddress(network: Network = networks.bitcoin): Address {
14
+ throw new Error('Method not implemented.');
15
+ }
16
+
17
+ /**
18
+ * @description Get the contract address
19
+ */
20
+ public getAddress(): Address {
21
+ return this.address;
22
+ }
23
+ }