@btc-vision/transaction 1.0.120 → 1.0.122
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 +29 -26
- 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 +43 -41
- 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.122";
|
package/build/_version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '1.0.
|
|
1
|
+
export const version = '1.0.122';
|
|
@@ -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,34 @@ 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
|
-
import { ADDRESS_BYTE_LENGTH } from '../utils/types.js';
|
|
15
14
|
import { AddressVerificator } from './AddressVerificator.js';
|
|
16
15
|
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
16
|
+
const hexPattern = /^[0-9a-fA-F]+$/;
|
|
17
|
+
const isHexadecimal = (input) => {
|
|
18
|
+
return hexPattern.test(input);
|
|
19
|
+
};
|
|
17
20
|
export class Address extends Uint8Array {
|
|
18
21
|
constructor(bytes) {
|
|
19
|
-
super(
|
|
20
|
-
this.isP2TROnly = false;
|
|
22
|
+
super(32);
|
|
21
23
|
_Address_p2tr.set(this, void 0);
|
|
22
24
|
_Address_network.set(this, void 0);
|
|
23
|
-
|
|
25
|
+
_Address_originalPublicKey.set(this, void 0);
|
|
26
|
+
_Address_keyPair.set(this, void 0);
|
|
24
27
|
if (!bytes) {
|
|
25
28
|
return;
|
|
26
29
|
}
|
|
27
30
|
this.set(bytes);
|
|
28
31
|
}
|
|
32
|
+
get originalPublicKey() {
|
|
33
|
+
return __classPrivateFieldGet(this, _Address_originalPublicKey, "f");
|
|
34
|
+
}
|
|
29
35
|
get keyPair() {
|
|
30
|
-
if (!this
|
|
36
|
+
if (!__classPrivateFieldGet(this, _Address_keyPair, "f")) {
|
|
31
37
|
throw new Error('Public key not set for address');
|
|
32
38
|
}
|
|
33
|
-
return this
|
|
34
|
-
}
|
|
35
|
-
get tweakedBytes() {
|
|
36
|
-
return __classPrivateFieldGet(this, _Address_tweakedBytes, "f") || this;
|
|
39
|
+
return __classPrivateFieldGet(this, _Address_keyPair, "f");
|
|
37
40
|
}
|
|
38
41
|
static dead() {
|
|
39
42
|
return Address.fromString('0x04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f');
|
|
@@ -45,6 +48,9 @@ export class Address extends Uint8Array {
|
|
|
45
48
|
if (pubKey.startsWith('0x')) {
|
|
46
49
|
pubKey = pubKey.slice(2);
|
|
47
50
|
}
|
|
51
|
+
if (!isHexadecimal(pubKey)) {
|
|
52
|
+
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.');
|
|
53
|
+
}
|
|
48
54
|
return new Address(Buffer.from(pubKey, 'hex'));
|
|
49
55
|
}
|
|
50
56
|
static wrap(bytes) {
|
|
@@ -57,24 +63,22 @@ export class Address extends Uint8Array {
|
|
|
57
63
|
return Buffer.from(this);
|
|
58
64
|
}
|
|
59
65
|
equals(a) {
|
|
60
|
-
const b = this
|
|
61
|
-
|
|
62
|
-
if (c.length !== b.length) {
|
|
66
|
+
const b = this;
|
|
67
|
+
if (a.length !== b.length) {
|
|
63
68
|
return false;
|
|
64
69
|
}
|
|
65
70
|
for (let i = 0; i < b.length; i++) {
|
|
66
|
-
if (b[i] !==
|
|
71
|
+
if (b[i] !== a[i]) {
|
|
67
72
|
return false;
|
|
68
73
|
}
|
|
69
74
|
}
|
|
70
75
|
return true;
|
|
71
76
|
}
|
|
72
77
|
lessThan(a) {
|
|
73
|
-
const b = this
|
|
74
|
-
const c = a.isP2TROnly ? a : __classPrivateFieldGet(a, _Address_tweakedBytes, "f");
|
|
78
|
+
const b = this;
|
|
75
79
|
for (let i = 0; i < 32; i++) {
|
|
76
80
|
const thisByte = b[i];
|
|
77
|
-
const aByte =
|
|
81
|
+
const aByte = a[i];
|
|
78
82
|
if (thisByte < aByte) {
|
|
79
83
|
return true;
|
|
80
84
|
}
|
|
@@ -85,11 +89,10 @@ export class Address extends Uint8Array {
|
|
|
85
89
|
return false;
|
|
86
90
|
}
|
|
87
91
|
greaterThan(a) {
|
|
88
|
-
const b = this
|
|
89
|
-
const c = a.isP2TROnly ? a : __classPrivateFieldGet(a, _Address_tweakedBytes, "f");
|
|
92
|
+
const b = this;
|
|
90
93
|
for (let i = 0; i < 32; i++) {
|
|
91
94
|
const thisByte = b[i];
|
|
92
|
-
const aByte =
|
|
95
|
+
const aByte = a[i];
|
|
93
96
|
if (thisByte > aByte) {
|
|
94
97
|
return true;
|
|
95
98
|
}
|
|
@@ -104,15 +107,15 @@ export class Address extends Uint8Array {
|
|
|
104
107
|
throw new Error(`Invalid public key length ${publicKey.length}`);
|
|
105
108
|
}
|
|
106
109
|
if (publicKey.length === 32) {
|
|
107
|
-
this.isP2TROnly = true;
|
|
108
110
|
const buf = Buffer.alloc(32);
|
|
109
111
|
buf.set(publicKey);
|
|
110
112
|
super.set(publicKey);
|
|
111
113
|
}
|
|
112
114
|
else {
|
|
113
|
-
this
|
|
114
|
-
__classPrivateFieldSet(this,
|
|
115
|
-
|
|
115
|
+
__classPrivateFieldSet(this, _Address_originalPublicKey, Uint8Array.from(publicKey), "f");
|
|
116
|
+
__classPrivateFieldSet(this, _Address_keyPair, EcKeyPair.fromPublicKey(__classPrivateFieldGet(this, _Address_originalPublicKey, "f")), "f");
|
|
117
|
+
const tweakedBytes = toXOnly(EcKeyPair.tweakPublicKey(Buffer.from(__classPrivateFieldGet(this, _Address_originalPublicKey, "f"))));
|
|
118
|
+
super.set(tweakedBytes);
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
isValid(network) {
|
|
@@ -137,7 +140,7 @@ export class Address extends Uint8Array {
|
|
|
137
140
|
if (__classPrivateFieldGet(this, _Address_p2tr, "f") && __classPrivateFieldGet(this, _Address_network, "f") === network) {
|
|
138
141
|
return __classPrivateFieldGet(this, _Address_p2tr, "f");
|
|
139
142
|
}
|
|
140
|
-
const p2trAddy = EcKeyPair.tweakedPubKeyBufferToAddress(this
|
|
143
|
+
const p2trAddy = EcKeyPair.tweakedPubKeyBufferToAddress(this, network);
|
|
141
144
|
if (p2trAddy) {
|
|
142
145
|
__classPrivateFieldSet(this, _Address_network, network, "f");
|
|
143
146
|
__classPrivateFieldSet(this, _Address_p2tr, p2trAddy, "f");
|
|
@@ -146,4 +149,4 @@ export class Address extends Uint8Array {
|
|
|
146
149
|
throw new Error('Public key not set');
|
|
147
150
|
}
|
|
148
151
|
}
|
|
149
|
-
_Address_p2tr = new WeakMap(), _Address_network = new WeakMap(),
|
|
152
|
+
_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.122",
|
|
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.122';
|
|
@@ -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
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
import { Network } from '@btc-vision/bitcoin';
|
|
2
2
|
import { EcKeyPair } from './EcKeyPair.js';
|
|
3
3
|
import { ECPairInterface } from 'ecpair';
|
|
4
|
-
import { ADDRESS_BYTE_LENGTH } from '../utils/types.js';
|
|
5
4
|
import { AddressVerificator } from './AddressVerificator.js';
|
|
6
5
|
import { toXOnly } from '@btc-vision/bitcoin/src/psbt/bip371.js';
|
|
7
6
|
|
|
7
|
+
const hexPattern = /^[0-9a-fA-F]+$/;
|
|
8
|
+
const isHexadecimal = (input: string): boolean => {
|
|
9
|
+
return hexPattern.test(input);
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Objects of type "Address" are the representation of tweaked public keys. They can be converted to different address formats.
|
|
14
|
+
* @category KeyPair
|
|
15
|
+
*/
|
|
8
16
|
export class Address extends Uint8Array {
|
|
9
|
-
private isP2TROnly: boolean = false;
|
|
10
17
|
#p2tr: string | undefined;
|
|
11
18
|
#network: Network | undefined;
|
|
12
|
-
#
|
|
19
|
+
#originalPublicKey: Uint8Array | undefined;
|
|
20
|
+
#keyPair: ECPairInterface | undefined;
|
|
13
21
|
|
|
14
22
|
public constructor(bytes?: ArrayLike<number>) {
|
|
15
|
-
super(
|
|
23
|
+
super(32);
|
|
16
24
|
|
|
17
25
|
if (!bytes) {
|
|
18
26
|
return;
|
|
@@ -21,25 +29,24 @@ export class Address extends Uint8Array {
|
|
|
21
29
|
this.set(bytes);
|
|
22
30
|
}
|
|
23
31
|
|
|
24
|
-
|
|
32
|
+
/**
|
|
33
|
+
* If available, this will return the original public key associated with the address.
|
|
34
|
+
* @returns {Uint8Array} The original public key used to create the address.
|
|
35
|
+
*/
|
|
36
|
+
public get originalPublicKey(): Uint8Array | undefined {
|
|
37
|
+
return this.#originalPublicKey;
|
|
38
|
+
}
|
|
25
39
|
|
|
26
40
|
/**
|
|
27
41
|
* Get the key pair for the address
|
|
42
|
+
* @description This is only for internal use. Please use address.tweakedBytes instead.
|
|
28
43
|
*/
|
|
29
|
-
|
|
30
|
-
if (!this
|
|
44
|
+
private get keyPair(): ECPairInterface {
|
|
45
|
+
if (!this.#keyPair) {
|
|
31
46
|
throw new Error('Public key not set for address');
|
|
32
47
|
}
|
|
33
48
|
|
|
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;
|
|
49
|
+
return this.#keyPair;
|
|
43
50
|
}
|
|
44
51
|
|
|
45
52
|
public static dead(): Address {
|
|
@@ -62,6 +69,12 @@ export class Address extends Uint8Array {
|
|
|
62
69
|
pubKey = pubKey.slice(2);
|
|
63
70
|
}
|
|
64
71
|
|
|
72
|
+
if (!isHexadecimal(pubKey)) {
|
|
73
|
+
throw new Error(
|
|
74
|
+
'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.',
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
65
78
|
return new Address(Buffer.from(pubKey, 'hex'));
|
|
66
79
|
}
|
|
67
80
|
|
|
@@ -91,15 +104,14 @@ export class Address extends Uint8Array {
|
|
|
91
104
|
}
|
|
92
105
|
|
|
93
106
|
public equals(a: Address): boolean {
|
|
94
|
-
const b = this
|
|
95
|
-
const c = a.isP2TROnly ? a : (a.#tweakedBytes as Uint8Array);
|
|
107
|
+
const b: Address = this as Address;
|
|
96
108
|
|
|
97
|
-
if (
|
|
109
|
+
if (a.length !== b.length) {
|
|
98
110
|
return false;
|
|
99
111
|
}
|
|
100
112
|
|
|
101
113
|
for (let i = 0; i < b.length; i++) {
|
|
102
|
-
if (b[i] !==
|
|
114
|
+
if (b[i] !== a[i]) {
|
|
103
115
|
return false;
|
|
104
116
|
}
|
|
105
117
|
}
|
|
@@ -112,13 +124,11 @@ export class Address extends Uint8Array {
|
|
|
112
124
|
* @returns {boolean} If bigger
|
|
113
125
|
*/
|
|
114
126
|
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);
|
|
127
|
+
const b: Address = this as Address;
|
|
118
128
|
|
|
119
129
|
for (let i = 0; i < 32; i++) {
|
|
120
130
|
const thisByte = b[i];
|
|
121
|
-
const aByte =
|
|
131
|
+
const aByte = a[i];
|
|
122
132
|
|
|
123
133
|
if (thisByte < aByte) {
|
|
124
134
|
return true; // this is less than a
|
|
@@ -136,12 +146,11 @@ export class Address extends Uint8Array {
|
|
|
136
146
|
*/
|
|
137
147
|
public greaterThan(a: Address): boolean {
|
|
138
148
|
// 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);
|
|
149
|
+
const b = this as Address;
|
|
141
150
|
|
|
142
151
|
for (let i = 0; i < 32; i++) {
|
|
143
152
|
const thisByte = b[i];
|
|
144
|
-
const aByte =
|
|
153
|
+
const aByte = a[i];
|
|
145
154
|
|
|
146
155
|
if (thisByte > aByte) {
|
|
147
156
|
return true; // this is greater than a
|
|
@@ -164,23 +173,19 @@ export class Address extends Uint8Array {
|
|
|
164
173
|
}
|
|
165
174
|
|
|
166
175
|
if (publicKey.length === 32) {
|
|
167
|
-
this.isP2TROnly = true;
|
|
168
|
-
|
|
169
176
|
const buf = Buffer.alloc(32);
|
|
170
177
|
buf.set(publicKey);
|
|
171
178
|
|
|
172
179
|
super.set(publicKey);
|
|
173
180
|
} else {
|
|
174
|
-
this
|
|
181
|
+
this.#originalPublicKey = Uint8Array.from(publicKey);
|
|
182
|
+
this.#keyPair = EcKeyPair.fromPublicKey(this.#originalPublicKey);
|
|
175
183
|
|
|
176
|
-
|
|
177
|
-
Buffer.from(
|
|
178
|
-
EcKeyPair.tweakPublicKey(this._keyPair.publicKey.toString('hex')),
|
|
179
|
-
'hex',
|
|
180
|
-
),
|
|
184
|
+
const tweakedBytes = toXOnly(
|
|
185
|
+
EcKeyPair.tweakPublicKey(Buffer.from(this.#originalPublicKey)),
|
|
181
186
|
);
|
|
182
|
-
|
|
183
|
-
super.set(
|
|
187
|
+
|
|
188
|
+
super.set(tweakedBytes);
|
|
184
189
|
}
|
|
185
190
|
}
|
|
186
191
|
|
|
@@ -237,10 +242,7 @@ export class Address extends Uint8Array {
|
|
|
237
242
|
return this.#p2tr;
|
|
238
243
|
}
|
|
239
244
|
|
|
240
|
-
const p2trAddy: string | undefined = EcKeyPair.tweakedPubKeyBufferToAddress(
|
|
241
|
-
this.isP2TROnly ? this : (this.#tweakedBytes as Uint8Array),
|
|
242
|
-
network,
|
|
243
|
-
);
|
|
245
|
+
const p2trAddy: string | undefined = EcKeyPair.tweakedPubKeyBufferToAddress(this, network);
|
|
244
246
|
|
|
245
247
|
if (p2trAddy) {
|
|
246
248
|
this.#network = network;
|