@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.
- package/browser/_version.d.ts +1 -0
- package/browser/chain/ChainData.d.ts +4 -0
- package/browser/{src/epoch → epoch}/interfaces/IChallengeSolution.d.ts +4 -4
- package/browser/{src/generators → generators}/Features.d.ts +6 -1
- package/browser/{src/generators → generators}/Generator.d.ts +1 -0
- package/browser/generators/MLDSAData.d.ts +15 -0
- package/browser/index.js +1 -1
- package/browser/{src/keypair → keypair}/Address.d.ts +9 -3
- package/browser/{src/keypair → keypair}/MessageSigner.d.ts +9 -0
- package/browser/{src/opnet.d.ts → opnet.d.ts} +1 -0
- package/browser/{src/transaction → transaction}/browser/Web3Provider.d.ts +15 -4
- package/browser/transaction/browser/types/OPWallet.d.ts +6 -0
- package/browser/{src/transaction → transaction}/builders/CustomScriptTransaction.d.ts +1 -0
- package/browser/{src/transaction → transaction}/builders/DeploymentTransaction.d.ts +1 -0
- package/browser/{src/transaction → transaction}/builders/TransactionBuilder.d.ts +4 -0
- package/browser/{src/transaction → transaction}/interfaces/ITransactionParameters.d.ts +3 -0
- package/browser/{src/transaction → transaction}/shared/TweakedTransaction.d.ts +6 -0
- package/browser/{src/utxo → utxo}/OPNetLimitedProvider.d.ts +1 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/chain/ChainData.d.ts +4 -0
- package/build/chain/ChainData.js +20 -0
- package/build/epoch/ChallengeSolution.js +4 -4
- package/build/epoch/interfaces/IChallengeSolution.d.ts +4 -4
- package/build/generators/Features.d.ts +6 -1
- package/build/generators/Features.js +1 -0
- package/build/generators/Generator.d.ts +1 -0
- package/build/generators/Generator.js +24 -2
- package/build/generators/MLDSAData.d.ts +15 -0
- package/build/generators/MLDSAData.js +19 -0
- package/build/generators/builders/CalldataGenerator.js +1 -1
- package/build/generators/builders/DeploymentGenerator.js +1 -1
- package/build/generators/builders/P2WDAGenerator.js +1 -1
- package/build/keypair/Address.d.ts +9 -3
- package/build/keypair/Address.js +63 -38
- package/build/keypair/MessageSigner.d.ts +9 -0
- package/build/keypair/MessageSigner.js +101 -3
- package/build/opnet.d.ts +1 -0
- package/build/opnet.js +1 -0
- package/build/transaction/TransactionFactory.js +3 -0
- package/build/transaction/browser/Web3Provider.d.ts +15 -4
- package/build/transaction/browser/types/OPWallet.d.ts +2 -10
- package/build/transaction/browser/types/OPWallet.js +4 -2
- package/build/transaction/builders/CustomScriptTransaction.d.ts +1 -0
- package/build/transaction/builders/CustomScriptTransaction.js +3 -0
- package/build/transaction/builders/DeploymentTransaction.d.ts +1 -0
- package/build/transaction/builders/DeploymentTransaction.js +26 -1
- package/build/transaction/builders/InteractionTransaction.js +14 -1
- package/build/transaction/builders/InteractionTransactionP2WDA.js +14 -1
- package/build/transaction/builders/TransactionBuilder.d.ts +4 -0
- package/build/transaction/builders/TransactionBuilder.js +77 -0
- package/build/transaction/interfaces/ITransactionParameters.d.ts +3 -0
- package/build/transaction/shared/P2TR_MS.js +1 -0
- package/build/transaction/shared/TweakedTransaction.d.ts +6 -0
- package/build/transaction/shared/TweakedTransaction.js +19 -0
- package/build/utxo/OPNetLimitedProvider.d.ts +1 -0
- package/build/utxo/OPNetLimitedProvider.js +11 -1
- package/eslint.config.js +2 -1
- package/package.json +1 -1
- package/src/_version.ts +1 -1
- package/src/chain/ChainData.ts +32 -0
- package/src/epoch/ChallengeSolution.ts +4 -4
- package/src/epoch/interfaces/IChallengeSolution.ts +4 -4
- package/src/generators/Features.ts +8 -2
- package/src/generators/Generator.ts +35 -2
- package/src/generators/MLDSAData.ts +30 -0
- package/src/generators/builders/CalldataGenerator.ts +1 -1
- package/src/generators/builders/DeploymentGenerator.ts +2 -1
- package/src/generators/builders/LegacyCalldataGenerator.ts +1 -0
- package/src/generators/builders/P2WDAGenerator.ts +5 -1
- package/src/keypair/Address.ts +78 -38
- package/src/keypair/MessageSigner.ts +214 -15
- package/src/opnet.ts +2 -0
- package/src/transaction/TransactionFactory.ts +3 -0
- package/src/transaction/browser/Web3Provider.ts +64 -4
- package/src/transaction/browser/types/OPWallet.ts +6 -53
- package/src/transaction/builders/CustomScriptTransaction.ts +4 -0
- package/src/transaction/builders/DeploymentTransaction.ts +36 -8
- package/src/transaction/builders/InteractionTransaction.ts +17 -7
- package/src/transaction/builders/InteractionTransactionP2WDA.ts +17 -7
- package/src/transaction/builders/TransactionBuilder.ts +107 -0
- package/src/transaction/interfaces/ITransactionParameters.ts +12 -0
- package/src/transaction/shared/P2TR_MS.ts +1 -0
- package/src/transaction/shared/TweakedTransaction.ts +35 -0
- package/src/utxo/OPNetLimitedProvider.ts +19 -2
- package/test/address.test.ts +18 -20
- package/test/addressmap.test.ts +783 -0
- package/test/addressverificator-mldsa.test.ts +40 -16
- package/test/messagesigner-mldsa.test.ts +50 -50
- package/test/messagesigner-schnorr.test.ts +40 -40
- package/tsconfig.webpack.json +2 -6
- package/webpack.config.js +1 -1
- package/browser/src/_version.d.ts +0 -1
- package/browser/src/transaction/browser/types/OPWallet.d.ts +0 -14
- package/browser/test/address.test.d.ts +0 -1
- package/browser/test/addressverificator-mldsa.test.d.ts +0 -1
- package/browser/test/derivePath.test.d.ts +0 -1
- package/browser/test/fastmap-setall.test.d.ts +0 -1
- package/browser/test/fastmap.test.d.ts +0 -1
- package/browser/test/messagesigner-mldsa.test.d.ts +0 -1
- package/browser/test/messagesigner-schnorr.test.d.ts +0 -1
- package/browser/test/network-awareness.test.d.ts +0 -1
- package/browser/test/old/FastBigIntMap.d.ts +0 -18
- package/browser/test/oldfastmap.test.d.ts +0 -1
- /package/browser/{src/abi → abi}/ABICoder.d.ts +0 -0
- /package/browser/{src/buffer → buffer}/BinaryReader.d.ts +0 -0
- /package/browser/{src/buffer → buffer}/BinaryWriter.d.ts +0 -0
- /package/browser/{src/bytecode → bytecode}/Compressor.d.ts +0 -0
- /package/browser/{src/consensus → consensus}/Consensus.d.ts +0 -0
- /package/browser/{src/consensus → consensus}/ConsensusConfig.d.ts +0 -0
- /package/browser/{src/consensus → consensus}/metadata/RoswellConsensus.d.ts +0 -0
- /package/browser/{src/crypto → crypto}/crypto-browser.d.ts +0 -0
- /package/browser/{src/crypto → crypto}/crypto.d.ts +0 -0
- /package/browser/{src/deterministic → deterministic}/AddressMap.d.ts +0 -0
- /package/browser/{src/deterministic → deterministic}/AddressSet.d.ts +0 -0
- /package/browser/{src/deterministic → deterministic}/CustomMap.d.ts +0 -0
- /package/browser/{src/deterministic → deterministic}/DeterministicMap.d.ts +0 -0
- /package/browser/{src/deterministic → deterministic}/DeterministicSet.d.ts +0 -0
- /package/browser/{src/deterministic → deterministic}/FastMap.d.ts +0 -0
- /package/browser/{src/epoch → epoch}/ChallengeSolution.d.ts +0 -0
- /package/browser/{src/epoch → epoch}/validator/EpochValidator.d.ts +0 -0
- /package/browser/{src/event → event}/NetEvent.d.ts +0 -0
- /package/browser/{src/generators → generators}/AddressGenerator.d.ts +0 -0
- /package/browser/{src/generators → generators}/builders/CalldataGenerator.d.ts +0 -0
- /package/browser/{src/generators → generators}/builders/CustomGenerator.d.ts +0 -0
- /package/browser/{src/generators → generators}/builders/DeploymentGenerator.d.ts +0 -0
- /package/browser/{src/generators → generators}/builders/LegacyCalldataGenerator.d.ts +0 -0
- /package/browser/{src/generators → generators}/builders/MultiSignGenerator.d.ts +0 -0
- /package/browser/{src/generators → generators}/builders/P2WDAGenerator.d.ts +0 -0
- /package/browser/{src/index.d.ts → index.d.ts} +0 -0
- /package/browser/{src/keypair → keypair}/AddressVerificator.d.ts +0 -0
- /package/browser/{src/keypair → keypair}/EcKeyPair.d.ts +0 -0
- /package/browser/{src/keypair → keypair}/Secp256k1PointDeriver.d.ts +0 -0
- /package/browser/{src/keypair → keypair}/Wallet.d.ts +0 -0
- /package/browser/{src/keypair → keypair}/interfaces/IWallet.d.ts +0 -0
- /package/browser/{src/metadata → metadata}/ContractBaseMetadata.d.ts +0 -0
- /package/browser/{src/metadata → metadata}/tokens.d.ts +0 -0
- /package/browser/{src/mnemonic → mnemonic}/BIPStandard.d.ts +0 -0
- /package/browser/{src/mnemonic → mnemonic}/Mnemonic.d.ts +0 -0
- /package/browser/{src/mnemonic → mnemonic}/MnemonicStrength.d.ts +0 -0
- /package/browser/{src/network → network}/ChainId.d.ts +0 -0
- /package/browser/{src/p2wda → p2wda}/P2WDADetector.d.ts +0 -0
- /package/browser/{src/signer → signer}/SignerUtils.d.ts +0 -0
- /package/browser/{src/signer → signer}/TweakedSigner.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/ContractAddress.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/TransactionFactory.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/browser/BrowserSignerBase.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/browser/extensions/UnisatSigner.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/browser/extensions/XverseSigner.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/browser/types/Unisat.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/browser/types/Xverse.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/builders/CancelTransaction.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/builders/ChallengeSolutionTransaction.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/builders/FundingTransaction.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/builders/InteractionTransaction.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/builders/InteractionTransactionP2WDA.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/builders/MultiSignTransaction.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/builders/SharedInteractionTransaction.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/enums/TransactionType.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/interfaces/Tap.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/mineable/IP2WSHAddress.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/mineable/TimelockGenerator.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/processor/PsbtTransaction.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/psbt/PSBTTypes.d.ts +0 -0
- /package/browser/{src/transaction → transaction}/shared/P2TR_MS.d.ts +0 -0
- /package/browser/{src/utils → utils}/BitcoinUtils.d.ts +0 -0
- /package/browser/{src/utils → utils}/BufferHelper.d.ts +0 -0
- /package/browser/{src/utils → utils}/StringToBuffer.d.ts +0 -0
- /package/browser/{src/utils → utils}/lengths.d.ts +0 -0
- /package/browser/{src/utils → utils}/types.d.ts +0 -0
- /package/browser/{src/utxo → utxo}/interfaces/BroadcastResponse.d.ts +0 -0
- /package/browser/{src/utxo → utxo}/interfaces/IUTXO.d.ts +0 -0
- /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;
|
|
@@ -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(
|
|
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
package/src/_version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.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.
|
|
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.
|
|
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
|
-
|
|
148
|
-
|
|
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
|
|
35
|
-
readonly
|
|
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
|
|
51
|
-
readonly
|
|
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 =
|
|
6
|
-
EPOCH_SUBMISSION =
|
|
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.
|
|
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
|
+
}
|
|
@@ -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.
|
|
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.
|
|
97
|
+
writer.writeBytes(challenge.publicKey.toBuffer());
|
|
94
98
|
writer.writeBytes(challenge.solution);
|
|
95
99
|
|
|
96
100
|
// Calldata with length prefix
|