@btc-vision/transaction 1.7.7 → 1.7.10

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 (173) hide show
  1. package/browser/_version.d.ts +1 -0
  2. package/browser/chain/ChainData.d.ts +4 -0
  3. package/browser/{src/epoch → epoch}/interfaces/IChallengeSolution.d.ts +4 -4
  4. package/browser/{src/generators → generators}/Features.d.ts +6 -1
  5. package/browser/{src/generators → generators}/Generator.d.ts +1 -0
  6. package/browser/generators/MLDSAData.d.ts +15 -0
  7. package/browser/index.js +1 -1
  8. package/browser/{src/keypair → keypair}/Address.d.ts +9 -3
  9. package/browser/{src/keypair → keypair}/MessageSigner.d.ts +9 -0
  10. package/browser/{src/opnet.d.ts → opnet.d.ts} +1 -0
  11. package/browser/{src/transaction → transaction}/browser/Web3Provider.d.ts +15 -4
  12. package/browser/transaction/browser/types/OPWallet.d.ts +6 -0
  13. package/browser/{src/transaction → transaction}/builders/CustomScriptTransaction.d.ts +1 -0
  14. package/browser/{src/transaction → transaction}/builders/DeploymentTransaction.d.ts +1 -0
  15. package/browser/{src/transaction → transaction}/builders/TransactionBuilder.d.ts +4 -0
  16. package/browser/{src/transaction → transaction}/interfaces/ITransactionParameters.d.ts +3 -0
  17. package/browser/{src/transaction → transaction}/shared/TweakedTransaction.d.ts +6 -0
  18. package/browser/{src/utxo → utxo}/OPNetLimitedProvider.d.ts +1 -0
  19. package/build/_version.d.ts +1 -1
  20. package/build/_version.js +1 -1
  21. package/build/chain/ChainData.d.ts +4 -0
  22. package/build/chain/ChainData.js +20 -0
  23. package/build/epoch/ChallengeSolution.js +4 -4
  24. package/build/epoch/interfaces/IChallengeSolution.d.ts +4 -4
  25. package/build/generators/Features.d.ts +6 -1
  26. package/build/generators/Features.js +1 -0
  27. package/build/generators/Generator.d.ts +1 -0
  28. package/build/generators/Generator.js +24 -2
  29. package/build/generators/MLDSAData.d.ts +15 -0
  30. package/build/generators/MLDSAData.js +19 -0
  31. package/build/generators/builders/CalldataGenerator.js +1 -1
  32. package/build/generators/builders/DeploymentGenerator.js +1 -1
  33. package/build/generators/builders/P2WDAGenerator.js +1 -1
  34. package/build/keypair/Address.d.ts +9 -3
  35. package/build/keypair/Address.js +63 -38
  36. package/build/keypair/MessageSigner.d.ts +9 -0
  37. package/build/keypair/MessageSigner.js +101 -3
  38. package/build/opnet.d.ts +1 -0
  39. package/build/opnet.js +1 -0
  40. package/build/transaction/TransactionFactory.js +3 -0
  41. package/build/transaction/browser/Web3Provider.d.ts +15 -4
  42. package/build/transaction/browser/types/OPWallet.d.ts +2 -10
  43. package/build/transaction/browser/types/OPWallet.js +4 -2
  44. package/build/transaction/builders/CustomScriptTransaction.d.ts +1 -0
  45. package/build/transaction/builders/CustomScriptTransaction.js +3 -0
  46. package/build/transaction/builders/DeploymentTransaction.d.ts +1 -0
  47. package/build/transaction/builders/DeploymentTransaction.js +26 -1
  48. package/build/transaction/builders/InteractionTransaction.js +14 -1
  49. package/build/transaction/builders/InteractionTransactionP2WDA.js +14 -1
  50. package/build/transaction/builders/TransactionBuilder.d.ts +4 -0
  51. package/build/transaction/builders/TransactionBuilder.js +77 -0
  52. package/build/transaction/interfaces/ITransactionParameters.d.ts +3 -0
  53. package/build/transaction/shared/P2TR_MS.js +1 -0
  54. package/build/transaction/shared/TweakedTransaction.d.ts +6 -0
  55. package/build/transaction/shared/TweakedTransaction.js +19 -0
  56. package/build/utxo/OPNetLimitedProvider.d.ts +1 -0
  57. package/build/utxo/OPNetLimitedProvider.js +11 -1
  58. package/eslint.config.js +2 -1
  59. package/package.json +1 -1
  60. package/src/_version.ts +1 -1
  61. package/src/chain/ChainData.ts +32 -0
  62. package/src/epoch/ChallengeSolution.ts +4 -4
  63. package/src/epoch/interfaces/IChallengeSolution.ts +4 -4
  64. package/src/generators/Features.ts +8 -2
  65. package/src/generators/Generator.ts +35 -2
  66. package/src/generators/MLDSAData.ts +30 -0
  67. package/src/generators/builders/CalldataGenerator.ts +1 -1
  68. package/src/generators/builders/DeploymentGenerator.ts +2 -1
  69. package/src/generators/builders/LegacyCalldataGenerator.ts +1 -0
  70. package/src/generators/builders/P2WDAGenerator.ts +5 -1
  71. package/src/keypair/Address.ts +78 -38
  72. package/src/keypair/MessageSigner.ts +214 -15
  73. package/src/opnet.ts +2 -0
  74. package/src/transaction/TransactionFactory.ts +3 -0
  75. package/src/transaction/browser/Web3Provider.ts +64 -4
  76. package/src/transaction/browser/types/OPWallet.ts +6 -53
  77. package/src/transaction/builders/CustomScriptTransaction.ts +4 -0
  78. package/src/transaction/builders/DeploymentTransaction.ts +36 -8
  79. package/src/transaction/builders/InteractionTransaction.ts +17 -7
  80. package/src/transaction/builders/InteractionTransactionP2WDA.ts +17 -7
  81. package/src/transaction/builders/TransactionBuilder.ts +107 -0
  82. package/src/transaction/interfaces/ITransactionParameters.ts +12 -0
  83. package/src/transaction/shared/P2TR_MS.ts +1 -0
  84. package/src/transaction/shared/TweakedTransaction.ts +35 -0
  85. package/src/utxo/OPNetLimitedProvider.ts +19 -2
  86. package/test/address.test.ts +18 -20
  87. package/test/addressmap.test.ts +783 -0
  88. package/test/addressverificator-mldsa.test.ts +40 -16
  89. package/test/messagesigner-mldsa.test.ts +50 -50
  90. package/test/messagesigner-schnorr.test.ts +40 -40
  91. package/tsconfig.webpack.json +2 -6
  92. package/webpack.config.js +1 -1
  93. package/browser/src/_version.d.ts +0 -1
  94. package/browser/src/transaction/browser/types/OPWallet.d.ts +0 -14
  95. package/browser/test/address.test.d.ts +0 -1
  96. package/browser/test/addressverificator-mldsa.test.d.ts +0 -1
  97. package/browser/test/derivePath.test.d.ts +0 -1
  98. package/browser/test/fastmap-setall.test.d.ts +0 -1
  99. package/browser/test/fastmap.test.d.ts +0 -1
  100. package/browser/test/messagesigner-mldsa.test.d.ts +0 -1
  101. package/browser/test/messagesigner-schnorr.test.d.ts +0 -1
  102. package/browser/test/network-awareness.test.d.ts +0 -1
  103. package/browser/test/old/FastBigIntMap.d.ts +0 -18
  104. package/browser/test/oldfastmap.test.d.ts +0 -1
  105. /package/browser/{src/abi → abi}/ABICoder.d.ts +0 -0
  106. /package/browser/{src/buffer → buffer}/BinaryReader.d.ts +0 -0
  107. /package/browser/{src/buffer → buffer}/BinaryWriter.d.ts +0 -0
  108. /package/browser/{src/bytecode → bytecode}/Compressor.d.ts +0 -0
  109. /package/browser/{src/consensus → consensus}/Consensus.d.ts +0 -0
  110. /package/browser/{src/consensus → consensus}/ConsensusConfig.d.ts +0 -0
  111. /package/browser/{src/consensus → consensus}/metadata/RoswellConsensus.d.ts +0 -0
  112. /package/browser/{src/crypto → crypto}/crypto-browser.d.ts +0 -0
  113. /package/browser/{src/crypto → crypto}/crypto.d.ts +0 -0
  114. /package/browser/{src/deterministic → deterministic}/AddressMap.d.ts +0 -0
  115. /package/browser/{src/deterministic → deterministic}/AddressSet.d.ts +0 -0
  116. /package/browser/{src/deterministic → deterministic}/CustomMap.d.ts +0 -0
  117. /package/browser/{src/deterministic → deterministic}/DeterministicMap.d.ts +0 -0
  118. /package/browser/{src/deterministic → deterministic}/DeterministicSet.d.ts +0 -0
  119. /package/browser/{src/deterministic → deterministic}/FastMap.d.ts +0 -0
  120. /package/browser/{src/epoch → epoch}/ChallengeSolution.d.ts +0 -0
  121. /package/browser/{src/epoch → epoch}/validator/EpochValidator.d.ts +0 -0
  122. /package/browser/{src/event → event}/NetEvent.d.ts +0 -0
  123. /package/browser/{src/generators → generators}/AddressGenerator.d.ts +0 -0
  124. /package/browser/{src/generators → generators}/builders/CalldataGenerator.d.ts +0 -0
  125. /package/browser/{src/generators → generators}/builders/CustomGenerator.d.ts +0 -0
  126. /package/browser/{src/generators → generators}/builders/DeploymentGenerator.d.ts +0 -0
  127. /package/browser/{src/generators → generators}/builders/LegacyCalldataGenerator.d.ts +0 -0
  128. /package/browser/{src/generators → generators}/builders/MultiSignGenerator.d.ts +0 -0
  129. /package/browser/{src/generators → generators}/builders/P2WDAGenerator.d.ts +0 -0
  130. /package/browser/{src/index.d.ts → index.d.ts} +0 -0
  131. /package/browser/{src/keypair → keypair}/AddressVerificator.d.ts +0 -0
  132. /package/browser/{src/keypair → keypair}/EcKeyPair.d.ts +0 -0
  133. /package/browser/{src/keypair → keypair}/Secp256k1PointDeriver.d.ts +0 -0
  134. /package/browser/{src/keypair → keypair}/Wallet.d.ts +0 -0
  135. /package/browser/{src/keypair → keypair}/interfaces/IWallet.d.ts +0 -0
  136. /package/browser/{src/metadata → metadata}/ContractBaseMetadata.d.ts +0 -0
  137. /package/browser/{src/metadata → metadata}/tokens.d.ts +0 -0
  138. /package/browser/{src/mnemonic → mnemonic}/BIPStandard.d.ts +0 -0
  139. /package/browser/{src/mnemonic → mnemonic}/Mnemonic.d.ts +0 -0
  140. /package/browser/{src/mnemonic → mnemonic}/MnemonicStrength.d.ts +0 -0
  141. /package/browser/{src/network → network}/ChainId.d.ts +0 -0
  142. /package/browser/{src/p2wda → p2wda}/P2WDADetector.d.ts +0 -0
  143. /package/browser/{src/signer → signer}/SignerUtils.d.ts +0 -0
  144. /package/browser/{src/signer → signer}/TweakedSigner.d.ts +0 -0
  145. /package/browser/{src/transaction → transaction}/ContractAddress.d.ts +0 -0
  146. /package/browser/{src/transaction → transaction}/TransactionFactory.d.ts +0 -0
  147. /package/browser/{src/transaction → transaction}/browser/BrowserSignerBase.d.ts +0 -0
  148. /package/browser/{src/transaction → transaction}/browser/extensions/UnisatSigner.d.ts +0 -0
  149. /package/browser/{src/transaction → transaction}/browser/extensions/XverseSigner.d.ts +0 -0
  150. /package/browser/{src/transaction → transaction}/browser/types/Unisat.d.ts +0 -0
  151. /package/browser/{src/transaction → transaction}/browser/types/Xverse.d.ts +0 -0
  152. /package/browser/{src/transaction → transaction}/builders/CancelTransaction.d.ts +0 -0
  153. /package/browser/{src/transaction → transaction}/builders/ChallengeSolutionTransaction.d.ts +0 -0
  154. /package/browser/{src/transaction → transaction}/builders/FundingTransaction.d.ts +0 -0
  155. /package/browser/{src/transaction → transaction}/builders/InteractionTransaction.d.ts +0 -0
  156. /package/browser/{src/transaction → transaction}/builders/InteractionTransactionP2WDA.d.ts +0 -0
  157. /package/browser/{src/transaction → transaction}/builders/MultiSignTransaction.d.ts +0 -0
  158. /package/browser/{src/transaction → transaction}/builders/SharedInteractionTransaction.d.ts +0 -0
  159. /package/browser/{src/transaction → transaction}/enums/TransactionType.d.ts +0 -0
  160. /package/browser/{src/transaction → transaction}/interfaces/Tap.d.ts +0 -0
  161. /package/browser/{src/transaction → transaction}/mineable/IP2WSHAddress.d.ts +0 -0
  162. /package/browser/{src/transaction → transaction}/mineable/TimelockGenerator.d.ts +0 -0
  163. /package/browser/{src/transaction → transaction}/processor/PsbtTransaction.d.ts +0 -0
  164. /package/browser/{src/transaction → transaction}/psbt/PSBTTypes.d.ts +0 -0
  165. /package/browser/{src/transaction → transaction}/shared/P2TR_MS.d.ts +0 -0
  166. /package/browser/{src/utils → utils}/BitcoinUtils.d.ts +0 -0
  167. /package/browser/{src/utils → utils}/BufferHelper.d.ts +0 -0
  168. /package/browser/{src/utils → utils}/StringToBuffer.d.ts +0 -0
  169. /package/browser/{src/utils → utils}/lengths.d.ts +0 -0
  170. /package/browser/{src/utils → utils}/types.d.ts +0 -0
  171. /package/browser/{src/utxo → utxo}/interfaces/BroadcastResponse.d.ts +0 -0
  172. /package/browser/{src/utxo → utxo}/interfaces/IUTXO.d.ts +0 -0
  173. /package/browser/{src/verification → verification}/TapscriptVerificator.d.ts +0 -0
