@btc-vision/transaction 1.0.1 → 1.0.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 (90) hide show
  1. package/browser/_version.d.ts +1 -1
  2. package/browser/generators/AddressGenerator.d.ts +7 -0
  3. package/browser/generators/builders/DeploymentGenerator.d.ts +1 -0
  4. package/browser/index.js +1 -1
  5. package/browser/keypair/Wallet.d.ts +1 -0
  6. package/browser/opnet.d.ts +2 -0
  7. package/browser/tests/Regtest.d.ts +3 -0
  8. package/browser/tests/gen.d.ts +1 -0
  9. package/browser/tests/test.d.ts +1 -0
  10. package/browser/tests/transfer.d.ts +1 -0
  11. package/browser/transaction/builders/TransactionBuilder.d.ts +4 -3
  12. package/browser/verification/TapscriptVerificator.d.ts +17 -0
  13. package/build/_version.d.ts +1 -1
  14. package/build/_version.js +1 -1
  15. package/build/generators/AddressGenerator.d.ts +7 -0
  16. package/build/generators/AddressGenerator.js +21 -0
  17. package/build/generators/OPNetAddressGenerator.d.ts +0 -0
  18. package/build/generators/OPNetAddressGenerator.js +1 -0
  19. package/build/generators/builders/DeploymentGenerator.d.ts +1 -0
  20. package/build/generators/builders/DeploymentGenerator.js +10 -7
  21. package/build/keypair/Wallet.d.ts +1 -0
  22. package/build/keypair/Wallet.js +6 -0
  23. package/build/opnet.d.ts +2 -0
  24. package/build/opnet.js +2 -0
  25. package/build/scripts/Regtest.d.ts +0 -1
  26. package/build/scripts/Regtest.js +0 -14
  27. package/build/scripts/test.js +7 -7
  28. package/build/tests/gen.d.ts +1 -0
  29. package/build/tests/gen.js +15 -0
  30. package/build/tests/test.d.ts +1 -0
  31. package/build/tests/test.js +51 -1
  32. package/build/tests/transfer.d.ts +1 -0
  33. package/build/tests/transfer.js +74 -0
  34. package/build/transaction/builders/TransactionBuilder.d.ts +4 -3
  35. package/build/transaction/builders/TransactionBuilder.js +9 -4
  36. package/build/verification/TapscriptVerificator.d.ts +17 -0
  37. package/build/verification/TapscriptVerificator.js +43 -0
  38. package/docs/assets/navigation.js +1 -1
  39. package/docs/assets/search.js +1 -1
  40. package/docs/classes/AddressGenerator.html +178 -0
  41. package/docs/classes/BitcoinUtils.html +3 -3
  42. package/docs/classes/CalldataGenerator.html +10 -10
  43. package/docs/classes/Compressor.html +4 -4
  44. package/docs/classes/ContractBaseMetadata.html +4 -4
  45. package/docs/classes/DeploymentGenerator.html +10 -9
  46. package/docs/classes/EcKeyPair.html +16 -16
  47. package/docs/classes/FundingTransaction.html +73 -50
  48. package/docs/classes/Generator.html +9 -9
  49. package/docs/classes/InteractionTransaction.html +94 -71
  50. package/docs/classes/TapscriptVerificator.html +180 -0
  51. package/docs/classes/TransactionBuilder.html +76 -53
  52. package/docs/classes/TransactionFactory.html +2 -2
  53. package/docs/classes/TweakedSigner.html +2 -2
  54. package/docs/classes/UTXOManager.html +3 -3
  55. package/docs/classes/Wallet.html +11 -9
  56. package/docs/classes/wBTC.html +7 -7
  57. package/docs/enums/TransactionType.html +2 -2
  58. package/docs/interfaces/ContractAddressVerificationParams.html +179 -0
  59. package/docs/interfaces/FetchUTXOParams.html +2 -2
  60. package/docs/interfaces/IFundingTransactionParameters.html +2 -2
  61. package/docs/interfaces/IInteractionParameters.html +2 -2
  62. package/docs/interfaces/ITransactionDataContractDeployment.html +2 -2
  63. package/docs/interfaces/ITransactionDataContractInteractionWrap.html +2 -2
  64. package/docs/interfaces/ITransactionParameters.html +2 -2
  65. package/docs/interfaces/IWallet.html +4 -4
  66. package/docs/interfaces/NetworkInformation.html +2 -2
  67. package/docs/interfaces/PsbtInputExtended.html +1 -1
  68. package/docs/interfaces/PsbtOutputExtendedAddress.html +2 -2
  69. package/docs/interfaces/PsbtOutputExtendedScript.html +2 -2
  70. package/docs/interfaces/RawUTXOResponse.html +2 -2
  71. package/docs/interfaces/TapLeafScript.html +2 -2
  72. package/docs/interfaces/TweakSettings.html +3 -3
  73. package/docs/interfaces/UTXO.html +2 -2
  74. package/docs/interfaces/UpdateInput.html +2 -2
  75. package/docs/modules.html +5 -2
  76. package/docs/types/PsbtOutputExtended.html +1 -1
  77. package/docs/variables/version.html +1 -1
  78. package/package.json +2 -1
  79. package/src/_version.ts +1 -1
  80. package/src/generators/AddressGenerator.ts +29 -0
  81. package/src/generators/builders/DeploymentGenerator.ts +16 -13
  82. package/src/keypair/Wallet.ts +12 -0
  83. package/src/opnet.ts +4 -0
  84. package/src/tests/gen.ts +24 -0
  85. package/src/tests/test.ts +17 -54
  86. package/src/tests/transfer.ts +102 -0
  87. package/src/transaction/builders/TransactionBuilder.ts +12 -5
  88. package/src/verification/TapscriptVerificator.ts +89 -0
  89. package/tests/TransactionBuilder.test.ts +58 -58
  90. package/tsconfig.webpack.json +8 -0
