@btc-vision/transaction 1.6.1 → 1.6.5
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/epoch/ChallengeSolution.d.ts +3 -3
- package/browser/epoch/validator/EpochValidator.d.ts +5 -6
- package/browser/generators/builders/P2WDAGenerator.d.ts +13 -0
- package/browser/index.js +1 -1
- package/browser/keypair/Address.d.ts +3 -2
- package/browser/keypair/AddressVerificator.d.ts +13 -1
- package/browser/keypair/Wallet.d.ts +3 -0
- package/browser/opnet.d.ts +4 -0
- package/browser/p2wda/P2WDADetector.d.ts +16 -0
- package/browser/transaction/TransactionFactory.d.ts +3 -1
- package/browser/transaction/builders/DeploymentTransaction.d.ts +3 -3
- package/browser/transaction/builders/InteractionTransactionP2WDA.d.ts +37 -0
- package/browser/transaction/builders/SharedInteractionTransaction.d.ts +4 -4
- package/browser/transaction/builders/TransactionBuilder.d.ts +3 -0
- package/browser/transaction/interfaces/ITransactionParameters.d.ts +1 -0
- package/browser/transaction/mineable/IP2WSHAddress.d.ts +4 -0
- package/browser/transaction/mineable/TimelockGenerator.d.ts +2 -5
- package/browser/transaction/shared/TweakedTransaction.d.ts +23 -0
- package/build/_version.d.ts +1 -1
- package/build/_version.js +1 -1
- package/build/epoch/ChallengeSolution.d.ts +3 -3
- package/build/epoch/ChallengeSolution.js +3 -3
- package/build/epoch/validator/EpochValidator.d.ts +5 -6
- package/build/epoch/validator/EpochValidator.js +11 -12
- package/build/generators/builders/P2WDAGenerator.d.ts +13 -0
- package/build/generators/builders/P2WDAGenerator.js +62 -0
- package/build/keypair/Address.d.ts +3 -2
- package/build/keypair/Address.js +28 -2
- package/build/keypair/AddressVerificator.d.ts +13 -1
- package/build/keypair/AddressVerificator.js +82 -1
- package/build/keypair/Wallet.d.ts +3 -0
- package/build/keypair/Wallet.js +4 -0
- package/build/opnet.d.ts +4 -0
- package/build/opnet.js +4 -0
- package/build/p2wda/P2WDADetector.d.ts +16 -0
- package/build/p2wda/P2WDADetector.js +97 -0
- package/build/transaction/TransactionFactory.d.ts +3 -1
- package/build/transaction/TransactionFactory.js +35 -4
- package/build/transaction/builders/DeploymentTransaction.d.ts +3 -3
- package/build/transaction/builders/DeploymentTransaction.js +1 -1
- package/build/transaction/builders/InteractionTransactionP2WDA.d.ts +37 -0
- package/build/transaction/builders/InteractionTransactionP2WDA.js +205 -0
- package/build/transaction/builders/SharedInteractionTransaction.d.ts +4 -4
- package/build/transaction/builders/SharedInteractionTransaction.js +3 -3
- package/build/transaction/builders/TransactionBuilder.d.ts +3 -0
- package/build/transaction/builders/TransactionBuilder.js +18 -3
- package/build/transaction/interfaces/ITransactionParameters.d.ts +1 -0
- package/build/transaction/mineable/IP2WSHAddress.d.ts +4 -0
- package/build/transaction/mineable/IP2WSHAddress.js +1 -0
- package/build/transaction/mineable/TimelockGenerator.d.ts +2 -5
- package/build/transaction/shared/TweakedTransaction.d.ts +23 -0
- package/build/transaction/shared/TweakedTransaction.js +154 -18
- package/doc/README.md +0 -0
- package/doc/addresses/P2OP.md +1 -0
- package/doc/addresses/P2WDA.md +240 -0
- package/package.json +2 -2
- package/src/_version.ts +1 -1
- package/src/epoch/ChallengeSolution.ts +4 -4
- package/src/epoch/validator/EpochValidator.ts +12 -16
- package/src/generators/builders/P2WDAGenerator.ts +174 -0
- package/src/keypair/Address.ts +58 -3
- package/src/keypair/AddressVerificator.ts +147 -2
- package/src/keypair/Wallet.ts +16 -0
- package/src/opnet.ts +4 -0
- package/src/p2wda/P2WDADetector.ts +218 -0
- package/src/transaction/TransactionFactory.ts +79 -5
- package/src/transaction/builders/DeploymentTransaction.ts +4 -3
- package/src/transaction/builders/InteractionTransactionP2WDA.ts +376 -0
- package/src/transaction/builders/SharedInteractionTransaction.ts +7 -6
- package/src/transaction/builders/TransactionBuilder.ts +30 -3
- package/src/transaction/interfaces/ITransactionParameters.ts +1 -0
- package/src/transaction/mineable/IP2WSHAddress.ts +4 -0
- package/src/transaction/mineable/TimelockGenerator.ts +2 -6
- package/src/transaction/shared/TweakedTransaction.ts +246 -23
|
@@ -5,13 +5,25 @@ export declare enum AddressTypes {
|
|
|
5
5
|
P2SH_OR_P2SH_P2WPKH = "P2SH_OR_P2SH-P2WPKH",
|
|
6
6
|
P2PK = "P2PK",
|
|
7
7
|
P2TR = "P2TR",
|
|
8
|
-
P2WPKH = "P2WPKH"
|
|
8
|
+
P2WPKH = "P2WPKH",
|
|
9
|
+
P2WSH = "P2WSH",
|
|
10
|
+
P2WDA = "P2WDA"
|
|
11
|
+
}
|
|
12
|
+
export interface ValidatedP2WDAAddress {
|
|
13
|
+
readonly isValid: boolean;
|
|
14
|
+
readonly isPotentiallyP2WDA: boolean;
|
|
15
|
+
readonly isDefinitelyP2WDA: boolean;
|
|
16
|
+
readonly publicKey?: Buffer;
|
|
17
|
+
readonly error?: string;
|
|
9
18
|
}
|
|
10
19
|
export declare class AddressVerificator {
|
|
11
20
|
static isValidP2TRAddress(inAddress: string, network: Network): boolean;
|
|
12
21
|
static isP2WPKHAddress(inAddress: string, network: Network): boolean;
|
|
22
|
+
static isP2WDAWitnessScript(witnessScript: Buffer): boolean;
|
|
13
23
|
static isP2PKHOrP2SH(addy: string, network: Network): boolean;
|
|
14
24
|
static isValidPublicKey(input: string, network: Network): boolean;
|
|
15
25
|
static requireRedeemScript(addy: string, network: Network): boolean;
|
|
16
26
|
static detectAddressType(addy: string, network: Network): AddressTypes | null;
|
|
27
|
+
static detectAddressTypeWithWitnessScript(addy: string, network: Network, witnessScript?: Buffer): AddressTypes | null;
|
|
28
|
+
static validateP2WDAAddress(address: string, network: Network, witnessScript?: Buffer): ValidatedP2WDAAddress;
|
|
17
29
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { address, initEccLib } from '@btc-vision/bitcoin';
|
|
1
|
+
import { address, initEccLib, payments } from '@btc-vision/bitcoin';
|
|
2
2
|
import * as ecc from '@bitcoinerlab/secp256k1';
|
|
3
3
|
import { EcKeyPair } from './EcKeyPair.js';
|
|
4
4
|
import { BitcoinUtils } from '../utils/BitcoinUtils.js';
|
|
5
|
+
import { P2WDADetector } from '../p2wda/P2WDADetector.js';
|
|
5
6
|
initEccLib(ecc);
|
|
6
7
|
export var AddressTypes;
|
|
7
8
|
(function (AddressTypes) {
|
|
@@ -11,6 +12,8 @@ export var AddressTypes;
|
|
|
11
12
|
AddressTypes["P2PK"] = "P2PK";
|
|
12
13
|
AddressTypes["P2TR"] = "P2TR";
|
|
13
14
|
AddressTypes["P2WPKH"] = "P2WPKH";
|
|
15
|
+
AddressTypes["P2WSH"] = "P2WSH";
|
|
16
|
+
AddressTypes["P2WDA"] = "P2WDA";
|
|
14
17
|
})(AddressTypes || (AddressTypes = {}));
|
|
15
18
|
export class AddressVerificator {
|
|
16
19
|
static isValidP2TRAddress(inAddress, network) {
|
|
@@ -38,6 +41,9 @@ export class AddressVerificator {
|
|
|
38
41
|
catch { }
|
|
39
42
|
return isValidSegWitAddress;
|
|
40
43
|
}
|
|
44
|
+
static isP2WDAWitnessScript(witnessScript) {
|
|
45
|
+
return P2WDADetector.isP2WDAWitnessScript(witnessScript);
|
|
46
|
+
}
|
|
41
47
|
static isP2PKHOrP2SH(addy, network) {
|
|
42
48
|
try {
|
|
43
49
|
const decodedBase58 = address.fromBase58Check(addy);
|
|
@@ -112,6 +118,9 @@ export class AddressVerificator {
|
|
|
112
118
|
if (decodedBech32.version === 0 && decodedBech32.data.length === 20) {
|
|
113
119
|
return AddressTypes.P2WPKH;
|
|
114
120
|
}
|
|
121
|
+
if (decodedBech32.version === 0 && decodedBech32.data.length === 32) {
|
|
122
|
+
return AddressTypes.P2WSH;
|
|
123
|
+
}
|
|
115
124
|
if (decodedBech32.version === 1 && decodedBech32.data.length === 32) {
|
|
116
125
|
return AddressTypes.P2TR;
|
|
117
126
|
}
|
|
@@ -120,4 +129,76 @@ export class AddressVerificator {
|
|
|
120
129
|
catch { }
|
|
121
130
|
return null;
|
|
122
131
|
}
|
|
132
|
+
static detectAddressTypeWithWitnessScript(addy, network, witnessScript) {
|
|
133
|
+
const baseType = AddressVerificator.detectAddressType(addy, network);
|
|
134
|
+
if (baseType === AddressTypes.P2WSH && witnessScript) {
|
|
135
|
+
if (AddressVerificator.isP2WDAWitnessScript(witnessScript)) {
|
|
136
|
+
return AddressTypes.P2WDA;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return baseType;
|
|
140
|
+
}
|
|
141
|
+
static validateP2WDAAddress(address, network, witnessScript) {
|
|
142
|
+
try {
|
|
143
|
+
const addressType = AddressVerificator.detectAddressType(address, network);
|
|
144
|
+
if (addressType !== AddressTypes.P2WSH) {
|
|
145
|
+
return {
|
|
146
|
+
isValid: false,
|
|
147
|
+
isPotentiallyP2WDA: false,
|
|
148
|
+
isDefinitelyP2WDA: false,
|
|
149
|
+
error: 'Not a P2WSH address',
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
if (!witnessScript) {
|
|
153
|
+
return {
|
|
154
|
+
isValid: true,
|
|
155
|
+
isPotentiallyP2WDA: true,
|
|
156
|
+
isDefinitelyP2WDA: false,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
if (!AddressVerificator.isP2WDAWitnessScript(witnessScript)) {
|
|
160
|
+
return {
|
|
161
|
+
isValid: true,
|
|
162
|
+
isPotentiallyP2WDA: true,
|
|
163
|
+
isDefinitelyP2WDA: false,
|
|
164
|
+
error: 'Witness script does not match P2WDA pattern',
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
const p2wsh = payments.p2wsh({
|
|
168
|
+
redeem: { output: witnessScript },
|
|
169
|
+
network,
|
|
170
|
+
});
|
|
171
|
+
if (p2wsh.address !== address) {
|
|
172
|
+
return {
|
|
173
|
+
isValid: false,
|
|
174
|
+
isPotentiallyP2WDA: false,
|
|
175
|
+
isDefinitelyP2WDA: false,
|
|
176
|
+
error: 'Witness script does not match address',
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const publicKey = P2WDADetector.extractPublicKeyFromP2WDA(witnessScript);
|
|
180
|
+
if (!publicKey) {
|
|
181
|
+
return {
|
|
182
|
+
isValid: false,
|
|
183
|
+
isPotentiallyP2WDA: false,
|
|
184
|
+
isDefinitelyP2WDA: false,
|
|
185
|
+
error: 'Failed to extract public key from witness script',
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
return {
|
|
189
|
+
isValid: true,
|
|
190
|
+
isPotentiallyP2WDA: true,
|
|
191
|
+
isDefinitelyP2WDA: true,
|
|
192
|
+
publicKey,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
return {
|
|
197
|
+
isValid: false,
|
|
198
|
+
isPotentiallyP2WDA: false,
|
|
199
|
+
isDefinitelyP2WDA: false,
|
|
200
|
+
error: error.message,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
}
|
|
123
204
|
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { ECPairInterface } from 'ecpair';
|
|
2
2
|
import { Network } from '@btc-vision/bitcoin';
|
|
3
3
|
import { Address } from './Address.js';
|
|
4
|
+
import { IP2WSHAddress } from '../transaction/mineable/IP2WSHAddress.js';
|
|
4
5
|
export declare class Wallet {
|
|
5
6
|
readonly network: Network;
|
|
6
7
|
private readonly _keypair;
|
|
7
8
|
private readonly _p2wpkh;
|
|
8
9
|
private readonly _p2tr;
|
|
10
|
+
private readonly _p2wda;
|
|
9
11
|
private readonly _legacy;
|
|
10
12
|
private readonly _segwitLegacy;
|
|
11
13
|
private readonly _bufferPubKey;
|
|
@@ -17,6 +19,7 @@ export declare class Wallet {
|
|
|
17
19
|
get keypair(): ECPairInterface;
|
|
18
20
|
get p2wpkh(): string;
|
|
19
21
|
get p2tr(): string;
|
|
22
|
+
get p2wda(): IP2WSHAddress;
|
|
20
23
|
get legacy(): string;
|
|
21
24
|
get addresses(): string[];
|
|
22
25
|
get segwitLegacy(): string;
|
package/build/keypair/Wallet.js
CHANGED
|
@@ -20,6 +20,7 @@ export class Wallet {
|
|
|
20
20
|
this._p2wpkh = this._address.p2wpkh(this.network);
|
|
21
21
|
this._legacy = this._address.p2pkh(this.network);
|
|
22
22
|
this._segwitLegacy = this._address.p2wpkh(this.network);
|
|
23
|
+
this._p2wda = this._address.p2wda(this.network);
|
|
23
24
|
this._tweakedKey = this._address.toBuffer();
|
|
24
25
|
}
|
|
25
26
|
get address() {
|
|
@@ -39,6 +40,9 @@ export class Wallet {
|
|
|
39
40
|
get p2tr() {
|
|
40
41
|
return this._p2tr;
|
|
41
42
|
}
|
|
43
|
+
get p2wda() {
|
|
44
|
+
return this._p2wda;
|
|
45
|
+
}
|
|
42
46
|
get legacy() {
|
|
43
47
|
return this._legacy;
|
|
44
48
|
}
|
package/build/opnet.d.ts
CHANGED
|
@@ -6,9 +6,12 @@ export * from './generators/builders/CustomGenerator.js';
|
|
|
6
6
|
export * from './generators/builders/DeploymentGenerator.js';
|
|
7
7
|
export * from './generators/builders/LegacyCalldataGenerator.js';
|
|
8
8
|
export * from './generators/builders/MultiSignGenerator.js';
|
|
9
|
+
export * from './generators/builders/P2WDAGenerator.js';
|
|
9
10
|
export * from './generators/Features.js';
|
|
10
11
|
export * from './generators/Generator.js';
|
|
11
12
|
export * from './transaction/mineable/TimelockGenerator.js';
|
|
13
|
+
export * from './transaction/mineable/IP2WSHAddress.js';
|
|
14
|
+
export * from './p2wda/P2WDADetector.js';
|
|
12
15
|
export * from './generators/AddressGenerator.js';
|
|
13
16
|
export * from './verification/TapscriptVerificator.js';
|
|
14
17
|
export * from './keypair/AddressVerificator.js';
|
|
@@ -27,6 +30,7 @@ export * from './transaction/builders/CustomScriptTransaction.js';
|
|
|
27
30
|
export * from './transaction/builders/DeploymentTransaction.js';
|
|
28
31
|
export * from './transaction/builders/FundingTransaction.js';
|
|
29
32
|
export * from './transaction/builders/InteractionTransaction.js';
|
|
33
|
+
export * from './transaction/builders/InteractionTransactionP2WDA.js';
|
|
30
34
|
export * from './transaction/builders/MultiSignTransaction.js';
|
|
31
35
|
export * from './transaction/builders/SharedInteractionTransaction.js';
|
|
32
36
|
export * from './transaction/builders/TransactionBuilder.js';
|
package/build/opnet.js
CHANGED
|
@@ -5,9 +5,12 @@ export * from './generators/builders/CustomGenerator.js';
|
|
|
5
5
|
export * from './generators/builders/DeploymentGenerator.js';
|
|
6
6
|
export * from './generators/builders/LegacyCalldataGenerator.js';
|
|
7
7
|
export * from './generators/builders/MultiSignGenerator.js';
|
|
8
|
+
export * from './generators/builders/P2WDAGenerator.js';
|
|
8
9
|
export * from './generators/Features.js';
|
|
9
10
|
export * from './generators/Generator.js';
|
|
10
11
|
export * from './transaction/mineable/TimelockGenerator.js';
|
|
12
|
+
export * from './transaction/mineable/IP2WSHAddress.js';
|
|
13
|
+
export * from './p2wda/P2WDADetector.js';
|
|
11
14
|
export * from './generators/AddressGenerator.js';
|
|
12
15
|
export * from './verification/TapscriptVerificator.js';
|
|
13
16
|
export * from './keypair/AddressVerificator.js';
|
|
@@ -26,6 +29,7 @@ export * from './transaction/builders/CustomScriptTransaction.js';
|
|
|
26
29
|
export * from './transaction/builders/DeploymentTransaction.js';
|
|
27
30
|
export * from './transaction/builders/FundingTransaction.js';
|
|
28
31
|
export * from './transaction/builders/InteractionTransaction.js';
|
|
32
|
+
export * from './transaction/builders/InteractionTransactionP2WDA.js';
|
|
29
33
|
export * from './transaction/builders/MultiSignTransaction.js';
|
|
30
34
|
export * from './transaction/builders/SharedInteractionTransaction.js';
|
|
31
35
|
export * from './transaction/builders/TransactionBuilder.js';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import { Network } from '@btc-vision/bitcoin';
|
|
3
|
+
import { UTXO } from '../utxo/interfaces/IUTXO.js';
|
|
4
|
+
import { IP2WSHAddress } from '../transaction/mineable/IP2WSHAddress.js';
|
|
5
|
+
export declare class P2WDADetector {
|
|
6
|
+
static isP2WDAUTXO(utxo: UTXO): boolean;
|
|
7
|
+
static isP2WDAWitnessScript(witnessScript: Buffer): boolean;
|
|
8
|
+
static generateP2WDAAddress(publicKey: Buffer, network: Network): IP2WSHAddress & {
|
|
9
|
+
scriptPubKey: Buffer;
|
|
10
|
+
};
|
|
11
|
+
static extractPublicKeyFromP2WDA(witnessScript: Buffer): Buffer | null;
|
|
12
|
+
static createSimpleP2WDAWitness(transactionSignature: Buffer, witnessScript: Buffer): Buffer[];
|
|
13
|
+
static validateP2WDASignature(publicKey: Buffer, dataSignature: Buffer, operationData: Buffer): boolean;
|
|
14
|
+
static estimateP2WDAWitnessSize(dataSize?: number): number;
|
|
15
|
+
static couldBeP2WDA(scriptPubKey: Buffer): boolean;
|
|
16
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import { opcodes, payments, script } from '@btc-vision/bitcoin';
|
|
3
|
+
export class P2WDADetector {
|
|
4
|
+
static isP2WDAUTXO(utxo) {
|
|
5
|
+
if (!utxo.witnessScript) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
const witnessScript = Buffer.isBuffer(utxo.witnessScript)
|
|
9
|
+
? utxo.witnessScript
|
|
10
|
+
: Buffer.from(utxo.witnessScript, 'hex');
|
|
11
|
+
return this.isP2WDAWitnessScript(witnessScript);
|
|
12
|
+
}
|
|
13
|
+
static isP2WDAWitnessScript(witnessScript) {
|
|
14
|
+
try {
|
|
15
|
+
const decompiled = script.decompile(witnessScript);
|
|
16
|
+
if (!decompiled || decompiled.length !== 7) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
for (let i = 0; i < 5; i++) {
|
|
20
|
+
if (decompiled[i] !== opcodes.OP_2DROP) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return (Buffer.isBuffer(decompiled[5]) &&
|
|
25
|
+
decompiled[5].length === 33 &&
|
|
26
|
+
decompiled[6] === opcodes.OP_CHECKSIG);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
static generateP2WDAAddress(publicKey, network) {
|
|
33
|
+
if (publicKey.length !== 33) {
|
|
34
|
+
throw new Error('Public key must be 33 bytes (compressed)');
|
|
35
|
+
}
|
|
36
|
+
const witnessScript = script.compile([
|
|
37
|
+
opcodes.OP_2DROP,
|
|
38
|
+
opcodes.OP_2DROP,
|
|
39
|
+
opcodes.OP_2DROP,
|
|
40
|
+
opcodes.OP_2DROP,
|
|
41
|
+
opcodes.OP_2DROP,
|
|
42
|
+
publicKey,
|
|
43
|
+
opcodes.OP_CHECKSIG,
|
|
44
|
+
]);
|
|
45
|
+
const p2wsh = payments.p2wsh({
|
|
46
|
+
redeem: { output: witnessScript },
|
|
47
|
+
network,
|
|
48
|
+
});
|
|
49
|
+
if (!p2wsh.address || !p2wsh.output) {
|
|
50
|
+
throw new Error('Failed to generate P2WDA address');
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
address: p2wsh.address,
|
|
54
|
+
witnessScript,
|
|
55
|
+
scriptPubKey: p2wsh.output,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
static extractPublicKeyFromP2WDA(witnessScript) {
|
|
59
|
+
try {
|
|
60
|
+
const decompiled = script.decompile(witnessScript);
|
|
61
|
+
if (!decompiled || decompiled.length !== 7) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
for (let i = 0; i < 5; i++) {
|
|
65
|
+
if (decompiled[i] !== opcodes.OP_2DROP) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (Buffer.isBuffer(decompiled[5]) &&
|
|
70
|
+
decompiled[5].length === 33 &&
|
|
71
|
+
decompiled[6] === opcodes.OP_CHECKSIG) {
|
|
72
|
+
return decompiled[5];
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
static createSimpleP2WDAWitness(transactionSignature, witnessScript) {
|
|
81
|
+
const witnessStack = [transactionSignature];
|
|
82
|
+
for (let i = 0; i < 10; i++) {
|
|
83
|
+
witnessStack.push(Buffer.alloc(0));
|
|
84
|
+
}
|
|
85
|
+
witnessStack.push(witnessScript);
|
|
86
|
+
return witnessStack;
|
|
87
|
+
}
|
|
88
|
+
static validateP2WDASignature(publicKey, dataSignature, operationData) {
|
|
89
|
+
return dataSignature.length === 64;
|
|
90
|
+
}
|
|
91
|
+
static estimateP2WDAWitnessSize(dataSize = 0) {
|
|
92
|
+
return 72 + dataSize + 39 + 12;
|
|
93
|
+
}
|
|
94
|
+
static couldBeP2WDA(scriptPubKey) {
|
|
95
|
+
return scriptPubKey.length === 34 && scriptPubKey[0] === 0x00 && scriptPubKey[1] === 0x20;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -26,7 +26,7 @@ export interface BitcoinTransferBase {
|
|
|
26
26
|
readonly nextUTXOs: UTXO[];
|
|
27
27
|
}
|
|
28
28
|
export interface InteractionResponse {
|
|
29
|
-
readonly fundingTransaction: string;
|
|
29
|
+
readonly fundingTransaction: string | null;
|
|
30
30
|
readonly interactionTransaction: string;
|
|
31
31
|
readonly estimatedFees: bigint;
|
|
32
32
|
readonly nextUTXOs: UTXO[];
|
|
@@ -45,7 +45,9 @@ export declare class TransactionFactory {
|
|
|
45
45
|
private detectInteractionOPWallet;
|
|
46
46
|
private detectDeploymentOPWallet;
|
|
47
47
|
private createFundTransaction;
|
|
48
|
+
private hasP2WDAInputs;
|
|
48
49
|
private writePSBTHeader;
|
|
50
|
+
private signP2WDAInteraction;
|
|
49
51
|
private getPriorityFee;
|
|
50
52
|
private getUTXOAsTransaction;
|
|
51
53
|
}
|
|
@@ -4,6 +4,8 @@ import { DeploymentTransaction } from './builders/DeploymentTransaction.js';
|
|
|
4
4
|
import { FundingTransaction } from './builders/FundingTransaction.js';
|
|
5
5
|
import { InteractionTransaction } from './builders/InteractionTransaction.js';
|
|
6
6
|
import { TransactionBuilder } from './builders/TransactionBuilder.js';
|
|
7
|
+
import { P2WDADetector } from '../p2wda/P2WDADetector.js';
|
|
8
|
+
import { InteractionTransactionP2WDA } from './builders/InteractionTransactionP2WDA.js';
|
|
7
9
|
export class TransactionFactory {
|
|
8
10
|
async createCustomScriptTransaction(interactionParameters) {
|
|
9
11
|
if (!interactionParameters.to) {
|
|
@@ -84,6 +86,10 @@ export class TransactionFactory {
|
|
|
84
86
|
if (!('signer' in interactionParameters)) {
|
|
85
87
|
throw new Error('Field "signer" not provided, OP_WALLET not detected.');
|
|
86
88
|
}
|
|
89
|
+
const useP2WDA = this.hasP2WDAInputs(interactionParameters.utxos);
|
|
90
|
+
if (useP2WDA) {
|
|
91
|
+
return this.signP2WDAInteraction(interactionParameters);
|
|
92
|
+
}
|
|
87
93
|
const inputs = this.parseOptionalInputs(interactionParameters.optionalInputs);
|
|
88
94
|
const preTransaction = new InteractionTransaction({
|
|
89
95
|
...interactionParameters,
|
|
@@ -121,7 +127,7 @@ export class TransactionFactory {
|
|
|
121
127
|
...this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.to, 0),
|
|
122
128
|
],
|
|
123
129
|
randomBytes: preTransaction.getRndBytes(),
|
|
124
|
-
challenge: preTransaction.
|
|
130
|
+
challenge: preTransaction.getChallenge(),
|
|
125
131
|
nonWitnessUtxo: signedTransaction.tx.toBuffer(),
|
|
126
132
|
estimatedFees: preTransaction.estimatedFees,
|
|
127
133
|
optionalInputs: inputs,
|
|
@@ -133,7 +139,7 @@ export class TransactionFactory {
|
|
|
133
139
|
interactionTransaction: outTx.toHex(),
|
|
134
140
|
estimatedFees: preTransaction.estimatedFees,
|
|
135
141
|
nextUTXOs: this.getUTXOAsTransaction(signedTransaction.tx, interactionParameters.from, 1),
|
|
136
|
-
challenge: preTransaction.
|
|
142
|
+
challenge: preTransaction.getChallenge().toRaw(),
|
|
137
143
|
};
|
|
138
144
|
}
|
|
139
145
|
async signDeployment(deploymentParameters) {
|
|
@@ -189,7 +195,7 @@ export class TransactionFactory {
|
|
|
189
195
|
...deploymentParameters,
|
|
190
196
|
utxos: [newUtxo],
|
|
191
197
|
randomBytes: preTransaction.getRndBytes(),
|
|
192
|
-
challenge: preTransaction.
|
|
198
|
+
challenge: preTransaction.getChallenge(),
|
|
193
199
|
nonWitnessUtxo: signedTransaction.toBuffer(),
|
|
194
200
|
estimatedFees: preTransaction.estimatedFees,
|
|
195
201
|
optionalInputs: inputs,
|
|
@@ -211,7 +217,7 @@ export class TransactionFactory {
|
|
|
211
217
|
contractAddress: finalTransaction.getContractAddress(),
|
|
212
218
|
contractPubKey: finalTransaction.contractPubKey,
|
|
213
219
|
utxos: [refundUTXO],
|
|
214
|
-
challenge: preTransaction.
|
|
220
|
+
challenge: preTransaction.getChallenge().toRaw(),
|
|
215
221
|
};
|
|
216
222
|
}
|
|
217
223
|
async createBTCTransfer(parameters) {
|
|
@@ -307,6 +313,9 @@ export class TransactionFactory {
|
|
|
307
313
|
nextUTXOs: this.getUTXOAsTransaction(signedTransaction, parameters.to, 0),
|
|
308
314
|
};
|
|
309
315
|
}
|
|
316
|
+
hasP2WDAInputs(utxos) {
|
|
317
|
+
return utxos.some((utxo) => P2WDADetector.isP2WDAUTXO(utxo));
|
|
318
|
+
}
|
|
310
319
|
writePSBTHeader(type, psbt) {
|
|
311
320
|
const buf = Buffer.from(psbt, 'base64');
|
|
312
321
|
const header = Buffer.alloc(2);
|
|
@@ -314,6 +323,28 @@ export class TransactionFactory {
|
|
|
314
323
|
header.writeUInt8(currentConsensus, 1);
|
|
315
324
|
return Buffer.concat([header, buf]).toString('hex');
|
|
316
325
|
}
|
|
326
|
+
async signP2WDAInteraction(interactionParameters) {
|
|
327
|
+
if (!interactionParameters.from) {
|
|
328
|
+
throw new Error('Field "from" not provided.');
|
|
329
|
+
}
|
|
330
|
+
if (!('signer' in interactionParameters)) {
|
|
331
|
+
throw new Error('P2WDA interactions require a signer. OP_WALLET is not supported for P2WDA.');
|
|
332
|
+
}
|
|
333
|
+
const inputs = this.parseOptionalInputs(interactionParameters.optionalInputs);
|
|
334
|
+
const p2wdaTransaction = new InteractionTransactionP2WDA({
|
|
335
|
+
...interactionParameters,
|
|
336
|
+
optionalInputs: inputs,
|
|
337
|
+
});
|
|
338
|
+
const signedTx = await p2wdaTransaction.signTransaction();
|
|
339
|
+
const txHex = signedTx.toHex();
|
|
340
|
+
return {
|
|
341
|
+
fundingTransaction: null,
|
|
342
|
+
interactionTransaction: txHex,
|
|
343
|
+
estimatedFees: p2wdaTransaction.estimatedFees,
|
|
344
|
+
nextUTXOs: this.getUTXOAsTransaction(signedTx, interactionParameters.from, signedTx.outs.length - 1),
|
|
345
|
+
challenge: interactionParameters.challenge.toRaw(),
|
|
346
|
+
};
|
|
347
|
+
}
|
|
317
348
|
getPriorityFee(params) {
|
|
318
349
|
const totalFee = params.priorityFee + params.gasSatFee;
|
|
319
350
|
if (totalFee < TransactionBuilder.MINIMUM_DUST) {
|
|
@@ -4,13 +4,13 @@ import { P2TRPayment, Psbt } from '@btc-vision/bitcoin';
|
|
|
4
4
|
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
5
5
|
import { TapLeafScript } from '../interfaces/Tap.js';
|
|
6
6
|
import { Address } from '../../keypair/Address.js';
|
|
7
|
-
import { ITimeLockOutput } from '../mineable/TimelockGenerator.js';
|
|
8
7
|
import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
|
|
8
|
+
import { IP2WSHAddress } from '../mineable/IP2WSHAddress.js';
|
|
9
9
|
export declare class DeploymentTransaction extends TransactionBuilder<TransactionType.DEPLOYMENT> {
|
|
10
10
|
static readonly MAXIMUM_CONTRACT_SIZE: number;
|
|
11
11
|
type: TransactionType.DEPLOYMENT;
|
|
12
12
|
protected readonly challenge: ChallengeSolution;
|
|
13
|
-
protected readonly epochChallenge:
|
|
13
|
+
protected readonly epochChallenge: IP2WSHAddress;
|
|
14
14
|
protected readonly _contractAddress: Address;
|
|
15
15
|
protected tapLeafScript: TapLeafScript | null;
|
|
16
16
|
private readonly deploymentVersion;
|
|
@@ -31,7 +31,7 @@ export declare class DeploymentTransaction extends TransactionBuilder<Transactio
|
|
|
31
31
|
get contractAddress(): Address;
|
|
32
32
|
get p2trAddress(): string;
|
|
33
33
|
getRndBytes(): Buffer;
|
|
34
|
-
|
|
34
|
+
getChallenge(): ChallengeSolution;
|
|
35
35
|
getContractAddress(): string;
|
|
36
36
|
protected contractSignerXOnlyPubKey(): Buffer;
|
|
37
37
|
protected buildTransaction(): Promise<void>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import { Psbt } from '@btc-vision/bitcoin';
|
|
3
|
+
import { TransactionType } from '../enums/TransactionType.js';
|
|
4
|
+
import { IInteractionParameters } from '../interfaces/ITransactionParameters.js';
|
|
5
|
+
import { TransactionBuilder } from './TransactionBuilder.js';
|
|
6
|
+
import { ChallengeSolution } from '../../epoch/ChallengeSolution.js';
|
|
7
|
+
import { IP2WSHAddress } from '../mineable/IP2WSHAddress.js';
|
|
8
|
+
export declare class InteractionTransactionP2WDA extends TransactionBuilder<TransactionType.INTERACTION> {
|
|
9
|
+
private static readonly MAX_WITNESS_FIELDS;
|
|
10
|
+
private static readonly MAX_BYTES_PER_WITNESS;
|
|
11
|
+
readonly type: TransactionType.INTERACTION;
|
|
12
|
+
protected readonly epochChallenge: IP2WSHAddress;
|
|
13
|
+
protected readonly disableAutoRefund: boolean;
|
|
14
|
+
private readonly contractAddress;
|
|
15
|
+
private readonly contractSecret;
|
|
16
|
+
private readonly calldata;
|
|
17
|
+
private readonly challenge;
|
|
18
|
+
private readonly randomBytes;
|
|
19
|
+
private p2wdaGenerator;
|
|
20
|
+
private scriptSigner;
|
|
21
|
+
private p2wdaInputIndices;
|
|
22
|
+
private readonly compiledOperationData;
|
|
23
|
+
constructor(parameters: IInteractionParameters);
|
|
24
|
+
getRndBytes(): Buffer;
|
|
25
|
+
getChallenge(): ChallengeSolution;
|
|
26
|
+
getContractSecret(): Buffer;
|
|
27
|
+
protected buildTransaction(): Promise<void>;
|
|
28
|
+
protected createMineableRewardOutputs(): Promise<void>;
|
|
29
|
+
protected signInputs(transaction: Psbt): Promise<void>;
|
|
30
|
+
private generateFeatures;
|
|
31
|
+
private generateKeyPairFromSeed;
|
|
32
|
+
private scriptSignerXOnlyPubKey;
|
|
33
|
+
private validateP2WDAInputs;
|
|
34
|
+
private validateOperationDataSize;
|
|
35
|
+
private finalizePrimaryP2WDA;
|
|
36
|
+
private splitIntoWitnessChunks;
|
|
37
|
+
}
|