@@ -4,6 +4,12 @@ import { EcKeyPair } from '../../keypair/EcKeyPair.js';
4
4
  import { AddressVerificator } from '../../keypair/AddressVerificator.js';
5
5
  import { TweakedTransaction } from '../shared/TweakedTransaction.js';
6
6
  import { P2WDADetector } from '../../p2wda/P2WDADetector.js';
7
+ import { Features } from '../../generators/Features.js';
8
+ import { BITCOIN_PROTOCOL_ID, getChainId } from '../../chain/ChainData.js';
9
+ import { BinaryWriter } from '../../buffer/BinaryWriter.js';
10
+ import { MLDSASecurityLevel } from '@btc-vision/bip32';
11
+ import { MessageSigner } from '../../keypair/MessageSigner.js';
12
+ import { getLevelFromPublicKeyLength } from '../../generators/MLDSAData.js';
7
13
  initEccLib(ecc);
8
14
  export const MINIMUM_AMOUNT_REWARD = 330n;
9
15
  export const MINIMUM_AMOUNT_CA = 297n;
@@ -112,6 +118,7 @@ export class TransactionBuilder extends TweakedTransaction {
112
118
  amount: this.estimatedFees,
113
119
  optionalOutputs: this.optionalOutputs,
114
120
  optionalInputs: this.optionalInputs,
121
+ mldsaSigner: null,
115
122
  };
