@btc-vision/transaction 1.0.120 → 1.0.121
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 -1
- package/browser/buffer/BinaryWriter.d.ts +1 -1
- package/browser/index.js +1 -1
- package/browser/keypair/Address.d.ts +2 -5
- package/browser/keypair/EcKeyPair.d.ts +1 -1
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/buffer/BinaryWriter.d.ts +1 -1
- package/build/buffer/BinaryWriter.js +4 -5
- package/build/keypair/Address.d.ts +2 -5
- package/build/keypair/Address.js +28 -24
- package/build/keypair/EcKeyPair.d.ts +1 -1
- package/build/keypair/EcKeyPair.js +14 -7
- package/build/keypair/Wallet.js +1 -1
- package/build/utils/BitcoinUtils.js +1 -5
- package/gulpfile.js +1 -1
- package/package.json +20 -20
- package/src/_version.ts +1 -1
- package/src/buffer/BinaryWriter.ts +5 -6
- package/src/keypair/Address.ts +41 -38
- package/src/keypair/EcKeyPair.ts +19 -11
- package/src/keypair/Wallet.ts +1 -4
- package/src/utils/BitcoinUtils.ts +3 -7
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { Network } from '@btc-vision/bitcoin';
|
|
2
|
-
import { ECPairInterface } from 'ecpair';
|
|
3
2
|
export declare class Address extends Uint8Array {
|
|
4
3
|
#private;
|
|
5
|
-
private isP2TROnly;
|
|
6
4
|
constructor(bytes?: ArrayLike<number>);
|
|
7
|
-
|
|
8
|
-
get keyPair()
|
|
9
|
-
get tweakedBytes(): Uint8Array;
|
|
5
|
+
get originalPublicKey(): Uint8Array | undefined;
|
|
6
|
+
private get keyPair();
|
|
10
7
|
static dead(): Address;
|
|
11
8
|
static fromString(pubKey: string): Address;
|
|
12
9
|
static wrap(bytes: ArrayLike<number>): Address;
|
|
@@ -14,7 +14,7 @@ export declare class EcKeyPair {
|
|
|
14
14
|
static tweakedPubKeyToAddress(tweakedPubKeyHex: string, network: Network): string;
|
|
15
15
|
static tweakedPubKeyBufferToAddress(tweakedPubKeyBuffer: Buffer | Uint8Array, network: Network): string;
|
|
16
16
|
static xOnlyTweakedPubKeyToAddress(tweakedPubKeyHex: string, network: Network): string;
|
|
17
|
-
static tweakPublicKey(compressedPubKeyHex: string):
|
|
17
|
+
static tweakPublicKey(compressedPubKeyHex: string | Buffer): Buffer;
|
|
18
18
|
static generateWallet(network?: Network): IWallet;
|
|
19
19
|
static verifyContractAddress(contractAddress: string, network?: Network): boolean;
|
|
20
20
|
static getLegacySegwitAddress(keyPair: ECPairInterface, network?: Network): string;
|
package/build/_version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "1.0.
|
|
1
|
+
export declare const version = "1.0.121";
|
package/build/_version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.0.
|
|
1
|
+
export const version = '1.0.121';
|
|
@@ -67,8 +67,8 @@ export class BinaryWriter {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
writeAddress(value) {
|
|
70
|
-
|
|
71
|
-
this.writeBytes(
|
|
70
|
+
this.verifyAddress(value);
|
|
71
|
+
this.writeBytes(value);
|
|
72
72
|
}
|
|
73
73
|
writeStringWithLength(value) {
|
|
74
74
|
this.allocSafe(value.length + 2);
|
|
@@ -239,11 +239,10 @@ export class BinaryWriter {
|
|
|
239
239
|
this.writeSelector(selector);
|
|
240
240
|
});
|
|
241
241
|
}
|
|
242
|
-
|
|
243
|
-
if (pubKey.
|
|
242
|
+
verifyAddress(pubKey) {
|
|
243
|
+
if (pubKey.byteLength > ADDRESS_BYTE_LENGTH) {
|
|
244
244
|
throw new Error(`Address is too long ${pubKey.byteLength} > ${ADDRESS_BYTE_LENGTH} bytes`);
|
|
245
245
|
}
|
|
246
|
-
return pubKey.tweakedBytes;
|
|
247
246
|
}
|
|
248
247
|
resize(size) {
|
|
249
248
|
const buf = new Uint8Array(this.buffer.byteLength + size);
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { Network } from '@btc-vision/bitcoin';
|
|
2
|
-
import { ECPairInterface } from 'ecpair';
|
|
3
2
|
export declare class Address extends Uint8Array {
|
|
4
3
|
#private;
|
|
5
|
-
private isP2TROnly;
|
|
6
4
|
constructor(bytes?: ArrayLike<number>);
|
|
7
|
-
|
|
8
|
-
get keyPair()
|
|
9
|
-
get tweakedBytes(): Uint8Array;
|
|
5
|
+
get originalPublicKey(): Uint8Array | undefined;
|
|
6
|
+
private get keyPair();
|
|
10
7
|
static dead(): Address;
|
|
11
8
|
static fromString(pubKey: string): Address;
|
|
12
9
|
static wrap(bytes: ArrayLike<number>): Address;
|
package/build/keypair/Address.js
CHANGED
|
@@ -9,31 +9,35 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
|
9
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
10
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
11
|
};
|
|
12
|
-
var _Address_p2tr, _Address_network,
|
|
12
|
+
var _Address_p2tr, _Address_network, _Address_originalPublicKey, _Address_keyPair;
|
|
13
13
|
import { EcKeyPair } from './EcKeyPair.js';
|
|
14
14
|
import { ADDRESS_BYTE_LENGTH } from '../utils/types.js';
|
|
15
15
|
import { AddressVerificator } from './AddressVerificator.js';
|
|
16
16
|
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
17
|
+
const hexPattern = /^[0-9a-fA-F]+$/;
|
|
18
|
+
const isHexadecimal = (input) => {
|
|
19
|
+
return hexPattern.test(input);
|
|
20
|
+
};
|
|
17
21
|
export class Address extends Uint8Array {
|
|
18
22
|
constructor(bytes) {
|
|
19
23
|
super(bytes?.length || ADDRESS_BYTE_LENGTH);
|
|
20
|
-
this.isP2TROnly = false;
|
|
21
24
|
_Address_p2tr.set(this, void 0);
|
|
22
25
|
_Address_network.set(this, void 0);
|
|
23
|
-
|
|
26
|
+
_Address_originalPublicKey.set(this, void 0);
|
|
27
|
+
_Address_keyPair.set(this, void 0);
|
|
24
28
|
if (!bytes) {
|
|
25
29
|
return;
|
|
26
30
|
}
|
|
27
31
|
this.set(bytes);
|
|
28
32
|
}
|
|
33
|
+
get originalPublicKey() {
|
|
34
|
+
return __classPrivateFieldGet(this, _Address_originalPublicKey, "f");
|
|
35
|
+
}
|
|
29
36
|
get keyPair() {
|
|
30
|
-
if (!this
|
|
37
|
+
if (!__classPrivateFieldGet(this, _Address_keyPair, "f")) {
|
|
31
38
|
throw new Error('Public key not set for address');
|
|
32
39
|
}
|
|
33
|
-
return this
|
|
34
|
-
}
|
|
35
|
-
get tweakedBytes() {
|
|
36
|
-
return __classPrivateFieldGet(this, _Address_tweakedBytes, "f") || this;
|
|
40
|
+
return __classPrivateFieldGet(this, _Address_keyPair, "f");
|
|
37
41
|
}
|
|
38
42
|
static dead() {
|
|
39
43
|
return Address.fromString('0x04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f');
|
|
@@ -45,6 +49,9 @@ export class Address extends Uint8Array {
|
|
|
45
49
|
if (pubKey.startsWith('0x')) {
|
|
46
50
|
pubKey = pubKey.slice(2);
|
|
47
51
|
}
|
|
52
|
+
if (!isHexadecimal(pubKey)) {
|
|
53
|
+
throw new Error('You must only pass public keys in hexadecimal format. If you have an address such as bc1q... you must convert it to a public key first. Please refer to await provider.getPublicKeyInfo("bc1q..."). If the public key associated with the address is not found, you must force the user to enter the destination public key. It looks like: 0x020373626d317ae8788ce3280b491068610d840c23ecb64c14075bbb9f670af52c.');
|
|
54
|
+
}
|
|
48
55
|
return new Address(Buffer.from(pubKey, 'hex'));
|
|
49
56
|
}
|
|
50
57
|
static wrap(bytes) {
|
|
@@ -57,24 +64,22 @@ export class Address extends Uint8Array {
|
|
|
57
64
|
return Buffer.from(this);
|
|
58
65
|
}
|
|
59
66
|
equals(a) {
|
|
60
|
-
const b = this
|
|
61
|
-
|
|
62
|
-
if (c.length !== b.length) {
|
|
67
|
+
const b = this;
|
|
68
|
+
if (a.length !== b.length) {
|
|
63
69
|
return false;
|
|
64
70
|
}
|
|
65
71
|
for (let i = 0; i < b.length; i++) {
|
|
66
|
-
if (b[i] !==
|
|
72
|
+
if (b[i] !== a[i]) {
|
|
67
73
|
return false;
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
76
|
return true;
|
|
71
77
|
}
|
|
72
78
|
lessThan(a) {
|
|
73
|
-
const b = this
|
|
74
|
-
const c = a.isP2TROnly ? a : __classPrivateFieldGet(a, _Address_tweakedBytes, "f");
|
|
79
|
+
const b = this;
|
|
75
80
|
for (let i = 0; i < 32; i++) {
|
|
76
81
|
const thisByte = b[i];
|
|
77
|
-
const aByte =
|
|
82
|
+
const aByte = a[i];
|
|
78
83
|
if (thisByte < aByte) {
|
|
79
84
|
return true;
|
|
80
85
|
}
|
|
@@ -85,11 +90,10 @@ export class Address extends Uint8Array {
|
|
|
85
90
|
return false;
|
|
86
91
|
}
|
|
87
92
|
greaterThan(a) {
|
|
88
|
-
const b = this
|
|
89
|
-
const c = a.isP2TROnly ? a : __classPrivateFieldGet(a, _Address_tweakedBytes, "f");
|
|
93
|
+
const b = this;
|
|
90
94
|
for (let i = 0; i < 32; i++) {
|
|
91
95
|
const thisByte = b[i];
|
|
92
|
-
const aByte =
|
|
96
|
+
const aByte = a[i];
|
|
93
97
|
if (thisByte > aByte) {
|
|
94
98
|
return true;
|
|
95
99
|
}
|
|
@@ -104,15 +108,15 @@ export class Address extends Uint8Array {
|
|
|
104
108
|
throw new Error(`Invalid public key length ${publicKey.length}`);
|
|
105
109
|
}
|
|
106
110
|
if (publicKey.length === 32) {
|
|
107
|
-
this.isP2TROnly = true;
|
|
108
111
|
const buf = Buffer.alloc(32);
|
|
109
112
|
buf.set(publicKey);
|
|
110
113
|
super.set(publicKey);
|
|
111
114
|
}
|
|
112
115
|
else {
|
|
113
|
-
this
|
|
114
|
-
__classPrivateFieldSet(this,
|
|
115
|
-
|
|
116
|
+
__classPrivateFieldSet(this, _Address_originalPublicKey, Uint8Array.from(publicKey), "f");
|
|
117
|
+
__classPrivateFieldSet(this, _Address_keyPair, EcKeyPair.fromPublicKey(__classPrivateFieldGet(this, _Address_originalPublicKey, "f")), "f");
|
|
118
|
+
const tweakedBytes = toXOnly(EcKeyPair.tweakPublicKey(Buffer.from(__classPrivateFieldGet(this, _Address_originalPublicKey, "f"))));
|
|
119
|
+
super.set(tweakedBytes);
|
|
116
120
|
}
|
|
117
121
|
}
|
|
118
122
|
isValid(network) {
|
|
@@ -137,7 +141,7 @@ export class Address extends Uint8Array {
|
|
|
137
141
|
if (__classPrivateFieldGet(this, _Address_p2tr, "f") && __classPrivateFieldGet(this, _Address_network, "f") === network) {
|
|
138
142
|
return __classPrivateFieldGet(this, _Address_p2tr, "f");
|
|
139
143
|
}
|
|
140
|
-
const p2trAddy = EcKeyPair.tweakedPubKeyBufferToAddress(this
|
|
144
|
+
const p2trAddy = EcKeyPair.tweakedPubKeyBufferToAddress(this, network);
|
|
141
145
|
if (p2trAddy) {
|
|
142
146
|
__classPrivateFieldSet(this, _Address_network, network, "f");
|
|
143
147
|
__classPrivateFieldSet(this, _Address_p2tr, p2trAddy, "f");
|
|
@@ -146,4 +150,4 @@ export class Address extends Uint8Array {
|
|
|
146
150
|
throw new Error('Public key not set');
|
|
147
151
|
}
|
|
148
152
|
}
|
|
149
|
-
_Address_p2tr = new WeakMap(), _Address_network = new WeakMap(),
|
|
153
|
+
_Address_p2tr = new WeakMap(), _Address_network = new WeakMap(), _Address_originalPublicKey = new WeakMap(), _Address_keyPair = new WeakMap();
|
|
@@ -14,7 +14,7 @@ export declare class EcKeyPair {
|
|
|
14
14
|
static tweakedPubKeyToAddress(tweakedPubKeyHex: string, network: Network): string;
|
|
15
15
|
static tweakedPubKeyBufferToAddress(tweakedPubKeyBuffer: Buffer | Uint8Array, network: Network): string;
|
|
16
16
|
static xOnlyTweakedPubKeyToAddress(tweakedPubKeyHex: string, network: Network): string;
|
|
17
|
-
static tweakPublicKey(compressedPubKeyHex: string):
|
|
17
|
+
static tweakPublicKey(compressedPubKeyHex: string | Buffer): Buffer;
|
|
18
18
|
static generateWallet(network?: Network): IWallet;
|
|
19
19
|
static verifyContractAddress(contractAddress: string, network?: Network): boolean;
|
|
20
20
|
static getLegacySegwitAddress(keyPair: ECPairInterface, network?: Network): string;
|
|
@@ -3,13 +3,17 @@ import bip32, { BIP32Factory } from 'bip32';
|
|
|
3
3
|
import { address, initEccLib, networks, payments } from '@btc-vision/bitcoin';
|
|
4
4
|
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
5
5
|
import { ECPairFactory } from 'ecpair';
|
|
6
|
-
import { CURVE, Point
|
|
6
|
+
import { CURVE, ProjectivePoint as Point } from '@noble/secp256k1';
|
|
7
7
|
import { taggedHash } from '@btc-vision/bitcoin/src/crypto.js';
|
|
8
8
|
initEccLib(ecc);
|
|
9
9
|
const BIP32factory = typeof bip32 === 'function' ? bip32 : BIP32Factory;
|
|
10
10
|
if (!BIP32factory) {
|
|
11
11
|
throw new Error('Failed to load BIP32 library');
|
|
12
12
|
}
|
|
13
|
+
const mod = (a, b) => {
|
|
14
|
+
const result = a % b;
|
|
15
|
+
return result >= 0n ? result : result + b;
|
|
16
|
+
};
|
|
13
17
|
export class EcKeyPair {
|
|
14
18
|
static fromWIF(wif, network = networks.bitcoin) {
|
|
15
19
|
return this.ECPair.fromWIF(wif, network);
|
|
@@ -89,18 +93,21 @@ export class EcKeyPair {
|
|
|
89
93
|
return address;
|
|
90
94
|
}
|
|
91
95
|
static tweakPublicKey(compressedPubKeyHex) {
|
|
92
|
-
if (compressedPubKeyHex.startsWith('0x')) {
|
|
96
|
+
if (typeof compressedPubKeyHex === 'string' && compressedPubKeyHex.startsWith('0x')) {
|
|
93
97
|
compressedPubKeyHex = compressedPubKeyHex.slice(2);
|
|
94
98
|
}
|
|
99
|
+
if (typeof compressedPubKeyHex !== 'string') {
|
|
100
|
+
compressedPubKeyHex = compressedPubKeyHex.toString('hex');
|
|
101
|
+
}
|
|
95
102
|
let P = Point.fromHex(compressedPubKeyHex);
|
|
96
|
-
if (
|
|
103
|
+
if ((P.y & 1n) !== 0n) {
|
|
97
104
|
P = P.negate();
|
|
98
105
|
}
|
|
99
106
|
const x = P.toRawBytes(true).slice(1);
|
|
100
107
|
const tHash = taggedHash('TapTweak', Buffer.from(x));
|
|
101
|
-
const t =
|
|
102
|
-
const Q = P.add(Point.BASE.
|
|
103
|
-
return Q.
|
|
108
|
+
const t = mod(BigInt('0x' + Buffer.from(tHash).toString('hex')), CURVE.n);
|
|
109
|
+
const Q = P.add(Point.BASE.mul(t));
|
|
110
|
+
return Buffer.from(Q.toRawBytes(true));
|
|
104
111
|
}
|
|
105
112
|
static generateWallet(network = networks.bitcoin) {
|
|
106
113
|
const keyPair = this.ECPair.makeRandom({
|
|
@@ -176,7 +183,7 @@ export class EcKeyPair {
|
|
|
176
183
|
const privKey = fromSeed.privateKey;
|
|
177
184
|
if (!privKey)
|
|
178
185
|
throw new Error('Failed to generate key pair');
|
|
179
|
-
return this.ECPair.fromPrivateKey(privKey, { network });
|
|
186
|
+
return this.ECPair.fromPrivateKey(Buffer.from(privKey), { network });
|
|
180
187
|
}
|
|
181
188
|
}
|
|
182
189
|
EcKeyPair.BIP32 = BIP32factory(ecc);
|
package/build/keypair/Wallet.js
CHANGED
|
@@ -10,7 +10,7 @@ export class Wallet {
|
|
|
10
10
|
this._p2tr = EcKeyPair.getTaprootAddress(this._keypair, this.network);
|
|
11
11
|
this._legacy = EcKeyPair.getLegacyAddress(this._keypair, this.network);
|
|
12
12
|
this._segwitLegacy = EcKeyPair.getLegacySegwitAddress(this._keypair, this.network);
|
|
13
|
-
this._tweakedKey =
|
|
13
|
+
this._tweakedKey = EcKeyPair.tweakPublicKey(this._keypair.publicKey.toString('hex'));
|
|
14
14
|
this._bufferPubKey = this._keypair.publicKey;
|
|
15
15
|
this._address = new Address(this._keypair.publicKey);
|
|
16
16
|
}
|
|
@@ -19,11 +19,7 @@ export class BitcoinUtils {
|
|
|
19
19
|
return Buffer.from(array);
|
|
20
20
|
}
|
|
21
21
|
else {
|
|
22
|
-
|
|
23
|
-
for (let i = 0; i < length; i++) {
|
|
24
|
-
randomValues.push(Math.floor(Math.random() * 256));
|
|
25
|
-
}
|
|
26
|
-
return Buffer.from(randomValues);
|
|
22
|
+
throw new Error('No secure random number generator available. Please upgrade your environment.');
|
|
27
23
|
}
|
|
28
24
|
}
|
|
29
25
|
static opnetHash(data) {
|
package/gulpfile.js
CHANGED
|
@@ -3,7 +3,7 @@ import gulp from 'gulp';
|
|
|
3
3
|
import gulpcache from 'gulp-cached';
|
|
4
4
|
|
|
5
5
|
import gulpClean from 'gulp-clean';
|
|
6
|
-
import logger from 'gulp-logger';
|
|
6
|
+
import logger from 'gulp-logger-new';
|
|
7
7
|
import ts from 'gulp-typescript';
|
|
8
8
|
|
|
9
9
|
process.on('uncaughtException', function (err) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btc-vision/transaction",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.121",
|
|
5
5
|
"author": "BlobMaster41",
|
|
6
6
|
"description": "OPNet transaction library allows you to create and sign transactions for the OPNet network.",
|
|
7
7
|
"engines": {
|
|
@@ -64,29 +64,28 @@
|
|
|
64
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
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@babel/core": "^7.
|
|
67
|
+
"@babel/core": "^7.26.0",
|
|
68
68
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
69
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
70
|
-
"@babel/preset-env": "^7.
|
|
71
|
-
"@babel/preset-flow": "^7.
|
|
72
|
-
"@babel/preset-react": "^7.
|
|
73
|
-
"@babel/preset-typescript": "^7.
|
|
74
|
-
"@types/node": "^22.
|
|
69
|
+
"@babel/plugin-transform-runtime": "^7.25.9",
|
|
70
|
+
"@babel/preset-env": "^7.26.0",
|
|
71
|
+
"@babel/preset-flow": "^7.25.9",
|
|
72
|
+
"@babel/preset-react": "^7.25.9",
|
|
73
|
+
"@babel/preset-typescript": "^7.26.0",
|
|
74
|
+
"@types/node": "^22.8.7",
|
|
75
75
|
"@types/sha.js": "^2.4.4",
|
|
76
|
-
"eslint": "^9.
|
|
76
|
+
"eslint": "^9.14.0",
|
|
77
77
|
"gulp": "^5.0.0",
|
|
78
78
|
"gulp-cached": "^1.1.1",
|
|
79
|
-
"gulp-logger": "^0.0.2",
|
|
80
79
|
"gulp-typescript": "^6.0.0-alpha.1",
|
|
81
80
|
"https-browserify": "^1.0.0",
|
|
82
81
|
"os-browserify": "^0.3.0",
|
|
83
|
-
"prettier": "^3.3.
|
|
82
|
+
"prettier": "^3.3.3",
|
|
84
83
|
"stream-browserify": "^3.0.0",
|
|
85
84
|
"stream-http": "^3.2.0",
|
|
86
|
-
"typedoc": "^0.26.
|
|
85
|
+
"typedoc": "^0.26.11",
|
|
87
86
|
"typedoc-material-theme": "^1.1.0",
|
|
88
|
-
"typescript-eslint": "^8.
|
|
89
|
-
"webpack": "^5.
|
|
87
|
+
"typescript-eslint": "^8.13.0",
|
|
88
|
+
"webpack": "^5.96.1",
|
|
90
89
|
"webpack-cli": "^5.1.4"
|
|
91
90
|
},
|
|
92
91
|
"dependencies": {
|
|
@@ -95,25 +94,26 @@
|
|
|
95
94
|
"@btc-vision/bitcoin": "^6.3.0",
|
|
96
95
|
"@btc-vision/bsi-bitcoin-rpc": "^1.0.29",
|
|
97
96
|
"@btc-vision/logger": "^1.0.6",
|
|
98
|
-
"@eslint/js": "^9.
|
|
99
|
-
"@noble/secp256k1": "^1.
|
|
97
|
+
"@eslint/js": "^9.14.0",
|
|
98
|
+
"@noble/secp256k1": "^2.1.0",
|
|
100
99
|
"assert": "^2.1.0",
|
|
101
|
-
"babel-loader": "^9.1
|
|
100
|
+
"babel-loader": "^9.2.1",
|
|
102
101
|
"babel-plugin-transform-import-meta": "^2.2.1",
|
|
103
102
|
"babel-preset-react": "^6.24.1",
|
|
104
103
|
"babelify": "^10.0.0",
|
|
105
104
|
"bech32": "^2.0.0",
|
|
106
105
|
"bignumber.js": "^9.1.2",
|
|
107
|
-
"bip32": "^
|
|
106
|
+
"bip32": "^5.0.0-rc.0",
|
|
108
107
|
"browserify-zlib": "^0.2.0",
|
|
109
108
|
"buffer": "^6.0.3",
|
|
110
109
|
"ecpair": "^2.1.0",
|
|
111
110
|
"gulp-clean": "^0.4.0",
|
|
112
|
-
"gulp-eslint-new": "^2.
|
|
111
|
+
"gulp-eslint-new": "^2.4.0",
|
|
112
|
+
"gulp-logger-new": "^1.0.1",
|
|
113
113
|
"process": "^0.11.10",
|
|
114
114
|
"sha.js": "^2.4.11",
|
|
115
115
|
"ts-loader": "^9.5.1",
|
|
116
116
|
"ts-node": "^10.9.2",
|
|
117
|
-
"typescript": "^5.6.
|
|
117
|
+
"typescript": "^5.6.3"
|
|
118
118
|
}
|
|
119
119
|
}
|
package/src/_version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.0.
|
|
1
|
+
export const version = '1.0.121';
|
|
@@ -90,8 +90,9 @@ export class BinaryWriter {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
public writeAddress(value: Address): void {
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
this.verifyAddress(value);
|
|
94
|
+
|
|
95
|
+
this.writeBytes(value);
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
public writeStringWithLength(value: string): void {
|
|
@@ -305,14 +306,12 @@ export class BinaryWriter {
|
|
|
305
306
|
});
|
|
306
307
|
}
|
|
307
308
|
|
|
308
|
-
private
|
|
309
|
-
if (pubKey.
|
|
309
|
+
private verifyAddress(pubKey: Address): void {
|
|
310
|
+
if (pubKey.byteLength > ADDRESS_BYTE_LENGTH) {
|
|
310
311
|
throw new Error(
|
|
311
312
|
`Address is too long ${pubKey.byteLength} > ${ADDRESS_BYTE_LENGTH} bytes`,
|
|
312
313
|
);
|
|
313
314
|
}
|
|
314
|
-
|
|
315
|
-
return pubKey.tweakedBytes;
|
|
316
315
|
}
|
|
317
316
|
|
|
318
317
|
private resize(size: u32): void {
|
package/src/keypair/Address.ts
CHANGED
|
@@ -5,11 +5,20 @@ import { ADDRESS_BYTE_LENGTH } from '../utils/types.js';
|
|
|
5
5
|
import { AddressVerificator } from './AddressVerificator.js';
|
|
6
6
|
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
7
7
|
|
|
8
|
+
const hexPattern = /^[0-9a-fA-F]+$/;
|
|
9
|
+
const isHexadecimal = (input: string): boolean => {
|
|
10
|
+
return hexPattern.test(input);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Objects of type "Address" are the representation of tweaked public keys. They can be converted to different address formats.
|
|
15
|
+
* @category KeyPair
|
|
16
|
+
*/
|
|
8
17
|
export class Address extends Uint8Array {
|
|
9
|
-
private isP2TROnly: boolean = false;
|
|
10
18
|
#p2tr: string | undefined;
|
|
11
19
|
#network: Network | undefined;
|
|
12
|
-
#
|
|
20
|
+
#originalPublicKey: Uint8Array | undefined;
|
|
21
|
+
#keyPair: ECPairInterface | undefined;
|
|
13
22
|
|
|
14
23
|
public constructor(bytes?: ArrayLike<number>) {
|
|
15
24
|
super(bytes?.length || ADDRESS_BYTE_LENGTH);
|
|
@@ -21,25 +30,24 @@ export class Address extends Uint8Array {
|
|
|
21
30
|
this.set(bytes);
|
|
22
31
|
}
|
|
23
32
|
|
|
24
|
-
|
|
33
|
+
/**
|
|
34
|
+
* If available, this will return the original public key associated with the address.
|
|
35
|
+
* @returns {Uint8Array} The original public key used to create the address.
|
|
36
|
+
*/
|
|
37
|
+
public get originalPublicKey(): Uint8Array | undefined {
|
|
38
|
+
return this.#originalPublicKey;
|
|
39
|
+
}
|
|
25
40
|
|
|
26
41
|
/**
|
|
27
42
|
* Get the key pair for the address
|
|
43
|
+
* @description This is only for internal use. Please use address.tweakedBytes instead.
|
|
28
44
|
*/
|
|
29
|
-
|
|
30
|
-
if (!this
|
|
45
|
+
private get keyPair(): ECPairInterface {
|
|
46
|
+
if (!this.#keyPair) {
|
|
31
47
|
throw new Error('Public key not set for address');
|
|
32
48
|
}
|
|
33
49
|
|
|
34
|
-
return this
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Get the tweaked bytes
|
|
39
|
-
* @returns {Uint8Array} The tweaked bytes
|
|
40
|
-
*/
|
|
41
|
-
public get tweakedBytes(): Uint8Array {
|
|
42
|
-
return this.#tweakedBytes || this;
|
|
50
|
+
return this.#keyPair;
|
|
43
51
|
}
|
|
44
52
|
|
|
45
53
|
public static dead(): Address {
|
|
@@ -62,6 +70,12 @@ export class Address extends Uint8Array {
|
|
|
62
70
|
pubKey = pubKey.slice(2);
|
|
63
71
|
}
|
|
64
72
|
|
|
73
|
+
if (!isHexadecimal(pubKey)) {
|
|
74
|
+
throw new Error(
|
|
75
|
+
'You must only pass public keys in hexadecimal format. If you have an address such as bc1q... you must convert it to a public key first. Please refer to await provider.getPublicKeyInfo("bc1q..."). If the public key associated with the address is not found, you must force the user to enter the destination public key. It looks like: 0x020373626d317ae8788ce3280b491068610d840c23ecb64c14075bbb9f670af52c.',
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
65
79
|
return new Address(Buffer.from(pubKey, 'hex'));
|
|
66
80
|
}
|
|
67
81
|
|
|
@@ -91,15 +105,14 @@ export class Address extends Uint8Array {
|
|
|
91
105
|
}
|
|
92
106
|
|
|
93
107
|
public equals(a: Address): boolean {
|
|
94
|
-
const b = this
|
|
95
|
-
const c = a.isP2TROnly ? a : (a.#tweakedBytes as Uint8Array);
|
|
108
|
+
const b: Address = this as Address;
|
|
96
109
|
|
|
97
|
-
if (
|
|
110
|
+
if (a.length !== b.length) {
|
|
98
111
|
return false;
|
|
99
112
|
}
|
|
100
113
|
|
|
101
114
|
for (let i = 0; i < b.length; i++) {
|
|
102
|
-
if (b[i] !==
|
|
115
|
+
if (b[i] !== a[i]) {
|
|
103
116
|
return false;
|
|
104
117
|
}
|
|
105
118
|
}
|
|
@@ -112,13 +125,11 @@ export class Address extends Uint8Array {
|
|
|
112
125
|
* @returns {boolean} If bigger
|
|
113
126
|
*/
|
|
114
127
|
public lessThan(a: Address): boolean {
|
|
115
|
-
|
|
116
|
-
const b = this.isP2TROnly ? this : (this.#tweakedBytes as Uint8Array);
|
|
117
|
-
const c = a.isP2TROnly ? a : (a.#tweakedBytes as Uint8Array);
|
|
128
|
+
const b: Address = this as Address;
|
|
118
129
|
|
|
119
130
|
for (let i = 0; i < 32; i++) {
|
|
120
131
|
const thisByte = b[i];
|
|
121
|
-
const aByte =
|
|
132
|
+
const aByte = a[i];
|
|
122
133
|
|
|
123
134
|
if (thisByte < aByte) {
|
|
124
135
|
return true; // this is less than a
|
|
@@ -136,12 +147,11 @@ export class Address extends Uint8Array {
|
|
|
136
147
|
*/
|
|
137
148
|
public greaterThan(a: Address): boolean {
|
|
138
149
|
// Compare the two addresses byte-by-byte, treating them as big-endian uint256
|
|
139
|
-
const b = this
|
|
140
|
-
const c = a.isP2TROnly ? a : (a.#tweakedBytes as Uint8Array);
|
|
150
|
+
const b = this as Address;
|
|
141
151
|
|
|
142
152
|
for (let i = 0; i < 32; i++) {
|
|
143
153
|
const thisByte = b[i];
|
|
144
|
-
const aByte =
|
|
154
|
+
const aByte = a[i];
|
|
145
155
|
|
|
146
156
|
if (thisByte > aByte) {
|
|
147
157
|
return true; // this is greater than a
|
|
@@ -164,23 +174,19 @@ export class Address extends Uint8Array {
|
|
|
164
174
|
}
|
|
165
175
|
|
|
166
176
|
if (publicKey.length === 32) {
|
|
167
|
-
this.isP2TROnly = true;
|
|
168
|
-
|
|
169
177
|
const buf = Buffer.alloc(32);
|
|
170
178
|
buf.set(publicKey);
|
|
171
179
|
|
|
172
180
|
super.set(publicKey);
|
|
173
181
|
} else {
|
|
174
|
-
this
|
|
182
|
+
this.#originalPublicKey = Uint8Array.from(publicKey);
|
|
183
|
+
this.#keyPair = EcKeyPair.fromPublicKey(this.#originalPublicKey);
|
|
175
184
|
|
|
176
|
-
|
|
177
|
-
Buffer.from(
|
|
178
|
-
EcKeyPair.tweakPublicKey(this._keyPair.publicKey.toString('hex')),
|
|
179
|
-
'hex',
|
|
180
|
-
),
|
|
185
|
+
const tweakedBytes = toXOnly(
|
|
186
|
+
EcKeyPair.tweakPublicKey(Buffer.from(this.#originalPublicKey)),
|
|
181
187
|
);
|
|
182
188
|
|
|
183
|
-
super.set(
|
|
189
|
+
super.set(tweakedBytes);
|
|
184
190
|
}
|
|
185
191
|
}
|
|
186
192
|
|
|
@@ -237,10 +243,7 @@ export class Address extends Uint8Array {
|
|
|
237
243
|
return this.#p2tr;
|
|
238
244
|
}
|
|
239
245
|
|
|
240
|
-
const p2trAddy: string | undefined = EcKeyPair.tweakedPubKeyBufferToAddress(
|
|
241
|
-
this.isP2TROnly ? this : (this.#tweakedBytes as Uint8Array),
|
|
242
|
-
network,
|
|
243
|
-
);
|
|
246
|
+
const p2trAddy: string | undefined = EcKeyPair.tweakedPubKeyBufferToAddress(this, network);
|
|
244
247
|
|
|
245
248
|
if (p2trAddy) {
|
|
246
249
|
this.#network = network;
|