@btc-vision/transaction 1.6.19 → 1.7.1
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/index.js +1 -1
- package/browser/index.js.LICENSE.txt +2 -0
- package/browser/src/_version.d.ts +1 -0
- package/browser/{epoch → src/epoch}/interfaces/IChallengeSolution.d.ts +2 -0
- package/browser/{keypair → src/keypair}/Address.d.ts +7 -4
- package/browser/{keypair → src/keypair}/AddressVerificator.d.ts +3 -0
- package/browser/{keypair → src/keypair}/EcKeyPair.d.ts +3 -2
- package/browser/{keypair → src/keypair}/MessageSigner.d.ts +9 -0
- package/browser/src/keypair/Wallet.d.ts +47 -0
- package/browser/{keypair → src/keypair}/interfaces/IWallet.d.ts +2 -0
- package/browser/src/mnemonic/BIPStandard.d.ts +8 -0
- package/browser/src/mnemonic/Mnemonic.d.ts +34 -0
- package/browser/src/mnemonic/MnemonicStrength.d.ts +7 -0
- package/browser/{opnet.d.ts → src/opnet.d.ts} +5 -0
- package/browser/src/transaction/browser/types/OPWallet.d.ts +14 -0
- package/browser/test/address.test.d.ts +1 -0
- package/browser/test/addressverificator-mldsa.test.d.ts +1 -0
- package/browser/test/derivePath.test.d.ts +1 -0
- package/browser/test/messagesigner-mldsa.test.d.ts +1 -0
- package/browser/test/messagesigner-schnorr.test.d.ts +1 -0
- package/browser/test/network-awareness.test.d.ts +1 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/crypto/crypto-browser.d.ts +11 -0
- package/build/crypto/crypto-browser.js +56 -0
- package/build/epoch/ChallengeSolution.js +3 -2
- package/build/epoch/interfaces/IChallengeSolution.d.ts +2 -0
- package/build/keypair/Address.d.ts +7 -4
- package/build/keypair/Address.js +88 -37
- package/build/keypair/AddressVerificator.d.ts +3 -0
- package/build/keypair/AddressVerificator.js +49 -1
- package/build/keypair/EcKeyPair.d.ts +3 -2
- package/build/keypair/EcKeyPair.js +17 -3
- package/build/keypair/MessageSigner.d.ts +9 -0
- package/build/keypair/MessageSigner.js +23 -0
- package/build/keypair/Wallet.d.ts +20 -3
- package/build/keypair/Wallet.js +108 -9
- package/build/keypair/interfaces/IWallet.d.ts +2 -0
- package/build/mnemonic/BIPStandard.d.ts +8 -0
- package/build/mnemonic/BIPStandard.js +24 -0
- package/build/mnemonic/Mnemonic.d.ts +34 -0
- package/build/mnemonic/Mnemonic.js +140 -0
- package/build/mnemonic/MnemonicStrength.d.ts +7 -0
- package/build/mnemonic/MnemonicStrength.js +8 -0
- package/build/opnet.d.ts +5 -0
- package/build/opnet.js +5 -0
- package/build/transaction/browser/types/OPWallet.d.ts +14 -0
- package/build/transaction/browser/types/OPWallet.js +6 -0
- package/documentation/README.md +32 -0
- package/documentation/quantum-support/01-introduction.md +88 -0
- package/documentation/quantum-support/02-mnemonic-and-wallet.md +445 -0
- package/documentation/quantum-support/03-address-generation.md +329 -0
- package/documentation/quantum-support/04-message-signing.md +623 -0
- package/documentation/quantum-support/05-address-verification.md +307 -0
- package/documentation/quantum-support/README.md +65 -0
- package/gulpfile.js +2 -2
- package/package.json +25 -17
- package/src/_version.ts +1 -1
- package/src/epoch/ChallengeSolution.ts +3 -2
- package/src/epoch/interfaces/IChallengeSolution.ts +2 -0
- package/src/keypair/Address.ts +145 -43
- package/src/keypair/AddressVerificator.ts +87 -2
- package/src/keypair/EcKeyPair.ts +58 -6
- package/src/keypair/MessageSigner.ts +58 -0
- package/src/keypair/Wallet.ts +339 -57
- package/src/keypair/interfaces/IWallet.ts +13 -3
- package/src/mnemonic/BIPStandard.ts +92 -0
- package/src/mnemonic/Mnemonic.ts +465 -0
- package/src/mnemonic/MnemonicStrength.ts +12 -0
- package/src/network/ChainId.ts +1 -4
- package/src/opnet.ts +17 -0
- package/src/transaction/browser/types/OPWallet.ts +73 -0
- package/test/address.test.ts +1068 -0
- package/test/addressverificator-mldsa.test.ts +473 -0
- package/test/derivePath.test.ts +513 -0
- package/test/messagesigner-mldsa.test.ts +1060 -0
- package/test/messagesigner-schnorr.test.ts +1011 -0
- package/test/network-awareness.test.ts +163 -0
- package/tsconfig.json +1 -1
- package/vitest.config.ts +21 -0
- package/browser/_version.d.ts +0 -1
- package/browser/keypair/Wallet.d.ts +0 -30
- package/doc/README.md +0 -0
- /package/browser/{abi → src/abi}/ABICoder.d.ts +0 -0
- /package/browser/{buffer → src/buffer}/BinaryReader.d.ts +0 -0
- /package/browser/{buffer → src/buffer}/BinaryWriter.d.ts +0 -0
- /package/browser/{bytecode → src/bytecode}/Compressor.d.ts +0 -0
- /package/browser/{consensus → src/consensus}/Consensus.d.ts +0 -0
- /package/browser/{consensus → src/consensus}/ConsensusConfig.d.ts +0 -0
- /package/browser/{consensus → src/consensus}/metadata/RoswellConsensus.d.ts +0 -0
- /package/browser/{crypto → src/crypto}/crypto-browser.d.ts +0 -0
- /package/browser/{crypto → src/crypto}/crypto.d.ts +0 -0
- /package/browser/{deterministic → src/deterministic}/AddressMap.d.ts +0 -0
- /package/browser/{deterministic → src/deterministic}/AddressSet.d.ts +0 -0
- /package/browser/{deterministic → src/deterministic}/DeterministicMap.d.ts +0 -0
- /package/browser/{deterministic → src/deterministic}/DeterministicSet.d.ts +0 -0
- /package/browser/{deterministic → src/deterministic}/Map.d.ts +0 -0
- /package/browser/{epoch → src/epoch}/ChallengeSolution.d.ts +0 -0
- /package/browser/{epoch → src/epoch}/validator/EpochValidator.d.ts +0 -0
- /package/browser/{event → src/event}/NetEvent.d.ts +0 -0
- /package/browser/{generators → src/generators}/AddressGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/Features.d.ts +0 -0
- /package/browser/{generators → src/generators}/Generator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/CalldataGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/CustomGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/DeploymentGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/LegacyCalldataGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/MultiSignGenerator.d.ts +0 -0
- /package/browser/{generators → src/generators}/builders/P2WDAGenerator.d.ts +0 -0
- /package/browser/{index.d.ts → src/index.d.ts} +0 -0
- /package/browser/{keypair → src/keypair}/Secp256k1PointDeriver.d.ts +0 -0
- /package/browser/{metadata → src/metadata}/ContractBaseMetadata.d.ts +0 -0
- /package/browser/{metadata → src/metadata}/tokens.d.ts +0 -0
- /package/browser/{network → src/network}/ChainId.d.ts +0 -0
- /package/browser/{p2wda → src/p2wda}/P2WDADetector.d.ts +0 -0
- /package/browser/{signer → src/signer}/SignerUtils.d.ts +0 -0
- /package/browser/{signer → src/signer}/TweakedSigner.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/ContractAddress.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/TransactionFactory.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/BrowserSignerBase.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/Web3Provider.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/extensions/UnisatSigner.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/extensions/XverseSigner.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/types/Unisat.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/browser/types/Xverse.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/CancelTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/ChallengeSolutionTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/CustomScriptTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/DeploymentTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/FundingTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/InteractionTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/InteractionTransactionP2WDA.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/MultiSignTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/SharedInteractionTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/builders/TransactionBuilder.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/enums/TransactionType.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/interfaces/ITransactionParameters.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/interfaces/Tap.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/mineable/IP2WSHAddress.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/mineable/TimelockGenerator.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/processor/PsbtTransaction.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/psbt/PSBTTypes.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/shared/P2TR_MS.d.ts +0 -0
- /package/browser/{transaction → src/transaction}/shared/TweakedTransaction.d.ts +0 -0
- /package/browser/{utils → src/utils}/BitcoinUtils.d.ts +0 -0
- /package/browser/{utils → src/utils}/BufferHelper.d.ts +0 -0
- /package/browser/{utils → src/utils}/StringToBuffer.d.ts +0 -0
- /package/browser/{utils → src/utils}/lengths.d.ts +0 -0
- /package/browser/{utils → src/utils}/types.d.ts +0 -0
- /package/browser/{utxo → src/utxo}/OPNetLimitedProvider.d.ts +0 -0
- /package/browser/{utxo → src/utxo}/interfaces/BroadcastResponse.d.ts +0 -0
- /package/browser/{utxo → src/utxo}/interfaces/IUTXO.d.ts +0 -0
- /package/browser/{verification → src/verification}/TapscriptVerificator.d.ts +0 -0
- /package/{doc → documentation}/addresses/P2OP.md +0 -0
- /package/{doc → documentation}/addresses/P2WDA.md +0 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
# Address Verification Guide
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
- [ML-DSA Public Key Validation](#ml-dsa-public-key-validation)
|
|
5
|
+
- [Address Type Detection](#address-type-detection)
|
|
6
|
+
- [Classical Address Validation](#classical-address-validation)
|
|
7
|
+
- [Complete Validation Example](#complete-validation-example)
|
|
8
|
+
|
|
9
|
+
## ML-DSA Public Key Validation
|
|
10
|
+
|
|
11
|
+
### Validating ML-DSA Public Keys
|
|
12
|
+
|
|
13
|
+
The `AddressVerificator` provides methods to validate ML-DSA public keys and determine their security level:
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { AddressVerificator, MLDSASecurityLevel } from '@btc-vision/transaction';
|
|
17
|
+
|
|
18
|
+
// Valid ML-DSA-44 public key (1312 bytes)
|
|
19
|
+
const level2Key = Buffer.alloc(1312);
|
|
20
|
+
const level2Check = AddressVerificator.isValidMLDSAPublicKey(level2Key);
|
|
21
|
+
console.log('LEVEL2 valid:', level2Check); // MLDSASecurityLevel.LEVEL2
|
|
22
|
+
|
|
23
|
+
// Valid ML-DSA-65 public key (1952 bytes)
|
|
24
|
+
const level3Key = Buffer.alloc(1952);
|
|
25
|
+
const level3Check = AddressVerificator.isValidMLDSAPublicKey(level3Key);
|
|
26
|
+
console.log('LEVEL3 valid:', level3Check); // MLDSASecurityLevel.LEVEL3
|
|
27
|
+
|
|
28
|
+
// Valid ML-DSA-87 public key (2592 bytes)
|
|
29
|
+
const level5Key = Buffer.alloc(2592);
|
|
30
|
+
const level5Check = AddressVerificator.isValidMLDSAPublicKey(level5Key);
|
|
31
|
+
console.log('LEVEL5 valid:', level5Check); // MLDSASecurityLevel.LEVEL5
|
|
32
|
+
|
|
33
|
+
// Invalid length
|
|
34
|
+
const invalidKey = Buffer.alloc(1000);
|
|
35
|
+
const invalidCheck = AddressVerificator.isValidMLDSAPublicKey(invalidKey);
|
|
36
|
+
console.log('Invalid:', invalidCheck); // null
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Input Format Support
|
|
40
|
+
|
|
41
|
+
Validation supports multiple input formats:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { AddressVerificator, MLDSASecurityLevel } from '@btc-vision/transaction';
|
|
45
|
+
|
|
46
|
+
// Hex string (with 0x prefix)
|
|
47
|
+
const hexWith0x = '0x' + 'a'.repeat(2624); // 1312 bytes in hex
|
|
48
|
+
const check1 = AddressVerificator.isValidMLDSAPublicKey(hexWith0x);
|
|
49
|
+
console.log('Hex with 0x:', check1); // MLDSASecurityLevel.LEVEL2
|
|
50
|
+
|
|
51
|
+
// Hex string (without 0x prefix)
|
|
52
|
+
const hexWithout0x = 'a'.repeat(2624);
|
|
53
|
+
const check2 = AddressVerificator.isValidMLDSAPublicKey(hexWithout0x);
|
|
54
|
+
console.log('Hex without 0x:', check2); // MLDSASecurityLevel.LEVEL2
|
|
55
|
+
|
|
56
|
+
// Buffer
|
|
57
|
+
const buffer = Buffer.alloc(1312);
|
|
58
|
+
const check3 = AddressVerificator.isValidMLDSAPublicKey(buffer);
|
|
59
|
+
console.log('Buffer:', check3); // MLDSASecurityLevel.LEVEL2
|
|
60
|
+
|
|
61
|
+
// Uint8Array
|
|
62
|
+
const uint8Array = new Uint8Array(1312);
|
|
63
|
+
const check4 = AddressVerificator.isValidMLDSAPublicKey(uint8Array);
|
|
64
|
+
console.log('Uint8Array:', check4); // MLDSASecurityLevel.LEVEL2
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Validating Wallet Keys
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
import { Mnemonic, AddressVerificator, MLDSASecurityLevel } from '@btc-vision/transaction';
|
|
71
|
+
import { networks } from '@btc-vision/bitcoin';
|
|
72
|
+
|
|
73
|
+
// Generate wallet
|
|
74
|
+
const mnemonic = Mnemonic.generate(undefined, '', networks.bitcoin, MLDSASecurityLevel.LEVEL2);
|
|
75
|
+
const wallet = mnemonic.derive(0);
|
|
76
|
+
|
|
77
|
+
// Validate quantum public key
|
|
78
|
+
const quantumKeyHex = wallet.quantumPublicKeyHex;
|
|
79
|
+
const securityLevel = AddressVerificator.isValidMLDSAPublicKey(quantumKeyHex);
|
|
80
|
+
|
|
81
|
+
console.log('Quantum key valid:', securityLevel !== null);
|
|
82
|
+
console.log('Security level:', securityLevel); // MLDSASecurityLevel.LEVEL2
|
|
83
|
+
console.log('Expected:', wallet.securityLevel); // MLDSASecurityLevel.LEVEL2
|
|
84
|
+
console.log('Match:', securityLevel === wallet.securityLevel); // true
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Error Cases
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
// Empty string
|
|
91
|
+
console.log(AddressVerificator.isValidMLDSAPublicKey('')); // null
|
|
92
|
+
|
|
93
|
+
// Empty Buffer
|
|
94
|
+
console.log(AddressVerificator.isValidMLDSAPublicKey(Buffer.alloc(0))); // null
|
|
95
|
+
|
|
96
|
+
// Invalid hex
|
|
97
|
+
console.log(AddressVerificator.isValidMLDSAPublicKey('not hex')); // null
|
|
98
|
+
|
|
99
|
+
// Wrong length (classical key size)
|
|
100
|
+
const classicalKey = Buffer.alloc(33);
|
|
101
|
+
console.log(AddressVerificator.isValidMLDSAPublicKey(classicalKey)); // null
|
|
102
|
+
|
|
103
|
+
// Wrong length (arbitrary size)
|
|
104
|
+
const wrongSize = Buffer.alloc(1500);
|
|
105
|
+
console.log(AddressVerificator.isValidMLDSAPublicKey(wrongSize)); // null
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Address Type Detection
|
|
109
|
+
|
|
110
|
+
### Detecting Address Types
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { AddressVerificator, AddressTypes } from '@btc-vision/transaction';
|
|
114
|
+
import { networks } from '@btc-vision/bitcoin';
|
|
115
|
+
|
|
116
|
+
const wallet = mnemonic.derive(0);
|
|
117
|
+
|
|
118
|
+
// P2TR Detection
|
|
119
|
+
const p2tr = wallet.p2tr;
|
|
120
|
+
const p2trType = AddressVerificator.detectAddressType(p2tr, networks.bitcoin);
|
|
121
|
+
console.log('P2TR type:', p2trType); // AddressTypes.P2TR
|
|
122
|
+
|
|
123
|
+
// P2WPKH Detection
|
|
124
|
+
const p2wpkh = wallet.p2wpkh;
|
|
125
|
+
const p2wpkhType = AddressVerificator.detectAddressType(p2wpkh, networks.bitcoin);
|
|
126
|
+
console.log('P2WPKH type:', p2wpkhType); // AddressTypes.P2WPKH
|
|
127
|
+
|
|
128
|
+
// P2PKH Detection
|
|
129
|
+
const p2pkh = wallet.p2pkh;
|
|
130
|
+
const p2pkhType = AddressVerificator.detectAddressType(p2pkh, networks.bitcoin);
|
|
131
|
+
console.log('P2PKH type:', p2pkhType); // AddressTypes.P2PKH
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Available Address Types
|
|
135
|
+
|
|
136
|
+
```typescript
|
|
137
|
+
enum AddressTypes {
|
|
138
|
+
P2PKH = 'P2PKH', // Legacy (1...)
|
|
139
|
+
P2SH_OR_P2SH_P2WPKH = 'P2SH_OR_P2SH-P2WPKH', // Script hash (3...)
|
|
140
|
+
P2PK = 'P2PK', // Public key
|
|
141
|
+
P2TR = 'P2TR', // Taproot (bc1p...)
|
|
142
|
+
P2WPKH = 'P2WPKH', // SegWit (bc1q...)
|
|
143
|
+
P2WSH = 'P2WSH', // SegWit script (bc1q...)
|
|
144
|
+
P2WDA = 'P2WDA', // Witness data auth
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Distinguishing Similar Addresses
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
const wallet = mnemonic.derive(0);
|
|
152
|
+
|
|
153
|
+
// P2TR vs P2WPKH (both Bech32 formats)
|
|
154
|
+
const p2tr = wallet.p2tr;
|
|
155
|
+
const p2wpkh = wallet.p2wpkh;
|
|
156
|
+
|
|
157
|
+
const p2trType = AddressVerificator.detectAddressType(p2tr, networks.bitcoin);
|
|
158
|
+
const p2wpkhType = AddressVerificator.detectAddressType(p2wpkh, networks.bitcoin);
|
|
159
|
+
|
|
160
|
+
console.log('P2TR detected as:', p2trType); // AddressTypes.P2TR
|
|
161
|
+
console.log('P2WPKH detected as:', p2wpkhType); // AddressTypes.P2WPKH
|
|
162
|
+
console.log('Different types:', p2trType !== p2wpkhType); // true
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Network-Specific Detection
|
|
166
|
+
|
|
167
|
+
```typescript
|
|
168
|
+
// Mainnet address on mainnet
|
|
169
|
+
const mainnetAddr = wallet.p2tr;
|
|
170
|
+
const mainnetDetect = AddressVerificator.detectAddressType(mainnetAddr, networks.bitcoin);
|
|
171
|
+
console.log('Mainnet on mainnet:', mainnetDetect); // AddressTypes.P2TR
|
|
172
|
+
|
|
173
|
+
// Mainnet address on wrong network
|
|
174
|
+
const wrongNetwork = AddressVerificator.detectAddressType(mainnetAddr, networks.testnet);
|
|
175
|
+
console.log('Mainnet on testnet:', wrongNetwork); // null
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## Classical Address Validation
|
|
179
|
+
|
|
180
|
+
### Validating Classical Public Keys
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { AddressVerificator } from '@btc-vision/transaction';
|
|
184
|
+
import { networks } from '@btc-vision/bitcoin';
|
|
185
|
+
|
|
186
|
+
const wallet = mnemonic.derive(0);
|
|
187
|
+
|
|
188
|
+
// Validate compressed public key (33 bytes)
|
|
189
|
+
const compressedKey = wallet.toPublicKeyHex();
|
|
190
|
+
const isValid = AddressVerificator.isValidPublicKey(compressedKey, networks.bitcoin);
|
|
191
|
+
console.log('Compressed key valid:', isValid); // true
|
|
192
|
+
|
|
193
|
+
// Validate uncompressed public key (65 bytes)
|
|
194
|
+
const uncompressedKey = wallet.toUncompressedPublicKey().toString('hex');
|
|
195
|
+
const isUncompressedValid = AddressVerificator.isValidPublicKey(uncompressedKey, networks.bitcoin);
|
|
196
|
+
console.log('Uncompressed key valid:', isUncompressedValid); // true
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Validating Other Address Types
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
// P2TR validation
|
|
203
|
+
const p2tr = wallet.p2tr;
|
|
204
|
+
const isP2TRValid = AddressVerificator.isValidP2TRAddress(p2tr, networks.bitcoin);
|
|
205
|
+
console.log('P2TR valid:', isP2TRValid); // true
|
|
206
|
+
|
|
207
|
+
// P2WPKH validation
|
|
208
|
+
const p2wpkh = wallet.p2wpkh;
|
|
209
|
+
const isP2WPKHValid = AddressVerificator.isP2WPKHAddress(p2wpkh, networks.bitcoin);
|
|
210
|
+
console.log('P2WPKH valid:', isP2WPKHValid); // true
|
|
211
|
+
|
|
212
|
+
// P2PKH or P2SH validation
|
|
213
|
+
const p2pkh = wallet.p2pkh;
|
|
214
|
+
const isLegacyValid = AddressVerificator.isP2PKHOrP2SH(p2pkh, networks.bitcoin);
|
|
215
|
+
console.log('Legacy valid:', isLegacyValid); // true
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Complete Validation Example
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
import {
|
|
222
|
+
Mnemonic,
|
|
223
|
+
AddressVerificator,
|
|
224
|
+
AddressTypes,
|
|
225
|
+
MLDSASecurityLevel,
|
|
226
|
+
} from '@btc-vision/transaction';
|
|
227
|
+
import { networks } from '@btc-vision/bitcoin';
|
|
228
|
+
|
|
229
|
+
// Generate wallet
|
|
230
|
+
const mnemonic = Mnemonic.generate(undefined, '', networks.bitcoin, MLDSASecurityLevel.LEVEL2);
|
|
231
|
+
const wallet = mnemonic.derive(0);
|
|
232
|
+
|
|
233
|
+
console.log('=== ML-DSA Public Key Validation ===');
|
|
234
|
+
|
|
235
|
+
// Validate quantum public key
|
|
236
|
+
const quantumKeyHex = wallet.quantumPublicKeyHex;
|
|
237
|
+
const quantumKeyBuffer = wallet.quantumPublicKey;
|
|
238
|
+
|
|
239
|
+
const securityLevelFromHex = AddressVerificator.isValidMLDSAPublicKey(quantumKeyHex);
|
|
240
|
+
const securityLevelFromBuffer = AddressVerificator.isValidMLDSAPublicKey(quantumKeyBuffer);
|
|
241
|
+
|
|
242
|
+
console.log('Hex validation:', securityLevelFromHex); // MLDSASecurityLevel.LEVEL2
|
|
243
|
+
console.log('Buffer validation:', securityLevelFromBuffer); // MLDSASecurityLevel.LEVEL2
|
|
244
|
+
console.log('Matches wallet:', securityLevelFromHex === wallet.securityLevel); // true
|
|
245
|
+
|
|
246
|
+
console.log('\n=== Address Type Detection ===');
|
|
247
|
+
|
|
248
|
+
// Detect all address types
|
|
249
|
+
const addresses = {
|
|
250
|
+
p2tr: wallet.p2tr,
|
|
251
|
+
p2wpkh: wallet.p2wpkh,
|
|
252
|
+
p2pkh: wallet.p2pkh,
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
for (const [name, addr] of Object.entries(addresses)) {
|
|
256
|
+
const type = AddressVerificator.detectAddressType(addr, networks.bitcoin);
|
|
257
|
+
console.log(`${name}: ${type}`);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
console.log('\n=== Classical Key Validation ===');
|
|
261
|
+
|
|
262
|
+
// Validate classical public key
|
|
263
|
+
const classicalKey = wallet.toPublicKeyHex();
|
|
264
|
+
const isClassicalValid = AddressVerificator.isValidPublicKey(classicalKey, networks.bitcoin);
|
|
265
|
+
|
|
266
|
+
console.log('Classical key:', classicalKey);
|
|
267
|
+
console.log('Classical valid:', isClassicalValid); // true
|
|
268
|
+
|
|
269
|
+
console.log('\n=== Cross-Network Validation ===');
|
|
270
|
+
|
|
271
|
+
// Test network mismatch
|
|
272
|
+
const mainnetP2TR = wallet.p2tr;
|
|
273
|
+
const testnetMnemonic = Mnemonic.generate(undefined, '', networks.testnet, MLDSASecurityLevel.LEVEL2);
|
|
274
|
+
const testnetWallet = testnetMnemonic.derive(0);
|
|
275
|
+
const testnetP2TR = testnetWallet.p2tr;
|
|
276
|
+
|
|
277
|
+
const mainnetType = AddressVerificator.detectAddressType(mainnetP2TR, networks.bitcoin);
|
|
278
|
+
const wrongNetworkType = AddressVerificator.detectAddressType(mainnetP2TR, networks.testnet);
|
|
279
|
+
|
|
280
|
+
console.log('Mainnet P2TR on mainnet:', mainnetType); // AddressTypes.P2TR
|
|
281
|
+
console.log('Mainnet P2TR on testnet:', wrongNetworkType); // null
|
|
282
|
+
|
|
283
|
+
console.log('\n=== Complete Wallet Validation ===');
|
|
284
|
+
|
|
285
|
+
function validateWallet(wallet: any, network: any): boolean {
|
|
286
|
+
// Validate quantum key
|
|
287
|
+
const quantumValid = AddressVerificator.isValidMLDSAPublicKey(
|
|
288
|
+
wallet.quantumPublicKey
|
|
289
|
+
) !== null;
|
|
290
|
+
|
|
291
|
+
// Validate classical key
|
|
292
|
+
const classicalValid = AddressVerificator.isValidPublicKey(
|
|
293
|
+
wallet.toPublicKeyHex(),
|
|
294
|
+
network
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
return quantumValid && classicalValid;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
const isWalletValid = validateWallet(wallet, networks.bitcoin);
|
|
301
|
+
console.log('Complete wallet validation:', isWalletValid); // true
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
## Next Steps
|
|
305
|
+
|
|
306
|
+
- [Message Signing](./04-message-signing.md) - Sign and verify messages
|
|
307
|
+
- [Introduction](./01-introduction.md) - Back to overview
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# OPNet ML-DSA Quantum Support Documentation
|
|
2
|
+
|
|
3
|
+
Welcome to the OPNet ML-DSA (Post-Quantum Cryptography) documentation! This guide will help you integrate quantum-resistant signatures and addresses into your OPNet applications.
|
|
4
|
+
|
|
5
|
+
## Documentation Index
|
|
6
|
+
|
|
7
|
+
### [1. Introduction to ML-DSA](./01-introduction.md)
|
|
8
|
+
Learn about ML-DSA (Module-Lattice-Based Digital Signature Algorithm), the hybrid quantum-classical architecture, and when to use quantum-resistant cryptography.
|
|
9
|
+
|
|
10
|
+
**Topics covered:**
|
|
11
|
+
- What is ML-DSA and post-quantum cryptography
|
|
12
|
+
- Three security levels: **LEVEL2 (BIP360 RECOMMENDED DEFAULT)**, LEVEL3, LEVEL5
|
|
13
|
+
- Hybrid classical + quantum architecture
|
|
14
|
+
- Quick start guide
|
|
15
|
+
- When to use ML-DSA vs classical crypto
|
|
16
|
+
|
|
17
|
+
### [2. Mnemonic & Wallet Management](./02-mnemonic-and-wallet.md)
|
|
18
|
+
Complete guide to generating and managing quantum-resistant wallets using BIP39 mnemonics and BIP360 quantum key derivation.
|
|
19
|
+
|
|
20
|
+
**Topics covered:**
|
|
21
|
+
- Generating new mnemonics with quantum support
|
|
22
|
+
- Loading existing mnemonics
|
|
23
|
+
- Deriving wallets (single and multiple)
|
|
24
|
+
- Wallet properties (classical and quantum keys)
|
|
25
|
+
- Security best practices
|
|
26
|
+
- Network awareness
|
|
27
|
+
- Advanced usage
|
|
28
|
+
|
|
29
|
+
### [3. Address Generation](./03-address-generation.md)
|
|
30
|
+
Learn to generate P2OP and classical Bitcoin addresses for all networks.
|
|
31
|
+
|
|
32
|
+
**Topics covered:**
|
|
33
|
+
- P2OP addresses (Pay-to-OPNet, for contract addresses)
|
|
34
|
+
- Classical addresses (P2TR, P2WPKH, P2PKH, P2SH)
|
|
35
|
+
- P2WDA (Witness Data Authentication)
|
|
36
|
+
- Network support (mainnet, testnet, regtest)
|
|
37
|
+
- Address comparison and ordering
|
|
38
|
+
- Time-locked addresses (CSV)
|
|
39
|
+
- Address caching
|
|
40
|
+
|
|
41
|
+
### [4. Message Signing](./04-message-signing.md)
|
|
42
|
+
Sign and verify messages using ML-DSA (quantum) and Schnorr (classical) signatures. Includes detailed explanation of `QuantumBIP32Factory.fromPublicKey()` usage for signature verification.
|
|
43
|
+
|
|
44
|
+
**Topics covered:**
|
|
45
|
+
- ML-DSA message signing and verification
|
|
46
|
+
- Schnorr message signing
|
|
47
|
+
- Multiple input formats (string, Buffer, Uint8Array, hex)
|
|
48
|
+
- Cross-format verification
|
|
49
|
+
- Tweaked signatures for Taproot
|
|
50
|
+
- Message hashing (SHA-256)
|
|
51
|
+
- Best practices
|
|
52
|
+
|
|
53
|
+
### [5. Address Verification](./05-address-verification.md)
|
|
54
|
+
Validate ML-DSA public keys and detect classical address types.
|
|
55
|
+
|
|
56
|
+
**Topics covered:**
|
|
57
|
+
- ML-DSA public key validation
|
|
58
|
+
- Address type detection
|
|
59
|
+
- Classical address validation
|
|
60
|
+
- Network-specific validation
|
|
61
|
+
- Complete validation examples
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
**Ready to get started?** Begin with the [Introduction](./01-introduction.md)!
|
package/gulpfile.js
CHANGED
|
@@ -13,8 +13,8 @@ process.on('uncaughtException', function (err) {
|
|
|
13
13
|
const tsProject = ts.createProject('tsconfig.json');
|
|
14
14
|
|
|
15
15
|
function buildESM() {
|
|
16
|
-
return
|
|
17
|
-
.src()
|
|
16
|
+
return gulp
|
|
17
|
+
.src(['src/**/*.ts', 'src/**/*.js', '!test/**/*'])
|
|
18
18
|
.pipe(gulpcache('ts-esm'))
|
|
19
19
|
.pipe(
|
|
20
20
|
logger({
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btc-vision/transaction",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.7.1",
|
|
5
5
|
"author": "BlobMaster41",
|
|
6
6
|
"description": "OPNet transaction library allows you to create and sign transactions for the OPNet network.",
|
|
7
7
|
"engines": {
|
|
@@ -61,19 +61,24 @@
|
|
|
61
61
|
"build": "gulp build",
|
|
62
62
|
"setup": "npm i && npm run build",
|
|
63
63
|
"browserBuild": "webpack --mode production",
|
|
64
|
-
"docs": "typedoc --out docs --exclude 'src/tests/*.ts' --tsconfig tsconfig.json --readme README.md --name OPNet --plugin typedoc-material-theme --themeColor '#cb9820' --exclude src/tests/test.ts --exclude src/index.ts src"
|
|
64
|
+
"docs": "typedoc --out docs --exclude 'src/tests/*.ts' --tsconfig tsconfig.json --readme README.md --name OPNet --plugin typedoc-material-theme --themeColor '#cb9820' --exclude src/tests/test.ts --exclude src/index.ts src",
|
|
65
|
+
"test": "npm run build && vitest run",
|
|
66
|
+
"test:watch": "npm run build && vitest",
|
|
67
|
+
"test:ui": "npm run build && vitest --ui",
|
|
68
|
+
"test:coverage": "npm run build && vitest run --coverage"
|
|
65
69
|
},
|
|
66
70
|
"devDependencies": {
|
|
67
|
-
"@babel/core": "^7.28.
|
|
71
|
+
"@babel/core": "^7.28.5",
|
|
68
72
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
69
|
-
"@babel/plugin-transform-runtime": "^7.28.
|
|
70
|
-
"@babel/preset-env": "^7.28.
|
|
73
|
+
"@babel/plugin-transform-runtime": "^7.28.5",
|
|
74
|
+
"@babel/preset-env": "^7.28.5",
|
|
71
75
|
"@babel/preset-flow": "^7.27.1",
|
|
72
|
-
"@babel/preset-react": "^7.
|
|
73
|
-
"@babel/preset-typescript": "^7.
|
|
74
|
-
"@types/node": "^24.
|
|
76
|
+
"@babel/preset-react": "^7.28.5",
|
|
77
|
+
"@babel/preset-typescript": "^7.28.5",
|
|
78
|
+
"@types/node": "^24.10.0",
|
|
75
79
|
"@types/sha.js": "^2.4.4",
|
|
76
|
-
"
|
|
80
|
+
"@vitest/ui": "^4.0.8",
|
|
81
|
+
"eslint": "^9.39.1",
|
|
77
82
|
"gulp": "^5.0.1",
|
|
78
83
|
"gulp-cached": "^1.1.1",
|
|
79
84
|
"gulp-typescript": "^6.0.0-alpha.1",
|
|
@@ -82,18 +87,21 @@
|
|
|
82
87
|
"prettier": "^3.6.2",
|
|
83
88
|
"stream-browserify": "^3.0.0",
|
|
84
89
|
"stream-http": "^3.2.0",
|
|
85
|
-
"typedoc": "^0.28.
|
|
86
|
-
"typescript-eslint": "^8.
|
|
90
|
+
"typedoc": "^0.28.14",
|
|
91
|
+
"typescript-eslint": "^8.46.3",
|
|
92
|
+
"vitest": "^4.0.8",
|
|
87
93
|
"webpack-cli": "^6.0.1"
|
|
88
94
|
},
|
|
89
95
|
"dependencies": {
|
|
90
96
|
"@babel/plugin-proposal-object-rest-spread": "^7.20.7",
|
|
91
97
|
"@bitcoinerlab/secp256k1": "^1.2.0",
|
|
98
|
+
"@btc-vision/bip32": "^6.0.3",
|
|
92
99
|
"@btc-vision/bitcoin": "^6.4.11",
|
|
93
100
|
"@btc-vision/bitcoin-rpc": "^1.0.5",
|
|
94
101
|
"@btc-vision/logger": "^1.0.7",
|
|
95
|
-
"@
|
|
96
|
-
"@
|
|
102
|
+
"@btc-vision/post-quantum": "^0.5.3",
|
|
103
|
+
"@eslint/js": "^9.39.1",
|
|
104
|
+
"@noble/secp256k1": "^3.0.0",
|
|
97
105
|
"assert": "^2.1.0",
|
|
98
106
|
"babel-loader": "^10.0.0",
|
|
99
107
|
"babel-plugin-transform-import-meta": "^2.3.3",
|
|
@@ -101,7 +109,7 @@
|
|
|
101
109
|
"babelify": "^10.0.0",
|
|
102
110
|
"bech32": "^2.0.0",
|
|
103
111
|
"bip174": "^2.1.1",
|
|
104
|
-
"
|
|
112
|
+
"bip39": "^3.1.0",
|
|
105
113
|
"browserify-zlib": "^0.2.0",
|
|
106
114
|
"buffer": "^6.0.3",
|
|
107
115
|
"ecpair": "^2.1.0",
|
|
@@ -110,9 +118,9 @@
|
|
|
110
118
|
"gulp-logger-new": "^1.0.1",
|
|
111
119
|
"process": "^0.11.10",
|
|
112
120
|
"sha.js": "^2.4.12",
|
|
113
|
-
"ts-loader": "^9.5.
|
|
121
|
+
"ts-loader": "^9.5.4",
|
|
114
122
|
"ts-node": "^10.9.2",
|
|
115
|
-
"typescript": "^5.9.
|
|
116
|
-
"webpack": "^5.
|
|
123
|
+
"typescript": "^5.9.3",
|
|
124
|
+
"webpack": "^5.102.1"
|
|
117
125
|
}
|
|
118
126
|
}
|
package/src/_version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.
|
|
1
|
+
export const version = '1.7.1';
|
|
@@ -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);
|
|
45
|
+
this.publicKey = Address.fromString(data.publicKey, data.classicPublicKey);
|
|
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);
|
|
79
|
+
this.publicKey = Address.fromString(data.publicKey, data.classicPublicKey);
|
|
80
80
|
this.solution = stringToBuffer(data.solution);
|
|
81
81
|
this.salt = stringToBuffer(data.salt);
|
|
82
82
|
this.graffiti = stringToBuffer(data.graffiti);
|
|
@@ -145,6 +145,7 @@ export class ChallengeSolution implements IChallengeSolution {
|
|
|
145
145
|
return {
|
|
146
146
|
epochNumber: this.epochNumber.toString(),
|
|
147
147
|
publicKey: this.publicKey.toHex(),
|
|
148
|
+
classicPublicKey: this.publicKey.tweakedToHex(),
|
|
148
149
|
solution: this.toHex(),
|
|
149
150
|
salt: '0x' + this.salt.toString('hex'),
|
|
150
151
|
graffiti: '0x' + this.graffiti.toString('hex'),
|
|
@@ -31,6 +31,7 @@ export interface RawChallengeVerification {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export interface RawChallengeSubmission {
|
|
34
|
+
readonly classicPublicKey: string;
|
|
34
35
|
readonly publicKey: string;
|
|
35
36
|
readonly solution: string;
|
|
36
37
|
readonly graffiti?: string;
|
|
@@ -46,6 +47,7 @@ export interface IChallengeSubmission {
|
|
|
46
47
|
|
|
47
48
|
export interface RawChallenge {
|
|
48
49
|
readonly epochNumber: string;
|
|
50
|
+
readonly classicPublicKey: string;
|
|
49
51
|
readonly publicKey: string;
|
|
50
52
|
readonly solution: string;
|
|
51
53
|
readonly salt: string;
|