116
123
  }
117
124
  setDestinationAddress(address) {
@@ -487,6 +494,76 @@ export class TransactionBuilder extends TweakedTransaction {
487
494
  }
488
495
  throw new Error('Output not found');
489
496
  }
497
+ generateLegacySignature() {
498
+ this.tweakSigner();
499
+ if (!this.tweakedSigner) {
500
+ throw new Error('Tweaked signer is not defined');
501
+ }
502
+ const tweakedKey = toXOnly(this.tweakedSigner.publicKey);
503
+ const chainId = getChainId(this.network);
504
+ const writer = new BinaryWriter();
505
+ writer.writeU8(MLDSASecurityLevel.LEVEL2);
506
+ writer.writeBytes(this.hashedPublicKey);
507
+ writer.writeBytes(tweakedKey);
508
+ writer.writeBytes(BITCOIN_PROTOCOL_ID);
509
+ writer.writeBytes(chainId);
510
+ const message = writer.getBuffer();
511
+ const signature = MessageSigner.signMessage(this.tweakedSigner, message);
512
+ const isValid = MessageSigner.verifySignature(tweakedKey, message, signature.signature);
513
+ if (!isValid) {
514
+ throw new Error('Could not verify generated legacy signature for MLDSA link request');
515
+ }
516
+ return Buffer.from(signature.signature);
517
+ }
518
+ generateMLDSASignature() {
519
+ if (!this.mldsaSigner) {
520
+ throw new Error('MLDSA signer is not defined');
521
+ }
522
+ this.tweakSigner();
523
+ if (!this.tweakedSigner) {
524
+ throw new Error('Tweaked signer is not defined');
525
+ }
526
+ const tweakedKey = toXOnly(this.tweakedSigner.publicKey);
527
+ const chainId = getChainId(this.network);
528
+ const level = getLevelFromPublicKeyLength(this.mldsaSigner.publicKey.length);
529
+ if (level !== MLDSASecurityLevel.LEVEL2) {
530
+ throw new Error('Only MLDSA level 2 is supported for link requests');
531
+ }
532
+ const writer = new BinaryWriter();
533
+ writer.writeU8(level);
534
+ writer.writeBytes(this.hashedPublicKey);
535
+ writer.writeBytes(this.mldsaSigner.publicKey);
536
+ writer.writeBytes(tweakedKey);
537
+ writer.writeBytes(BITCOIN_PROTOCOL_ID);
538
+ writer.writeBytes(chainId);
539
+ const message = writer.getBuffer();
540
+ const signature = MessageSigner.signMLDSAMessage(this.mldsaSigner, message);
541
+ const isValid = MessageSigner.verifyMLDSASignature(this.mldsaSigner, message, signature.signature);
542
+ if (!isValid) {
543
+ throw new Error('Could not verify generated MLDSA signature for link request');
544
+ }
545
+ return Buffer.from(signature.signature);
546
+ }
547
+ generateMLDSALinkRequest(parameters, features) {
548
+ const mldsaSigner = this.mldsaSigner;
549
+ const legacySignature = this.generateLegacySignature();
550
+ let mldsaSignature = null;
551
+ if (parameters.revealMLDSAPublicKey) {
552
+ mldsaSignature = this.generateMLDSASignature();
553
+ }
554
+ const mldsaRequest = {
555
+ opcode: Features.MLDSA_LINK_PUBKEY,
556
+ data: {
557
+ verifyRequest: !!parameters.revealMLDSAPublicKey,
558
+ publicKey: mldsaSigner.publicKey,
559
+ hashedPublicKey: this.hashedPublicKey,
560
+ level: getLevelFromPublicKeyLength(mldsaSigner.publicKey.length),
561
+ legacySignature: legacySignature,
562
+ mldsaSignature: mldsaSignature,
563
+ },
564
+ };
565
+ features.push(mldsaRequest);
566
+ }
490
567
  getTransactionOPNetFee() {
491
568
  const totalFee = this.priorityFee + this.gasSatFee;
492
569
  if (totalFee > TransactionBuilder.MINIMUM_DUST) {
@@ -10,6 +10,8 @@ export interface ITransactionParameters extends ITweakedTransactionData {
10
10
  readonly from?: string;
11
11
  readonly to?: string;
12
12
  readonly debugFees?: boolean;
13
+ readonly revealMLDSAPublicKey?: boolean;
14
+ readonly linkMLDSAPublicKeyToAddress?: boolean;
13
15
  utxos: UTXO[];
14
16
  nonWitnessUtxo?: Buffer;
15
17
  estimatedFees?: bigint;
@@ -22,6 +24,7 @@ export interface ITransactionParameters extends ITweakedTransactionData {
22
24
  readonly feeRate: number;
23
25
  readonly priorityFee: bigint;
24
26
  readonly gasSatFee: bigint;
27
+ readonly compiledTargetScript?: Buffer | string;
25
28
  }
26
29
  export interface IFundingTransactionParameters extends ITransactionParameters {
27
30
  amount: bigint;
@@ -15,6 +15,7 @@ export class P2TR_MS {
15
15
  receiver: 'a',
16
16
  requestedAmount: 1n,
17
17
  refundVault: 'a',
18
+ mldsaSigner: null,
18
19
  };
19
20
  const address = new MultiSignTransaction(multiSignParams).getScriptAddress();
20
21
  if (!address) {
@@ -6,8 +6,10 @@ import { TapLeafScript } from '../interfaces/Tap.js';
6
6
  import { ChainId } from '../../network/ChainId.js';
7
7
  import { UnisatSigner } from '../browser/extensions/UnisatSigner.js';
8
8
  import { Buffer } from 'buffer';
9
+ import { QuantumBIP32Interface } from '@btc-vision/bip32';
9
10
  export type SupportedTransactionVersion = 1 | 2 | 3;
10
11
  export interface ITweakedTransactionData {
12
+ readonly mldsaSigner: QuantumBIP32Interface | null;
11
13
  readonly signer: Signer | ECPairInterface | UnisatSigner;
12
14
  readonly network: Network;
13
15
  readonly chainId?: ChainId;
@@ -47,7 +49,11 @@ export declare abstract class TweakedTransaction extends Logger {
47
49
  protected noSignatures: boolean;
48
50
  protected unlockScript: Buffer[] | undefined;
49
51
  protected txVersion: SupportedTransactionVersion;
52
+ protected readonly _mldsaSigner: QuantumBIP32Interface | null;
53
+ protected readonly _hashedPublicKey: Buffer | null;
50
54
  protected constructor(data: ITweakedTransactionData);
55
+ protected get mldsaSigner(): QuantumBIP32Interface;
56
+ protected get hashedPublicKey(): Buffer;
51
57
  static readScriptWitnessToWitnessStack(buffer: Buffer): Buffer[];
52
58
  static preEstimateTaprootTransactionFees(feeRate: bigint, numInputs: bigint, numOutputs: bigint, numWitnessElements: bigint, witnessElementSize: bigint, emptyWitness: bigint, taprootControlWitnessSize?: bigint, taprootScriptSize?: bigint): bigint;
53
59
  protected static signInput(transaction: Psbt, input: PsbtInput, i: number, signer: Signer | ECPairInterface, sighashTypes: number[]): void;
@@ -5,6 +5,7 @@ import { canSignNonTaprootInput, isTaprootInput, pubkeyInScript, } from '../../s
5
5
  import { TransactionBuilder } from '../builders/TransactionBuilder.js';
6
6
  import { Buffer } from 'buffer';
7
7
  import { P2WDADetector } from '../../p2wda/P2WDADetector.js';
8
+ import { MessageSigner } from '../../keypair/MessageSigner.js';
8
9
  export var TransactionSequence;
9
10
  (function (TransactionSequence) {
10
11
  TransactionSequence[TransactionSequence["REPLACE_BY_FEE"] = 4294967293] = "REPLACE_BY_FEE";
@@ -34,6 +35,8 @@ export class TweakedTransaction extends Logger {
34
35
  this.ignoreSignatureErrors = false;
35
36
  this.noSignatures = false;
36
37
  this.txVersion = 2;
38
+ this._mldsaSigner = null;
39
+ this._hashedPublicKey = null;
37
40
  this.customFinalizerP2SH = (inputIndex, input, scriptA, isSegwit, isP2SH, isP2WSH) => {
38
41
  const inputDecoded = this.inputs[inputIndex];
39
42
  if (isP2SH && input.partialSig && inputDecoded && inputDecoded.redeemScript) {
@@ -78,6 +81,22 @@ export class TweakedTransaction extends Logger {
78
81
  if (data.txVersion) {
79
82
  this.txVersion = data.txVersion;
80
83
  }
84
+ if (data.mldsaSigner) {
85
+ this._mldsaSigner = data.mldsaSigner;
86
+ this._hashedPublicKey = MessageSigner.sha256(this._mldsaSigner.publicKey);
87
+ }
88
+ }
89
+ get mldsaSigner() {
90
+ if (!this._mldsaSigner) {
91
+ throw new Error('MLDSA Signer is not set');
92
+ }
93
+ return this._mldsaSigner;
94
+ }
95
+ get hashedPublicKey() {
96
+ if (!this._hashedPublicKey) {
97
+ throw new Error('Hashed public key is not set');
98
+ }
99
+ return this._hashedPublicKey;
81
100
  }
82
101
  static readScriptWitnessToWitnessStack(buffer) {
83
102
  let offset = 0;
@@ -6,6 +6,7 @@ export interface WalletUTXOs {
6
6
  readonly confirmed: RawUTXOResponse[];
7
7
  readonly pending: RawUTXOResponse[];
8
8
  readonly spentTransactions: RawUTXOResponse[];
9
+ readonly raw: string[];
9
10
  }
10
11
  export declare class OPNetLimitedProvider {
11
12
  private readonly opnetAPIUrl;
@@ -24,6 +24,7 @@ export class OPNetLimitedProvider {
24
24
  throw new Error(`Failed to fetch UTXO data: ${resp.statusText}`);
25
25
  }
26
26
  const fetchedData = (await resp.json());
27
+ const rawTransactions = fetchedData.raw ?? [];
27
28
  const allUtxos = settings.usePendingUTXO
28
29
  ? [...fetchedData.confirmed, ...fetchedData.pending]
29
30
  : fetchedData.confirmed;
@@ -52,13 +53,21 @@ export class OPNetLimitedProvider {
52
53
  if (utxoValue <= 0n) {
53
54
  continue;
54
55
  }
56
+ const rawIndex = utxo.raw;
57
+ if (rawIndex === undefined || rawIndex === null) {
58
+ throw new Error(`Missing raw index for UTXO ${utxo.transactionId}:${utxo.outputIndex}`);
59
+ }
60
+ const rawHex = rawTransactions[rawIndex];
61
+ if (!rawHex) {
62
+ throw new Error(`Invalid raw index ${rawIndex} - not found in raw transactions array`);
63
+ }
55
64
  currentAmount += utxoValue;
56
65
  finalUTXOs.push({
57
66
  transactionId: utxo.transactionId,
58
67
  outputIndex: utxo.outputIndex,
59
68
  value: utxoValue,
60
69
  scriptPubKey: utxo.scriptPubKey,
61
- nonWitnessUtxo: Buffer.from(utxo.raw, 'base64'),
70
+ nonWitnessUtxo: Buffer.from(rawHex, 'base64'),
62
71
  });
63
72
  if (currentAmount > amountRequested) {
64
73
  break;
@@ -124,6 +133,7 @@ export class OPNetLimitedProvider {
124
133
  splitInputsInto,
125
134
  priorityFee: 0n,
126
135
  gasSatFee: 330n,
136
+ mldsaSigner: null,
127
137
  };
128
138
  const transactionFactory = new TransactionFactory();
129
139
  const fundingTx = await transactionFactory.createBTCTransfer(fundingTransactionParameters);
package/eslint.config.js CHANGED
@@ -29,7 +29,8 @@ export default tseslint.config(
29
29
  '@typescript-eslint/no-duplicate-enum-values': 'off',
30
30
  'prefer-spread': 'off',
31
31
  '@typescript-eslint/no-empty-object-type': 'off',
32
- '@typescript-eslint/prefer-literal-enum-member': 'off'
32
+ '@typescript-eslint/prefer-literal-enum-member': 'off',
33
+ '@typescript-eslint/related-getter-setter-pairs': 'off'
33
34
  },
34
35
  },
35
36
  {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@btc-vision/transaction",
3
3
  "type": "module",
4
- "version": "1.7.7",
4
+ "version": "1.7.10",
5
5
  "author": "BlobMaster41",
6
6
  "description": "OPNet transaction library allows you to create and sign transactions for the OPNet network.",
7
7
  "engines": {
package/src/_version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '1.7.7';
1
+ export const version = '1.7.10';
@@ -0,0 +1,32 @@
1
+ import { Network, networks } from '@btc-vision/bitcoin';
2
+
3
+ function objectEqual<T>(obj1: T, obj2: T): boolean {
4
+ return JSON.stringify(obj1) === JSON.stringify(obj2);
5
+ }
6
+
7
+ export function getChainIdHex(network: Network): string {
8
+ if (objectEqual(network, networks.bitcoin)) {
9
+ return '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f';
10
+ }
11
+
12
+ if (objectEqual(network, networks.testnet)) {
13
+ return '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943';
14
+ }
15
+
16
+ if (objectEqual(network, networks.regtest)) {
17
+ return '0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206';
18
+ }
19
+
20
+ throw new Error('Unsupported network for chain ID retrieval');
21
+ }
22
+
23
+ export function getChainId(network: Network): Uint8Array {
24
+ return Uint8Array.from(Buffer.from(getChainIdHex(network), 'hex'));
25
+ }
26
+
27
+ export const BITCOIN_PROTOCOL_ID = Uint8Array.from(
28
+ Buffer.from(
29
+ 'e784995a412d773988c4b8e333d7b39dfb3cabf118d0d645411a916ca2407939', // sha256("OP_NET")
30
+ 'hex',
31
+ ),
32
+ );
@@ -42,7 +42,7 @@ export class ChallengeSubmission implements IChallengeSubmission {
42
42
  data: RawChallengeSubmission,
43
43
  public readonly epochNumber: bigint,
44
44
  ) {
45
- this.publicKey = Address.fromString(data.publicKey, data.classicPublicKey);
45
+ this.publicKey = Address.fromString(data.mldsaPublicKey, data.legacyPublicKey);
46
46
  this.solution = stringToBuffer(data.solution);
47
47
  this.graffiti = data.graffiti ? stringToBuffer(data.graffiti) : undefined;
48
48
  this.signature = stringToBuffer(data.signature);
@@ -76,7 +76,7 @@ export class ChallengeSolution implements IChallengeSolution {
76
76
 
77
77
  constructor(data: RawChallenge) {
78
78
  this.epochNumber = BigInt(data.epochNumber);
79
- this.publicKey = Address.fromString(data.publicKey, data.classicPublicKey);
79
+ this.publicKey = Address.fromString(data.mldsaPublicKey, data.legacyPublicKey);
80
80
  this.solution = stringToBuffer(data.solution);
81
81
  this.salt = stringToBuffer(data.salt);
82
82
  this.graffiti = stringToBuffer(data.graffiti);
@@ -144,8 +144,8 @@ export class ChallengeSolution implements IChallengeSolution {
144
144
  public toRaw(): RawChallenge {
145
145
  return {
146
146
  epochNumber: this.epochNumber.toString(),
147
- publicKey: this.publicKey.toHex(),
148
- classicPublicKey: this.publicKey.tweakedToHex(),
147
+ mldsaPublicKey: this.publicKey.toHex(),
148
+ legacyPublicKey: this.publicKey.tweakedToHex(),
149
149
  solution: this.toHex(),
150
150
  salt: '0x' + this.salt.toString('hex'),
151
151
  graffiti: '0x' + this.graffiti.toString('hex'),
@@ -31,8 +31,8 @@ export interface RawChallengeVerification {
31
31
  }
32
32
 
33
33
  export interface RawChallengeSubmission {
34
- readonly classicPublicKey: string;
35
- readonly publicKey: string;
34
+ readonly mldsaPublicKey: string;
35
+ readonly legacyPublicKey: string;
36
36
  readonly solution: string;
37
37
  readonly graffiti?: string;
38
38
  readonly signature: string;
@@ -47,8 +47,8 @@ export interface IChallengeSubmission {
47
47
 
48
48
  export interface RawChallenge {
49
49
  readonly epochNumber: string;
50
- readonly classicPublicKey: string;
51
- readonly publicKey: string;
50
+ readonly mldsaPublicKey: string;
51
+ readonly legacyPublicKey: string;
52
52
  readonly solution: string;
53
53
  readonly salt: string;
54
54
  readonly graffiti: string;
@@ -1,9 +1,11 @@
1
1
  import { LoadedStorage } from '../transaction/interfaces/ITransactionParameters.js';
2
2
  import { ChallengeSubmission } from '../epoch/ChallengeSolution.js';
3
+ import { MLDSARequestData } from './MLDSAData.js';
3
4
 
4
5
  export enum Features {
5
- ACCESS_LIST = 1,
6
- EPOCH_SUBMISSION = 2,
6
+ ACCESS_LIST = 0b1,
7
+ EPOCH_SUBMISSION = 0b10,
8
+ MLDSA_LINK_PUBKEY = 0b100,
7
9
  }
8
10
 
9
11
  export interface Feature<T extends Features> {
@@ -18,3 +20,7 @@ export interface AccessListFeature extends Feature<Features.ACCESS_LIST> {
18
20
  export interface EpochSubmissionFeature extends Feature<Features.EPOCH_SUBMISSION> {
19
21
  data: ChallengeSubmission;
20
22
  }
23
+
24
+ export interface MLDSALinkRequest extends Feature<Features.MLDSA_LINK_PUBKEY> {
25
+ data: MLDSARequestData;
26
+ }
@@ -1,6 +1,6 @@
1
1
  import { Network, networks, toXOnly } from '@btc-vision/bitcoin';
2
2
  import { BinaryWriter } from '../buffer/BinaryWriter.js';
3
- import { AccessListFeature, EpochSubmissionFeature, Feature, Features } from './Features.js';
3
+ import { AccessListFeature, EpochSubmissionFeature, Feature, Features, MLDSALinkRequest, } from './Features.js';
4
4
  import { Address } from '../keypair/Address.js';
5
5
  import { Compressor } from '../bytecode/Compressor.js';
6
6
 
@@ -117,6 +117,11 @@ export abstract class Generator {
117
117
  this.encodeChallengeSubmission(feature as EpochSubmissionFeature),
118
118
  );
119
119
  }
120
+ case Features.MLDSA_LINK_PUBKEY: {
121
+ return this.splitBufferIntoChunks(
122
+ this.encodeLinkRequest(feature as MLDSALinkRequest),
123
+ );
124
+ }
120
125
  default:
121
126
  throw new Error(`Unknown feature type: ${feature.opcode}`);
122
127
  }
@@ -154,7 +159,7 @@ export abstract class Generator {
154
159
  }
155
160
 
156
161
  const writer = new BinaryWriter();
157
- writer.writeBytes(feature.data.publicKey.originalPublicKeyBuffer());
162
+ writer.writeBytes(feature.data.publicKey.toBuffer());
158
163
  writer.writeBytes(feature.data.solution);
159
164
 
160
165
  if (feature.data.graffiti) {
@@ -163,4 +168,32 @@ export abstract class Generator {
163
168
 
164
169
  return Buffer.from(writer.getBuffer());
165
170
  }
171
+
172
+ private encodeLinkRequest(feature: MLDSALinkRequest): Buffer {
173
+ const data = feature.data;
174
+
175
+ const writer = new BinaryWriter();
176
+ writer.writeU8(data.level);
177
+ writer.writeBytes(data.hashedPublicKey);
178
+ writer.writeBoolean(data.verifyRequest);
179
+
180
+ if (data.verifyRequest) {
181
+ if (!data.publicKey || !data.mldsaSignature) {
182
+ throw new Error(
183
+ 'MLDSA public key and signature required when verifyRequest is true',
184
+ );
185
+ }
186
+
187
+ writer.writeBytes(data.publicKey);
188
+ writer.writeBytes(data.mldsaSignature);
189
+ }
190
+
191
+ if (!data.legacySignature || data.legacySignature.length !== 64) {
192
+ throw new Error('Legacy signature must be exactly 64 bytes');
193
+ }
194
+
195
+ writer.writeBytes(data.legacySignature);
196
+
197
+ return Buffer.from(writer.getBuffer());
198
+ }
166
199
  }
@@ -0,0 +1,30 @@
1
+ import { MLDSASecurityLevel } from '@btc-vision/bip32';
2
+
3
+ export enum MLDSAPublicKeyMetadata {
4
+ MLDSA44 = 1312,
5
+ MLDSA65 = 1952,
6
+ MLDSA87 = 2592,
7
+ }
8
+
9
+ export interface MLDSARequestData {
10
+ readonly verifyRequest: boolean;
11
+ readonly publicKey: Uint8Array | Buffer | null;
12
+ readonly hashedPublicKey: Uint8Array | Buffer;
13
+ readonly level: MLDSASecurityLevel;
14
+
15
+ readonly mldsaSignature: Uint8Array | Buffer | null;
16
+ readonly legacySignature: Uint8Array | Buffer;
17
+ }
18
+
19
+ export function getLevelFromPublicKeyLength(length: number): MLDSASecurityLevel {
20
+ switch (length) {
21
+ case MLDSAPublicKeyMetadata.MLDSA44 as number:
22
+ return MLDSASecurityLevel.LEVEL2;
23
+ case MLDSAPublicKeyMetadata.MLDSA65 as number:
24
+ return MLDSASecurityLevel.LEVEL3;
25
+ case MLDSAPublicKeyMetadata.MLDSA87 as number:
26
+ return MLDSASecurityLevel.LEVEL5;
27
+ default:
28
+ throw new Error(`Invalid MLDSA public key length: ${length}`);
29
+ }
30
+ }
@@ -90,7 +90,7 @@ export class CalldataGenerator extends Generator {
90
90
  opcodes.OP_TOALTSTACK,
91
91
 
92
92
  // CHALLENGE PREIMAGE FOR REWARD,
93
- challenge.publicKey.originalPublicKeyBuffer(),
93
+ challenge.publicKey.toBuffer(),
94
94
  opcodes.OP_TOALTSTACK,
95
95
 
96
96
  challenge.solution,
@@ -41,6 +41,7 @@ export class DeploymentGenerator extends Generator {
41
41
  calldata,
42
42
  features,
43
43
  );
44
+
44
45
  const compiled = script.compile(asm);
45
46
 
46
47
  /**
@@ -85,7 +86,7 @@ export class DeploymentGenerator extends Generator {
85
86
  opcodes.OP_TOALTSTACK,
86
87
 
87
88
  // CHALLENGE PREIMAGE FOR REWARD,
88
- challenge.publicKey.originalPublicKeyBuffer(),
89
+ challenge.publicKey.toBuffer(),
89
90
  opcodes.OP_TOALTSTACK,
90
91
 
91
92
  challenge.solution,
@@ -7,6 +7,7 @@ import { Feature, Features } from '../Features.js';
7
7
 
8
8
  /**
9
9
  * Class to generate bitcoin script for interaction transactions
10
+ * @deprecated
10
11
  */
11
12
  export class LegacyCalldataGenerator extends Generator {
12
13
  constructor(senderPubKey: Buffer, network: Network = networks.bitcoin) {
@@ -4,6 +4,10 @@ import { Feature, Features } from '../Features.js';
4
4
  import { Generator } from '../Generator.js';
5
5
  import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
6
6
 
7
+ /**
8
+ * @category Generators
9
+ * @remarks Not fully implemented yet
10
+ */
7
11
  export class P2WDAGenerator extends Generator {
8
12
  private static readonly P2WDA_VERSION = 0x01;
9
13
 
@@ -90,7 +94,7 @@ export class P2WDAGenerator extends Generator {
90
94
  writer.writeBytes(contractSecret);
91
95
 
92
96
  // Challenge components for epoch rewards
93
- writer.writeBytes(challenge.publicKey.originalPublicKeyBuffer());
97
+ writer.writeBytes(challenge.publicKey.toBuffer());
94
98
  writer.writeBytes(challenge.solution);
95
99
 
96
100
  // Calldata with length prefix