@@ -13,4 +13,5 @@ export declare class Wallet {
13
13
  get p2wpkh(): Address;
14
14
  get p2tr(): Address;
15
15
  get publicKey(): Buffer;
16
+ get xOnly(): Buffer;
16
17
  }
@@ -3,6 +3,8 @@ export * from './bytecode/Compressor.js';
3
3
  export * from './generators/Generator.js';
4
4
  export * from './generators/builders/CalldataGenerator.js';
5
5
  export * from './generators/builders/DeploymentGenerator.js';
6
+ export * from './generators/AddressGenerator.js';
7
+ export * from './verification/TapscriptVerificator.js';
6
8
  export * from './keypair/EcKeyPair.js';
7
9
  export * from './keypair/Wallet.js';
8
10
  export * from './keypair/interfaces/IWallet.js';
@@ -0,0 +1,3 @@
1
+ import { NetworkInformation } from '../network/NetworkInformation.js';
2
+ export declare const Regtest: NetworkInformation;
3
+ export declare const Testnet: NetworkInformation;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -5,9 +5,10 @@ import { TransactionType } from '../enums/TransactionType.js';
5
5
  import { IFundingTransactionParameters, ITransactionParameters } from '../interfaces/ITransactionParameters.js';
6
6
  import { Address } from '@btc-vision/bsi-binary';
7
7
  import { UTXO } from '../../utxo/interfaces/IUTXO.js';
8
- export declare abstract class TransactionBuilder<T extends TransactionType> {
9
- protected static readonly LOCK_LEAF_SCRIPT: Buffer;
10
- protected static readonly MINIMUM_DUST: bigint;
8
+ import { Logger } from '@btc-vision/logger';
9
+ export declare abstract class TransactionBuilder<T extends TransactionType> extends Logger {
10
+ static readonly LOCK_LEAF_SCRIPT: Buffer;
11
+ static readonly MINIMUM_DUST: bigint;
11
12
  abstract readonly type: T;
12
13
  readonly logColor: string;
13
14
  transactionFee: bigint;
@@ -0,0 +1,17 @@
1
+ /// <reference types="node" />
2
+ import { Network } from 'bitcoinjs-lib';
3
+ import { Taptree } from 'bitcoinjs-lib/src/types.js';
4
+ export interface ContractAddressVerificationParams {
5
+ readonly deployerPubKeyXOnly: Buffer;
6
+ readonly contractSaltPubKey: Buffer;
7
+ readonly originalSalt: Buffer;
8
+ readonly bytecode: Buffer;
9
+ readonly network?: Network;
10
+ }
11
+ export declare class TapscriptVerificator {
12
+ private static readonly TAP_SCRIPT_VERSION;
13
+ static getContractAddress(params: ContractAddressVerificationParams): string | undefined;
14
+ static getContractSeed(deployerPubKey: Buffer, bytecode: Buffer, saltHash: Buffer): Buffer;
15
+ static generateContractVirtualAddress(deployerPubKey: Buffer, bytecode: Buffer, saltHash: Buffer, network?: Network): string;
16
+ static generateAddressFromScript(params: ContractAddressVerificationParams, scriptTree: Taptree): string | undefined;
17
+ }
@@ -1 +1 @@
1
- export declare const version = "1.0.1";
1
+ export declare const version = "1.0.3";
package/build/_version.js CHANGED
@@ -1 +1 @@
1
- export const version = '1.0.1';
1
+ export const version = '1.0.3';
@@ -0,0 +1,7 @@
1
+ /// <reference types="node" />
2
+ import { Network } from 'bitcoinjs-lib';
3
+ export declare class AddressGenerator {
4
+ static generatePKSH(sha256Hash: Buffer, network: Network): string;
5
+ private static ripemd160;
6
+ private static toSegwitAddress;
7
+ }
@@ -0,0 +1,21 @@
1
+ import { createHash } from 'crypto';
2
+ import { bech32 } from 'bech32';
3
+ import { initEccLib } from 'bitcoinjs-lib';
4
+ import * as ecc from 'tiny-secp256k1';
5
+ initEccLib(ecc);
6
+ export class AddressGenerator {
7
+ static generatePKSH(sha256Hash, network) {
8
+ if (sha256Hash.length !== 32)
9
+ throw new Error('Invalid hash length');
10
+ const pkh = this.ripemd160(sha256Hash);
11
+ return this.toSegwitAddress(pkh, network);
12
+ }
13
+ static ripemd160(data) {
14
+ return createHash('ripemd160').update(data).digest();
15
+ }
16
+ static toSegwitAddress(pkh, network) {
17
+ const words = bech32.toWords(pkh);
18
+ words.unshift(0x00);
19
+ return bech32.encode(network.bech32, words);
20
+ }
21
+ }
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -4,4 +4,5 @@ import { Generator } from '../Generator.js';
4
4
  export declare class DeploymentGenerator extends Generator {
5
5
  constructor(senderPubKey: Buffer, contractSaltPubKey: Buffer, network?: Network);
6
6
  compile(contractBytecode: Buffer, contractSalt: Buffer): Buffer;
7
+ private getAsm;
7
8
  }
@@ -5,8 +5,17 @@ export class DeploymentGenerator extends Generator {
5
5
  super(senderPubKey, contractSaltPubKey, network);
6
6
  }
7
7
  compile(contractBytecode, contractSalt) {
8
+ const asm = this.getAsm(contractBytecode, contractSalt);
9
+ const compiled = script.compile(asm);
10
+ const decompiled = script.decompile(compiled);
11
+ if (!decompiled) {
12
+ throw new Error('Failed to decompile script??');
13
+ }
14
+ return compiled;
15
+ }
16
+ getAsm(contractBytecode, contractSalt) {
8
17
  const dataChunks = this.splitBufferIntoChunks(contractBytecode);
9
- const asm = [
18
+ return [
10
19
  this.senderPubKey,
11
20
  opcodes.OP_CHECKSIGVERIFY,
12
21
  this.contractSaltPubKey,
@@ -28,11 +37,5 @@ export class DeploymentGenerator extends Generator {
28
37
  opcodes.OP_1,
29
38
  opcodes.OP_ENDIF,
30
39
  ].flat();
31
- const compiled = script.compile(asm);
32
- const decompiled = script.decompile(compiled);
33
- if (!decompiled) {
34
- throw new Error('Failed to decompile script??');
35
- }
36
- return compiled;
37
40
  }
38
41
  }
@@ -13,4 +13,5 @@ export declare class Wallet {
13
13
  get p2wpkh(): Address;
14
14
  get p2tr(): Address;
15
15
  get publicKey(): Buffer;
16
+ get xOnly(): Buffer;
16
17
  }
@@ -1,5 +1,6 @@
1
1
  import { EcKeyPair } from './EcKeyPair.js';
2
2
  import { networks } from 'bitcoinjs-lib';
3
+ import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
3
4
  export class Wallet {
4
5
  network;
5
6
  _keypair;
@@ -27,4 +28,9 @@ export class Wallet {
27
28
  throw new Error('Keypair not set');
28
29
  return this.keypair.publicKey;
29
30
  }
31
+ get xOnly() {
32
+ if (!this.keypair)
33
+ throw new Error('Keypair not set');
34
+ return toXOnly(this.keypair.publicKey);
35
+ }
30
36
  }
package/build/opnet.d.ts CHANGED
@@ -3,6 +3,8 @@ export * from './bytecode/Compressor.js';
3
3
  export * from './generators/Generator.js';
4
4
  export * from './generators/builders/CalldataGenerator.js';
5
5
  export * from './generators/builders/DeploymentGenerator.js';
6
+ export * from './generators/AddressGenerator.js';
7
+ export * from './verification/TapscriptVerificator.js';
6
8
  export * from './keypair/EcKeyPair.js';
7
9
  export * from './keypair/Wallet.js';
8
10
  export * from './keypair/interfaces/IWallet.js';
package/build/opnet.js CHANGED
@@ -3,6 +3,8 @@ export * from './bytecode/Compressor.js';
3
3
  export * from './generators/Generator.js';
4
4
  export * from './generators/builders/CalldataGenerator.js';
5
5
  export * from './generators/builders/DeploymentGenerator.js';
6
+ export * from './generators/AddressGenerator.js';
7
+ export * from './verification/TapscriptVerificator.js';
6
8
  export * from './keypair/EcKeyPair.js';
7
9
  export * from './keypair/Wallet.js';
8
10
  export * from './keypair/interfaces/IWallet.js';
@@ -1,3 +1,2 @@
1
1
  import { NetworkInformation } from '../network/NetworkInformation.js';
2
2
  export declare const Regtest: NetworkInformation;
3
- export declare const Testnet: NetworkInformation;
@@ -13,17 +13,3 @@ export const Regtest = {
13
13
  BITCOIND_PASSWORD: 'YHEFHSDJ23JOIhjjef2ied9u290efu2930u90U',
14
14
  },
15
15
  };
16
- export const Testnet = {
17
- wallet: {
18
- address: 'tb1qcfszz8dcvsz9mcp70ezw5zy2r3ydr0cfz60d3t',
19
- privateKey: 'cSZU2QB9aUYvaL6ukU9d3DKq7QaxTRms1BCQnx5vqXbxBk4bdBc4',
20
- publicKey: '026764d622f083d78f47c2f2a007ab08e96edf398de74acc0251a7bba202ffb92b',
21
- },
22
- config: {
23
- BITCOIND_NETWORK: BitcoinNetwork.TestNet,
24
- BITCOIND_HOST: '51.81.67.34',
25
- BITCOIND_PORT: 9237,
26
- BITCOIND_USERNAME: 'HJSiowseujhs',
27
- BITCOIND_PASSWORD: 'YHEFHSDJ23JOIhjjef2ied9u290efu2930u90U',
28
- },
29
- };
@@ -1,16 +1,16 @@
1
1
  import { wBTC } from '../metadata/contracts/wBTC.js';
2
2
  import { Wallet } from '../keypair/Wallet.js';
3
- import { Testnet } from './Regtest.js';
3
+ import { Regtest } from './Regtest.js';
4
4
  import { UTXOManager } from '../utxo/UTXOManager.js';
5
5
  import { networks } from 'bitcoinjs-lib';
6
6
  import { TransactionFactory } from '../transaction/TransactionFactory.js';
7
7
  import { BitcoinRPC } from '@btc-vision/bsi-bitcoin-rpc';
8
8
  import { ABICoder, BinaryWriter } from '@btc-vision/bsi-binary';
9
- const network = networks.testnet;
9
+ const network = networks.regtest;
10
10
  const rpc = new BitcoinRPC();
11
11
  const wBtc = new wBTC(network);
12
- const wallet = new Wallet(Testnet.wallet, network);
13
- const utxoManager = new UTXOManager('https://testnet.opnet.org');
12
+ const wallet = new Wallet(Regtest.wallet, network);
13
+ const utxoManager = new UTXOManager('http://localhost:9001');
14
14
  const factory = new TransactionFactory();
15
15
  const abiCoder = new ABICoder();
16
16
  const transferSelector = Number(`0x` + abiCoder.encodeSelector('transfer'));
@@ -21,7 +21,7 @@ function getTransferToCalldata(to, amount) {
21
21
  addCalldata.writeU256(amount);
22
22
  return Buffer.from(addCalldata.getBuffer());
23
23
  }
24
- const shouldMineBlock = false;
24
+ const shouldMineBlock = true;
25
25
  async function mineBlock() {
26
26
  const ok = await rpc.generateToAddress(1, wallet.p2wpkh, 'default');
27
27
  if (!ok) {
@@ -31,7 +31,7 @@ async function mineBlock() {
31
31
  return !!ok.length;
32
32
  }
33
33
  (async () => {
34
- await rpc.init(Testnet.config);
34
+ await rpc.init(Regtest.config);
35
35
  const utxoSetting = {
36
36
  address: wallet.p2wpkh,
37
37
  minAmount: 10000n,
@@ -42,7 +42,7 @@ async function mineBlock() {
42
42
  if (!utxos) {
43
43
  throw new Error('No UTXOs found');
44
44
  }
45
- const calldata = getTransferToCalldata('tb1pt3ncc5ktfzpry2uvnag06v3jkv4quvmdydf09q8fx6rkgd7f5s8q3aenuk', 5000000n);
45
+ const calldata = getTransferToCalldata(wBtc.getAddress(), 5000000n);
46
46
  const interactionParameters = {
47
47
  from: wallet.p2wpkh,
48
48
  to: wBtc.getAddress(),
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import { TapscriptVerificator } from '../verification/TapscriptVerificator.js';
2
+ import { networks } from 'bitcoinjs-lib';
3
+ import { Regtest } from './Regtest.js';
4
+ import { Wallet } from '../keypair/Wallet.js';
5
+ const wallet = new Wallet(Regtest.wallet, networks.regtest);
6
+ const params = {
7
+ bytecode: Buffer.from('deadbeef', 'hex'),
8
+ contractSaltPubKey: Buffer.from('deadbeef', 'hex'),
9
+ deployerPubKeyXOnly: wallet.xOnly,
10
+ originalSalt: Buffer.from('deadbeef', 'hex'),
11
+ network: networks.regtest,
12
+ };
13
+ const contractAddress = TapscriptVerificator.getContractAddress(params);
14
+ const virtualAddress = TapscriptVerificator.generateContractVirtualAddress(params.deployerPubKeyXOnly, params.bytecode, params.originalSalt, networks.regtest);
15
+ console.log('contract sewgit address', virtualAddress, '\ncontract p2tr address', contractAddress);
@@ -0,0 +1 @@
1
+ export {};
@@ -1 +1,51 @@
1
- "use strict";
1
+ import { Wallet } from '../keypair/Wallet.js';
2
+ import { Regtest } from './Regtest.js';
3
+ import { UTXOManager } from '../utxo/UTXOManager.js';
4
+ import { networks } from 'bitcoinjs-lib';
5
+ import { BitcoinRPC } from '@btc-vision/bsi-bitcoin-rpc';
6
+ import { FundingTransaction } from '../transaction/builders/FundingTransaction.js';
7
+ const network = networks.regtest;
8
+ const rpc = new BitcoinRPC();
9
+ const wallet = new Wallet(Regtest.wallet, network);
10
+ const utxoManager = new UTXOManager('http://localhost:9001');
11
+ const shouldMineBlock = true;
12
+ async function mineBlock() {
13
+ const ok = await rpc.generateToAddress(1, wallet.p2wpkh, 'default');
14
+ if (!ok) {
15
+ throw new Error('Could not mine block');
16
+ }
17
+ console.log(`Mined block`, ok);
18
+ return !!ok.length;
19
+ }
20
+ (async () => {
21
+ await rpc.init(Regtest.config);
22
+ const utxoSetting = {
23
+ address: wallet.p2wpkh,
24
+ minAmount: 10000n,
25
+ requestedAmount: 100000n,
26
+ };
27
+ const utxos = await utxoManager.fetchUTXO(utxoSetting);
28
+ if (!utxos) {
29
+ throw new Error('No UTXOs found');
30
+ }
31
+ const interactionParameters = {
32
+ from: wallet.p2wpkh,
33
+ to: 'bcrt1qqvf4gprr05z248ph6gvx54rpg08p8ngq3zh8uh',
34
+ utxos: utxos,
35
+ signer: wallet.keypair,
36
+ network: network,
37
+ feeRate: 150,
38
+ priorityFee: 1000n,
39
+ childTransactionRequiredFees: 0n,
40
+ };
41
+ const fundingTransaction = new FundingTransaction(interactionParameters);
42
+ const fundingTx = fundingTransaction.signTransaction();
43
+ console.log(fundingTx.toHex());
44
+ const secondTxBroadcast = await rpc.sendRawTransaction({
45
+ hexstring: fundingTx.toHex(),
46
+ });
47
+ console.log(`Transaction broadcasted: ${secondTxBroadcast}`);
48
+ if (shouldMineBlock) {
49
+ await mineBlock();
50
+ }
51
+ })();
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ import { wBTC } from '../metadata/contracts/wBTC.js';
2
+ import { Wallet } from '../keypair/Wallet.js';
3
+ import { Testnet } from './Regtest.js';
4
+ import { UTXOManager } from '../utxo/UTXOManager.js';
5
+ import { networks } from 'bitcoinjs-lib';
6
+ import { TransactionFactory } from '../transaction/TransactionFactory.js';
7
+ import { BitcoinRPC } from '@btc-vision/bsi-bitcoin-rpc';
8
+ import { ABICoder, BinaryWriter } from '@btc-vision/bsi-binary';
9
+ const network = networks.testnet;
10
+ const rpc = new BitcoinRPC();
11
+ const wBtc = new wBTC(network);
12
+ const wallet = new Wallet(Testnet.wallet, network);
13
+ const utxoManager = new UTXOManager('https://testnet.opnet.org');
14
+ const factory = new TransactionFactory();
15
+ const abiCoder = new ABICoder();
16
+ const transferSelector = Number(`0x` + abiCoder.encodeSelector('transfer'));
17
+ function getTransferToCalldata(to, amount) {
18
+ const addCalldata = new BinaryWriter();
19
+ addCalldata.writeSelector(transferSelector);
20
+ addCalldata.writeAddress(to);
21
+ addCalldata.writeU256(amount);
22
+ return Buffer.from(addCalldata.getBuffer());
23
+ }
24
+ const shouldMineBlock = false;
25
+ async function mineBlock() {
26
+ const ok = await rpc.generateToAddress(1, wallet.p2wpkh, 'default');
27
+ if (!ok) {
28
+ throw new Error('Could not mine block');
29
+ }
30
+ console.log(`Mined block`, ok);
31
+ return !!ok.length;
32
+ }
33
+ (async () => {
34
+ await rpc.init(Testnet.config);
35
+ const utxoSetting = {
36
+ address: wallet.p2wpkh,
37
+ minAmount: 10000n,
38
+ requestedAmount: 100000n,
39
+ };
40
+ const utxos = await utxoManager.fetchUTXO(utxoSetting);
41
+ console.log(`UTXOs:`, utxos);
42
+ if (!utxos) {
43
+ throw new Error('No UTXOs found');
44
+ }
45
+ const calldata = getTransferToCalldata('tb1pt3ncc5ktfzpry2uvnag06v3jkv4quvmdydf09q8fx6rkgd7f5s8q3aenuk', 5000000n);
46
+ const interactionParameters = {
47
+ from: wallet.p2wpkh,
48
+ to: wBtc.getAddress(),
49
+ utxos: utxos,
50
+ signer: wallet.keypair,
51
+ network: network,
52
+ feeRate: 150,
53
+ priorityFee: 50000n,
54
+ calldata: calldata,
55
+ };
56
+ const finalTx = factory.signInteraction(interactionParameters);
57
+ const firstTxBroadcast = await rpc.sendRawTransaction({
58
+ hexstring: finalTx[0],
59
+ });
60
+ console.log(`First transaction broadcasted: ${firstTxBroadcast}`);
61
+ if (!firstTxBroadcast) {
62
+ throw new Error('Could not broadcast first transaction');
63
+ }
64
+ const secondTxBroadcast = await rpc.sendRawTransaction({
65
+ hexstring: finalTx[1],
66
+ });
67
+ console.log(`Second transaction broadcasted: ${secondTxBroadcast}`);
68
+ if (!secondTxBroadcast) {
69
+ throw new Error('Could not broadcast second transaction');
70
+ }
71
+ if (shouldMineBlock) {
72
+ await mineBlock();
73
+ }
74
+ })();
@@ -5,9 +5,10 @@ import { TransactionType } from '../enums/TransactionType.js';
5
5
  import { IFundingTransactionParameters, ITransactionParameters } from '../interfaces/ITransactionParameters.js';
6
6
  import { Address } from '@btc-vision/bsi-binary';
7
7
  import { UTXO } from '../../utxo/interfaces/IUTXO.js';
8
- export declare abstract class TransactionBuilder<T extends TransactionType> {
9
- protected static readonly LOCK_LEAF_SCRIPT: Buffer;
10
- protected static readonly MINIMUM_DUST: bigint;
8
+ import { Logger } from '@btc-vision/logger';
9
+ export declare abstract class TransactionBuilder<T extends TransactionType> extends Logger {
10
+ static readonly LOCK_LEAF_SCRIPT: Buffer;
11
+ static readonly MINIMUM_DUST: bigint;
11
12
  abstract readonly type: T;
12
13
  readonly logColor: string;
13
14
  transactionFee: bigint;
@@ -3,8 +3,12 @@ import { varuint } from 'bitcoinjs-lib/src/bufferutils.js';
3
3
  import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
4
4
  import * as ecc from 'tiny-secp256k1';
5
5
  import { EcKeyPair } from '../../keypair/EcKeyPair.js';
6
- export class TransactionBuilder {
7
- static LOCK_LEAF_SCRIPT = script.compile([opcodes.OP_0]);
6
+ import { Logger } from '@btc-vision/logger';
7
+ export class TransactionBuilder extends Logger {
8
+ static LOCK_LEAF_SCRIPT = script.compile([
9
+ opcodes.OP_0,
10
+ opcodes.OP_VERIFY,
11
+ ]);
8
12
  static MINIMUM_DUST = 330n;
9
13
  logColor = '#785def';
10
14
  transactionFee = 0n;
@@ -26,6 +30,7 @@ export class TransactionBuilder {
26
30
  from;
27
31
  _maximumFeeRate = 100000000;
28
32
  constructor(parameters) {
33
+ super();
29
34
  this.signer = parameters.signer;
30
35
  this.network = parameters.network;
31
36
  this.feeRate = parameters.feeRate;
@@ -121,7 +126,7 @@ export class TransactionBuilder {
121
126
  });
122
127
  return;
123
128
  }
124
- console.warn(`Amount to send back is less than the minimum dust, will be consumed in fees instead.`);
129
+ this.warn(`Amount to send back is less than the minimum dust, will be consumed in fees instead.`);
125
130
  }
126
131
  getTransactionOPNetFee() {
127
132
  if (this.priorityFee > TransactionBuilder.MINIMUM_DUST) {
@@ -265,7 +270,7 @@ export class TransactionBuilder {
265
270
  }
266
271
  catch (e) {
267
272
  const err = e;
268
- console.error(`[internalBuildTransaction] Something went wrong while getting building the transaction: ${err.stack}`);
273
+ this.error(`[internalBuildTransaction] Something went wrong while getting building the transaction: ${err.stack}`);
269
274
  }
270
275
  return false;
271
276
  }
@@ -0,0 +1,17 @@
1
+ /// <reference types="node" />
2
+ import { Network } from 'bitcoinjs-lib';
3
+ import { Taptree } from 'bitcoinjs-lib/src/types.js';
4
+ export interface ContractAddressVerificationParams {
5
+ readonly deployerPubKeyXOnly: Buffer;
6
+ readonly contractSaltPubKey: Buffer;
7
+ readonly originalSalt: Buffer;
8
+ readonly bytecode: Buffer;
9
+ readonly network?: Network;
10
+ }
11
+ export declare class TapscriptVerificator {
12
+ private static readonly TAP_SCRIPT_VERSION;
13
+ static getContractAddress(params: ContractAddressVerificationParams): string | undefined;
14
+ static getContractSeed(deployerPubKey: Buffer, bytecode: Buffer, saltHash: Buffer): Buffer;
15
+ static generateContractVirtualAddress(deployerPubKey: Buffer, bytecode: Buffer, saltHash: Buffer, network?: Network): string;
16
+ static generateAddressFromScript(params: ContractAddressVerificationParams, scriptTree: Taptree): string | undefined;
17
+ }
@@ -0,0 +1,43 @@
1
+ import bitcoin, { networks, payments } from 'bitcoinjs-lib';
2
+ import { toXOnly } from 'bitcoinjs-lib/src/psbt/bip371.js';
3
+ import { DeploymentGenerator } from '../generators/builders/DeploymentGenerator.js';
4
+ import { TransactionBuilder } from '../transaction/builders/TransactionBuilder.js';
5
+ import { AddressGenerator } from '../generators/AddressGenerator.js';
6
+ export class TapscriptVerificator {
7
+ static TAP_SCRIPT_VERSION = 192;
8
+ static getContractAddress(params) {
9
+ const network = params.network || networks.bitcoin;
10
+ const scriptBuilder = new DeploymentGenerator(params.deployerPubKeyXOnly, toXOnly(params.contractSaltPubKey), network);
11
+ const compiledTargetScript = scriptBuilder.compile(params.bytecode, params.originalSalt);
12
+ const scriptTree = [
13
+ {
14
+ output: compiledTargetScript,
15
+ version: TapscriptVerificator.TAP_SCRIPT_VERSION,
16
+ },
17
+ {
18
+ output: TransactionBuilder.LOCK_LEAF_SCRIPT,
19
+ version: TapscriptVerificator.TAP_SCRIPT_VERSION,
20
+ },
21
+ ];
22
+ return TapscriptVerificator.generateAddressFromScript(params, scriptTree);
23
+ }
24
+ static getContractSeed(deployerPubKey, bytecode, saltHash) {
25
+ const sha256OfBytecode = bitcoin.crypto.hash256(bytecode);
26
+ const buf = Buffer.concat([deployerPubKey, saltHash, sha256OfBytecode]);
27
+ return bitcoin.crypto.hash256(buf);
28
+ }
29
+ static generateContractVirtualAddress(deployerPubKey, bytecode, saltHash, network = networks.bitcoin) {
30
+ const virtualAddress = TapscriptVerificator.getContractSeed(deployerPubKey, bytecode, saltHash);
31
+ return AddressGenerator.generatePKSH(virtualAddress, network);
32
+ }
33
+ static generateAddressFromScript(params, scriptTree) {
34
+ const network = params.network || networks.bitcoin;
35
+ const transactionData = {
36
+ internalPubkey: params.deployerPubKeyXOnly,
37
+ network: network,
38
+ scriptTree: scriptTree,
39
+ };
40
+ const tx = payments.p2tr(transactionData);
41
+ return tx.address;
42
+ }
43
+ }
@@ -1 +1 @@
1
- window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAACp2V224aMRCG38XXqDRE6YG7kkOF2jQoEKVSlYvJegALr9eyZ0NWVd69ckrBu3YG6O3O/38z9oxnf/0WhM8khmLmwHgoSFVm1lgUPWGBlmIo0NSl73fC75ZUatETK2WkGH566W05I0VFpcwdKe13kEKD9+j7cbTNOBnElHPQWgLBVzTogCqXohIJy6tK69D7LGgb4wmGHBQ0Ao/XSBBS51ipiqNeoNVVU6Ih5qQZEce8LL5hMwGVIW1DnP+qNlKZRdTxFJRqOCJztoNONDaEbjN8XFV5HUeOZKNaaYmZElPNgcQrKKhyDUvcaFjiGmGFcqoWJlteHOY4d7OfN9dgYJGjREGOcQ9aI6X2v98553o0O0994Ss7i0jFMtQ2AQdltFBUaPUcijCLbU0bNzj7EA9SOrevJiR0eTjrYFNFw7gvR1bKwqNyLoDg39rZbYp8or22/0kaVX/vwB6VueM9NP2+Cz2+W93Bjmm54W7bfyCtK7cam3nlSmgvp4iUyjjoxD/S2NiaLp8JjUSZZSaqfcibmiL1FynDv+9NdFZ9XIpp4ZTNX+1bYi7BLazDY79FbyvjMcvtaDjcDOx3hDlTZEvBosImniKRMov8jbYUHCpUnyWEAGu0EghfByLv38WP6+KORo3Ntq7De//548nZIGI+ofOtl/EETsGjRt/fhNqE08HLwx8aM5UwoAoAAA=="
1
+ window.navigationData = "data:application/octet-stream;base64,H4sIAAAAAAAACp2VW2/aQBCF/4ufUWmo0gtvJZcKtWlQcJpKUR4m9gAr7PVqdxxiVfnvlYmL197JAH31nPOd2cus7/9EhM8UjaPYgnaQkCp0XBmMBpEBWkXjCHWZu2Gv/G5FeRYNorXSaTT+/DLYcb6mqUXnvqFGC1TYFpRk4By6YV/RZZ2MfNpEUVIofUsqcyHJr0qUM8iyFAiEpgKJyCtyUy+BBe1qMkGThYQm4PAKCepojhWqJOo5mqyoctQkrJQRScyL5DtWM1AMaVeS/JelTpVeevcnBIUaiSis7aAVTTWhba6y1BWvk8gxGJdYZegXWrVQCd8kpxKpbfikVFmKHDPQHEi8hIQKW4nERiMSNwhrTOdqqdn2/LLEuY1/X1+BhiVH8YoS4w6yDCm0v36XnJtJfBb66q+HzHLzru1OVRV6BhZy7+FS9ZVaQOLN9puubuTo9KM/VEjJqt4OIaCnkXDTcAC3JiS0PFx0iFHeVO3LYKUi3GvnHAj+7XH75PFBe23/E+p1f2fBHJXc8x4av29Djz+t/iz5NG6euvafSJvCrqd6Udgcuq+sRwplEnTmHmmqTUkXz4Q6xZRlBqp9yOuSPHUzlW+iWfVxEfPtP+DAhFexFHADm3rYb9CZQjtkuT2NhIvB/EBYCE12FCKqfvznSKT0kt/RjkJC1d2zhLogGk0KhNsLwfvb+nGn2NKoMuzR9Xjvv3w6OR15zCe0rjMZT2AVPGbohk2pS/gwenn4C/vJ5J23CwAA"
@@ -1 +1 @@
1
- window.searchData = "data:application/octet-stream;base64,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";
1
+ window.searchData = "data:application/octet-stream;base64,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";